From aa8101de1d3ed62a5e7629504b6b5f45e95438cb Mon Sep 17 00:00:00 2001 From: Mohit Karekar Date: Thu, 22 May 2025 21:37:56 +0200 Subject: [PATCH 1/3] Tuples and type improvement --- a.out | Bin 0 -> 33544 bytes examples/test_2 | Bin 0 -> 33544 bytes examples/test_2.gom | 1 + examples/test_2.s | 147 +++ examples/test_3 | Bin 0 -> 33528 bytes examples/test_3.gom | 30 + examples/test_3.ll | 110 ++ package-lock.json | 41 +- package.json | 2 + run.ts | 17 +- src/codegen/llvm.ts | 181 ++- src/parser/rd/index.ts | 140 ++- src/parser/rd/nodes/index.ts | 156 ++- src/parser/rd/tree.ts | 7 +- src/parser/rd/visitor.ts | 21 + src/semantics/index.ts | 55 +- src/semantics/scope.ts | 51 +- src/semantics/type.ts | 76 +- src/util/error.ts | 6 +- test_2 | Bin 0 -> 33544 bytes tree.json | 2212 +++++++++++++--------------------- 21 files changed, 1787 insertions(+), 1466 deletions(-) create mode 100755 a.out create mode 100755 examples/test_2 create mode 100644 examples/test_2.s create mode 100755 examples/test_3 create mode 100644 examples/test_3.gom create mode 100644 examples/test_3.ll create mode 100755 test_2 diff --git a/a.out b/a.out new file mode 100755 index 0000000000000000000000000000000000000000..4ea0e71b4d8a2be2ca98bdc31f7eefeebf248677 GIT binary patch literal 33544 zcmeI5U2IfE6vyZ8w$QSLR@wljKvxq?wb&vUK|bV`QYk_xmYP(E4%_Z6-L%~<-CZdy zV)+b)7m6kFqG&LY5{<_2;5CsnAsP)aSR-JJXrUN(5ll(yLkVR)XYSqY?xONwqA&lG zoI7*QnLTsncke#V%(>e)@8$@h2@(hC1EhfrA@&J3^@Mnkw2D;9_2sK7H&)hEvo}@L zk5gUuSe)kv8YpFLWnFD*Sp8m4^$FX~BzIhSgp?tpBg8#R((|<}vlg@0E{bhlS3)vG zccM=nDTASKeK6rl&o}&xm5&%HVLLfrmYpvim$D%kYWMlK*yGdl-Ldmk*m1U#B{?_y zr40MG`TSn#^Eb9BJC&cl+^Vn1PQrG24m+e8DUBxC*zRdHEN^;!C+vLjSH!k6DS=Cf z_*BZv@AW9Dlq<_?%VkCNx((J(b^D{DR!LgRIa&EN<&jFcr7h{T{%yW28mmN4t!n}~ z?N_eC1d7c!ao9pARh8MoTwwuVVBb!;zApMGL zu3_FTA#`eqlUPrhEb;F+Ie&7T`^EJ8zj}XDDCQ>R@2o5wY%go^)t7mPxkLY(WZ`)i zk#dadb9l>XIofzFRL_R(!I05fx}uco^3~HIl1E56e}6YIruI?WW?n3_NI4#$bsx2g zWH$r^KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`; zKmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1pX5Ou?jITm@CXku5Lz2#jDwc z5o$_w$>WtSayQC!P*CE{nqz*v`~Z?I69my3jXC103B(`jrW<;quMn;^ZLDC$d~)T`T%xXY4umXp}RvuUK@~MAitiirZ>oHgQ`a%mdu666W9< z-Mn0_n^!7yb7+-rUgCL{3p2W0HzUsMlaYyHlmH$Q!%KQ-|7dSyqCOgRik@Q4_IsE1 zP+g-BQA~{skex3^Y42xmlyXNXceI4oQbsvxjtI>WT|o9in!AMNE~B{@(A*1k^EA&* z>sEO>miExT)ZXi~R$8B$Gvb_dlINwpxV?k<`e+8VV_lVfu|1mNOnXf~&U5Ia!clZ# zr7sxr_!|s&y%E}G7=Cx)3Ae}ZbqD4zc8fV)F-hDrqNUUxLmeKa_R`LzVpx(}-XqI< z&vj~9dEYpTuAbu$-iMn*JE3RTyR4T|%0s-xHcvPTXp1xLKUQ0Hd5$L8j@epX zPLZ0A_v2n2iz%s9Bj`~zW!~G`TMn*A?b*F+#Ye{Dn>ijgsqIecqYDBc00JNY0w4ea zAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd& z00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0wC}|5OC9+>q+ZK`3mmjYq;tBgoN-} z194G(olaTM;~x9B@lyq4pxx&WH725(6m7I9PxvM08ce|TzroXpN$#u#^ol?~) z?K)FP-2OSIpVA(tr19JZpoSyyC`5oCG%`X{VcD;Ff^BeoG&KtTE9(efr+JhT2cJBM|wGTe2Yx^?V*q?E6 zV4&GiU6&c#acW2Bz8^n7SoQkc_wN^<_1@;^j;#3U+pk@YMaR#*<1vg`6ZUD8@G zGP}Lzi|2ni|J(jsM;e{)&YkeoNJCNMt;w!WzyJOCcbj$({(9JP>gN6O|J(Q<(}r(c kYpD)3U(jB7v3S?9g-4H_`Yg+}DYM}5tItMe?6GM53ApYUVE_OC literal 0 HcmV?d00001 diff --git a/examples/test_2 b/examples/test_2 new file mode 100755 index 0000000000000000000000000000000000000000..6277a727cd6f6374038e9d87941582bbb545834b GIT binary patch literal 33544 zcmeI5Uu@G=6vywc-C(1G4K@KCWAyum{@S%g<-tT>z9%`q zd(Szy=brod{rY(CJ$38aojf5lL1H5vPwLMSVz+QoPl)?TYe=PBQ@OnQx$3%F_NI&a zak}d+i}U zSF%qXDTAT5#$eKwneWCE@qENc3EQdpa;$ubxRg!7P{8ZkXpPUzciYNWWyRS}mDJqq zm$J>b)$4OhudjKtveWtLi{tfqtR!q_=CDGlk<#$U=76i!h2-}F zr}fHJc;vfXwPN+k>ZL0Z3+l?Ki)@x0YmuBIHP53$ba8$B)$qdSTDFJm2C|v;WYVw6 z<{D=26hfz#IEgi+sgn4PQ}d_BxnD-V|Eu>mj$%$y{?5wVf`RfDZ)3T8TZ@})mSR$_ z5u?T-Bs@~HJu%Th+`<2<+Nf0HUa z?*dYeaeX#-B`rrAsfFrUyDbW z;zhC>0sSe+G-d+r+<#q<#Rjz6^}W^G`AQd?i$fD%Nj!+9;NouPN8C0Qd{05 z%X`mtYFT;TIE${HBM;t(n@2mLCtJI$7g5T6yv4Ra*otV2GwnZCTXlJlEQ{7rC$#pd zT0vf^nveJ6UK)-msaGTDQ8RA#8`|qOu1D?Jy%UcQj>I=`JYiDXmC{ES1V8`;KmY_l z00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck) z1V8`;KmY_l00ck)1V8`;KmY_l00ck)1V8`;KmY_l;C~?Cq&e4+Hjwfa+^N@a)AkBm}qnZ?S{zLroaJ$&kNyi!-<;QJ)T80)sqX%G`yU0$D<6x`D03K;R@7Or+oaq_tbJZ-)fKP7?d zpQvmh_Rtv&Z1er-`P4aT+0!hW?>XoAbj#*58`!3M-nr$jlEmHZPP&=??m8vcDU)?d zRj0J-Oe1mYm%M&Tdw`NAau<=0%GY)X8_~9@rAUhN>tM+hVyE9}Q&+#oJ^%RBc3EL9 zWCTO9LbzVJG{$><@6#_W`{HciWXr9CC7;jPdSLwViqnJLADEtV@9%i;!-maYMVtGx z&JGN0vehP?qnlvHiGylP=< z(csiT-Iq`O`u*=O-aOcBe{065d4o-*%{Rw7KK}0dk#E<(5dLky?ZmZv<^Q+wKPKL| ldby=GwCRkt?%A@Phvy$UeBzTF$NKD|nU|JDCU+}be*$*o96kU5 literal 0 HcmV?d00001 diff --git a/examples/test_2.gom b/examples/test_2.gom index cd20e9c..429da07 100644 --- a/examples/test_2.gom +++ b/examples/test_2.gom @@ -1,5 +1,6 @@ import io; +// struct type Point = { x: int, y: int diff --git a/examples/test_2.s b/examples/test_2.s new file mode 100644 index 0000000..122037f --- /dev/null +++ b/examples/test_2.s @@ -0,0 +1,147 @@ + .section __TEXT,__text,regular,pure_instructions + .build_version macos, 14, 0 + .globl _square ; -- Begin function square + .p2align 2 +_square: ; @square + .cfi_startproc +; %bb.0: ; %entry + sub sp, sp, #16 + .cfi_def_cfa_offset 16 + mov w8, w0 + mul w0, w0, w0 + str w8, [sp, #12] + add sp, sp, #16 + ret + .cfi_endproc + ; -- End function + .globl _add ; -- Begin function add + .p2align 2 +_add: ; @add + .cfi_startproc +; %bb.0: ; %entry + sub sp, sp, #16 + .cfi_def_cfa_offset 16 + mov w8, w0 + add w0, w0, w1 + stp w1, w8, [sp, #8] + add sp, sp, #16 + ret + .cfi_endproc + ; -- End function + .globl _distance ; -- Begin function distance + .p2align 2 +_distance: ; @distance + .cfi_startproc +; %bb.0: ; %entry + sub sp, sp, #48 + stp x20, x19, [sp, #16] ; 16-byte Folded Spill + stp x29, x30, [sp, #32] ; 16-byte Folded Spill + .cfi_def_cfa_offset 48 + .cfi_offset w30, -8 + .cfi_offset w29, -16 + .cfi_offset w19, -24 + .cfi_offset w20, -32 + sub w8, w0, w2 + stp w0, w1, [sp, #8] + mov w0, w8 + stp w2, w3, [sp] + bl _square + ldr w8, [sp, #12] + mov w19, w0 + ldr w9, [sp, #4] + sub w0, w8, w9 + bl _square + add w0, w19, w0 + ldp x29, x30, [sp, #32] ; 16-byte Folded Reload + ldp x20, x19, [sp, #16] ; 16-byte Folded Reload + add sp, sp, #48 + ret + .cfi_endproc + ; -- End function + .globl _main ; -- Begin function main + .p2align 2 +_main: ; @main + .cfi_startproc +; %bb.0: ; %entry + sub sp, sp, #96 + stp x22, x21, [sp, #48] ; 16-byte Folded Spill + stp x20, x19, [sp, #64] ; 16-byte Folded Spill + stp x29, x30, [sp, #80] ; 16-byte Folded Spill + .cfi_def_cfa_offset 96 + .cfi_offset w30, -8 + .cfi_offset w29, -16 + .cfi_offset w19, -24 + .cfi_offset w20, -32 + .cfi_offset w21, -40 + .cfi_offset w22, -48 + mov x8, #1 + mov x9, #3 + movk x8, #2, lsl #32 + movk x9, #4, lsl #32 + mov w0, #1 + mov w1, #2 + mov w2, #3 + mov w3, #4 + stp x9, x8, [sp, #32] + bl _distance + mov w19, w0 + str w0, [sp, #28] +Lloh0: + adrp x0, l_.strliteral@PAGE +Lloh1: + add x0, x0, l_.strliteral@PAGEOFF + bl _printf +Lloh2: + adrp x20, l_fmt.int@PAGE + str x19, [sp] +Lloh3: + add x20, x20, l_fmt.int@PAGEOFF + mov x0, x20 + bl _printf +Lloh4: + adrp x19, l_newline@PAGE +Lloh5: + add x19, x19, l_newline@PAGEOFF + mov x0, x19 + bl _printf + ldp w0, w1, [sp, #40] + ldp w2, w3, [sp, #32] + stp w0, w1, [sp, #8] + stp w2, w3, [sp, #16] + bl _distance + mov w21, w0 +Lloh6: + adrp x0, l_.strliteral.1@PAGE +Lloh7: + add x0, x0, l_.strliteral.1@PAGEOFF + bl _printf + mov x0, x20 + str x21, [sp] + bl _printf + mov x0, x19 + bl _printf + ldp x29, x30, [sp, #80] ; 16-byte Folded Reload + ldp x20, x19, [sp, #64] ; 16-byte Folded Reload + ldp x22, x21, [sp, #48] ; 16-byte Folded Reload + add sp, sp, #96 + ret + .loh AdrpAdd Lloh6, Lloh7 + .loh AdrpAdd Lloh4, Lloh5 + .loh AdrpAdd Lloh2, Lloh3 + .loh AdrpAdd Lloh0, Lloh1 + .cfi_endproc + ; -- End function + .section __TEXT,__cstring,cstring_literals +l_.strliteral: ; @.strliteral + .asciz "Distance between p1 and p2: " + +l_fmt.int: ; @fmt.int + .asciz "%d" + +l_newline: ; @newline + .asciz "\n" + +l_.strliteral.1: ; @.strliteral.1 + .asciz "Distance between l.p1 and l.p2: " + +.subsections_via_symbols diff --git a/examples/test_3 b/examples/test_3 new file mode 100755 index 0000000000000000000000000000000000000000..e1ac3e982fbe7335685c62edf532b8ce99d0de26 GIT binary patch literal 33528 zcmeI5U2IfE6vyZ87T8KDg%G~6tEpI&vPW{mI$S3`_O>NwB6pNtKD|ly_>eQ z$|Au?NK6-s;s-{9Q7~xy=mRy9v@tO}X^RSKjC>>{tppN`L6?NC=ghr#yIZV0_+U)_ zCpkNF=FB~F<~MgA&)jcrT^r32LK7q|(ixVEAnzGuOOt*So&m0rBJ&A@Lqv*HmWC2Xh1^Vsnmzm&d+84k4Uu;-7Dx6F>W%=WXLF6ps( zT*_!mTcD*;23q{B%Fg6hXUA)@gRnh5hV4>~ltz>EhwFoeH99`OGj_a3?T6TQrv;cQ zgtL?y<#RnkD&@w~no_x8Yeltny1M;RQLAKJ%Q0E`nDR)a+|inLtP{rb&|D>YW?qwN z&^~hI9(!*$Z>o5zY~v;?E5WCq@xGDG@}~`red%$CLyYs|=Xm2QY`clhC*A+Y+5O)xr!g<7wI)Z&Reg1)+Nk>>8d3YBmZgyP$8oyXDl_%N z>#ihaALr+4ET!#gW4Ta1)g2Mj2o|j`qPzkPG>K#}DaSt*6N1lfiET44mPMrOucLh* zv6AFr2nc`x2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=9 z00@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*>muLvYJh@p#ak+?KPB!;Kx ziEJv@Tr#jG?$NTZ)@!1M$|z@zxb=i*UaYE66McmuR^`#eOxD5~Vii3f?{~{{&b-3q z);!My^OAdMJzDG1bdk6`NA&S?!*ldLinlZ9tVelFxZYlCy%C!8(%K2uvgahf6hpT= zT_-O3M4Z;?zOR2xyn*t%kW9WhvOw<}c4vPu%=?b$tA;5TI=F7Jup~Z5h#qD!;udk* zb3%7)8|cb=Czl^sYbWwcIWyNl#Aj-^{F4{x%7l^ z<)3RZ&Cu%N;4^SI(lV-?1OA)6Jnu>A9*}nric@==NtW!ObJ}3fC;V44P|bS+reMLTkTQ z%gf0ZydKx5c{M2t*kHd~bU#Nw?{?8oZ>J{1h8gYKEfj9$YZWBlzaZ$chu+RmvlDK*X5D_kxz8q@&KF0}_siMlI}q6ByB65y@13(< zVEg$q=VY==3GbKHOJAVBGa0Fpp{=DQlVRCg8Qc7=Uvl~>{2>bItTBtmh=R6TxM(Gp zA|lDp_*v*Wk3Dr>m-^JZHS&+Y8eIvYL^F+uDOZSB9`Sv#__5e~@3KBZt1;IeKic{MU*rS=UQW Ky!QF?3f5mI@z?kO literal 0 HcmV?d00001 diff --git a/examples/test_3.gom b/examples/test_3.gom new file mode 100644 index 0000000..f749932 --- /dev/null +++ b/examples/test_3.gom @@ -0,0 +1,30 @@ +import io; + +// tuple +type HttpResponse = { int, bool }; + +fn process_http(url: str): HttpResponse { + if(url == "http://www.example.com") { + return { 200, true }; + } + + return { 401, false }; +} + +fn process_http_retry(url: str, retries: int): HttpResponse { + let i = 0; + for(i = retries; i > 0; i = i - 1) { + io.log("Round: ", i); + let resp = process_http(url); + if(resp.1) { + return resp; + } + } + + return { 500, false }; +} + +fn main() { + let resp = process_http_retry("http://www.example.com", 3); + io.log("Status: ", resp.0, " Success: ", resp.1); +} \ No newline at end of file diff --git a/examples/test_3.ll b/examples/test_3.ll new file mode 100644 index 0000000..f8dc67f --- /dev/null +++ b/examples/test_3.ll @@ -0,0 +1,110 @@ +; ModuleID = 'mod' +source_filename = "mod" + +@.strliteral = private unnamed_addr constant [23 x i8] c"http://www.example.com\00", align 1 +@.strliteral.1 = private unnamed_addr constant [8 x i8] c"Round: \00", align 1 +@fmt.int = private unnamed_addr constant [3 x i8] c"%d\00", align 1 +@newline = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@.strliteral.2 = private unnamed_addr constant [23 x i8] c"http://www.example.com\00", align 1 +@.strliteral.3 = private unnamed_addr constant [9 x i8] c"Status: \00", align 1 +@.strliteral.4 = private unnamed_addr constant [11 x i8] c" Success: \00", align 1 +@fmt.bool = private unnamed_addr constant [3 x i8] c"%d\00", align 1 + +declare i32 @printf(i8*, ...) + +define void @process_http({ i32, i1 }* "noalias" "sret" %0, i8* %1) { +entry: + %2 = alloca i8*, align 8 + store i8* %1, i8** %2, align 8 + %url.load = load i8*, i8** %2, align 8 + %eqtmp = icmp eq i8* %url.load, getelementptr inbounds ([23 x i8], [23 x i8]* @.strliteral, i32 0, i32 0) + br i1 %eqtmp, label %then, label %else + +then: ; preds = %entry + %fieldptr = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 0 + store i32 200, i32* %fieldptr, align 4 + %fieldptr1 = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 1 + store i1 true, i1* %fieldptr1, align 1 + ret void + br label %merge + +else: ; preds = %entry + br label %merge + +merge: ; preds = %else, %then + %fieldptr2 = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 0 + store i32 401, i32* %fieldptr2, align 4 + %fieldptr3 = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 1 + store i1 false, i1* %fieldptr3, align 1 + ret void +} + +define void @process_http_retry({ i32, i1 }* "noalias" "sret" %0, i8* %1, i32 %2) { +entry: + %3 = alloca i8*, align 8 + store i8* %1, i8** %3, align 8 + %4 = alloca i32, align 4 + store i32 %2, i32* %4, align 4 + %i = alloca i32, align 4 + store i32 0, i32* %i, align 4 + %retries.load = load i32, i32* %4, align 4 + store i32 %retries.load, i32* %i, align 4 + br label %loop + +loop: ; preds = %loopupdate, %entry + %i.load = load i32, i32* %i, align 4 + %gttmp = icmp sgt i32 %i.load, 0 + br i1 %gttmp, label %loopbody, label %afterloop + +loopbody: ; preds = %loop + %i.load1 = load i32, i32* %i, align 4 + %calltmp0 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.strliteral.1, i32 0, i32 0)) + %calltmp1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @fmt.int, i32 0, i32 0), i32 %i.load1) + %newline = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @newline, i32 0, i32 0)) + %resp = alloca { i32, i1 }, align 8 + %url.load = load i8*, i8** %3, align 8 + call void @process_http({ i32, i1 }* %resp, i8* %url.load) + %fieldptr = getelementptr { i32, i1 }, { i32, i1 }* %resp, i32 0, i32 1 + %fieldload = load i1, i1* %fieldptr, align 1 + br i1 %fieldload, label %then, label %else + +loopupdate: ; preds = %merge + %i.load2 = load i32, i32* %i, align 4 + %subtmp = sub i32 %i.load2, 1 + store i32 %subtmp, i32* %i, align 4 + br label %loop + +afterloop: ; preds = %loop + %fieldptr3 = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 0 + store i32 500, i32* %fieldptr3, align 4 + %fieldptr4 = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 1 + store i1 false, i1* %fieldptr4, align 1 + ret void + +then: ; preds = %loopbody + %resp.load = load { i32, i1 }, { i32, i1 }* %resp, align 4 + ret { i32, i1 } %resp.load + br label %merge + +else: ; preds = %loopbody + br label %merge + +merge: ; preds = %else, %then + br label %loopupdate +} + +define void @main() { +entry: + %resp = alloca { i32, i1 }, align 8 + call void @process_http_retry({ i32, i1 }* %resp, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.strliteral.2, i32 0, i32 0), i32 3) + %fieldptr = getelementptr { i32, i1 }, { i32, i1 }* %resp, i32 0, i32 0 + %fieldload = load i32, i32* %fieldptr, align 4 + %fieldptr1 = getelementptr { i32, i1 }, { i32, i1 }* %resp, i32 0, i32 1 + %fieldload2 = load i1, i1* %fieldptr1, align 1 + %calltmp0 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.strliteral.3, i32 0, i32 0)) + %calltmp1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @fmt.int, i32 0, i32 0), i32 %fieldload) + %calltmp2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.strliteral.4, i32 0, i32 0)) + %calltmp3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @fmt.bool, i32 0, i32 0), i1 %fieldload2) + %newline = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @newline, i32 0, i32 0)) + ret void +} diff --git a/package-lock.json b/package-lock.json index 3dd32b8..0791c63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,24 @@ { - "name": "gom", - "version": "0.0.1", + "name": "gom-lang", + "version": "0.0.2", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "gom", - "version": "0.0.1", + "name": "gom-lang", + "version": "0.0.2", "license": "ISC", "dependencies": { + "chalk": "^5.4.1", "commander": "^13.1.0", "cors": "^2.8.5", "llvm-bindings": "github:TypeFox/llvm-bindings", + "ts-pattern": "^5.6.2", "typescript": "^5.4.5" }, + "bin": { + "gomc": "run.sh" + }, "devDependencies": { "@changesets/cli": "^2.28.1", "@hono/node-server": "^1.13.8", @@ -1793,6 +1798,18 @@ "node": "*" } }, + "node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -4506,6 +4523,12 @@ } } }, + "node_modules/ts-pattern": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.6.2.tgz", + "integrity": "sha512-d4IxJUXROL5NCa3amvMg6VQW2HVtZYmUTPfvVtO7zJWGYLJ+mry9v2OmYm+z67aniQoQ8/yFNadiEwtNS9qQiw==", + "license": "MIT" + }, "node_modules/tsx": { "version": "4.19.2", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", @@ -6580,6 +6603,11 @@ "traverse": ">=0.3.0 <0.4" } }, + "chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==" + }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -8545,6 +8573,11 @@ "yn": "3.1.1" } }, + "ts-pattern": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.6.2.tgz", + "integrity": "sha512-d4IxJUXROL5NCa3amvMg6VQW2HVtZYmUTPfvVtO7zJWGYLJ+mry9v2OmYm+z67aniQoQ8/yFNadiEwtNS9qQiw==" + }, "tsx": { "version": "4.19.2", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", diff --git a/package.json b/package.json index 3eec672..f77e5f1 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,11 @@ "author": "", "license": "ISC", "dependencies": { + "chalk": "^5.4.1", "commander": "^13.1.0", "cors": "^2.8.5", "llvm-bindings": "github:TypeFox/llvm-bindings", + "ts-pattern": "^5.6.2", "typescript": "^5.4.5" }, "devDependencies": { diff --git a/run.ts b/run.ts index 0fbd5aa..dac1253 100755 --- a/run.ts +++ b/run.ts @@ -1,7 +1,22 @@ #!/usr/bin/env tsx import { runCompile } from "./src/index"; +import { execSync } from "child_process"; const filePath = process.argv[2]; const target = (process.argv[3] || "c") as "c" | "llvm"; -(async () => await runCompile(filePath, target))(); +(async () => { + await runCompile(filePath, target); + + if (target === "llvm") { + // compile using clang + execSync( + `clang -o ${filePath.replace(".gom", "")} ${filePath.replace( + ".gom", + ".ll" + )}`, + { stdio: "inherit" } + ); + console.log(`✅ Executable generated at: ${filePath.replace(".gom", "")}`); + } +})(); diff --git a/src/codegen/llvm.ts b/src/codegen/llvm.ts index 1250d9c..a841b9f 100644 --- a/src/codegen/llvm.ts +++ b/src/codegen/llvm.ts @@ -18,14 +18,17 @@ import { NodeReturnStatement, NodeStructInit, NodeTerm, + NodeTupleLiteral, NodeTypeDefinition, } from "../parser/rd/nodes"; import { ScopeManager } from "../semantics/scope"; import { + GomCompositeType, GomFunctionType, GomPrimitiveTypeOrAlias, GomPrimitiveTypeOrAliasValue, GomStructType, + GomTupleType, GomType, GomTypeKind, } from "../semantics/type"; @@ -33,6 +36,8 @@ import { GomToken } from "../lexer/tokens"; import { GomErrorManager } from "../util/error"; import { Node } from "../parser/rd/tree"; import { BaseCodeGenerator } from "./common"; +import { match } from "ts-pattern"; +import { instanceOf } from "ts-pattern/dist/patterns"; export enum LLVMType { I8 = "int", @@ -40,6 +45,11 @@ export enum LLVMType { VOID = "void", } +type ExpressionContext = Partial<{ + declLhs: NodeTerm; + pointer: llvm.Value; +}>; + /** * Generates LLVM IR - todo to use llvm bindings */ @@ -104,11 +114,22 @@ export class CodeGenerator extends BaseCodeGenerator { return llvm.Type.getFloatTy(this.context); case "void": return llvm.Type.getVoidTy(this.context); + case "bool": + return llvm.Type.getInt1Ty(this.context); + case "str": + return llvm.Type.getInt8PtrTy(this.context); default: throw new Error("Unknown type: " + type.toStr()); } } + private mapGomTupleTypeToLLVMType(type: GomTupleType) { + const types = Array.from(type.fields).map((t) => + this.mapGomTypeToLLVMType(t[1]) + ); + return llvm.StructType.get(this.context, types); + } + private mapGomStructTypeToLLVMType(type: GomStructType) { const structType = this.structTypes[type.name]; if (!structType) { @@ -118,11 +139,13 @@ export class CodeGenerator extends BaseCodeGenerator { return structType; } - private mapGomTypeToLLVMType(type: GomType) { + private mapGomTypeToLLVMType(type: GomType): llvm.Type { if (type instanceof GomPrimitiveTypeOrAlias) { return this.mapGomPrimitiveTypeToLLVMType(type); } else if (type instanceof GomStructType) { return this.mapGomStructTypeToLLVMType(type); + } else if (type instanceof GomTupleType) { + return this.mapGomTupleTypeToLLVMType(type); } throw new Error("Unknown type: " + type.toStr()); @@ -186,9 +209,12 @@ export class CodeGenerator extends BaseCodeGenerator { } override generate(): string { - console.log("Generating code..."); this.symbolTableReader.enterScope("global"); this.writeGlobalVariables(); + // Somehow this works now + // Global functions have to be written here as writing format + // strings in the global scope causes an error + this.writeGlobalFunctions(); this.visit(this.ast); this.symbolTableReader.exitScope(); return this.module.print(); @@ -220,14 +246,23 @@ export class CodeGenerator extends BaseCodeGenerator { visitFunctionDefinition(node: NodeFunctionDefinition): void { this.symbolTableReader.enterScope(node.name.value); this.irScopeManager.enterScope(node.name.value); - const returnType = this.mapGomTypeToLLVMType( - (node.resultantType as GomFunctionType).returnType - ); + const fnType = node.resultantType as GomFunctionType; + const returnTypeGom = fnType.returnType; + const returnType = this.mapGomTypeToLLVMType(returnTypeGom); const argsType = (node.resultantType as GomFunctionType).args.map((arg) => this.mapGomTypeToLLVMType(arg as GomPrimitiveTypeOrAlias) ); - const funcType = llvm.FunctionType.get(returnType, argsType, false); + if (fnType.usesSret()) { + const sretArgType = llvm.PointerType.getUnqual(returnType); + argsType.unshift(sretArgType); + } + + const funcType = llvm.FunctionType.get( + fnType.usesSret() ? llvm.Type.getVoidTy(this.context) : returnType, + argsType, + false + ); const fn = llvm.Function.Create( funcType, llvm.Function.LinkageTypes.ExternalLinkage, @@ -235,14 +270,20 @@ export class CodeGenerator extends BaseCodeGenerator { this.module ); + if (fnType.usesSret()) { + fn.addParamAttr(0, llvm.Attribute.get(this.context, "sret")); + fn.addParamAttr(0, llvm.Attribute.get(this.context, "noalias")); + } + const entry = llvm.BasicBlock.Create(this.context, "entry", fn); this.builder.SetInsertPoint(entry); node.args.forEach((arg, i) => { - const alloca = this.builder.CreateAlloca(argsType[i], null); + const index = fnType.usesSret() ? i + 1 : i; + const alloca = this.builder.CreateAlloca(argsType[index], null); const argId = this.symbolTableReader.getIdentifier(arg.name.token.value); - this.builder.CreateStore(fn.getArg(i), alloca); + this.builder.CreateStore(fn.getArg(index), alloca); if (argId) { argId.allocaInst = alloca; @@ -269,10 +310,6 @@ export class CodeGenerator extends BaseCodeGenerator { this.module ); - // Global functions have to be written here as writing format - // strings in the global scope causes an error - this.writeGlobalFunctions(); - const entry = llvm.BasicBlock.Create(this.context, "entry", mainFunction); this.builder.SetInsertPoint(entry); @@ -307,7 +344,7 @@ export class CodeGenerator extends BaseCodeGenerator { continue; } - this.builder.SetInsertPoint(this.currentFunctionEntry); + // this.builder.SetInsertPoint(this.currentFunctionEntry); const type = this.mapGomTypeToLLVMType(decl.lhs.resultantType); const alloca = this.builder.CreateAlloca( @@ -321,7 +358,10 @@ export class CodeGenerator extends BaseCodeGenerator { id.allocaInst = alloca; } - const rhsValue = this.visitExpression(decl.rhs, decl.lhs); + const rhsValue = this.visitExpression(decl.rhs, { + declLhs: decl.lhs, + pointer: alloca, + }); if (!type.isStructTy()) { this.builder.CreateStore(rhsValue, alloca); @@ -342,8 +382,18 @@ export class CodeGenerator extends BaseCodeGenerator { } if (node.expr) { - const exprValue = this.visitExpression(node.expr); - this.builder.CreateRet(exprValue); + console.log("return statement", node.expr); + if (node.expr.resultantType instanceof GomPrimitiveTypeOrAlias) { + const exprValue = this.visitExpression(node.expr); + this.builder.CreateRet(exprValue); + } else { + const fn = this.currentFunction; + const sretPointer = fn.getArg(0); + this.visitExpression(node.expr, { + pointer: sretPointer, + }); + this.builder.CreateRetVoid(); + } } else { this.builder.CreateRetVoid(); } @@ -442,9 +492,13 @@ export class CodeGenerator extends BaseCodeGenerator { this.builder.CreateCondBr(condValue, bodyBB, afterBB); this.builder.SetInsertPoint(bodyBB); + this.symbolTableReader.enterScope("for"); + this.irScopeManager.enterScope("for"); node.body.forEach((stmt) => this.visit(stmt)); - + this.symbolTableReader.exitScope(); + this.irScopeManager.exitScope(); this.builder.CreateBr(updateBB); + this.builder.SetInsertPoint(updateBB); this.visitExpression(node.updateExpr); this.builder.CreateBr(loopBB); @@ -465,7 +519,11 @@ export class CodeGenerator extends BaseCodeGenerator { this.builder.CreateBr(loopBB); this.builder.SetInsertPoint(loopBB); + this.symbolTableReader.enterScope("for"); + this.irScopeManager.enterScope("for"); node.body.forEach((stmt) => this.visit(stmt)); + this.symbolTableReader.exitScope(); + this.irScopeManager.exitScope(); this.builder.CreateBr(loopBB); // later for break; @@ -473,19 +531,21 @@ export class CodeGenerator extends BaseCodeGenerator { } } - visitExpression(expr: NodeExpr, declLhs?: NodeTerm): llvm.Value { + visitExpression(expr: NodeExpr, context?: ExpressionContext): llvm.Value { if (expr instanceof NodeAccess) { return this.visitAccess(expr); } else if (expr instanceof NodeBinaryOp) { return this.visitBinaryOp(expr); } else if (expr instanceof NodeCall) { - return this.visitCall(expr); + return this.visitCall(expr, context); } else if (expr instanceof NodeTerm) { return this.visitTerm(expr); } else if (expr instanceof NodeAssignment) { return this.visitAssignment(expr); } else if (expr instanceof NodeStructInit) { - return this.visitStructInit(expr, declLhs); + return this.visitStructInit(expr, context); + } else if (expr instanceof NodeTupleLiteral) { + return this.visitTupleLiteral(expr, context); } else if (expr instanceof NodeExprBracketed) { return this.visitExpression(expr.expr); } @@ -507,14 +567,19 @@ export class CodeGenerator extends BaseCodeGenerator { return rhsValue; } - visitStructInit(node: NodeStructInit, declLhs?: NodeTerm): llvm.Value { - if (!declLhs) { + visitStructInit( + node: NodeStructInit, + context?: ExpressionContext + ): llvm.Value { + if (!context?.declLhs) { this.errorManager.throwCodegenError({ loc: node.loc, message: "Struct init without declaration", }); } - const structId = this.symbolTableReader.getIdentifier(declLhs.token.value); + const structId = this.symbolTableReader.getIdentifier( + context.declLhs.token.value + ); if (!structId) { this.errorManager.throwCodegenError({ loc: node.loc, @@ -544,12 +609,35 @@ export class CodeGenerator extends BaseCodeGenerator { return structAlloca; } + visitTupleLiteral( + node: NodeTupleLiteral, + context?: ExpressionContext + ): llvm.Value { + const type = this.mapGomTypeToLLVMType(node.resultantType as GomTupleType); + const tuple = + context?.pointer ?? this.builder.CreateAlloca(type, null, "tuple"); + node.elements.forEach((element, i) => { + const fieldVal = this.visitExpression(element); + const fieldPtr = this.builder.CreateGEP( + type, + tuple, + [this.builder.getInt32(0), this.builder.getInt32(i)], + "fieldptr" + ); + this.builder.CreateStore(fieldVal, fieldPtr); + }); + return tuple; + } + visitAccess(node: NodeAccess): llvm.Value { const idName = node.lhs.token.value; if (idName === "io" && node.rhs instanceof NodeCall) { const fn = this.module.getFunction("printf"); if (!fn) { - throw new Error("printf function not added globally"); + this.errorManager.throwCodegenError({ + message: "printf function not added globally", + loc: node.loc, + }); } const args = node.rhs.args.map((arg) => this.visitExpression(arg)); @@ -582,10 +670,11 @@ export class CodeGenerator extends BaseCodeGenerator { this.builder.CreateCall(fn, [newline], "newline"); return this.builder.getInt32(0); } else if ( - node.lhs.resultantType instanceof GomStructType && + (node.lhs.resultantType instanceof GomStructType || + node.lhs.resultantType instanceof GomTupleType) && node.rhs instanceof NodeTerm ) { - const type = node.lhs.resultantType as GomStructType; + const type = node.lhs.resultantType; const structType = this.mapGomTypeToLLVMType(node.lhs.resultantType); const struct = this.symbolTableReader.getIdentifier(idName); if (!struct) { @@ -602,9 +691,12 @@ export class CodeGenerator extends BaseCodeGenerator { }); } - const index = this.builder.getInt32( - Array.from(type.fields.keys()).indexOf(node.rhs.token.value) - ); + const index = + type instanceof GomStructType + ? this.builder.getInt32( + Array.from(type.fields.keys()).indexOf(node.rhs.token.value) + ) + : this.builder.getInt32(Number(node.rhs.token.value)); const ptr = this.builder.CreateGEP( structType, @@ -651,14 +743,33 @@ export class CodeGenerator extends BaseCodeGenerator { } } - visitCall(node: NodeCall): llvm.Value { + visitCall(node: NodeCall, context?: ExpressionContext): llvm.Value { const fn = this.module.getFunction(node.id.token!.value); - if (!fn) { + const gomFn = this.symbolTableReader.getIdentifier(node.id.token!.value); + if (!fn || !gomFn) { throw new Error("Unknown function: " + node.id.token!.value); } - const args = node.args.map((arg) => this.visitExpression(arg)); - return this.builder.CreateCall(fn, args, "calltmp"); + /** + * Check if the function uses sret (for any function returning a non-primitive type) + */ + if (gomFn.type instanceof GomFunctionType && gomFn.type.usesSret()) { + const sretPointer = + context?.pointer ?? + this.builder.CreateAlloca( + this.mapGomTypeToLLVMType(gomFn.type.returnType), + null, + "sret" + ); + const args = node.args.map((arg) => this.visitExpression(arg)); + this.builder.CreateCall(fn, [sretPointer, ...args]); + return sretPointer; + } else { + const args = node.args.map((arg) => + this.visitExpression(arg, { pointer: context?.pointer }) + ); + return this.builder.CreateCall(fn, args, "calltmp"); + } } visitTerm(node: NodeTerm): llvm.Value { @@ -690,9 +801,9 @@ export class CodeGenerator extends BaseCodeGenerator { id.name + ".load" ); } else if (type === GomToken.TRUE) { - return this.builder.getInt32(1); + return this.builder.getInt1(true); } else if (type === GomToken.FALSE) { - return this.builder.getInt32(0); + return this.builder.getInt1(false); } else { throw new Error("Unknown term type: " + type); } diff --git a/src/parser/rd/index.ts b/src/parser/rd/index.ts index 3e536aa..192d93b 100644 --- a/src/parser/rd/index.ts +++ b/src/parser/rd/index.ts @@ -1,7 +1,7 @@ import { Lexer, Token } from "../../lexer"; import { GomToken } from "../../lexer/tokens"; import { GomErrorManager } from "../../util/error"; -import { GomModule } from "./modules"; +import chalk from "chalk"; import { NodeAccess, NodeArgumentItem, @@ -15,18 +15,23 @@ import { NodeForStatement, NodeFunctionDefinition, NodeFunctionReturnType, - NodeGomTypeIdOrArray, + NodeGomType, + NodeGomTypeComposite, + NodeGomTypeId, NodeGomTypeStruct, NodeGomTypeStructField, + NodeGomTypeTuple, NodeIfStatement, NodeImportDeclaration, NodeLetStatement, + NodeListLiteral, NodeMainFunction, NodeProgram, NodeReturnStatement, NodeStatement, NodeStructInit, NodeTerm, + NodeTupleLiteral, NodeTypeDefinition, } from "./nodes"; import { NodeType } from "./tree"; @@ -57,7 +62,9 @@ export class RecursiveDescentParser { return matched; } else { this.errorManager.throwSyntaxError({ - message: `Unexpected token: ${this.token.value}`, + message: `Unexpected token: ${chalk.red( + this.token.value + )}, expected ${chalk.green(type)}`, loc: this.token.start, }); } @@ -196,19 +203,68 @@ export class RecursiveDescentParser { }); } - parseGomType(typeName: NodeTerm) { - if (this.peek(GomToken.LBRACE)) { - return this.parseStructType(typeName); - } else if ( - this.peek(GomToken.IDENTIFIER) || - this.peek(GomToken.BUILT_IN_TYPE) - ) { - return this.parseTypeIdOrArray(); + parseGomType(typeName?: NodeTerm): NodeGomType { + if (this.peek(GomToken.FN)) { + // Function type + } else if (this.peek(GomToken.LBRACE)) { + this.buffer.push(this.lexer.nextToken(), this.lexer.nextToken()); + if ( + this.buffer[this.buffer.length - 1].type === GomToken.COLON && + typeName + ) { + return this.parseStructType(typeName); + } else { + return this.parseTupleType(); + } + } else if (this.peek(GomToken.IDENTIFIER)) { + this.buffer.push(this.lexer.nextToken()); + if (this.buffer[this.buffer.length - 1].type === GomToken.LT) { + // composite type + return this.parseCompositeType(); + } else { + return this.parseTypeId(); + } + } else if (this.peek(GomToken.BUILT_IN_TYPE)) { + return this.parseTypeId(); } throw new Error(`Unexpected token: ${this.token.value}`); } + parseCompositeType(): NodeGomTypeComposite { + const baseType = this.parseTerm(); + this.match(GomToken.LT); + const fields = this.parseOneOrMore(() => { + const type = this.parseGomType(baseType); + if (!this.peek(GomToken.GT)) { + this.match(GomToken.COMMA); + } + return type; + }); + this.match(GomToken.GT); + + return new NodeGomTypeComposite({ + id: baseType, + fields, + loc: baseType.token.start, + }); + } + + parseTupleType(): NodeGomTypeTuple { + const loc = this.token.start; + this.match(GomToken.LBRACE); + const fields = this.parseZeroOrMore(() => { + const type = this.parseGomType(); + if (!this.peek(GomToken.RBRACE)) { + this.match(GomToken.COMMA); + } + return type; + }); + this.match(GomToken.RBRACE); + + return new NodeGomTypeTuple({ fields, loc }); + } + parseStructType(typeName: NodeTerm) { const loc = this.token.start; this.match(GomToken.LBRACE); @@ -222,7 +278,7 @@ export class RecursiveDescentParser { const loc = this.token.start; const name = this.match(GomToken.IDENTIFIER); this.match(GomToken.COLON); - const type = this.parseTypeIdOrArray(); + const type = this.parseTypeId(); if (!this.peek(GomToken.RBRACE)) { this.match(GomToken.COMMA); } @@ -230,22 +286,12 @@ export class RecursiveDescentParser { return new NodeGomTypeStructField({ name, fieldType: type, loc }); } - parseTypeIdOrArray() { - const baseType = this.parseTerm() as NodeTerm; - - if (this.accept(GomToken.LBRACKET)) { - const size = this.parseTerm(); - this.match(GomToken.RBRACKET); - return new NodeGomTypeIdOrArray({ - id: baseType, - arrSize: size, - loc: baseType.token.start, - }); - } + parseTypeId() { + const type = this.parseTerm() as NodeTerm; - return new NodeGomTypeIdOrArray({ - id: baseType, - loc: baseType.token.start, + return new NodeGomTypeId({ + id: type, + loc: type.token.start, }); } @@ -287,8 +333,7 @@ export class RecursiveDescentParser { parseFunctionReturnType() { const loc = this.token.start; this.match(GomToken.COLON); - const type = this.match(GomToken.BUILT_IN_TYPE); // can be custom type - + const type = this.parseGomType(); return new NodeFunctionReturnType({ returnType: type, loc }); } @@ -414,7 +459,8 @@ export class RecursiveDescentParser { * 3. Quot * 4. Expo * 5. Call - * 6. Term + * 6. Tuple/list literal + * 7. Term */ parseExpression(): NodeExpr { @@ -424,6 +470,10 @@ export class RecursiveDescentParser { const expr = this.parseExpression(); this.match(GomToken.RPAREN); return new NodeExprBracketed({ expr, loc }); + } else if (this.peek(GomToken.LBRACE)) { + return this.parseTupleLiteral(); + } else if (this.peek(GomToken.LBRACKET)) { + return this.parseListLiteral(); } else if (this.peek(GomToken.IDENTIFIER)) { this.buffer.push(this.lexer.nextToken()); if (this.buffer[1].type === GomToken.EQ) { @@ -436,6 +486,36 @@ export class RecursiveDescentParser { } } + parseTupleLiteral(): NodeTupleLiteral { + const loc = this.token.start; + this.match(GomToken.LBRACE); + const elements = this.parseZeroOrMore(() => { + const expr = this.parseExpression(); + if (!this.peek(GomToken.RBRACE)) { + this.match(GomToken.COMMA); + } + return expr; + }); + this.match(GomToken.RBRACE); + + return new NodeTupleLiteral({ elements, loc }); + } + + parseListLiteral(): NodeListLiteral { + const loc = this.token.start; + this.match(GomToken.LBRACKET); + const elements = this.parseZeroOrMore(() => { + const expr = this.parseExpression(); + if (!this.peek(GomToken.RBRACKET)) { + this.match(GomToken.COMMA); + } + return expr; + }); + this.match(GomToken.RBRACKET); + + return new NodeListLiteral({ elements, loc }); + } + parseAssignment(): NodeAssignment { const loc = this.token.start; const lhs = this.parseTerm() as NodeTerm; diff --git a/src/parser/rd/nodes/index.ts b/src/parser/rd/nodes/index.ts index 65559f3..8eef51a 100644 --- a/src/parser/rd/nodes/index.ts +++ b/src/parser/rd/nodes/index.ts @@ -2,9 +2,12 @@ import { Token } from "../../../lexer"; import { GomToken } from "../../../lexer/tokens"; import { GomArrayType, + GomCompositeType, + GomCompositeTypeKind, GomFunctionType, GomPrimitiveTypeOrAlias, GomStructType, + GomTupleType, GomType, } from "../../../semantics/type"; import { AbstractNode, Node, NodeType } from "../tree"; @@ -334,10 +337,10 @@ export class NodeArgumentItem extends AbstractNode { export class NodeFunctionReturnType extends AbstractNode { type: NodeType; - returnType: Token; + returnType: NodeGomType; children: Node[]; - constructor({ returnType, loc }: { returnType: Token; loc: number }) { + constructor({ returnType, loc }: { returnType: NodeGomType; loc: number }) { super(); this.type = NodeType.FUNCTION_RETURN_TYPE; this.loc = loc; @@ -346,35 +349,43 @@ export class NodeFunctionReturnType extends AbstractNode { } } -export type NodeGomType = NodeGomTypeIdOrArray | NodeGomTypeStruct; -export class NodeGomTypeIdOrArray extends AbstractNode { +export type NodeGomType = + | NodeGomTypeId + | NodeGomTypeStruct + | NodeGomTypeComposite + | NodeGomTypeTuple; +export class NodeGomTypeId extends AbstractNode { type: NodeType; id: NodeTerm; - arrSize?: NodeTerm; gomType: GomType; children: Node[]; - constructor({ - id, - arrSize, - loc, - }: { - id: NodeTerm; - arrSize?: NodeTerm; - loc: number; - }) { + constructor({ id, loc }: { id: NodeTerm; arrSize?: NodeTerm; loc: number }) { super(); - this.type = NodeType.GOM_TYPE_ID_OR_ARRAY; + this.type = NodeType.GOM_TYPE_ID; this.loc = loc; this.id = id; - this.arrSize = arrSize; - this.gomType = arrSize - ? new GomArrayType(id.resultantType, Number(arrSize.token.value)) - : id.resultantType; + this.gomType = id.resultantType; this.children = []; } } +export class NodeGomTypeTuple extends AbstractNode { + type: NodeType; + fields: NodeGomType[]; + gomType: GomType; + children: Node[]; + + constructor({ fields, loc }: { fields: NodeGomType[]; loc: number }) { + super(); + this.type = NodeType.GOM_TYPE_TUPLE; + this.loc = loc; + this.fields = fields; + this.gomType = new GomTupleType(fields.map((field) => field.gomType)); + this.children = formChildrenArray(fields); + } +} + export class NodeGomTypeStruct extends AbstractNode { type: NodeType; fields: NodeGomTypeStructField[]; @@ -404,6 +415,44 @@ export class NodeGomTypeStruct extends AbstractNode { } } +export class NodeGomTypeComposite extends AbstractNode { + type: NodeType; + id: NodeTerm; + fields: NodeGomType[]; + gomType: GomType; + children: Node[]; + + constructor({ + id, + fields, + loc, + }: { + id: NodeTerm; + fields: NodeGomType[]; + loc: number; + }) { + super(); + this.type = NodeType.GOM_TYPE_COMPOSITE; + this.loc = loc; + this.id = id; + this.fields = fields; + this.gomType = new GomCompositeType( + NodeGomTypeComposite.getGomCompositeTypeKind(id), + fields.map((field) => field.gomType) + ); + this.children = []; + } + + static getGomCompositeTypeKind(id: NodeTerm): GomCompositeTypeKind { + switch (id.token.value) { + case "List": + return GomCompositeTypeKind.List; + default: + return GomCompositeTypeKind._Custom; + } + } +} + export class NodeGomTypeStructField extends AbstractNode { type: NodeType; name: Token; @@ -434,8 +483,11 @@ export type NodeExprBasic = | NodeAssignment | NodeStructInit | NodeAccess + | NodeIndexedAccess | NodeCall | NodeBinaryOp + | NodeTupleLiteral + | NodeListLiteral | NodeTerm; export class NodeAssignment extends AbstractNode { @@ -593,6 +645,72 @@ export class NodeExprBracketed extends AbstractNode { } } +export class NodeIndexedAccess extends AbstractNode { + type: NodeType; + lhs: NodeExpr; + index: NodeExpr; + children: Node[]; + resultantType: GomType; + + constructor({ + lhs, + index, + loc, + }: { + lhs: NodeExpr; + index: NodeExpr; + loc: number; + }) { + super(); + this.type = NodeType.INDEXED_ACCESS; + this.loc = loc; + this.lhs = lhs; + this.index = index; + this.children = formChildrenArray(lhs, index); + this.resultantType = new GomPrimitiveTypeOrAlias("void"); + } +} + +export class NodeTupleLiteral extends AbstractNode { + type: NodeType; + elements: NodeExpr[]; + children: Node[]; + gomType: GomType; + resultantType: GomType; + + constructor({ elements, loc }: { elements: NodeExpr[]; loc: number }) { + super(); + this.type = NodeType.TUPLE_LITERAL; + this.loc = loc; + this.elements = elements; + this.children = elements; + this.gomType = new GomTupleType( + elements.map((elements) => elements.resultantType) + ); + this.resultantType = this.gomType; + } +} + +export class NodeListLiteral extends AbstractNode { + type: NodeType; + elements: NodeExpr[]; + children: Node[]; + gomType: GomType; + resultantType: GomType; + + constructor({ elements, loc }: { elements: NodeExpr[]; loc: number }) { + super(); + this.type = NodeType.LIST_LITERAL; + this.loc = loc; + this.elements = elements; + this.children = elements; + this.gomType = new GomCompositeType(GomCompositeTypeKind.List, [ + elements[0].resultantType, + ]); + this.resultantType = this.gomType; + } +} + export class NodeTerm extends AbstractNode { type: NodeType; token: Token; diff --git a/src/parser/rd/tree.ts b/src/parser/rd/tree.ts index 42ce60c..a580947 100644 --- a/src/parser/rd/tree.ts +++ b/src/parser/rd/tree.ts @@ -40,9 +40,11 @@ export enum NodeType { LET_STATEMENT = "LET_STATEMENT", CONST_STATEMENT = "CONST_STATEMENT", EXPRESSION_STATEMENT = "EXPRESSION_STATEMENT", - GOM_TYPE_ID_OR_ARRAY = "GOM_TYPE_ID_OR_ARRAY", + GOM_TYPE_ID = "GOM_TYPE_ID", + GOM_TYPE_TUPLE = "GOM_TYPE_TUPLE", GOM_TYPE_STRUCT = "GOM_TYPE_STRUCT", GOM_TYPE_STRUCT_FIELD = "GOM_TYPE_STRUCT_FIELD", + GOM_TYPE_COMPOSITE = "GOM_TYPE_COMPOSITE", ARGUMENT_ITEM = "ARGUMENT_ITEM", FUNCTION_RETURN_TYPE = "FUNCTION_RETURN_TYPE", EXPR_BASIC = "EXPR_BASIC", @@ -55,6 +57,9 @@ export enum NodeType { SUM = "SUM", QUOT = "QUOT", EXPO = "EXPO", + TUPLE_LITERAL = "TUPLE_LITERAL", + INDEXED_ACCESS = "INDEXED_ACCESS", + LIST_LITERAL = "LIST_LITERAL", TERM = "TERM", TERMINAL = "TERMINAL", } diff --git a/src/parser/rd/visitor.ts b/src/parser/rd/visitor.ts index 249a538..6c194a9 100644 --- a/src/parser/rd/visitor.ts +++ b/src/parser/rd/visitor.ts @@ -12,12 +12,15 @@ import { NodeGomTypeStructField, NodeIfStatement, NodeImportDeclaration, + NodeIndexedAccess, NodeLetStatement, + NodeListLiteral, NodeMainFunction, NodeProgram, NodeReturnStatement, NodeStructInit, NodeTerm, + NodeTupleLiteral, NodeTypeDefinition, } from "./nodes"; import { Node, NodeType } from "./tree"; @@ -118,6 +121,15 @@ export class SimpleVisitor implements Visitor { case NodeType.EXPRESSION_STATEMENT: this.visitExpressionStatement(node as NodeExpressionStatement); return; + case NodeType.TUPLE_LITERAL: + this.visitTupleLiteral(node as NodeTupleLiteral); + return; + case NodeType.LIST_LITERAL: + this.visitListLiteral(node as NodeListLiteral); + return; + case NodeType.INDEXED_ACCESS: + this.visitIndexedAccess(node as NodeIndexedAccess); + return; case NodeType.TERM: this.visitTerm(node as NodeTerm); return; @@ -187,6 +199,15 @@ export class SimpleVisitor implements Visitor { visitExpressionStatement(node: NodeExpressionStatement) { this.visitChildren(node); } + visitTupleLiteral(node: NodeTupleLiteral) { + this.visitChildren(node); + } + visitListLiteral(node: NodeListLiteral) { + this.visitChildren(node); + } + visitIndexedAccess(node: NodeIndexedAccess) { + this.visitChildren(node); + } visitTerm(node: NodeTerm) { this.visitChildren(node); } diff --git a/src/semantics/index.ts b/src/semantics/index.ts index 78524cb..13e2f40 100644 --- a/src/semantics/index.ts +++ b/src/semantics/index.ts @@ -5,6 +5,8 @@ import { NodeExpr, NodeForStatement, NodeFunctionDefinition, + NodeGomTypeComposite, + NodeGomTypeId, NodeGomTypeStruct, NodeGomTypeStructField, NodeIfStatement, @@ -14,6 +16,7 @@ import { NodeProgram, NodeStructInit, NodeTerm, + NodeTupleLiteral, NodeTypeDefinition, } from "../parser/rd/nodes"; import { ScopeManager, SymbolTableReader } from "./scope"; @@ -22,6 +25,7 @@ import { GomFunctionType, GomPrimitiveTypeOrAlias, GomStructType, + GomTupleType, GomType, } from "./type"; import { GomErrorManager } from "../util/error"; @@ -80,17 +84,33 @@ export class SemanticAnalyzer extends SimpleVisitor { visitFunctionDefinition(node: NodeFunctionDefinition): void { let returnType: GomType; + const nodeReturnType = node.returnType; + if (nodeReturnType) { + const returnTypeType = nodeReturnType.returnType; - if (node.returnType) { - const type = this.scopeManager.getType(node.returnType.returnType.value); - if (!type) { - this.errorManager.throwTypeError({ - message: `Return type ${node.returnType.returnType.value} not found`, - loc: node.returnType?.loc || node.loc, + if ( + returnTypeType instanceof NodeGomTypeId && + returnTypeType.id.token.type !== GomToken.BUILT_IN_TYPE + ) { + const type = this.scopeManager.getType(returnTypeType.id.token.value); + if (!type) { + this.errorManager.throwTypeError({ + message: `Return type ${nodeReturnType.returnType.token?.value} not found`, + loc: nodeReturnType?.loc || node.loc, + }); + } + returnType = type.gomType; + } else if (returnTypeType instanceof NodeGomTypeId) { + returnType = new GomPrimitiveTypeOrAlias(returnTypeType.id.token.value); + } else if (returnTypeType instanceof NodeGomTypeStruct) { + const fields = new Map(); + returnTypeType.fields.forEach((field) => { + return field.fieldType; }); + returnType = new GomStructType(node.name.value + "_return", fields); + } else { + returnType = returnTypeType.gomType; } - - returnType = type.gomType; } else { returnType = new GomPrimitiveTypeOrAlias("void"); } @@ -190,6 +210,11 @@ export class SemanticAnalyzer extends SimpleVisitor { inferredType, decl.rhs ); + console.log( + "let", + decl.lhs.token.value, + this.scopeManager.getCurrentSymbolTableNode().getName() + ); } }); } @@ -300,7 +325,7 @@ class TypeResolver extends SimpleVisitor { } const gomType = type.gomType; - if (gomType instanceof GomStructType) { + if (gomType instanceof GomStructType || gomType instanceof GomTupleType) { Array.from(gomType.fields.entries()).forEach(([key, field]) => { const _field = field as GomPrimitiveTypeOrAlias; if (_field.typeString.startsWith("resolve_type@@")) { @@ -338,7 +363,7 @@ class TypeResolver extends SimpleVisitor { if (id && !id.isFunction()) { // ensure that node.lhs is a struct // only support member access for structs for now - if (id.type instanceof GomStructType) { + if (id.type instanceof GomStructType || id.type instanceof GomTupleType) { node.lhs.resultantType = id.type; if (node.rhs instanceof NodeTerm) { const structType = id.type; @@ -474,6 +499,16 @@ class TypeResolver extends SimpleVisitor { } } + visitTupleLiteral(node: NodeTupleLiteral): void { + const elements = node.elements.map((element) => { + this.visit(element); + return this.currentType!; + }); + + node.resultantType = new GomTupleType(elements); + this.currentType = node.resultantType; + } + visitTerm(node: NodeTerm): void { const type = node.gomType; diff --git a/src/semantics/scope.ts b/src/semantics/scope.ts index 49b2ae9..cfd0d9d 100644 --- a/src/semantics/scope.ts +++ b/src/semantics/scope.ts @@ -2,8 +2,10 @@ import llvm from "llvm-bindings"; import { NodeExpr, NodeFunctionDefinition, - NodeGomTypeIdOrArray, + NodeGomTypeComposite, + NodeGomTypeId, NodeGomTypeStruct, + NodeGomTypeTuple, NodeTerm, NodeTypeDefinition, } from "../parser/rd/nodes"; @@ -12,6 +14,7 @@ import { GomPrimitiveTypeOrAlias, GomPrimitiveTypeOrAliasValue, GomStructType, + GomTupleType, GomType, } from "./type"; import { GOM_BUILT_IN_TYPES, GomToken } from "../lexer/tokens"; @@ -54,22 +57,33 @@ class TypeEntry { constructor(name: string, node: NodeTypeDefinition) { this.name = name; this.node = node; - this.gomType = - node.rhs instanceof NodeGomTypeStruct - ? new GomStructType( - name, - node.rhs.fields.reduce((acc, field) => { - if (field instanceof NodeGomTypeStruct) { - throw new SyntaxError({ - message: `Nested structs are not supported`, - loc: [1, field.loc], - }); - } - acc.set(field.name.value, field.fieldType.gomType); - return acc; - }, new Map()) - ) - : new GomPrimitiveTypeOrAlias(node.name.token.value); + this.gomType = this.makeGomType(); + } + + private makeGomType() { + return this.node.rhs.gomType; + // if (this.node.rhs instanceof NodeGomTypeStruct) { + // return new GomStructType( + // this.name, + // this.node.rhs.fields.reduce((acc, field) => { + // if (field instanceof NodeGomTypeStruct) { + // throw new SyntaxError({ + // message: `Nested structs are not supported`, + // loc: [1, field.loc], + // }); + // } + // acc.set(field.name.value, field.fieldType.gomType); + // return acc; + // }, new Map()) + // ); + // } else if (this.node.rhs instanceof NodeGomTypeTuple) { + // return new GomTupleType( + // this.node.rhs.fields.map((field) => field.gomType) + // ); + // } else if (this.node.rhs instanceof NodeGomTypeComposite) { + // } else { + // return new GomPrimitiveTypeOrAlias(this.node.name.token.value); + // } } getValue() { @@ -214,14 +228,13 @@ export class ScopeManager { end: 0, type: GomToken.BUILT_IN_TYPE, }), - rhs: new NodeGomTypeIdOrArray({ + rhs: new NodeGomTypeId({ id: new NodeTerm({ value: type, start: 0, end: 0, type: GomToken.BUILT_IN_TYPE, }), - arrSize: undefined, loc: 0, }), loc: 0, diff --git a/src/semantics/type.ts b/src/semantics/type.ts index 397bb42..790cec2 100644 --- a/src/semantics/type.ts +++ b/src/semantics/type.ts @@ -1,20 +1,33 @@ /** * Gom type can be: * - Primitive, e.g. int, bool, float, str, void + * - Tuple, e.g. (int, bool) * - Struct e.g. { x: int, y: int } - * - Custom, e.g. type Number = int + * - Composite, e.g. type IntList = List * - Function, e.g. fn add(a: int, b: int): int * * For now, structs are not supported & custom types can only be aliases to primitives. */ +import assert from "assert"; + export enum GomTypeKind { PrimitiveOrAlias = "PrimitiveOrAlias", + // Deprecated, use Composite instead Array = "Array", + Tuple = "Tuple", Struct = "Struct", + Composite = "Composite", Function = "Function", } +export enum GomCompositeTypeKind { + List = "List", + _Custom = "_Custom", + // Map = "Map", + // Set = "Set", +} + export class GomType { kind: GomTypeKind = GomTypeKind.PrimitiveOrAlias; toStr(): string { @@ -55,6 +68,9 @@ export class GomPrimitiveTypeOrAlias extends GomType { } } +/** + * Deprecated, use GomCompositeType instead + */ export class GomArrayType extends GomType { kind: GomTypeKind; elementType: GomType; @@ -81,6 +97,43 @@ export class GomArrayType extends GomType { } } +export class GomTupleType extends GomType { + kind: GomTypeKind; + fields: Map; + + constructor(fields: GomType[]) { + super(); + this.kind = GomTypeKind.Tuple; + this.fields = fields.reduce((acc, field, i) => { + acc.set(i.toString(), field); + return acc; + }, new Map()); + } + + isEqual(other: GomTupleType): boolean { + if (other.kind !== GomTypeKind.Tuple) { + return false; + } + if (this.fields.size !== other.fields.size) { + return false; + } + for (let i = 0; i < this.fields.size; i++) { + const otherField = other.fields.get(i.toString()); + assert(otherField); + if (!this.fields.get(i.toString())?.isEqual(otherField)) { + return false; + } + } + return true; + } + + toStr(): string { + return `{ ${Array.from(this.fields) + .map((field) => field[1].toStr()) + .join(", ")} }`; + } +} + export class GomStructType extends GomType { kind: GomTypeKind; name: string; @@ -114,6 +167,19 @@ export class GomStructType extends GomType { } } +export class GomCompositeType extends GomType { + kind: GomTypeKind; + compositeKind: GomCompositeTypeKind; + fieldTypes: GomType[]; + + constructor(compositeKind: GomCompositeTypeKind, fieldTypes: GomType[]) { + super(); + this.kind = GomTypeKind.Composite; + this.compositeKind = compositeKind; + this.fieldTypes = fieldTypes; + } +} + export class GomFunctionType extends GomType { kind: GomTypeKind; args: GomType[]; @@ -147,4 +213,12 @@ export class GomFunctionType extends GomType { .map((arg) => arg.toStr()) .join(", ")}) => ${this.returnType.toStr()}`; } + + usesSret(): boolean { + return ( + this.returnType instanceof GomStructType || + this.returnType instanceof GomCompositeType || + this.returnType instanceof GomTupleType + ); + } } diff --git a/src/util/error.ts b/src/util/error.ts index 0f37c5d..8213502 100644 --- a/src/util/error.ts +++ b/src/util/error.ts @@ -1,6 +1,10 @@ +import chalk from "chalk"; + export class SyntaxError extends Error { constructor({ loc, message }: { loc: [number, number]; message: string }) { - super(`SyntaxError at ${loc.join(":")}: ${message}`); + super( + chalk.bold(`${chalk.red(`SyntaxError at ${loc.join(":")}`)}: ${message}`) + ); } } diff --git a/test_2 b/test_2 new file mode 100755 index 0000000000000000000000000000000000000000..ac0c9b30657bbee9c6802e5d76cc295522f611a6 GIT binary patch literal 33544 zcmeI5U2IfE6vyY@ZJ}igt+WA5fvzT)YLQ|wf_%s=rBZ}YEH$YRGi8 z&Yd~u%$_;(yLTUF=G>i|_i}{L1c^@i5NR+&h<(CCJs}<@ts<3jZTX7I^_4Z%>`fK* z<5bsu7U%ha21;35Sy!7HR=+n=eZsLb$sJc7A!WpDk8sbH^n5K#?8WSLiej7Bm5>b4 zmFQDP%5bEuKAdo+=No#?&PR-tu$`PQ%gGmyOW6>Pg#3X`&iM3vcb$9{PMqyzNzToF zDcb^D{Q;l!2O2jkJC&cY)UL0|Ny2t|4kx41d7c)ci|gaBh8I51v75-QBb!-IBmIhO zu3_#jAq;AXlUPfdEb;F+Ie&7T`^EJ8zj}X@DCQyM@2s>f94c+`*O&UXwfM+pDJ11O zE}jh(o?ZCtj@`AdelvNiUS38%52-yTXPKn>YPs4y*AwJX>!X&XnAXR6?$ZAzS$N(B zq#Wb=bYD3wM;oh!>RGof95GwxESp1h`Ri#A$z!CPzpslJQ~S7MGcT4Iq#O^@x{umL zvKs;dAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0w4ea zAOHd&00JNY0w4eaAOHd&00JNY0w4eaAOHd&00JNY0{;nt(F)N&kSnZcu3^PU#cSDx zKp$qVt=Ww#S|Q(Vh-C*o&B|466aJ5VUB%SFPvk}s^msWi5ba^J6I~^&DsHQV)x>Ruunus$LRbT< z4C`{WVO^;(tictAb&2O$Dy-O2!-~4HPe#X!VFGwa3@z%W{i8k6@y2k>CAy0>$M0L* zO?3@FLNPTiNOry$roEp%G0GjK+_4f`ODW}~IifU2Y#!P3Y3>r5yOidhM|00NtkXO< zty|@3U))XmQhTn`T4{Z1&Zuj`NuHPX;`R*W8^amYj&xS`j_%PEXWDD}ah`4r3%%&V za(_7D4K$dZdNZ=sGy|UCQyy=?=LwcA^oUtLF+tonqGgUVhB`b-?WLVg#jqr|yhoPz zo*UG%^1g8vLp{eHybm{rc0x~cc3Cf`l!thWZJy8zXp1xLKUQ0Hd57I9PxvM08ce{sfroX>V$#u#^ol?~) zojOxU-1#}DkJ28dr19JZ|~)IKK{-Y$0|9J-WL3-S+(BQ`_r=wTKyx z$TBhR^vqYzZ_oaytYm1(_2zBOhxcEdJ9w$B|IzEK53bMHvG2p3AAC}``O8>iU&h7$ z{${l^y1n-9wWZ{vSV8M<+; jr8?4lL3`=t;$6q)A3b*Jvn=<9%z`JcJ|CU7N8$PtrA8Re literal 0 HcmV?d00001 diff --git a/tree.json b/tree.json index 42ed419..3ee2e1f 100644 --- a/tree.json +++ b/tree.json @@ -16,307 +16,447 @@ "typeDefinitions": [ { "type": "TYPE_DEFINITION", - "loc": 12, + "loc": 21, "name": { "type": "TERM", - "loc": 17, + "loc": 26, "token": { "type": "identifier", - "value": "Point", - "start": 17, - "end": 21 + "value": "HttpResponse", + "start": 26, + "end": 37 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "resolve_type@@HttpResponse" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "resolve_type@@HttpResponse" } }, "rhs": { - "type": "GOM_TYPE_STRUCT", - "loc": 25, + "type": "GOM_TYPE_TUPLE", + "loc": 41, "fields": [ { - "type": "GOM_TYPE_STRUCT_FIELD", - "loc": 31, - "name": { - "type": "identifier", - "value": "x", - "start": 31, - "end": 31 - }, - "fieldType": { - "type": "GOM_TYPE_ID_OR_ARRAY", - "loc": 34, - "id": { - "type": "TERM", - "loc": 34, - "token": { - "type": "built_in_type", - "value": "int", - "start": 34, - "end": 36 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } + "type": "GOM_TYPE_ID", + "loc": 43, + "id": { + "type": "TERM", + "loc": 43, + "token": { + "type": "built_in_type", + "value": "int", + "start": 43, + "end": 45 }, "gomType": { "kind": "PrimitiveOrAlias", "typeString": "int" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" } + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" } }, { - "type": "GOM_TYPE_STRUCT_FIELD", - "loc": 43, - "name": { - "type": "identifier", - "value": "y", - "start": 43, - "end": 43 - }, - "fieldType": { - "type": "GOM_TYPE_ID_OR_ARRAY", - "loc": 46, - "id": { - "type": "TERM", - "loc": 46, - "token": { - "type": "built_in_type", - "value": "int", - "start": 46, - "end": 48 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } + "type": "GOM_TYPE_ID", + "loc": 48, + "id": { + "type": "TERM", + "loc": 48, + "token": { + "type": "built_in_type", + "value": "bool", + "start": 48, + "end": 51 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "bool" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" } + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" } } ], "gomType": { - "kind": "Struct", - "name": "Point", + "kind": "Tuple", "fields": {} } } - }, + } + ], + "globalVariables": [], + "functionDeclarations": [ { - "type": "TYPE_DEFINITION", - "loc": 54, + "type": "FUNCTION_DEFINITION", + "loc": 57, "name": { - "type": "TERM", - "loc": 59, - "token": { - "type": "identifier", - "value": "Line", - "start": 59, - "end": 62 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Line" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Line" - } + "type": "identifier", + "value": "process_http", + "start": 60, + "end": 71 }, - "rhs": { - "type": "GOM_TYPE_STRUCT", - "loc": 66, - "fields": [ - { - "type": "GOM_TYPE_STRUCT_FIELD", - "loc": 72, - "name": { + "args": [ + { + "type": "ARGUMENT_ITEM", + "loc": 73, + "name": { + "type": "TERM", + "loc": 73, + "token": { "type": "identifier", - "value": "p1", - "start": 72, - "end": 73 + "value": "url", + "start": 73, + "end": 75 }, - "fieldType": { - "type": "GOM_TYPE_ID_OR_ARRAY", - "loc": 76, - "id": { + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@url" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@url" + } + }, + "expectedType": { + "type": "TERM", + "loc": 78, + "token": { + "type": "built_in_type", + "value": "str", + "start": 78, + "end": 80 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "str" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "str" + } + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "str" + } + } + ], + "returnType": { + "type": "FUNCTION_RETURN_TYPE", + "loc": 82, + "returnType": { + "type": "GOM_TYPE_ID", + "loc": 84, + "id": { + "type": "TERM", + "loc": 84, + "token": { + "type": "identifier", + "value": "HttpResponse", + "start": 84, + "end": 95 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@HttpResponse" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@HttpResponse" + } + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@HttpResponse" + } + } + }, + "body": [ + { + "type": "IF_STATEMENT", + "loc": 101, + "conditionExpr": { + "type": "EXPR_BRACKETED", + "loc": 103, + "expr": { + "type": "COMPARISON", + "loc": 104, + "lhs": { "type": "TERM", - "loc": 76, + "loc": 104, "token": { "type": "identifier", - "value": "Point", - "start": 76, - "end": 80 + "value": "url", + "start": 104, + "end": 106 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "resolve_type@@url" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "str" } }, - "gomType": { + "op": { + "type": "==", + "value": "==", + "start": 108, + "end": 109 + }, + "rhs": { + "type": "TERM", + "loc": 111, + "token": { + "type": "strliteral", + "value": "\"http://www.example.com\"", + "start": 111, + "end": 134 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "str" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "str" + } + }, + "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "bool" } + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "void" } }, - { - "type": "GOM_TYPE_STRUCT_FIELD", - "loc": 87, - "name": { - "type": "identifier", - "value": "p2", - "start": 87, - "end": 88 - }, - "fieldType": { - "type": "GOM_TYPE_ID_OR_ARRAY", - "loc": 91, - "id": { + "body": [ + { + "type": "RETURN_STATEMENT", + "loc": 143, + "expr": { + "type": "TUPLE_LITERAL", + "loc": 150, + "elements": [ + { + "type": "TERM", + "loc": 152, + "token": { + "type": "numliteral", + "value": "200", + "start": 152, + "end": 154 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } + }, + { + "type": "TERM", + "loc": 157, + "token": { + "type": "true", + "value": "true", + "start": 157, + "end": 160 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" + } + } + ], + "gomType": { + "kind": "Tuple", + "fields": {} + }, + "resultantType": { + "kind": "Tuple", + "fields": {} + } + } + } + ] + }, + { + "type": "RETURN_STATEMENT", + "loc": 174, + "expr": { + "type": "TUPLE_LITERAL", + "loc": 181, + "elements": [ + { "type": "TERM", - "loc": 91, + "loc": 183, "token": { - "type": "identifier", - "value": "Point", - "start": 91, - "end": 95 + "type": "numliteral", + "value": "401", + "start": 183, + "end": 185 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "int" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "int" } }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + { + "type": "TERM", + "loc": 188, + "token": { + "type": "false", + "value": "false", + "start": 188, + "end": 192 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" + } } + ], + "gomType": { + "kind": "Tuple", + "fields": {} + }, + "resultantType": { + "kind": "Tuple", + "fields": {} } } + } + ], + "resultantType": { + "kind": "Function", + "args": [ + { + "kind": "PrimitiveOrAlias", + "typeString": "str" + } ], - "gomType": { - "kind": "Struct", - "name": "Line", + "returnType": { + "kind": "Tuple", "fields": {} } } - } - ], - "globalVariables": [ + }, { - "type": "LET_STATEMENT", - "loc": 101, - "decls": [ + "type": "FUNCTION_DEFINITION", + "loc": 200, + "name": { + "type": "identifier", + "value": "process_http_retry", + "start": 203, + "end": 220 + }, + "args": [ { - "type": "ASSIGNMENT", - "loc": 105, - "lhs": { + "type": "ARGUMENT_ITEM", + "loc": 222, + "name": { "type": "TERM", - "loc": 105, + "loc": 222, "token": { "type": "identifier", - "value": "GLOBAL", - "start": 105, - "end": 110 + "value": "url", + "start": 222, + "end": 224 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@GLOBAL" + "typeString": "resolve_type@@url" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "resolve_type@@url" } }, - "rhs": { + "expectedType": { "type": "TERM", - "loc": 114, + "loc": 227, "token": { - "type": "numliteral", - "value": "1", - "start": 114, - "end": 114 + "type": "built_in_type", + "value": "str", + "start": 227, + "end": 229 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "str" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "str" } }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "void" + "typeString": "str" } - } - ] - } - ], - "functionDeclarations": [ - { - "type": "FUNCTION_DEFINITION", - "loc": 118, - "name": { - "type": "identifier", - "value": "square", - "start": 121, - "end": 126 - }, - "args": [ + }, { "type": "ARGUMENT_ITEM", - "loc": 128, + "loc": 232, "name": { "type": "TERM", - "loc": 128, + "loc": 232, "token": { "type": "identifier", - "value": "x", - "start": 128, - "end": 128 + "value": "retries", + "start": 232, + "end": 238 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" + "typeString": "resolve_type@@retries" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" + "typeString": "resolve_type@@retries" } }, "expectedType": { "type": "TERM", - "loc": 131, + "loc": 241, "token": { "type": "built_in_type", "value": "int", - "start": 131, - "end": 133 + "start": 241, + "end": 243 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -335,650 +475,172 @@ ], "returnType": { "type": "FUNCTION_RETURN_TYPE", - "loc": 135, + "loc": 245, "returnType": { - "type": "built_in_type", - "value": "int", - "start": 137, - "end": 139 - } - }, - "body": [ - { - "type": "RETURN_STATEMENT", - "loc": 147, - "expr": { - "type": "QUOT", - "loc": 154, - "lhs": { - "type": "TERM", - "loc": 154, - "token": { - "type": "identifier", - "value": "x", - "start": 154, - "end": 154 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "op": { - "type": "*", - "value": "*", - "start": 156, - "end": 156 - }, - "rhs": { - "type": "TERM", - "loc": 158, - "token": { - "type": "identifier", - "value": "x", - "start": 158, - "end": 158 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - } - } - ], - "resultantType": { - "kind": "Function", - "args": [ - { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - ], - "returnType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - } - }, - { - "type": "FUNCTION_DEFINITION", - "loc": 164, - "name": { - "type": "identifier", - "value": "add", - "start": 167, - "end": 169 - }, - "args": [ - { - "type": "ARGUMENT_ITEM", - "loc": 171, - "name": { + "type": "GOM_TYPE_ID", + "loc": 247, + "id": { "type": "TERM", - "loc": 171, + "loc": 247, "token": { "type": "identifier", - "value": "a", - "start": 171, - "end": 171 + "value": "HttpResponse", + "start": 247, + "end": 258 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@a" + "typeString": "resolve_type@@HttpResponse" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@a" + "typeString": "resolve_type@@HttpResponse" } }, - "expectedType": { - "type": "TERM", - "loc": 174, - "token": { - "type": "built_in_type", - "value": "int", - "start": 174, - "end": 176 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "resultantType": { + "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - { - "type": "ARGUMENT_ITEM", - "loc": 179, - "name": { - "type": "TERM", - "loc": 179, - "token": { - "type": "identifier", - "value": "b", - "start": 179, - "end": 179 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@b" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@b" - } - }, - "expectedType": { - "type": "TERM", - "loc": 182, - "token": { - "type": "built_in_type", - "value": "int", - "start": 182, - "end": 184 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "resolve_type@@HttpResponse" } } - ], - "returnType": { - "type": "FUNCTION_RETURN_TYPE", - "loc": 186, - "returnType": { - "type": "built_in_type", - "value": "int", - "start": 188, - "end": 190 - } }, "body": [ { - "type": "RETURN_STATEMENT", - "loc": 198, - "expr": { - "type": "SUM", - "loc": 205, + "type": "LET_STATEMENT", + "loc": 264, + "decls": [ + { + "type": "ASSIGNMENT", + "loc": 268, + "lhs": { + "type": "TERM", + "loc": 268, + "token": { + "type": "identifier", + "value": "i", + "start": 268, + "end": 268 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@i" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } + }, + "rhs": { + "type": "TERM", + "loc": 272, + "token": { + "type": "numliteral", + "value": "0", + "start": 272, + "end": 272 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "void" + } + } + ] + }, + { + "type": "FOR_STATEMENT", + "loc": 277, + "initExpr": { + "type": "ASSIGNMENT", + "loc": 281, "lhs": { "type": "TERM", - "loc": 205, + "loc": 281, "token": { "type": "identifier", - "value": "a", - "start": 205, - "end": 205 + "value": "i", + "start": 281, + "end": 281 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@a" + "typeString": "resolve_type@@i" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "resolve_type@@i" } }, - "op": { - "type": "+", - "value": "+", - "start": 207, - "end": 207 - }, "rhs": { "type": "TERM", - "loc": 209, + "loc": 285, "token": { "type": "identifier", - "value": "b", - "start": 209, - "end": 209 + "value": "retries", + "start": 285, + "end": 291 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@b" + "typeString": "resolve_type@@retries" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "resolve_type@@retries" } }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "int" - } - } - } - ], - "resultantType": { - "kind": "Function", - "args": [ - { - "kind": "PrimitiveOrAlias", - "typeString": "int" - }, - { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - ], - "returnType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - } - }, - { - "type": "FUNCTION_DEFINITION", - "loc": 215, - "name": { - "type": "identifier", - "value": "distance", - "start": 218, - "end": 225 - }, - "args": [ - { - "type": "ARGUMENT_ITEM", - "loc": 227, - "name": { - "type": "TERM", - "loc": 227, - "token": { - "type": "identifier", - "value": "p1", - "start": 227, - "end": 228 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" - } - }, - "expectedType": { - "type": "TERM", - "loc": 231, - "token": { - "type": "identifier", - "value": "Point", - "start": 231, - "end": 235 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" - } - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - }, - { - "type": "ARGUMENT_ITEM", - "loc": 238, - "name": { - "type": "TERM", - "loc": 238, - "token": { - "type": "identifier", - "value": "p2", - "start": 238, - "end": 239 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" - } - }, - "expectedType": { - "type": "TERM", - "loc": 242, - "token": { - "type": "identifier", - "value": "Point", - "start": 242, - "end": 246 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "void" } }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - } - ], - "returnType": { - "type": "FUNCTION_RETURN_TYPE", - "loc": 248, - "returnType": { - "type": "built_in_type", - "value": "int", - "start": 250, - "end": 252 - } - }, - "body": [ - { - "type": "RETURN_STATEMENT", - "loc": 260, - "expr": { - "type": "SUM", - "loc": 267, + "conditionExpr": { + "type": "COMPARISON", + "loc": 294, "lhs": { - "type": "CALL", - "loc": 267, - "id": { - "type": "TERM", - "loc": 267, - "token": { - "type": "identifier", - "value": "square", - "start": 267, - "end": 272 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@square" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@square" - } + "type": "TERM", + "loc": 294, + "token": { + "type": "identifier", + "value": "i", + "start": 294, + "end": 294 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@i" }, - "args": [ - { - "type": "SUM", - "loc": 274, - "lhs": { - "type": "ACCESS", - "loc": 274, - "lhs": { - "type": "TERM", - "loc": 274, - "token": { - "type": "identifier", - "value": "p1", - "start": 274, - "end": 275 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - }, - "rhs": { - "type": "TERM", - "loc": 277, - "token": { - "type": "identifier", - "value": "x", - "start": 277, - "end": 277 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "op": { - "type": "-", - "value": "-", - "start": 279, - "end": 279 - }, - "rhs": { - "type": "ACCESS", - "loc": 281, - "lhs": { - "type": "TERM", - "loc": 281, - "token": { - "type": "identifier", - "value": "p2", - "start": 281, - "end": 282 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - }, - "rhs": { - "type": "TERM", - "loc": 284, - "token": { - "type": "identifier", - "value": "x", - "start": 284, - "end": 284 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - } - ], "resultantType": { "kind": "PrimitiveOrAlias", "typeString": "int" } }, "op": { - "type": "+", - "value": "+", - "start": 287, - "end": 287 + "type": ">", + "value": ">", + "start": 296, + "end": 296 }, "rhs": { - "type": "CALL", - "loc": 289, - "id": { - "type": "TERM", - "loc": 289, - "token": { - "type": "identifier", - "value": "square", - "start": 289, - "end": 294 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@square" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@square" - } + "type": "TERM", + "loc": 298, + "token": { + "type": "numliteral", + "value": "0", + "start": 298, + "end": 298 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" }, - "args": [ - { - "type": "SUM", - "loc": 296, - "lhs": { - "type": "ACCESS", - "loc": 296, - "lhs": { - "type": "TERM", - "loc": 296, - "token": { - "type": "identifier", - "value": "p1", - "start": 296, - "end": 297 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - }, - "rhs": { - "type": "TERM", - "loc": 299, - "token": { - "type": "identifier", - "value": "y", - "start": 299, - "end": 299 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@y" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "op": { - "type": "-", - "value": "-", - "start": 301, - "end": 301 - }, - "rhs": { - "type": "ACCESS", - "loc": 303, - "lhs": { - "type": "TERM", - "loc": 303, - "token": { - "type": "identifier", - "value": "p2", - "start": 303, - "end": 304 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - }, - "rhs": { - "type": "TERM", - "loc": 306, - "token": { - "type": "identifier", - "value": "y", - "start": 306, - "end": 306 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@y" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - } - ], "resultantType": { "kind": "PrimitiveOrAlias", "typeString": "int" @@ -986,244 +648,293 @@ }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "bool" } - } - } - ], - "resultantType": { - "kind": "Function", - "args": [ - { - "kind": "Struct", - "name": "Point", - "fields": {} }, - { - "kind": "Struct", - "name": "Point", - "fields": {} - } - ], - "returnType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" - } - } - } - ], - "exportStatements": [], - "mainFunction": { - "type": "MAIN_FUNCTION", - "loc": 316, - "body": [ - { - "type": "LET_STATEMENT", - "loc": 329, - "decls": [ - { + "updateExpr": { "type": "ASSIGNMENT", - "loc": 333, + "loc": 301, "lhs": { "type": "TERM", - "loc": 333, + "loc": 301, "token": { "type": "identifier", - "value": "p1", - "start": 333, - "end": 334 + "value": "i", + "start": 301, + "end": 301 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" + "typeString": "resolve_type@@i" }, "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@i" } }, "rhs": { - "type": "STRUCT_INIT", - "loc": 338, - "structTypeName": { + "type": "SUM", + "loc": 305, + "lhs": { "type": "TERM", - "loc": 338, + "loc": 305, "token": { "type": "identifier", - "value": "Point", - "start": 338, - "end": 342 + "value": "i", + "start": 305, + "end": 305 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "resolve_type@@i" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" + "typeString": "int" } }, - "fields": [ - [ - { + "op": { + "type": "-", + "value": "-", + "start": 307, + "end": 307 + }, + "rhs": { + "type": "TERM", + "loc": 309, + "token": { + "type": "numliteral", + "value": "1", + "start": 309, + "end": 309 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "void" + } + }, + "body": [ + { + "type": "EXPRESSION_STATEMENT", + "loc": 318, + "expr": { + "type": "ACCESS", + "loc": 318, + "lhs": { + "type": "TERM", + "loc": 318, + "token": { + "type": "identifier", + "value": "io", + "start": 318, + "end": 319 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@io" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@io" + } + }, + "rhs": { + "type": "CALL", + "loc": 321, + "id": { "type": "TERM", - "loc": 346, + "loc": 321, "token": { "type": "identifier", - "value": "x", - "start": 346, - "end": 346 + "value": "log", + "start": 321, + "end": 323 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" + "typeString": "resolve_type@@log" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" + "typeString": "resolve_type@@log" } }, - { - "type": "TERM", - "loc": 349, - "token": { - "type": "numliteral", - "value": "1", - "start": 349, - "end": 349 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" + "args": [ + { + "type": "TERM", + "loc": 325, + "token": { + "type": "strliteral", + "value": "\"Round: \"", + "start": 325, + "end": 333 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "str" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "str" + } }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" + { + "type": "TERM", + "loc": 336, + "token": { + "type": "identifier", + "value": "i", + "start": 336, + "end": 336 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@i" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } } + ], + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "void" } - ], - [ - { + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "void" + } + } + }, + { + "type": "LET_STATEMENT", + "loc": 344, + "decls": [ + { + "type": "ASSIGNMENT", + "loc": 348, + "lhs": { "type": "TERM", - "loc": 352, + "loc": 348, "token": { "type": "identifier", - "value": "y", - "start": 352, - "end": 352 + "value": "resp", + "start": 348, + "end": 351 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@y" + "typeString": "resolve_type@@resp" }, "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@y" + "kind": "Tuple", + "fields": {} } }, - { - "type": "TERM", + "rhs": { + "type": "CALL", "loc": 355, - "token": { - "type": "numliteral", - "value": "2", - "start": 355, - "end": 355 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" + "id": { + "type": "TERM", + "loc": 355, + "token": { + "type": "identifier", + "value": "process_http", + "start": 355, + "end": 366 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@process_http" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@process_http" + } }, + "args": [ + { + "type": "TERM", + "loc": 368, + "token": { + "type": "identifier", + "value": "url", + "start": 368, + "end": 370 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@url" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "str" + } + } + ], "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" + "kind": "Tuple", + "fields": {} } + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "void" } - ] - ], - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "void" - } - }, - { - "type": "ASSIGNMENT", - "loc": 360, - "lhs": { - "type": "TERM", - "loc": 360, - "token": { - "type": "identifier", - "value": "p2", - "start": 360, - "end": 361 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - }, - "rhs": { - "type": "STRUCT_INIT", - "loc": 365, - "structTypeName": { - "type": "TERM", - "loc": 365, - "token": { - "type": "identifier", - "value": "Point", - "start": 365, - "end": 369 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Point" } - }, - "fields": [ - [ - { + ] + }, + { + "type": "IF_STATEMENT", + "loc": 378, + "conditionExpr": { + "type": "EXPR_BRACKETED", + "loc": 380, + "expr": { + "type": "ACCESS", + "loc": 381, + "lhs": { "type": "TERM", - "loc": 373, + "loc": 381, "token": { "type": "identifier", - "value": "x", - "start": 373, - "end": 373 + "value": "resp", + "start": 381, + "end": 384 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" + "typeString": "resolve_type@@resp" }, "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@x" + "kind": "Tuple", + "fields": {} } }, - { + "rhs": { "type": "TERM", - "loc": 376, + "loc": 386, "token": { "type": "numliteral", - "value": "3", - "start": 376, - "end": 376 + "value": "1", + "start": 386, + "end": 386 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1231,151 +942,212 @@ }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "bool" } + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" } - ], - [ - { + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "void" + } + }, + "body": [ + { + "type": "RETURN_STATEMENT", + "loc": 397, + "expr": { "type": "TERM", - "loc": 379, + "loc": 404, "token": { "type": "identifier", - "value": "y", - "start": 379, - "end": 379 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@y" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@y" - } - }, - { - "type": "TERM", - "loc": 382, - "token": { - "type": "numliteral", - "value": "4", - "start": 382, - "end": 382 + "value": "resp", + "start": 404, + "end": 407 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "resolve_type@@resp" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "resolve_type@@resp" } } - ] - ], - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} + } + ] + } + ] + }, + { + "type": "RETURN_STATEMENT", + "loc": 423, + "expr": { + "type": "TUPLE_LITERAL", + "loc": 430, + "elements": [ + { + "type": "TERM", + "loc": 432, + "token": { + "type": "numliteral", + "value": "500", + "start": 432, + "end": 434 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } + }, + { + "type": "TERM", + "loc": 437, + "token": { + "type": "false", + "value": "false", + "start": 437, + "end": 441 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" + } } + ], + "gomType": { + "kind": "Tuple", + "fields": {} }, "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "void" + "kind": "Tuple", + "fields": {} } } - ] - }, + } + ], + "resultantType": { + "kind": "Function", + "args": [ + { + "kind": "PrimitiveOrAlias", + "typeString": "str" + }, + { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } + ], + "returnType": { + "kind": "Tuple", + "fields": {} + } + } + } + ], + "exportStatements": [], + "mainFunction": { + "type": "MAIN_FUNCTION", + "loc": 452, + "body": [ { "type": "LET_STATEMENT", - "loc": 391, + "loc": 463, "decls": [ { "type": "ASSIGNMENT", - "loc": 395, + "loc": 467, "lhs": { "type": "TERM", - "loc": 395, + "loc": 467, "token": { "type": "identifier", - "value": "d", - "start": 395, - "end": 395 + "value": "resp", + "start": 467, + "end": 470 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@d" + "typeString": "resolve_type@@resp" }, "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" + "kind": "Tuple", + "fields": {} } }, "rhs": { "type": "CALL", - "loc": 399, + "loc": 474, "id": { "type": "TERM", - "loc": 399, + "loc": 474, "token": { "type": "identifier", - "value": "distance", - "start": 399, - "end": 406 + "value": "process_http_retry", + "start": 474, + "end": 491 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@distance" + "typeString": "resolve_type@@process_http_retry" }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@distance" + "typeString": "resolve_type@@process_http_retry" } }, "args": [ { "type": "TERM", - "loc": 408, + "loc": 493, "token": { - "type": "identifier", - "value": "p1", - "start": 408, - "end": 409 + "type": "strliteral", + "value": "\"http://www.example.com\"", + "start": 493, + "end": 516 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" + "typeString": "str" }, "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} + "kind": "PrimitiveOrAlias", + "typeString": "str" } }, { "type": "TERM", - "loc": 412, + "loc": 519, "token": { - "type": "identifier", - "value": "p2", - "start": 412, - "end": 413 + "type": "numliteral", + "value": "3", + "start": 519, + "end": 519 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" + "typeString": "int" }, "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} + "kind": "PrimitiveOrAlias", + "typeString": "int" } } ], "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "int" + "kind": "Tuple", + "fields": {} } }, "resultantType": { @@ -1387,18 +1159,18 @@ }, { "type": "EXPRESSION_STATEMENT", - "loc": 421, + "loc": 525, "expr": { "type": "ACCESS", - "loc": 421, + "loc": 525, "lhs": { "type": "TERM", - "loc": 421, + "loc": 525, "token": { "type": "identifier", "value": "io", - "start": 421, - "end": 422 + "start": 525, + "end": 526 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1411,15 +1183,15 @@ }, "rhs": { "type": "CALL", - "loc": 424, + "loc": 528, "id": { "type": "TERM", - "loc": 424, + "loc": 528, "token": { "type": "identifier", "value": "log", - "start": 424, - "end": 426 + "start": 528, + "end": 530 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1433,12 +1205,12 @@ "args": [ { "type": "TERM", - "loc": 428, + "loc": 532, "token": { "type": "strliteral", - "value": "\"Distance between p1 and p2: \"", - "start": 428, - "end": 457 + "value": "\"Status: \"", + "start": 532, + "end": 541 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1450,229 +1222,57 @@ } }, { - "type": "TERM", - "loc": 460, - "token": { - "type": "identifier", - "value": "d", - "start": 460, - "end": 460 + "type": "ACCESS", + "loc": 544, + "lhs": { + "type": "TERM", + "loc": 544, + "token": { + "type": "identifier", + "value": "resp", + "start": 544, + "end": 547 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@resp" + }, + "resultantType": { + "kind": "Tuple", + "fields": {} + } }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@d" + "rhs": { + "type": "TERM", + "loc": 549, + "token": { + "type": "numliteral", + "value": "0", + "start": 549, + "end": 549 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } }, "resultantType": { "kind": "PrimitiveOrAlias", "typeString": "int" } - } - ], - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "void" - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "void" - } - } - }, - { - "type": "LET_STATEMENT", - "loc": 469, - "decls": [ - { - "type": "ASSIGNMENT", - "loc": 473, - "lhs": { - "type": "TERM", - "loc": 473, - "token": { - "type": "identifier", - "value": "l", - "start": 473, - "end": 473 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@l" - }, - "resultantType": { - "kind": "Struct", - "name": "Line", - "fields": {} - } - }, - "rhs": { - "type": "STRUCT_INIT", - "loc": 477, - "structTypeName": { - "type": "TERM", - "loc": 477, - "token": { - "type": "identifier", - "value": "Line", - "start": 477, - "end": 480 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Line" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@Line" - } - }, - "fields": [ - [ - { - "type": "TERM", - "loc": 484, - "token": { - "type": "identifier", - "value": "p1", - "start": 484, - "end": 485 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" - } - }, - { - "type": "TERM", - "loc": 488, - "token": { - "type": "identifier", - "value": "p1", - "start": 488, - "end": 489 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - } - ], - [ - { - "type": "TERM", - "loc": 492, - "token": { - "type": "identifier", - "value": "p2", - "start": 492, - "end": 493 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" - } - }, - { - "type": "TERM", - "loc": 496, - "token": { - "type": "identifier", - "value": "p2", - "start": 496, - "end": 497 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - } - ] - ], - "resultantType": { - "kind": "Struct", - "name": "Line", - "fields": {} - } - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "void" - } - } - ] - }, - { - "type": "EXPRESSION_STATEMENT", - "loc": 506, - "expr": { - "type": "ACCESS", - "loc": 506, - "lhs": { - "type": "TERM", - "loc": 506, - "token": { - "type": "identifier", - "value": "io", - "start": 506, - "end": 507 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@io" - }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@io" - } - }, - "rhs": { - "type": "CALL", - "loc": 509, - "id": { - "type": "TERM", - "loc": 509, - "token": { - "type": "identifier", - "value": "log", - "start": 509, - "end": 511 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@log" }, - "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@log" - } - }, - "args": [ { "type": "TERM", - "loc": 513, + "loc": 552, "token": { "type": "strliteral", - "value": "\"Distance between l.p1 and l.p2: \"", - "start": 513, - "end": 546 + "value": "\" Success: \"", + "start": 552, + "end": 563 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1684,125 +1284,47 @@ } }, { - "type": "CALL", - "loc": 549, - "id": { + "type": "ACCESS", + "loc": 566, + "lhs": { "type": "TERM", - "loc": 549, + "loc": 566, "token": { "type": "identifier", - "value": "distance", - "start": 549, - "end": 556 + "value": "resp", + "start": 566, + "end": 569 }, "gomType": { "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@distance" + "typeString": "resolve_type@@resp" }, "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@distance" + "kind": "Tuple", + "fields": {} } }, - "args": [ - { - "type": "ACCESS", - "loc": 558, - "lhs": { - "type": "TERM", - "loc": 558, - "token": { - "type": "identifier", - "value": "l", - "start": 558, - "end": 558 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@l" - }, - "resultantType": { - "kind": "Struct", - "name": "Line", - "fields": {} - } - }, - "rhs": { - "type": "TERM", - "loc": 560, - "token": { - "type": "identifier", - "value": "p1", - "start": 560, - "end": 561 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p1" - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } + "rhs": { + "type": "TERM", + "loc": 571, + "token": { + "type": "numliteral", + "value": "1", + "start": 571, + "end": 571 }, - { - "type": "ACCESS", - "loc": 564, - "lhs": { - "type": "TERM", - "loc": 564, - "token": { - "type": "identifier", - "value": "l", - "start": 564, - "end": 564 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@l" - }, - "resultantType": { - "kind": "Struct", - "name": "Line", - "fields": {} - } - }, - "rhs": { - "type": "TERM", - "loc": 566, - "token": { - "type": "identifier", - "value": "p2", - "start": 566, - "end": 567 - }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@p2" - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } - }, - "resultantType": { - "kind": "Struct", - "name": "Point", - "fields": {} - } + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "bool" } - ], + }, "resultantType": { "kind": "PrimitiveOrAlias", - "typeString": "int" + "typeString": "bool" } } ], From 1a0afa13b2743b1ece1f9e61145b71f292f8444d Mon Sep 17 00:00:00 2001 From: Mohit Karekar Date: Sat, 24 May 2025 21:25:26 +0200 Subject: [PATCH 2/3] Fix tuples, add context to NodeTerm codegen for sret --- examples/test_3 | Bin 33528 -> 33528 bytes examples/test_3.gom | 5 +- examples/test_3.ll | 27 ++- run.ts | 35 +-- src/codegen/llvm.ts | 152 +++++++++---- src/index.ts | 8 +- src/semantics/index.ts | 33 +++ tree.json | 474 +++++++++++++++++++++++------------------ 8 files changed, 451 insertions(+), 283 deletions(-) diff --git a/examples/test_3 b/examples/test_3 index e1ac3e982fbe7335685c62edf532b8ce99d0de26..068f85205fbe0af1a74c5158357f9d3890e1a17d 100755 GIT binary patch delta 763 zcmYk4QAkr^6vxkZufwZs=tgR_Yg^K2DTJb;*6!|VP%nYtEVR-~s1yaMxILIk*M>AH z!n-f9mugB6n?V%wVG^Msgjrx_WW8CCT$3Kmm#Z|^xtoF?oR9DP&UeoJ|1Y05#Arjz z$R~^H0w4fT#o&fZbtymHW?sxtV+I0GD~M=z?$FvD>WmMPdM4j-;qUq5a=GDYOT4M- zRK;hy!q$>d{6N-1Eu9n!$QYd$F5XV|O~;ZfD5+Ukj06v9V?moX?zJVR*-S*eQX-0H z6tgeNN(qiYx5)sF=^SgZG|Rcc8NeK!El!|@5%}j)E&)88m~BaR}yN*gH1Mh-_@%4s4uyr3~R?D&Gr*^aI`}%`21J=fga54zCc@BM-LvUBo>?WSKz@hdhm2uEHg$3 zFp!S{kVR+2Bjj29ml*aKLj%CVw_CWWy)-CS8`R#emkfO)TT4Rj%%kD4Cl5{RKCRN7 zyh)(j@>~T|g}J_nzoW-5RYC!~HfJ@B7k+H{@oqgBds0$3KNdQgci-Z8z3{U0`8B#Z z=&^GF_1x%Shu{@$XFfa*yS^V&zpQS^D>cTm!>i)S2h?{*c9eu|OO=Y30G12tt delta 544 zcmey-%Jid^X~G4eEw&5{j0_A61t0PLUVl4m&v*847b58A3q(m+X`IY^AxI873ZJj=%Pj-QnkC z13L*tpjNQJ|HBLy|5h`te2~mA5vY8E;sKk9Nem4^_a`s3lVOyZyw6VDG{<(LAOph` zperXZIM`0)1F}K3ykusW$ie6^NrRE$Cs+=sjvc11VltP#sYGx|Vo7PSl>&o8aA|UK zYB7kZn!>;}Io@8D7Zg+uK#d@*GP%=Uo97M#0~3P)5Gyb+O+H|+!nkJhQ~OB{JQHde zm>HJT0EsQtlbah%S+`Ud!Ko$Pe)sLsB?a`0PLO~QqP-SLlJ&zO9! W@ZaJK9 0; i = i - 1) { - io.log("Round: ", i); + io.log("Round: ", retries - i + 1); let resp = process_http(url); if(resp.1) { return resp; @@ -25,6 +26,6 @@ fn process_http_retry(url: str, retries: int): HttpResponse { } fn main() { - let resp = process_http_retry("http://www.example.com", 3); + let resp = process_http_retry("http://www.example.com", 10); io.log("Status: ", resp.0, " Success: ", resp.1); } \ No newline at end of file diff --git a/examples/test_3.ll b/examples/test_3.ll index f8dc67f..00b447a 100644 --- a/examples/test_3.ll +++ b/examples/test_3.ll @@ -47,6 +47,7 @@ entry: store i32 %2, i32* %4, align 4 %i = alloca i32, align 4 store i32 0, i32* %i, align 4 + store i32 0, i32* %i, align 4 %retries.load = load i32, i32* %4, align 4 store i32 %retries.load, i32* %i, align 4 br label %loop @@ -57,9 +58,12 @@ loop: ; preds = %loopupdate, %entry br i1 %gttmp, label %loopbody, label %afterloop loopbody: ; preds = %loop - %i.load1 = load i32, i32* %i, align 4 + %retries.load1 = load i32, i32* %4, align 4 + %i.load2 = load i32, i32* %i, align 4 + %subtmp = sub i32 %retries.load1, %i.load2 + %addtmp = add i32 %subtmp, 1 %calltmp0 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.strliteral.1, i32 0, i32 0)) - %calltmp1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @fmt.int, i32 0, i32 0), i32 %i.load1) + %calltmp1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @fmt.int, i32 0, i32 0), i32 %addtmp) %newline = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @newline, i32 0, i32 0)) %resp = alloca { i32, i1 }, align 8 %url.load = load i8*, i8** %3, align 8 @@ -69,21 +73,22 @@ loopbody: ; preds = %loop br i1 %fieldload, label %then, label %else loopupdate: ; preds = %merge - %i.load2 = load i32, i32* %i, align 4 - %subtmp = sub i32 %i.load2, 1 - store i32 %subtmp, i32* %i, align 4 + %i.load3 = load i32, i32* %i, align 4 + %subtmp4 = sub i32 %i.load3, 1 + store i32 %subtmp4, i32* %i, align 4 br label %loop afterloop: ; preds = %loop - %fieldptr3 = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 0 - store i32 500, i32* %fieldptr3, align 4 - %fieldptr4 = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 1 - store i1 false, i1* %fieldptr4, align 1 + %fieldptr5 = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 0 + store i32 500, i32* %fieldptr5, align 4 + %fieldptr6 = getelementptr { i32, i1 }, { i32, i1 }* %0, i32 0, i32 1 + store i1 false, i1* %fieldptr6, align 1 ret void then: ; preds = %loopbody %resp.load = load { i32, i1 }, { i32, i1 }* %resp, align 4 - ret { i32, i1 } %resp.load + store { i32, i1 } %resp.load, { i32, i1 }* %0, align 4 + ret void br label %merge else: ; preds = %loopbody @@ -96,7 +101,7 @@ merge: ; preds = %else, %then define void @main() { entry: %resp = alloca { i32, i1 }, align 8 - call void @process_http_retry({ i32, i1 }* %resp, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.strliteral.2, i32 0, i32 0), i32 3) + call void @process_http_retry({ i32, i1 }* %resp, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.strliteral.2, i32 0, i32 0), i32 10) %fieldptr = getelementptr { i32, i1 }, { i32, i1 }* %resp, i32 0, i32 0 %fieldload = load i32, i32* %fieldptr, align 4 %fieldptr1 = getelementptr { i32, i1 }, { i32, i1 }* %resp, i32 0, i32 1 diff --git a/run.ts b/run.ts index dac1253..973731c 100755 --- a/run.ts +++ b/run.ts @@ -5,18 +5,23 @@ import { execSync } from "child_process"; const filePath = process.argv[2]; const target = (process.argv[3] || "c") as "c" | "llvm"; -(async () => { - await runCompile(filePath, target); - - if (target === "llvm") { - // compile using clang - execSync( - `clang -o ${filePath.replace(".gom", "")} ${filePath.replace( - ".gom", - ".ll" - )}`, - { stdio: "inherit" } - ); - console.log(`✅ Executable generated at: ${filePath.replace(".gom", "")}`); - } -})(); +runCompile(filePath, target) + .then(() => { + if (target === "llvm") { + // compile using clang + execSync( + `clang -o ${filePath.replace(".gom", "")} ${filePath.replace( + ".gom", + ".ll" + )}`, + { stdio: "inherit" } + ); + console.log( + `✅ Executable generated at: ${filePath.replace(".gom", "")}` + ); + } + }) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/src/codegen/llvm.ts b/src/codegen/llvm.ts index a841b9f..afb55db 100644 --- a/src/codegen/llvm.ts +++ b/src/codegen/llvm.ts @@ -382,7 +382,6 @@ export class CodeGenerator extends BaseCodeGenerator { } if (node.expr) { - console.log("return statement", node.expr); if (node.expr.resultantType instanceof GomPrimitiveTypeOrAlias) { const exprValue = this.visitExpression(node.expr); this.builder.CreateRet(exprValue); @@ -535,11 +534,11 @@ export class CodeGenerator extends BaseCodeGenerator { if (expr instanceof NodeAccess) { return this.visitAccess(expr); } else if (expr instanceof NodeBinaryOp) { - return this.visitBinaryOp(expr); + return this.visitBinaryOp(expr, context); } else if (expr instanceof NodeCall) { return this.visitCall(expr, context); } else if (expr instanceof NodeTerm) { - return this.visitTerm(expr); + return this.visitTerm(expr, context); } else if (expr instanceof NodeAssignment) { return this.visitAssignment(expr); } else if (expr instanceof NodeStructInit) { @@ -714,33 +713,50 @@ export class CodeGenerator extends BaseCodeGenerator { return this.builder.getInt32(0); } - visitBinaryOp(node: NodeBinaryOp): llvm.Value { + visitBinaryOp(node: NodeBinaryOp, context?: ExpressionContext): llvm.Value { + const pointer = context?.pointer; const op = node.op; const lhs = this.visitExpression(node.lhs); const rhs = this.visitExpression(node.rhs); + let irOperation: llvm.Value | null = null; switch (op.type) { case GomToken.PLUS: - return this.builder.CreateAdd(lhs, rhs, "addtmp"); + irOperation = this.builder.CreateAdd(lhs, rhs, "addtmp"); + break; case GomToken.MINUS: - return this.builder.CreateSub(lhs, rhs, "subtmp"); + irOperation = this.builder.CreateSub(lhs, rhs, "subtmp"); + break; case GomToken.MUL: - return this.builder.CreateMul(lhs, rhs, "multmp"); + irOperation = this.builder.CreateMul(lhs, rhs, "multmp"); + break; case GomToken.DIV: - return this.builder.CreateSDiv(lhs, rhs, "divtmp"); + irOperation = this.builder.CreateSDiv(lhs, rhs, "divtmp"); + break; case GomToken.EQEQ: - return this.builder.CreateICmpEQ(lhs, rhs, "eqtmp"); + irOperation = this.builder.CreateICmpEQ(lhs, rhs, "eqtmp"); + break; case GomToken.LT: - return this.builder.CreateICmpSLT(lhs, rhs, "lttmp"); + irOperation = this.builder.CreateICmpSLT(lhs, rhs, "lttmp"); + break; case GomToken.GT: - return this.builder.CreateICmpSGT(lhs, rhs, "gttmp"); + irOperation = this.builder.CreateICmpSGT(lhs, rhs, "gttmp"); + break; case GomToken.LTE: - return this.builder.CreateICmpSLE(lhs, rhs, "ltetmp"); + irOperation = this.builder.CreateICmpSLE(lhs, rhs, "ltetmp"); + break; case GomToken.GTE: - return this.builder.CreateICmpSGE(lhs, rhs, "gtetmp"); + irOperation = this.builder.CreateICmpSGE(lhs, rhs, "gtetmp"); + break; default: throw new Error("Unknown operator: " + op.type); } + + if (pointer) { + return this.builder.CreateStore(irOperation, pointer); + } else { + return irOperation; + } } visitCall(node: NodeCall, context?: ExpressionContext): llvm.Value { @@ -772,40 +788,88 @@ export class CodeGenerator extends BaseCodeGenerator { } } - visitTerm(node: NodeTerm): llvm.Value { + visitTerm(node: NodeTerm, context?: ExpressionContext): llvm.Value { + const pointer = context?.pointer; const type = node.token.type; - if (type === GomToken.NUMLITERAL) { - return this.builder.getInt32(parseInt(node.token.value)); - } else if (type === GomToken.STRLITERAL) { - return this.getStringLiteralPointer(node); - } else if (type === GomToken.IDENTIFIER) { - const id = this.symbolTableReader.getIdentifier(node.token.value); - if (!id) { - // throw new Error("Unknown identifier: " + node.token.value); - this.errorManager.throwCodegenError({ - loc: node.loc, - message: "Unknown identifier: " + node.token.value, - }); - } - if (!id.allocaInst) { - // throw new Error("Identifier not allocated: " + node.token.value); - this.errorManager.throwCodegenError({ - loc: node.loc, - message: "Identifier not allocated: " + node.token.value, - }); - } + if (pointer) { + if (type === GomToken.NUMLITERAL) { + const value = parseInt(node.token.value); + const intValue = this.builder.getInt32(value); + this.builder.CreateStore(intValue, pointer); + return intValue; + } else if (type === GomToken.STRLITERAL) { + const strPtr = this.getStringLiteralPointer(node); + this.builder.CreateStore(strPtr, pointer); + return strPtr; + } else if (type === GomToken.IDENTIFIER) { + const id = this.symbolTableReader.getIdentifier(node.token.value); + if (!id) { + // throw new Error("Unknown identifier: " + node.token.value); + this.errorManager.throwCodegenError({ + loc: node.loc, + message: "Unknown identifier: " + node.token.value, + }); + } + if (!id.allocaInst) { + // throw new Error("Identifier not allocated: " + node.token.value); + this.errorManager.throwCodegenError({ + loc: node.loc, + message: "Identifier not allocated: " + node.token.value, + }); + } - return this.builder.CreateLoad( - this.mapGomTypeToLLVMType(id.type as GomPrimitiveTypeOrAlias), - id.allocaInst, - id.name + ".load" - ); - } else if (type === GomToken.TRUE) { - return this.builder.getInt1(true); - } else if (type === GomToken.FALSE) { - return this.builder.getInt1(false); + const loadInst = this.builder.CreateLoad( + this.mapGomTypeToLLVMType(id.type as GomPrimitiveTypeOrAlias), + id.allocaInst, + id.name + ".load" + ); + this.builder.CreateStore(loadInst, pointer); + return loadInst; + } else if (type === GomToken.TRUE) { + const trueValue = this.builder.getInt1(true); + this.builder.CreateStore(trueValue, pointer); + return trueValue; + } else if (type === GomToken.FALSE) { + const falseValue = this.builder.getInt1(false); + this.builder.CreateStore(falseValue, pointer); + return falseValue; + } else { + throw new Error("Unknown term type: " + type); + } } else { - throw new Error("Unknown term type: " + type); + if (type === GomToken.NUMLITERAL) { + return this.builder.getInt32(parseInt(node.token.value)); + } else if (type === GomToken.STRLITERAL) { + return this.getStringLiteralPointer(node); + } else if (type === GomToken.IDENTIFIER) { + const id = this.symbolTableReader.getIdentifier(node.token.value); + if (!id) { + // throw new Error("Unknown identifier: " + node.token.value); + this.errorManager.throwCodegenError({ + loc: node.loc, + message: "Unknown identifier: " + node.token.value, + }); + } + if (!id.allocaInst) { + // throw new Error("Identifier not allocated: " + node.token.value); + this.errorManager.throwCodegenError({ + loc: node.loc, + message: "Identifier not allocated: " + node.token.value, + }); + } + + return this.builder.CreateLoad( + this.mapGomTypeToLLVMType(id.type as GomPrimitiveTypeOrAlias), + id.allocaInst, + id.name + ".load" + ); + } else if (type === GomToken.TRUE) { + return this.builder.getInt1(true); + } else if (type === GomToken.FALSE) { + return this.builder.getInt1(false); + } else { + throw new Error("Unknown term type: " + type); + } } } } diff --git a/src/index.ts b/src/index.ts index 7070c98..bd13758 100644 --- a/src/index.ts +++ b/src/index.ts @@ -116,10 +116,6 @@ export const compileAndReturn = async ( }; export const runCompile = async (srcPath: string, target: "llvm" | "c") => { - try { - const src = await readFile(srcPath, "utf-8"); - await compile(srcPath, src, target); - } catch (e) { - console.error(e); - } + const src = await readFile(srcPath, "utf-8"); + await compile(srcPath, src, target); }; diff --git a/src/semantics/index.ts b/src/semantics/index.ts index 13e2f40..4d2805b 100644 --- a/src/semantics/index.ts +++ b/src/semantics/index.ts @@ -14,6 +14,7 @@ import { NodeLetStatement, NodeMainFunction, NodeProgram, + NodeReturnStatement, NodeStructInit, NodeTerm, NodeTupleLiteral, @@ -34,6 +35,7 @@ import { GomModule } from "../parser/rd/modules"; export class SemanticAnalyzer extends SimpleVisitor { scopeManager: ScopeManager; + private currentFunctionDefinition: NodeFunctionDefinition | null = null; constructor(private ast: NodeProgram, private errorManager: GomErrorManager) { super(); @@ -83,6 +85,7 @@ export class SemanticAnalyzer extends SimpleVisitor { } visitFunctionDefinition(node: NodeFunctionDefinition): void { + this.currentFunctionDefinition = node; let returnType: GomType; const nodeReturnType = node.returnType; if (nodeReturnType) { @@ -141,6 +144,7 @@ export class SemanticAnalyzer extends SimpleVisitor { }); node.body.forEach((stmt) => this.visit(stmt)); this.scopeManager.endScope(); + this.currentFunctionDefinition = null; } visitForStatement(node: NodeForStatement): void { @@ -219,6 +223,35 @@ export class SemanticAnalyzer extends SimpleVisitor { }); } + visitReturnStatement(node: NodeReturnStatement): void { + let returnType: GomType | null = null; + if (node.expr) { + this.visit(node.expr); + const typeResolver = new TypeResolver( + this.scopeManager, + this.errorManager + ); + returnType = typeResolver.resolveType(node.expr); + } + if (this.currentFunctionDefinition) { + const fnType = this.currentFunctionDefinition.resultantType; + if ( + fnType instanceof GomFunctionType && + returnType && + !returnType.isEqual(fnType.returnType) && + !( + returnType instanceof GomPrimitiveTypeOrAlias && + returnType.typeString === "void" + ) + ) { + this.errorManager.throwTypeError({ + message: `Return type mismatch: expected ${fnType.returnType.toStr()}, got ${returnType.toStr()}`, + loc: node.loc, + }); + } + } + } + visitAccess(node: NodeAccess): void { const typeResolver = new TypeResolver(this.scopeManager, this.errorManager); typeResolver.resolveType(node); diff --git a/tree.json b/tree.json index 3ee2e1f..f4fcc3d 100644 --- a/tree.json +++ b/tree.json @@ -103,25 +103,25 @@ "functionDeclarations": [ { "type": "FUNCTION_DEFINITION", - "loc": 57, + "loc": 58, "name": { "type": "identifier", "value": "process_http", - "start": 60, - "end": 71 + "start": 61, + "end": 72 }, "args": [ { "type": "ARGUMENT_ITEM", - "loc": 73, + "loc": 74, "name": { "type": "TERM", - "loc": 73, + "loc": 74, "token": { "type": "identifier", "value": "url", - "start": 73, - "end": 75 + "start": 74, + "end": 76 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -134,12 +134,12 @@ }, "expectedType": { "type": "TERM", - "loc": 78, + "loc": 79, "token": { "type": "built_in_type", "value": "str", - "start": 78, - "end": 80 + "start": 79, + "end": 81 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -158,18 +158,18 @@ ], "returnType": { "type": "FUNCTION_RETURN_TYPE", - "loc": 82, + "loc": 83, "returnType": { "type": "GOM_TYPE_ID", - "loc": 84, + "loc": 85, "id": { "type": "TERM", - "loc": 84, + "loc": 85, "token": { "type": "identifier", "value": "HttpResponse", - "start": 84, - "end": 95 + "start": 85, + "end": 96 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -189,21 +189,21 @@ "body": [ { "type": "IF_STATEMENT", - "loc": 101, + "loc": 102, "conditionExpr": { "type": "EXPR_BRACKETED", - "loc": 103, + "loc": 104, "expr": { "type": "COMPARISON", - "loc": 104, + "loc": 105, "lhs": { "type": "TERM", - "loc": 104, + "loc": 105, "token": { "type": "identifier", "value": "url", - "start": 104, - "end": 106 + "start": 105, + "end": 107 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -217,17 +217,17 @@ "op": { "type": "==", "value": "==", - "start": 108, - "end": 109 + "start": 109, + "end": 110 }, "rhs": { "type": "TERM", - "loc": 111, + "loc": 112, "token": { "type": "strliteral", "value": "\"http://www.example.com\"", - "start": 111, - "end": 134 + "start": 112, + "end": 135 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -251,19 +251,19 @@ "body": [ { "type": "RETURN_STATEMENT", - "loc": 143, + "loc": 144, "expr": { "type": "TUPLE_LITERAL", - "loc": 150, + "loc": 151, "elements": [ { "type": "TERM", - "loc": 152, + "loc": 153, "token": { "type": "numliteral", "value": "200", - "start": 152, - "end": 154 + "start": 153, + "end": 155 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -276,12 +276,12 @@ }, { "type": "TERM", - "loc": 157, + "loc": 158, "token": { "type": "true", "value": "true", - "start": 157, - "end": 160 + "start": 158, + "end": 161 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -307,19 +307,19 @@ }, { "type": "RETURN_STATEMENT", - "loc": 174, + "loc": 175, "expr": { "type": "TUPLE_LITERAL", - "loc": 181, + "loc": 182, "elements": [ { "type": "TERM", - "loc": 183, + "loc": 184, "token": { "type": "numliteral", "value": "401", - "start": 183, - "end": 185 + "start": 184, + "end": 186 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -332,12 +332,12 @@ }, { "type": "TERM", - "loc": 188, + "loc": 189, "token": { "type": "false", "value": "false", - "start": 188, - "end": 192 + "start": 189, + "end": 193 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -376,25 +376,25 @@ }, { "type": "FUNCTION_DEFINITION", - "loc": 200, + "loc": 201, "name": { "type": "identifier", "value": "process_http_retry", - "start": 203, - "end": 220 + "start": 204, + "end": 221 }, "args": [ { "type": "ARGUMENT_ITEM", - "loc": 222, + "loc": 223, "name": { "type": "TERM", - "loc": 222, + "loc": 223, "token": { "type": "identifier", "value": "url", - "start": 222, - "end": 224 + "start": 223, + "end": 225 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -407,12 +407,12 @@ }, "expectedType": { "type": "TERM", - "loc": 227, + "loc": 228, "token": { "type": "built_in_type", "value": "str", - "start": 227, - "end": 229 + "start": 228, + "end": 230 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -430,15 +430,15 @@ }, { "type": "ARGUMENT_ITEM", - "loc": 232, + "loc": 233, "name": { "type": "TERM", - "loc": 232, + "loc": 233, "token": { "type": "identifier", "value": "retries", - "start": 232, - "end": 238 + "start": 233, + "end": 239 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -451,12 +451,12 @@ }, "expectedType": { "type": "TERM", - "loc": 241, + "loc": 242, "token": { "type": "built_in_type", "value": "int", - "start": 241, - "end": 243 + "start": 242, + "end": 244 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -475,18 +475,18 @@ ], "returnType": { "type": "FUNCTION_RETURN_TYPE", - "loc": 245, + "loc": 246, "returnType": { "type": "GOM_TYPE_ID", - "loc": 247, + "loc": 248, "id": { "type": "TERM", - "loc": 247, + "loc": 248, "token": { "type": "identifier", "value": "HttpResponse", - "start": 247, - "end": 258 + "start": 248, + "end": 259 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -506,19 +506,19 @@ "body": [ { "type": "LET_STATEMENT", - "loc": 264, + "loc": 265, "decls": [ { "type": "ASSIGNMENT", - "loc": 268, + "loc": 269, "lhs": { "type": "TERM", - "loc": 268, + "loc": 269, "token": { "type": "identifier", "value": "i", - "start": 268, - "end": 268 + "start": 269, + "end": 269 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -531,12 +531,12 @@ }, "rhs": { "type": "TERM", - "loc": 272, + "loc": 273, "token": { "type": "numliteral", "value": "0", - "start": 272, - "end": 272 + "start": 273, + "end": 273 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -556,18 +556,18 @@ }, { "type": "FOR_STATEMENT", - "loc": 277, + "loc": 278, "initExpr": { "type": "ASSIGNMENT", - "loc": 281, + "loc": 282, "lhs": { "type": "TERM", - "loc": 281, + "loc": 282, "token": { "type": "identifier", "value": "i", - "start": 281, - "end": 281 + "start": 282, + "end": 282 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -580,12 +580,12 @@ }, "rhs": { "type": "TERM", - "loc": 285, + "loc": 286, "token": { "type": "identifier", "value": "retries", - "start": 285, - "end": 291 + "start": 286, + "end": 292 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -603,15 +603,15 @@ }, "conditionExpr": { "type": "COMPARISON", - "loc": 294, + "loc": 295, "lhs": { "type": "TERM", - "loc": 294, + "loc": 295, "token": { "type": "identifier", "value": "i", - "start": 294, - "end": 294 + "start": 295, + "end": 295 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -625,17 +625,17 @@ "op": { "type": ">", "value": ">", - "start": 296, - "end": 296 + "start": 297, + "end": 297 }, "rhs": { "type": "TERM", - "loc": 298, + "loc": 299, "token": { "type": "numliteral", "value": "0", - "start": 298, - "end": 298 + "start": 299, + "end": 299 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -653,15 +653,15 @@ }, "updateExpr": { "type": "ASSIGNMENT", - "loc": 301, + "loc": 302, "lhs": { "type": "TERM", - "loc": 301, + "loc": 302, "token": { "type": "identifier", "value": "i", - "start": 301, - "end": 301 + "start": 302, + "end": 302 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -674,15 +674,15 @@ }, "rhs": { "type": "SUM", - "loc": 305, + "loc": 306, "lhs": { "type": "TERM", - "loc": 305, + "loc": 306, "token": { "type": "identifier", "value": "i", - "start": 305, - "end": 305 + "start": 306, + "end": 306 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -696,17 +696,17 @@ "op": { "type": "-", "value": "-", - "start": 307, - "end": 307 + "start": 308, + "end": 308 }, "rhs": { "type": "TERM", - "loc": 309, + "loc": 310, "token": { "type": "numliteral", "value": "1", - "start": 309, - "end": 309 + "start": 310, + "end": 310 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -730,18 +730,18 @@ "body": [ { "type": "EXPRESSION_STATEMENT", - "loc": 318, + "loc": 319, "expr": { "type": "ACCESS", - "loc": 318, + "loc": 319, "lhs": { "type": "TERM", - "loc": 318, + "loc": 319, "token": { "type": "identifier", "value": "io", - "start": 318, - "end": 319 + "start": 319, + "end": 320 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -754,15 +754,15 @@ }, "rhs": { "type": "CALL", - "loc": 321, + "loc": 322, "id": { "type": "TERM", - "loc": 321, + "loc": 322, "token": { "type": "identifier", "value": "log", - "start": 321, - "end": 323 + "start": 322, + "end": 324 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -776,12 +776,12 @@ "args": [ { "type": "TERM", - "loc": 325, + "loc": 326, "token": { "type": "strliteral", "value": "\"Round: \"", - "start": 325, - "end": 333 + "start": 326, + "end": 334 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -793,17 +793,81 @@ } }, { - "type": "TERM", - "loc": 336, - "token": { - "type": "identifier", - "value": "i", - "start": 336, - "end": 336 + "type": "SUM", + "loc": 337, + "lhs": { + "type": "SUM", + "loc": 337, + "lhs": { + "type": "TERM", + "loc": 337, + "token": { + "type": "identifier", + "value": "retries", + "start": 337, + "end": 343 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@retries" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } + }, + "op": { + "type": "-", + "value": "-", + "start": 345, + "end": 345 + }, + "rhs": { + "type": "TERM", + "loc": 347, + "token": { + "type": "identifier", + "value": "i", + "start": 347, + "end": 347 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "resolve_type@@i" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } }, - "gomType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@i" + "op": { + "type": "+", + "value": "+", + "start": 349, + "end": 349 + }, + "rhs": { + "type": "TERM", + "loc": 351, + "token": { + "type": "numliteral", + "value": "1", + "start": 351, + "end": 351 + }, + "gomType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + }, + "resultantType": { + "kind": "PrimitiveOrAlias", + "typeString": "int" + } }, "resultantType": { "kind": "PrimitiveOrAlias", @@ -824,19 +888,19 @@ }, { "type": "LET_STATEMENT", - "loc": 344, + "loc": 359, "decls": [ { "type": "ASSIGNMENT", - "loc": 348, + "loc": 363, "lhs": { "type": "TERM", - "loc": 348, + "loc": 363, "token": { "type": "identifier", "value": "resp", - "start": 348, - "end": 351 + "start": 363, + "end": 366 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -849,15 +913,15 @@ }, "rhs": { "type": "CALL", - "loc": 355, + "loc": 370, "id": { "type": "TERM", - "loc": 355, + "loc": 370, "token": { "type": "identifier", "value": "process_http", - "start": 355, - "end": 366 + "start": 370, + "end": 381 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -871,12 +935,12 @@ "args": [ { "type": "TERM", - "loc": 368, + "loc": 383, "token": { "type": "identifier", "value": "url", - "start": 368, - "end": 370 + "start": 383, + "end": 385 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -902,21 +966,21 @@ }, { "type": "IF_STATEMENT", - "loc": 378, + "loc": 393, "conditionExpr": { "type": "EXPR_BRACKETED", - "loc": 380, + "loc": 395, "expr": { "type": "ACCESS", - "loc": 381, + "loc": 396, "lhs": { "type": "TERM", - "loc": 381, + "loc": 396, "token": { "type": "identifier", "value": "resp", - "start": 381, - "end": 384 + "start": 396, + "end": 399 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -929,12 +993,12 @@ }, "rhs": { "type": "TERM", - "loc": 386, + "loc": 401, "token": { "type": "numliteral", "value": "1", - "start": 386, - "end": 386 + "start": 401, + "end": 401 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -958,23 +1022,23 @@ "body": [ { "type": "RETURN_STATEMENT", - "loc": 397, + "loc": 412, "expr": { "type": "TERM", - "loc": 404, + "loc": 419, "token": { "type": "identifier", "value": "resp", - "start": 404, - "end": 407 + "start": 419, + "end": 422 }, "gomType": { "kind": "PrimitiveOrAlias", "typeString": "resolve_type@@resp" }, "resultantType": { - "kind": "PrimitiveOrAlias", - "typeString": "resolve_type@@resp" + "kind": "Tuple", + "fields": {} } } } @@ -984,19 +1048,19 @@ }, { "type": "RETURN_STATEMENT", - "loc": 423, + "loc": 438, "expr": { "type": "TUPLE_LITERAL", - "loc": 430, + "loc": 445, "elements": [ { "type": "TERM", - "loc": 432, + "loc": 447, "token": { "type": "numliteral", "value": "500", - "start": 432, - "end": 434 + "start": 447, + "end": 449 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1009,12 +1073,12 @@ }, { "type": "TERM", - "loc": 437, + "loc": 452, "token": { "type": "false", "value": "false", - "start": 437, - "end": 441 + "start": 452, + "end": 456 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1059,23 +1123,23 @@ "exportStatements": [], "mainFunction": { "type": "MAIN_FUNCTION", - "loc": 452, + "loc": 467, "body": [ { "type": "LET_STATEMENT", - "loc": 463, + "loc": 478, "decls": [ { "type": "ASSIGNMENT", - "loc": 467, + "loc": 482, "lhs": { "type": "TERM", - "loc": 467, + "loc": 482, "token": { "type": "identifier", "value": "resp", - "start": 467, - "end": 470 + "start": 482, + "end": 485 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1088,15 +1152,15 @@ }, "rhs": { "type": "CALL", - "loc": 474, + "loc": 489, "id": { "type": "TERM", - "loc": 474, + "loc": 489, "token": { "type": "identifier", "value": "process_http_retry", - "start": 474, - "end": 491 + "start": 489, + "end": 506 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1110,12 +1174,12 @@ "args": [ { "type": "TERM", - "loc": 493, + "loc": 508, "token": { "type": "strliteral", "value": "\"http://www.example.com\"", - "start": 493, - "end": 516 + "start": 508, + "end": 531 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1128,12 +1192,12 @@ }, { "type": "TERM", - "loc": 519, + "loc": 534, "token": { "type": "numliteral", - "value": "3", - "start": 519, - "end": 519 + "value": "10", + "start": 534, + "end": 535 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1159,18 +1223,18 @@ }, { "type": "EXPRESSION_STATEMENT", - "loc": 525, + "loc": 541, "expr": { "type": "ACCESS", - "loc": 525, + "loc": 541, "lhs": { "type": "TERM", - "loc": 525, + "loc": 541, "token": { "type": "identifier", "value": "io", - "start": 525, - "end": 526 + "start": 541, + "end": 542 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1183,15 +1247,15 @@ }, "rhs": { "type": "CALL", - "loc": 528, + "loc": 544, "id": { "type": "TERM", - "loc": 528, + "loc": 544, "token": { "type": "identifier", "value": "log", - "start": 528, - "end": 530 + "start": 544, + "end": 546 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1205,12 +1269,12 @@ "args": [ { "type": "TERM", - "loc": 532, + "loc": 548, "token": { "type": "strliteral", "value": "\"Status: \"", - "start": 532, - "end": 541 + "start": 548, + "end": 557 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1223,15 +1287,15 @@ }, { "type": "ACCESS", - "loc": 544, + "loc": 560, "lhs": { "type": "TERM", - "loc": 544, + "loc": 560, "token": { "type": "identifier", "value": "resp", - "start": 544, - "end": 547 + "start": 560, + "end": 563 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1244,12 +1308,12 @@ }, "rhs": { "type": "TERM", - "loc": 549, + "loc": 565, "token": { "type": "numliteral", "value": "0", - "start": 549, - "end": 549 + "start": 565, + "end": 565 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1267,12 +1331,12 @@ }, { "type": "TERM", - "loc": 552, + "loc": 568, "token": { "type": "strliteral", "value": "\" Success: \"", - "start": 552, - "end": 563 + "start": 568, + "end": 579 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1285,15 +1349,15 @@ }, { "type": "ACCESS", - "loc": 566, + "loc": 582, "lhs": { "type": "TERM", - "loc": 566, + "loc": 582, "token": { "type": "identifier", "value": "resp", - "start": 566, - "end": 569 + "start": 582, + "end": 585 }, "gomType": { "kind": "PrimitiveOrAlias", @@ -1306,12 +1370,12 @@ }, "rhs": { "type": "TERM", - "loc": 571, + "loc": 587, "token": { "type": "numliteral", "value": "1", - "start": 571, - "end": 571 + "start": 587, + "end": 587 }, "gomType": { "kind": "PrimitiveOrAlias", From e29af32e8933295d34250713c78d6d12f0e3ce81 Mon Sep 17 00:00:00 2001 From: Mohit Karekar Date: Sat, 24 May 2025 21:30:55 +0200 Subject: [PATCH 3/3] Remove build command --- package.json | 1 - src/codegen/c.ts | 39 +++++++++++++++++++-------------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index f77e5f1..15fc505 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "gomc": "run.sh" }, "scripts": { - "build": "tsc", "test": "vitest run", "compile": "tsx run.ts", "changeset": "changeset", diff --git a/src/codegen/c.ts b/src/codegen/c.ts index c17c0ee..37f5e39 100644 --- a/src/codegen/c.ts +++ b/src/codegen/c.ts @@ -111,26 +111,25 @@ export class CodeGenerator extends BaseCodeGenerator { } visitFunctionDefinition(node: NodeFunctionDefinition): void { - this.symbolTableReader.enterScope(node.name.value); - this.irScopeManager.enterScope(node.name.value); - const returnType = this.mapGomTypeToC( - node.gomType.returnType as GomPrimitiveTypeOrAlias - ); - const argsType = node.gomType.args.map((arg) => - this.mapGomTypeToC(arg as GomPrimitiveTypeOrAlias) - ); - - this.writeLine( - `${returnType} ${node.name.value}(${argsType - .map((type, i) => `${type} ${node.args[i].name.token.value}`) - .join(", ")}) {` - ); - this.indent++; - node.body.forEach((stmt) => this.visit(stmt)); - this.indent--; - this.writeLine("}"); - this.symbolTableReader.exitScope(); - this.irScopeManager.exitScope(); + // this.symbolTableReader.enterScope(node.name.value); + // this.irScopeManager.enterScope(node.name.value); + // const returnType = this.mapGomTypeToC( + // node.gomType.returnType as GomPrimitiveTypeOrAlias + // ); + // const argsType = node.gomType.args.map((arg) => + // this.mapGomTypeToC(arg as GomPrimitiveTypeOrAlias) + // ); + // this.writeLine( + // `${returnType} ${node.name.value}(${argsType + // .map((type, i) => `${type} ${node.args[i].name.token.value}`) + // .join(", ")}) {` + // ); + // this.indent++; + // node.body.forEach((stmt) => this.visit(stmt)); + // this.indent--; + // this.writeLine("}"); + // this.symbolTableReader.exitScope(); + // this.irScopeManager.exitScope(); } visitLetStatement(node: NodeLetStatement): void {