From 56f6aefac8e1aace28b7940f6b203c5bd9053ead Mon Sep 17 00:00:00 2001 From: zongor Date: Sun, 23 Feb 2025 21:07:33 -0500 Subject: [PATCH] migrate from icloud --- Makefile | 13 +++ compiler.f90 | 277 +++++++++++++++++++++++++++++++++++++++++++++++++++ favicon.ico | Bin 0 -> 25418 bytes index.html | 30 ++++++ main.f90 | 167 +++++++++++++++++++++++++++++++ module.wasm | Bin 0 -> 42 bytes style.css | 150 ++++++++++++++++++++++++++++ test.vq | 1 + varaq | Bin 0 -> 68176 bytes 9 files changed, 638 insertions(+) create mode 100644 Makefile create mode 100644 compiler.f90 create mode 100644 favicon.ico create mode 100644 index.html create mode 100644 main.f90 create mode 100644 module.wasm create mode 100644 style.css create mode 100644 test.vq create mode 100644 varaq diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a66cf7b --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +FC = gfortran +FCFLAGS = -O + +all: varaq + +varaq: + $(FC) $(FCFLAGS) -o varaq compiler.f90 main.f90 + +test: + ./varaq ./test.vq ./module.wasm && http-server . + +clean: + rm -f *.o *.mod varaq diff --git a/compiler.f90 b/compiler.f90 new file mode 100644 index 0000000..94d72ef --- /dev/null +++ b/compiler.f90 @@ -0,0 +1,277 @@ +module tokenizer_mod + implicit none + + type token + character(:), allocatable :: type + character(:), allocatable :: value + integer :: index + end type token + +contains + + type(token) function init_token(type, value, index) result(this) + character(:), allocatable :: type + character(:), allocatable :: value + integer :: index + + this%type = type + this%value = value + this%index = index + end function + + function tokenize(code) result(tokens) + character(:), allocatable :: code + type(token), dimension(:), allocatable :: tokens + integer :: pos1 = 1, pos2 + + do + pos2 = scan(code(pos1:), " \n\t\v\f\r") + if (pos2 == 0) then + tokens = [tokens, token("expression", code(pos1:), pos1)] + return + end if + + tokens = [tokens, token("expression", code(pos1:pos1+pos2-2), pos1)] + pos1 = pos2+pos1 + end do + + end function tokenize + + pure logical function isAlpha(c) + character, intent(in) :: c + isAlpha = (c .ge. 'a' .and. c .le. 'z') .or. (c .ge. 'A' .and. c .le. 'Z') .or. c .eq. '_' .or. c .eq. "'" .or. c .eq. '?' + end function isAlpha + + pure logical function isDigit(c) + character, intent(in) :: c + isDigit = (c .ge. '0' .and. c .le. '9') .or. c .eq. '-' + end function isDigit + +end module tokenizer_mod + +module parser_mod + implicit none + +contains + +end module parser_mod + +module opcodes_mod + implicit none + character, parameter :: UNREACHABLE = achar(0) + character, parameter :: NOP = achar(1) + character, parameter :: BLOCK = achar(2) + character, parameter :: LOOP = achar(3) + character, parameter :: IF = achar(4) + character, parameter :: ELSE = achar(5) + character, parameter :: TRY = achar(6) ! PROPOSED + character, parameter :: CATCH = achar(7) ! PROPOSED + character, parameter :: THROW = achar(8) ! PROPOSED + character, parameter :: RETHROW = achar(9) ! PROPOSED + character, parameter :: BR_ON_EXN = achar(10) ! PROPOSED + character, parameter :: END = achar(11) + character, parameter :: BR = achar(12) + character, parameter :: BR_IF = achar(13) + character, parameter :: BR_TABLE = achar(14) + character, parameter :: RETURN = achar(15) + character, parameter :: CALL = achar(16) + character, parameter :: CALL_INDIRECT = achar(17) + character, parameter :: RETURN_CALL = achar(18) ! PROPOSED + character, parameter :: RETURN_CALL_INDIRECT = achar(19) ! PROPOSED + character, parameter :: DROP = achar(26) + character, parameter :: SELECT = achar(27) + character, parameter :: SELECT_T = achar(28) ! PROPOSED + character, parameter :: LOCAL_GET = achar(32) + character, parameter :: LOCAL_SET = achar(33) + character, parameter :: LOCAL_TEE = achar(34) + character, parameter :: GLOBAL_GET = achar(35) + character, parameter :: GLOBAL_SET = achar(36) + character, parameter :: TABLE_GET = achar(37) ! PROPOSED + character, parameter :: TABLE_SET = achar(38) ! PROPOSED + character, parameter :: I32_LOAD = achar(40) + character, parameter :: I64_LOAD = achar(41) + character, parameter :: F32_LOAD = achar(42) + character, parameter :: F64_LOAD = achar(43) + character, parameter :: I32_LOAD8_S = achar(44) + character, parameter :: I32_LOAD8_U = achar(45) + character, parameter :: I32_LOAD16_S = achar(46) + character, parameter :: I32_LOAD16_U = achar(47) + character, parameter :: I64_LOAD8_S = achar(48) + character, parameter :: I64_LOAD8_U = achar(49) + character, parameter :: I64_LOAD16_S = achar(50) + character, parameter :: I64_LOAD16_U = achar(51) + character, parameter :: I64_LOAD32_S = achar(52) + character, parameter :: I64_LOAD32_U = achar(53) + character, parameter :: I32_STORE = achar(54) + character, parameter :: I64_STORE = achar(55) + character, parameter :: F32_STORE = achar(56) + character, parameter :: F64_STORE = achar(57) + character, parameter :: I32_STORE8 = achar(58) + character, parameter :: I32_STORE16 = achar(59) + character, parameter :: I64_STORE8 = achar(60) + character, parameter :: I64_STORE16 = achar(61) + character, parameter :: I64_STORE32 = achar(62) + character, parameter :: MEMORY_SIZE = achar(63) + character, parameter :: MEMORY_GROW = achar(64) + character, parameter :: I32_CONST = achar(65) + character, parameter :: I64_CONST = achar(66) + character, parameter :: F32_CONST = achar(67) + character, parameter :: F64_CONST = achar(68) + character, parameter :: I32_EQZ = achar(69) + character, parameter :: I32_EQ = achar(70) + character, parameter :: I32_NE = achar(71) + character, parameter :: I32_LT_S = achar(72) + character, parameter :: I32_LT_U = achar(73) + character, parameter :: I32_GT_S = achar(74) + character, parameter :: I32_GT_U = achar(75) + character, parameter :: I32_LE_S = achar(76) + character, parameter :: I32_LE_U = achar(77) + character, parameter :: I32_GE_S = achar(78) + character, parameter :: I32_GE_U = achar(79) + character, parameter :: I64_EQZ = achar(80) + character, parameter :: I64_EQ = achar(81) + character, parameter :: I64_NE = achar(82) + character, parameter :: I64_LT_S = achar(83) + character, parameter :: I64_LT_U = achar(84) + character, parameter :: I64_GT_S = achar(85) + character, parameter :: I64_GT_U = achar(86) + character, parameter :: I64_LE_S = achar(87) + character, parameter :: I64_LE_U = achar(88) + character, parameter :: I64_GE_S = achar(89) + character, parameter :: I64_GE_U = achar(90) + character, parameter :: F32_EQ = achar(91) + character, parameter :: F32_NE = achar(92) + character, parameter :: F32_LT = achar(93) + character, parameter :: F32_GT = achar(94) + character, parameter :: F32_LE = achar(95) + character, parameter :: F32_GE = achar(96) + character, parameter :: F64_EQ = achar(97) + character, parameter :: F64_NE = achar(98) + character, parameter :: F64_LT = achar(99) + character, parameter :: F64_GT = achar(100) + character, parameter :: F64_LE = achar(101) + character, parameter :: F64_GE = achar(102) + character, parameter :: I32_CLZ = achar(103) + character, parameter :: I32_CTZ = achar(104) + character, parameter :: I32_POPCNT = achar(105) + character, parameter :: I32_ADD = achar(106) + character, parameter :: I32_SUB = achar(107) + character, parameter :: I32_MUL = achar(108) + character, parameter :: I32_DIV_S = achar(109) + character, parameter :: I32_DIV_U = achar(110) + character, parameter :: I32_REM_S = achar(111) + character, parameter :: I32_REM_U = achar(112) + character, parameter :: I32_AND = achar(113) + character, parameter :: I32_OR = achar(114) + character, parameter :: I32_XOR = achar(115) + character, parameter :: I32_SHL = achar(116) + character, parameter :: I32_SHR_S = achar(117) + character, parameter :: I32_SHR_U = achar(118) + character, parameter :: I32_ROTL = achar(119) + character, parameter :: I32_ROTR = achar(120) + character, parameter :: I64_CLZ = achar(121) + character, parameter :: I64_CTZ = achar(122) + character, parameter :: I64_POPCNT = achar(123) + character, parameter :: I64_ADD = achar(124) + character, parameter :: I64_SUB = achar(125) + character, parameter :: I64_MUL = achar(126) + character, parameter :: I64_DIV_S = achar(127) + character, parameter :: I64_DIV_U = achar(128) + character, parameter :: I64_REM_S = achar(129) + character, parameter :: I64_REM_U = achar(130) + character, parameter :: I64_AND = achar(131) + character, parameter :: I64_OR = achar(132) + character, parameter :: I64_XOR = achar(133) + character, parameter :: I64_SHL = achar(134) + character, parameter :: I64_SHR_S = achar(135) + character, parameter :: I64_SHR_U = achar(136) + character, parameter :: I64_ROTL = achar(137) + character, parameter :: I64_ROTR = achar(138) + character, parameter :: F32_ABS = achar(139) + character, parameter :: F32_NEG = achar(140) + character, parameter :: F32_CEIL = achar(141) + character, parameter :: F32_FLOOR = achar(142) + character, parameter :: F32_TRUNC = achar(143) + character, parameter :: F32_NEAREST = achar(144) + character, parameter :: F32_SQRT = achar(145) + character, parameter :: F32_ADD = achar(146) + character, parameter :: F32_SUB = achar(147) + character, parameter :: F32_MUL = achar(148) + character, parameter :: F32_DIV = achar(149) + character, parameter :: F32_MIN = achar(150) + character, parameter :: F32_MAX = achar(151) + character, parameter :: F32_COPYSIGN = achar(152) + character, parameter :: F64_ABS = achar(153) + character, parameter :: F64_NEG = achar(154) + character, parameter :: F64_CEIL = achar(155) + character, parameter :: F64_FLOOR = achar(156) + character, parameter :: F64_TRUNC = achar(157) + character, parameter :: F64_NEAREST = achar(158) + character, parameter :: F64_SQRT = achar(159) + character, parameter :: F64_ADD = achar(160) + character, parameter :: F64_SUB = achar(161) + character, parameter :: F64_MUL = achar(162) + character, parameter :: F64_DIV = achar(163) + character, parameter :: F64_MIN = achar(164) + character, parameter :: F64_MAX = achar(165) + character, parameter :: F64_COPYSIGN = achar(166) + character, parameter :: I32_WRAP_I64 = achar(167) + character, parameter :: I32_TRUNC_F32_S = achar(168) + character, parameter :: I32_TRUNC_F32_U = achar(169) + character, parameter :: I32_TRUNC_F64_S = achar(170) + character, parameter :: I32_TRUNC_F64_U = achar(171) + character, parameter :: I64_EXTEND_I32_S = achar(172) + character, parameter :: I64_EXTEND_I32_U = achar(173) + character, parameter :: I64_TRUNC_F32_S = achar(174) + character, parameter :: I64_TRUNC_F32_U = achar(175) + character, parameter :: I64_TRUNC_F64_S = achar(176) + character, parameter :: I64_TRUNC_F64_U = achar(177) + character, parameter :: F32_CONVERT_I32_S = achar(178) + character, parameter :: F32_CONVERT_I32_U = achar(179) + character, parameter :: F32_CONVERT_I64_S = achar(180) + character, parameter :: F32_CONVERT_I64_U = achar(181) + character, parameter :: F32_DEMOTE_F64 = achar(182) + character, parameter :: F64_CONVERT_I32_S = achar(183) + character, parameter :: F64_CONVERT_I32_U = achar(184) + character, parameter :: F64_CONVERT_I64_S = achar(185) + character, parameter :: F64_CONVERT_I64_U = achar(186) + character, parameter :: F64_PROMOTE_F32 = achar(187) + character, parameter :: I32_REINTERPRET_F32 = achar(188) + character, parameter :: I64_REINTERPRET_F64 = achar(189) + character, parameter :: F32_REINTERPRET_I32 = achar(190) + character, parameter :: F64_REINTERPRET_I64 = achar(191) +end module opcodes_mod + +module types_mod + implicit none + ! https://webassembly.github.io/spec/core/binary/types.html + character, parameter :: i32 = achar(127) + character, parameter :: i64 = achar(126) + character, parameter :: f32 = achar(125) + character, parameter :: f64 = achar(124) + + ! http://webassembly.github.io/spec/core/binary/types.html#function-types + character, parameter :: type_function = achar(96) + + character, parameter :: type_empty_array = achar(0) + + ! http://webassembly.github.io/spec/core/binary/modules.html#export-section + character, parameter :: export_func = achar(0) + character, parameter :: export_table = achar(1) + character, parameter :: export_mem = achar(2) + character, parameter :: export_global = achar(3) + + ! https://webassembly.github.io/spec/core/binary/modules.html#sections + character, parameter :: section_custom = achar(0) + character, parameter :: section_type = achar(1) + character, parameter :: section_import = achar(2) + character, parameter :: section_func = achar(3) + character, parameter :: section_table = achar(4) + character, parameter :: section_memory = achar(5) + character, parameter :: section_global = achar(6) + character, parameter :: section_export = achar(7) + character, parameter :: section_start = achar(8) + character, parameter :: section_element = achar(9) + character, parameter :: section_code = achar(10) + character, parameter :: section_data = achar(11) +end module types_mod diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..236b619e2fb4d24c11b9dbd46c7af6c6a92c12af GIT binary patch literal 25418 zcmeI4517_fmB%lPyJNI9TKc4AjUfplCL$mTIs+0c3W$n|XgZ)-W+r6@D=Y(y0%^;* zYFe6qG8I!d9t;02CH^a2%s(aDw%aP3?qgeOlWDS>%k1~_dw=Jh^WOLOd*69`Cx)J9 z@ADk)x#ymH&bjCQJNN$HA%p>8r?AVeLHXX{&YeP-5<=Kxk3xC%J3@F}w7vH(lyBQ5 zgbUvt!o=1>dD!F-1~-Q=Ol?#Z1`Ck$r%HeL+5FI#u#wSDQW_&OYss1kO5TY@qz=k4kATKYnVijIUliIjsC*OH#k-uGwL7%ZLQP(R=CQ ziQ&o>lXKf&f60^pz>D6KjyWhCchtzl4rtV&!}mesvYTLoV1i(sm51&-BrN~@5ebO) zEx{zgeFBE`3Bd=DqeS}$1dj;bpO!aZ>+d(WB_P`S1dj^t7jz2FetzT0i5M2L%fR>jlFZ|GCGG5}NdXFL-ZS^VebPPv=2P+QWmt zt*m^kV549$ePCWF;lI87+)_Ddk4?8-F%2Hd^z&Ll^OV*Dk}*j8mb3@Y0_KJv-`4TN z17N(=`Ff*Ue*ZUSCVnBuzt{sXm#uEY&BqkwSv#LI$KdyT;K;MN>G|u$ySqckf`;WG zG<1aUUd_r~UJha8CsPm}^RriJdkZ54mG-K7ZQW7ZvrnV9qfm!jY)^^pVWir$;qPMt~I;g&>_hl z_ix{y6F#B2$C`iaj^o0nyN*xlPCfqMKpnc^W$k9k%A#TWd1s6(;YThyfQN58wxo`8 z0vobqK~q{Scs#|~Kz=XS$J2j&&xzsCG5aL|u5`QLX+eWvj$murezfra6-+aI!jb<& zfll!7E5R4AM=8;ZJnUY3`LuxVz?ImaUlp7uI7#r9V4&ci1UH-PR3~yC7F;FRBxo2j zYN)b;eB^y}#76?-41lLP+Qh@Ytd$sE7n~*dwP3dl`Ok@tUk;o)=>Th=*pFX4KRC2w zr?GmIa|l1t@0SE~V_wmaqg^AcWWL*(ozfp?p3vr!3tJNahc;vCfno_C7Q88-{oVA9 z@%B1INB)a~osIrI?SCo#56ZtJ7=%v%<|cgDlKN?}>KW4yvDVPB=5Hqzb%>t$!DN%a z_S9)2C-g1K8MEgF(@Y0E^dXgBoIlW6)2vOCr*?__f4I6Q*16%*sUjEX%9$6R68uJR zyI@b+vQA?8$bfdw4KvH+vkvL|UDr;xu}kz)R%#M3zwq<2?|yxH!pmAyO6;dCGQ6GG zp_ItMCl`KZLb9)y3V+8{Bxwm00(qJgpMW-aubt z9_$8UI=r>)(b(?yL(Ugu;4=WfcpdB+@tX4WG0vR8PJF=`g+Gvso;QBdmiV6ifjMmR zkui_uR4UV!F=UTn-;8-VPuL&efj6$NR%V{D-&8u6=o>s)bF!NJzN+t5;FJZIE!j1! zSke$yENuuY+Z)50_NK6=xiehfbVInlL2#s?Q9!xnhD;gA9j1x9x1d!}DGpP0%|7lc zAM~g0zUssFkn?c>6V^N&b) zpZreYzF%v<;is?k$G4@Q=gu#j&-mtBR~F*FGfy5<<`>$+>)Y3Yb2px;y)df{ea`ZQ z=RIM@L19Ykh|Kn$FAqmIGP3He-`H@=-v>~qOjehL|+|xPlZ=;>kUkEk}h+B#0 zOX|^w-hbCy#EXy3O>o9Si5LnwN2hX#=_y~7mO0P=OYpK_S7<4{M84`43TSr$F{4tk zo_U9E-XZV-01i#bV*eL}ze5n~zgjfp&NkhV{##V{LBSh>Cj||u+@gNU0Dc`ca%ckJ zMpv6Q0Xi-g@X!LT8+>95vG6*tJJNrh>emX0tw%bUCHjB*z)59ug0Xz`9lXoB(;~Cx1|oyrHpnjXy(w ztFQa*GpDOrQU4>tcfMxT$BMdbjG)nuy)X5_K=D2yKtJnf2=%sic|WMm`gf1lZMdsP z*3Si#O|Rv4_o5B^-pR9)H@->YrOo9gi?f3^?5##qz3ETZztPFzclA#TXJ0_(&4S%c zznwMo3mP^kjTXS0tbgROPgC#DQq>prv*-EweW~I^UoV`!iF*$|IdS>#I-l zKK?~-7kxN-@<&w_to}~nlkMzf&t+br8=7wmt~5ljUT|t$*PAk9=-0JxWA{IF$L|Kl z#~zRuzZg%YoWAG9A6~zY1-(3Uvln|>Ejasn9RKl-gioyBW=CH9=l8i_}x6X@A*+ZoL&$O{<%J@!{2-TlQJj+10qbb8BNq=hmi<&bOOZ zt$Mq;vtwIJ=Q7}kmd-B=RtuIbZRuRTt)+9-ww7wbd8e2tSSG0UP9c_J>Mx&dFTKT% zW+28!{T!%gd+|ep2#%W==%0od%g|V(&w1BFMPoFVzVtT=T22iY|T94_hEVRjDFLa z{P%&luX*KqeZcP*%pP)nD{$|PGxaTTYB=ZgLy~XgzW&^K2H`dDT(6PfaY*`SS-0znRFBSB+k;54=6t7wdcJu~U-YISkpS=R421(Zj;VwX@22 z*-QA{rSJQ~v&Uzyf7YJy!4vDPrChHMY!8??VgHJDFjn#0zApXEDE6|ptxx2vovima z-#6Yo;Kip~|2g~jW1c?`ug3@cwrk&y6vmhNo2SFm?d{$A%lzi|j#eh;_c6Xr9?rV6 zcAOb`eAVdn_<(UT8}hzyW$FL^EwjRi;f3F6S$lHUOD%i7pF6eex3Nw2_<+7xAJ$(t zqo#3SFZF)l_eHgirPrUe7sY+eE7#)#_J8w1t>eI6K)Hu<7hj%Xheyy5s>6#g#b6JAjU=ce_Y{mkCUp=J3&@@{gvuxUQJ z{5%ki4-4MzvbSy3j}h>#)A;y(T7#g(e=1hAAKgmp1SW@kx*rFXb7gqDS^umFVroAp zm|y14RNs3g)4p$@kKc8^$H!(WSM-7E2MV4PnBB?u+*E$7FW3H*f4Y-{ytRxU`@PvM zTBZzQ1s^962U{Cr1DhMPAHMCG$XapNZ;MnQqaGcBFmGv_GvI zB=#4atXG65-yMCNB3h;lVhC(z?K6gEgXN6B%?IuWMz>sYzw31K9r+OC;a8;*u8y%O z`at*|0=~D~94Ps&EqaMA6=VAsIvZ9xImr7su?%+1p5F6)B}2v{A0N?A;%M5?9srMH zYud2JSU=1Qr4I`DowN1jDd7$HONk!{7@hnSXZNkH4&Sv{9XTl~$3FOc%EvSH{|HP^ z^1apKl+gzbO=5ZC8>LvrBAc`I6 z;YK5$DcDJ1zZZb^pMs`8!Uyxz?kItm|5;lDv7M}SrA!}WoqMr8R`&ZHcM{gbd1oA& zyirI#6Jo2tY`RSNo~{i2V}f|j%rf~t7hkn`FiR}_{=)SAQ20RKciZb3W9|@2Wj^rx zh1XvRrww|DCplA$H`TGk*@Qp%=502Tvq1R0m(lL9_HizrqHOAvV*4)<&E)*I@Zs3S zKE%D5_?9yP8t+CqG8S!lxaT)Zu?=};`fa`@j`Do6gWsh5*x7cua38l_>grw-{yyK{ z~u`Vbp`M8hY=Xf7@ zyXX6P%X)|9%z=k9 z6`kx0R+g?c0<$qI-vBQ%^6q39Y<(eD%JKm*_BhWMPW7!DsG!o!8^1S6=79pQ=X7tcpQrJAi`rH5L2)g6nOV5~ep@0d`2ag#5zMpx zWaU{tuy_IfjDC!eOz(r@oe5j{K4p3`{MTnbu)Qk72iJ<`?|f$KM$w0vZ9XRs@_y#6 z&ezBHO3A6{1Mk0hovCe!E*0Z3?A1K*ZzFj!L?`C_g}{73PTaLZu(S2i-^0xhS!apu ziSQ`p`oPXon2-WSC8$=|H{v)#T+`FUY)`r+p#SjH~a#^2wtpV*CW zNY)o}=DzV)%6)7mojW<3v42pdw!Tihz0&8~818=ufw)@}b)iMubx%K$KukBjqFfqK1U!2z>$KRc*{f;m0w=dV@1KuXB554(4 z9kD+5ENer~T=IJxG=I)|TVverl&q=VoFj32E7#)#WLS*Eo!Vq(<;+#%rJvZ%o@Ts$ zT~W_B-D+cNZ%e(2B}`9NUat=re{2Sro3ReoOMIuW`(?~q%Wrl4dh)*mie>huT(1v^ z70n0a#BRh(_$KT7JomwBcG(>Fa*4(1D}J{4kb1t+ReB$(ri=P|eSi$VKYP19&RocQ zN6E62b>QCuy)2K{dLCuz>I)wrm$;YrYdh~)@637T19Ln}cW-FKjEuYAOBj1}`B=L* zvhsNP$_FN&*q1)X-?OZ~o}BjzeA3sl``QQf^s&F%;sa8D>F;m7h29tb?QdK9OTYI4 zcz@Z^UwY&I`*MHTw7vBDz8Y@-kHRt${@n2`T_fAO8#^}Amn~fj+PfP%mM8d@uJ-PZ zj*bN1DEy(0h6H~|_{NUL1n&^OWkpjD9twD)=v|>Xp@VM?EeYP_@Mhs}hxUXHzAbbo zc#Ff^yYzon3@FgsyPCVZmlyEvuEy@}4#OK9uJI_+TU&bYw&osuQDYCjq@f32>hMJl hZ*%;?$qDT}Z3lGs;NCXbT(qa%@a{Cx-# + + + + + + + + +
+
+ + + +
+
+ + + diff --git a/main.f90 b/main.f90 new file mode 100644 index 0000000..872d6e4 --- /dev/null +++ b/main.f90 @@ -0,0 +1,167 @@ +program varaq_wasm_compiler + use types_mod + use opcodes_mod + use tokenizer_mod + implicit none + + integer :: u, ios + character, dimension(:), allocatable :: tape + + character, dimension(4) :: magic_module_header = [ achar(0), achar(97), achar(115), achar(109) ] + character, dimension(4) :: module_version = [ achar(1), achar(0), achar(0), achar(0) ] + character, dimension(:), allocatable :: add_function_type + character, dimension(:), allocatable :: type_section + character, dimension(:), allocatable :: func_section + character, dimension(:), allocatable :: export_section + character, dimension(:), allocatable :: code_code + character, dimension(:), allocatable :: function_body + character, dimension(:), allocatable :: code_section + character, allocatable :: main_string(:) + character(len = :), allocatable :: main_text + integer :: a, b + + character(:), allocatable :: input_code + type(token), dimension(:), allocatable :: tokens + character(256) :: file_input, file_output + integer :: i, sz + + call getarg(1, file_input) + call getarg(2, file_output) + + open(u, file=file_input) + inquire(unit=u, size=sz) + close(u) + + allocate(character(len=sz) :: input_code) + + open(unit=u,file=file_input, status='old', access='stream') + do i=1,sz + read(u) input_code(i:i) + end do + + tokens = tokenize(input_code) + + do i=1,size(tokens) + print *, tokens(i)%index, tokens(i)%value, " ", tokens(i)%type + end do + + add_function_type = [type_function, encodeVector([f32, f32]), encodeVector([f32])] + + ! the type section is a vector of function types + type_section = createSection(section_type, encodeVector(add_function_type, 1)) + + ! the function section is a vector of type indices that indicate the type of each function + ! in the code section + func_section = createSection(section_func, encodeVector([achar(0)])) + + ! the export section is a vector of exported functions + main_text = "main" + main_string = transfer(main_text, ' ', size = len(main_text)) + + export_section = createSection(section_export, encodeVector([encodeString(main_string), export_func, achar(0)], 1)) + a = 0 + b = 1 + code_code = [LOCAL_GET, unsignedLEB128(a), LOCAL_GET, unsignedLEB128(b), F32_ADD] + function_body = encodeVector([type_empty_array, code_code, END]) + code_section = createSection(section_code, encodeVector([function_body], 1)) + + tape = [magic_module_header] + tape = [tape, module_version] + tape = [tape, type_section] + tape = [tape, func_section] + tape = [tape, export_section] + tape = [tape, code_section] + + open(unit=u, file=file_output, access='stream', status='replace', action='write', iostat=ios) + write(u, iostat=ios) tape + close(u, iostat=ios) + + deallocate(tape) + +contains + +function signedLEB128(n) result(buffer) + logical :: more + integer :: n + character :: byte + character, dimension(:), allocatable :: buffer + + more = .true. + do while (more) + byte = achar(iand(n, 127)) + n = rshift(n, 7) + if (((n .ne. 0) .and. (iand(ichar(byte), 64) .eq. 0) .or. ((n .eq. -1) .and. (iand(ichar(byte), 64) .ne. 0)))) then + more = .false. + else + byte = achar(ior(ichar(byte), 128)) + end if + + if (allocated(buffer)) then + buffer = [buffer, byte] + else + buffer = [byte] + end if + end do +end function signedLEB128 + +function unsignedLEB128(n) result(buffer) + integer :: n + character :: byte + character, dimension(:), allocatable :: buffer + + do + byte = achar(iand(n, 127)) + n = rshift(n, 7) + if (n .ne. 0) then + byte = achar(ior(ichar(byte), 128)) + end if + if (allocated(buffer)) then + buffer = [buffer, byte] + else + buffer = [byte] + end if + if (n .eq. 0) then + exit + end if + end do +end function unsignedLEB128 + +function encodeString(data, length) result(arr) + character, dimension(:) :: data + character, dimension(:), allocatable :: arr + integer, optional :: length + integer :: length_local + + if (present(length)) then + length_local = length + else + length_local = size(data) + end if + + arr = [unsignedLEB128(length_local), data] +end function encodeString + +function encodeVector(data, length) result(arr) + character, dimension(:) :: data + character, dimension(:), allocatable :: arr + integer, optional :: length + integer :: length_local + + if (present(length)) then + length_local = length + else + length_local = size(data) + end if + + arr = [unsignedLEB128(length_local), data] +end function encodeVector + +function createSection(section, data) result (arr) + character, dimension(:) :: data + character, dimension(:), allocatable :: arr + character :: section + + arr = [section, encodeVector(data)] +end function createSection + +end program varaq_wasm_compiler diff --git a/module.wasm b/module.wasm new file mode 100644 index 0000000000000000000000000000000000000000..40ef229d45ff1b895a39cb75efcfb5b5395ab37a GIT binary patch literal 42 xcmZQbEY4+QU|?WmXG~zKt!1obW@2Pu=U`;XP0Y+=VBq3pWM@!dP+*+I4FHEG1>OJv literal 0 HcmV?d00001 diff --git a/style.css b/style.css new file mode 100644 index 0000000..592355d --- /dev/null +++ b/style.css @@ -0,0 +1,150 @@ +* { + box-sizing: border-box; +} + +@media (prefers-color-scheme: light) { + body { + background-color: white; + color: black; + margin-top: 0px; + margin-left: 0px; + margin-right: 0px; + } + /* Header/logo Title */ + .header { + padding: 60px; + text-align: center; + background: #ddd; + color: black; + width: 100%; + } + + /* Style the top navigation bar */ + .navbar { + display: flex; + flex-flow: row wrap; + justify-content: flex-start; + background-color: #eee; + width: 100%; + } + + /* Style the navigation bar links */ + .navbar a { + color: black; + padding: 10px; + text-decoration: none; + text-align: center; + } + + /* Change color on hover */ + .navbar a:hover { + background-color: #ddd; + color: black; + } + + .navbar a.active { + background-color: #ccc; + color: #222; + } + + /* Column container */ + .row { + display: flex; + flex-wrap: wrap; + } + + /* Main column */ + .main { + flex: 70%; + background-color: white; + padding: 20px; + } + + /* Footer */ + .footer { + padding: 20px; + text-align: center; + background: #ddd; + position: fixed; + left: 0; + bottom: 0; + width: 100%; + } +} + +@media (prefers-color-scheme: dark) { + body { + background-color: black; + color: #ddd; + margin-top: 0px; + margin-left: 0px; + margin-right: 0px; + } + /* Header/logo Title */ + .header { + padding: 60px; + text-align: center; + background: #111; + color: #ddd; + width: 100%; + } + + /* Style the top navigation bar */ + .navbar { + display: flex; + flex-flow: row wrap; + justify-content: flex-start; + background-color: #222; + width: 100%; + } + + /* Style the navigation bar links */ + .navbar a { + color: #ddd; + padding: 14px 20px; + text-decoration: none; + text-align: center; + } + + /* Change color on hover */ + .navbar a:hover { + background-color: #111; + color: #ddd; + } + + .navbar a.active { + background-color: #ccc; + color: #222; + } + + /* Column container */ + .row { + display: flex; + flex-wrap: wrap; + } + + /* Main column */ + .main { + flex: 70%; + background-color: #000; + padding: 20px; + } + + /* Footer */ + .footer { + padding: 20px; + text-align: center; + background: #111; + position: fixed; + left: 0; + bottom: 0; + width: 100%; + } +} + +@media screen and (max-width: 700px) { + .row, + .navbar { + flex-direction: column; + } +} diff --git a/test.vq b/test.vq new file mode 100644 index 0000000..620d2ad --- /dev/null +++ b/test.vq @@ -0,0 +1 @@ +1 2 add disp \ No newline at end of file diff --git a/varaq b/varaq new file mode 100644 index 0000000000000000000000000000000000000000..1f8e8b73c53b347b5783cfdf2b180ccc0fc7c58f GIT binary patch literal 68176 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