From acd51dee98eab636bb74dddba0b59a306b93ddc7 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 11 Mar 2025 15:37:05 -0400 Subject: [PATCH 001/137] added tests for assignable and memory --- tests/sprint2/test/test_carls_mistake.alpha | 27 +++++++++++++++++++ tests/sprint2/test/test_invalid_recop.alpha | 10 +++++++ tests/sprint2/test/test_invalid_release.alpha | 8 ++++++ .../test/test_valid_assignable_and_mem.alpha | 12 +++++++++ 4 files changed, 57 insertions(+) create mode 100644 tests/sprint2/test/test_carls_mistake.alpha create mode 100644 tests/sprint2/test/test_invalid_recop.alpha create mode 100644 tests/sprint2/test/test_invalid_release.alpha create mode 100644 tests/sprint2/test/test_valid_assignable_and_mem.alpha diff --git a/tests/sprint2/test/test_carls_mistake.alpha b/tests/sprint2/test/test_carls_mistake.alpha new file mode 100644 index 0000000..fb75ca3 --- /dev/null +++ b/tests/sprint2/test/test_carls_mistake.alpha @@ -0,0 +1,27 @@ +type rec: [integer: x; integer: y] +type T1: integer -> integer +type T2: rec -> integer + +function foo : T1 +function bar1 : T2 +function bar2 : T2 + +foo(x) := { + return x * x; +} +bar1(a) := { + return a.x * a.y; +} +bar2 as (r,s) := { + return r * s; +} +entry(arg) := { + [ integer: result ; rec: w] + result := foo(5); + w := reserve(w); (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*) + w.x := 5; + w.y := 7; + result := bar1(w); (* pass w (a rec type value) to bar1 *) + result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) + return 0; +} \ No newline at end of file diff --git a/tests/sprint2/test/test_invalid_recop.alpha b/tests/sprint2/test/test_invalid_recop.alpha new file mode 100644 index 0000000..5ea874d --- /dev/null +++ b/tests/sprint2/test/test_invalid_recop.alpha @@ -0,0 +1,10 @@ +type rec: [integer: x; integer: y] + +entry(arg) := { + [rec: w] + w := reserve w; + w.x := 1; + w.y := 2; + w.z := 3; + return 0; +} \ No newline at end of file diff --git a/tests/sprint2/test/test_invalid_release.alpha b/tests/sprint2/test/test_invalid_release.alpha new file mode 100644 index 0000000..41fbd8a --- /dev/null +++ b/tests/sprint2/test/test_invalid_release.alpha @@ -0,0 +1,8 @@ +type rec: [integer: x; integer: y] + +entry(arg) := { + [rec: w] + w := reserve w; + w := release (w); + return 0; +} \ No newline at end of file diff --git a/tests/sprint2/test/test_valid_assignable_and_mem.alpha b/tests/sprint2/test/test_valid_assignable_and_mem.alpha new file mode 100644 index 0000000..43c5a5f --- /dev/null +++ b/tests/sprint2/test/test_valid_assignable_and_mem.alpha @@ -0,0 +1,12 @@ +type rec: [integer: x; integer: y] +type T2: rec -> integer + +entry(arg) := { + [rec: w] + w := reserve w; + w.x := 1; + w.y := 2; + w := release w; + return 0; + +} \ No newline at end of file From 7bd6af09b90f6d3289826f59a43bdeb8e163f01c Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 11 Mar 2025 15:39:15 -0400 Subject: [PATCH 002/137] Cleanup --- Grammar-FE-t-NoTask | 35 ----------------------------------- runner | Bin 31632 -> 0 bytes 2 files changed, 35 deletions(-) delete mode 100644 Grammar-FE-t-NoTask delete mode 100755 runner diff --git a/Grammar-FE-t-NoTask b/Grammar-FE-t-NoTask deleted file mode 100644 index 1ad478e..0000000 --- a/Grammar-FE-t-NoTask +++ /dev/null @@ -1,35 +0,0 @@ -* Dev - Sprint1-TokenLocationLogic-NoTask - Sprint1-TokenizeConstantsAndLiterals-FE-t#03 - Sprint2-BlockHandlingGrammar-FE-t#34 - Sprint2-CombineGrammarAndMakeAndRunner-BE-NoTask# - Sprint2-NewFormatPlusGrammar-FE-t#NoTask - Sprint2-PrintOutErrorTokenPositions-NoTask - Sprint2-Symbol_Table_Setup-FE-t#32 - Token_Error_Logic-No_Task - main - remotes/origin/Dev - remotes/origin/HEAD -> origin/main - remotes/origin/Sprint1-BasicProgSetup-FE-t#06 - remotes/origin/Sprint1-BasicProgSetupFix-t#06 - remotes/origin/Sprint1-HelpInput-FE-t#18 - remotes/origin/Sprint1-TokenLocationLogic-NoTask - remotes/origin/Sprint1-TokenizeConstantsAndLiterals-FE-t#03 - remotes/origin/Sprint1-TokenizeID_MainFunction-FE-t#04 - remotes/origin/Sprint1-TokenizeOperators-FE-t#08 - remotes/origin/Sprint1-Type/Keywards-FE-t#07 - remotes/origin/Sprint1-punctuation/grouping-FE-t#09 - remotes/origin/Sprint2-AssignableAndMemory-FE-t#39 - remotes/origin/Sprint2-BlockHandlingGrammar-FE-t#34 - remotes/origin/Sprint2-CombineGrammarAndMakeAndRunner-BE-NoTask# - remotes/origin/Sprint2-CommandLineHandling-FE-t#33 - remotes/origin/Sprint2-CompoundStmntGrmmr-FE-t#36 - remotes/origin/Sprint2-FunctionDefinition-FE-t#38 - remotes/origin/Sprint2-Infrastructure-FE-t#30 - remotes/origin/Sprint2-NewFormatPlusGrammar-FE-t#NoTask - remotes/origin/Sprint2-PrintOutErrorTokenPositions-NoTask - remotes/origin/Sprint2-SymbolTableOperations-FE-t#29 - remotes/origin/Sprint2-Symbol_Table_Setup-FE-t#32 - remotes/origin/Sprint2-addingTests-t#00 - remotes/origin/Token_Error_Logic-No_Task - remotes/origin/main diff --git a/runner b/runner deleted file mode 100755 index 2e82053c17fdb3d7d7accdf24e8b6de3f689a7ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31632 zcmeHwd3;pW-S?S<3t>7spHsKtsJTo_cUL9s=p8Wrt~p=|`Ju`2U?e`mRK?I_da1&?o`Rzw%NB9c(+HJuJKR4~$SJ7! zMtX&UZxl?%kM$9B1xU1Yf*lu+rByGU=e)Eh1J6l{}@P*C}kd_vbW zY0nM|z@wm`U9Vi~+2K5)#uTJ9D6IH2RQi9DUXj!rzew1z!!@#e3aa#$L67|MuLf1k z%Vm10>LDiEr-CwhHlebjc5vQsvL~}> z#0LN)8SW3qLu`v9JB?_nuZ$ji>!8E_H>%23`Ld^<)D@ZQ+kdL0QDH9d?BPZb zI(7r6 zCHVrI{2h{BXrnW)w`7ygTUJr+tE{-r&&nz){nY_h<*Td=lz@ruTjH$^`GO&Dm9L_j z)rNv4RW+=vCRkA&Dr4*Yp%PXWsPR{`vXaU`t)Er-t7`or$dv}dAyyXj`$?y|q^6D_ zjI*F$7>5W9mQ?zEL4PpF%J35ik|M<*8!RaY71E{12WZs+FY@FIRRpS;e^UjFZwyw1 z{H#QntElybLUoKXOvB4mwqWtXIdi>}@-LWdpp){aFz>>ZOT0+KzrLb2x8lMppLCt%r{+rGbbeEjh6n%@NXV~gl#g7Jr9*ueC@vy~2=kvP|V=)t5 z<&{`%CVH-vCD3l74>ZwL`z6~n#;Ty&DbdXXtZJu3AFPA{3#9#Sz^M~+URPdPSywOms>^h1Djy@-^|+ndqo6Bb1xyJq#*iH72@TVsY*!6TO#7ev65o zX`=5i(R-WdJ5BT~6MdJ7E|*%I`=E(#9`}A>qRS@5sjTz<>1jBT;nB5su@~@cZwjR)nmr9KXVA)* zvBZ>rUd7nS#E5SIvW75{FDJ&y_(zFEVkeK&gmyB1*oe~veKNk^h||P&GX8`SrwQ$3 z{2?PwljX_y9Y&lcwv+K2jW|tcC*#)`ahk|Z#(hSdCa{z7Wk#GPu9NZEMw}+Blktg0 zoF=N1@u5bXCa9C~K1Q4-rjv1p5zpfBFV3j)(t-lzH{vugq5MXiCM1;Kh|@%b@*8oQ zfKYxFhj**Ecd=L}e}yERsS{lgre_}7Jz!&iACAA1^(w-v2)Pi&g_s;6-# zZ8a0lw;_4DEI(_=Hbl_@8fSKgZBL_?Mqqk-$ce7;G=!*YbWgNo4cS6+FG&dbcZu0J zK@Xj|AX0zK6A3pr)E{$% zF2Zm64U_Sk7QWJ>yV19s(A$wjG?swn$crXoKvQW5q*P}dwl8`{&tlTm5? zf$N#i{t&;;C+IhP0+!kqM!uenw$V7{uVX2b(Y;V)u|wY`5;xYL*oXAOtE2815nJbY zbm!Zo>5h4Jc^u7IPqT}Ag!}7SF^COKj)-;zkf^o-zZ7(BiDJwn#2s_!S`gTDckKG7 zTKnnFJVbQOi(f}`L>mGa`z^c>ai3_YKf$uLUxaFe|K@{1?K}(kMTDbDUi${DhWa)Z z%F(s{AW}KeINfc;eH2_?l2>0cwZOti{UNl#riS`M=~>&qK^7t3WVAf0*RRG1^UuP- z_NJ`ue^f$xVK%BE289?Ua3%N=_fdV-QKE32Q%@9gf8UWEhP2)1R_8= zpYo1675NvLhX15o3yFO5PqKduEwCY$=Gi4$4d~|x)ppM4>M3dV=u5~rn&lg$R|`E6 zjmCaQc!WAqJ8CP+@pu3XV^3LW9vNR|(QA0{dGq!oe-v;H21tx!g`Vm&hE?fz!za zKTh{F4(jtfE2IRYu~V22J(2X-8iKmkhh$LWSx-C9Tuu~sYzO)rRlmDM*N7IuumuA8 zLDthv=n{?2<8V>d(_ON6xZk9K2Bdy8Ha#{9ff3Q7(j-dS1hjRES^NyT zB8l%p0yow-Z-wJF_se?P{U%Ri3))r(Y5bDNP|A7%9n<|LT%c0F9m6CyH{IPF{;@fs za7vx~F|4R8czDk>6=#-IE1UT+I_cN6U@%*KVWgpZq@n%@3y+68-@8n>Q`ZgwL&3}% zjV29vv;|(dn&ipbI~?P3{&t9NJt895*&BAOo*q%=P3W;*@X-ACZ}?eH4;zA7J- zF6cw39v^Ttj#-#5pLULxW~f%R85BWn>slT#WG_AzW6$1KVIw{QHuuuB93M#7>xA_o z>=0qy2)hG~JN_LesJ(X*c8ajO2#XVTH(?(Vb`N3i5OyzNuM_rT!uAuki?H7jb{}Dn z5mtsFIR2l6`3bv^uqz0=ov1VFiS} zPZ&)q@xz2oBwCcPNrXK|SUzD-5#}fF{t_7Gv6XUyX@?{~Ix0qqC@W2Dgwr(y6aMyiJd`?ogsposQ7=Qw{Y1n#y7K(T}f5wt{SL`VcJ z64AnGJmb3aYQbJ%VSDtV3|+gDXqcEW;%l5g{l#Di7KebYyN?p989i$nqOo6L^CCJS zeDP)mMUFx3^m59Ey9LW878(sgPqNA9CXErQYhMeI7-k^qCNxoj`iZ2*Phog?Yhwi362F4y&^eLfXa@w0niGy2Ml|Ui z;>T_^4E7|JFnDwsM_c0AGzT|oEf@ukmA!{tj$7BW{IU+>`XsO$+`4 z3n!zEjzfCWINRBsz!z4TwjI2E|8Wq=8hakXmAuD$E_{KFD*qFWwI&g5V4xINT!W;T7tfzxC|~)u2Fg9ZhIk4fW0Jh7p|N$(4-8qHb8>cwWSws@b) z);@}hnO~43p`j^_uh%F+s(ik@zaEVTj>Mv3PDU%O1Y@3PA-W?`r68(}D)|n%`s#m< z;-Og}zp~vHU&_n7hy!gh0h6PXj%ldh$Fgqw7<2ZGz+6~abc?z<0&iss?Jt*FwTGja z+ggyPsJjVG4d7+`vev0kd5>gu?Inu}?^f=Eo|1#Q`(?`EK@2_mswQd|FQZ+&Jj1=O z{yeBvk{bHZu{K)nVqxBt2zAA8kMPgc8_vD|xaOt1(LS%|0}gyd2SnK_>odlqfbFQc)@!R%EdpM0AW}U9j8i=18}>zao^vaX#g z5l2_iwM9T+VSYpXK^D%9x_Kvu!dHuhxz{ktwN3z?x;!$TCG52m+pve3huE!XC48pT zou|Qv>uD6qJVvs*_KKl$5DRa;Fn9WkS+_k2HQjkYN$c9PKo7TLr{_LGOElWMWZo|f zY_k~P{X?H}1LtLybDnfwf7x&5^`$b*%|NzS3lp;q6R?X+p^M3$vwH-|Mq?jlQD&W^ zg?t~2yuRv4!{=$}zq+#@7*sy2(z|m}=a-9kDL*7&I7Unze<2!mLB1Gu9uktj?LhK5 zAxU$olKzR1zS$;CgM)T8h`M{PbxP4Sl8v}e!{-Z03uh8>xsPqf+IU-2sJ{ohJJXJ2 zISw6Yw}5>bjqy9&r?9z0j>X2L-$1ccmm8DQ5iOt0^8KVX3Mg$%lHz_me<61Tr*Eu3 zy%h%e#^e+kbpAyqWlJM_uuu{klT)UR$(Jr^Zo2z4ZA_909V1i5X2z_OHYAw^Y)slQ z?rLQ}K%S?g*jrCyT!Wpp#;!k7e*yw-5`eD`xKCm9IbjsvIY1bb#Xk|zCXl2k{%D|7 z{G@o9ED82yCvZAqD}Ic8$@hM6aZ;&I%A$OwiZb1Of{LHi`LnE+vt5>+tO1pUth<}A z{Y0Z^s6WlZ8tlkDdD07}(>HkI!iC%$w6h&fC?*=(139yJL~HkeW@_eWjx=@Q&?c*4 zKH8A3orDBP5%+Ouy-VV{_M%Oz2wgMtIl+6x;K|_u6+k9wIf_#d-Fc6Y+ib{*E=&{L zamaGH_SPIvLlx?~p{k80TQqWH+TF&pzET*NX)}PVqgiZ>k{mXY?PQB)RZ|QpInNc^ zi3R3@V-$;M8Jy$%2XS=m1FL}ZbHp*y!om?D@SH_}k3rIPe4Vy*D9m6Wx~wN)Llut0 zu!hDkDo++@abC*}@iT=T+D$S7dIQj%$+aaa6ouESKt(NH1;BT)Yk3^QK-Tt0(KnH? z8K6LLH~~|g(u#6C(clo;E^z+z7q7(%M9T#oqgiVe@LpWq`RDl%9fN_p9kh0eh%Lci zfyR3MBay&5E|iU*8?X@y4aSl()TfnBK5r#ilonAx)Z`b z1r#G!#QiPew95P+hA9fb0&f7>MrvHt8B#cIV<83)QU6Bw@-C5}ha% z2M|bl0#n4K*!5kx%@5rKGBdcK^9zdYx1ABaiS~~(BAEV|*f5QgU*{jWqV@vUP{&WQ z6N<$hU+cYqi8OWwoFMQh8Y(lyA> ze4#YKqC}Zp3G35AMVlE5z`IU=A)ICv)}4Kb5Gg`4bACCG=j%fPhU;`^E8?R0zas>m zHw36r<47_shA9_Yy~AM8?9=Knw_)A+fY7_i&}-()2W*#b=N#wtLcnhkK)=F4rB)+& z6$B#MMLgzQB#4s<7+IzDKt!X5MXCG%yyc7rvePm~x~SPi!pC1IL|$Vrbtl6pMnio& z<4f@0VEm`nd~Y|h3A0S-UZX(b@#$%y#h3|n0_2<=VCz0=i{Eu+SVYl-X1N)v@Lu?^>-kN z(l}&9X_g}wQ8#fzX|&8J&}l+nduBFtWko$kxUStxpo8+ZhcjXy;F!bOO=zf3X7F>E zjlGU!VCO1nn)>{5VS0wewCeM2P|@e70`NXRLJ0S^3hU0nL=b&GO^CD>nzO1qze1e% zdF>_&bE_+Vd7+V)g~~7ep2F#RFW<`G^p|-4Hj1ixwQMM74*(a4>t5!+kW+ zVKr;pK`@c*RTS5?1q2Lta)I4kK$}S%>HCR7cz{J%brLk3JH+`?4&bq^cVqi&O&`--{Ckas=WY?ETUxyLOarK7KXxMPZaB0 zM#j;`$PBWXry(BEN<;!{q$q7r3-N##Nwi~{;TnzoUV$=YZ3@Jm=Q#LHEwoLgR;xKl zJ*uSvP>BBqKM+4N3!t$GQd%pa*v;L17qO!5HjD%ialTJcKa+@yC&h82w*Kr}W?@WAx9J`Q3#o zAse_c7vT+8&H-Ykmm>lWWFcc38C<*oL{iNOqpp}dcz>eNW4MyB3?!42)M*MOzdiSr zs7H$n#8AOgj>ew;07Ih4BA-{_Xsg2t;IN~SFm1=>^aYoYTVVcWsup#Vl23mNazqvU z7-pjG=TP<^-c{3 zqbRoBHU&8qw#nvm9yWB=YWVzIkqaEdP&L49atiHmzSOlZW{@1F2$A}4u||z(Q$RH@IcQkt zb)}W01@5#{PkDJeNYi81_tKY#wj2&PRmU?ItnNDPmdTZo+orV4$USdz}z2HVI=nhcTo9 zDXk$Y8tYY}oC^`95c>z3jV-gr5=wTC{>KuD4!TYx+{W84m*TyKbu1{&eEc5ne!lt= z5~cQoM6g>{PpR>|bpCXDpwk1L9_aKyrw2Mc(CL9r5Bv)rpugv%P*Hs?{*bcNRZ(3N z4!Jf~gvwnL$Gc`-Fy0jix~c=!u6$o*O}WqI3$AzdU_n+|QC6muSV_6RWP>*lD)$FT zT-x#q*^O*Osf+$!Q0f{sqIOshmWRh9nXo5wIF5~BqggI~`?3D`9fQAR&BogW`mllQ z9OlAb(hXuxb}k#$;lBZ}GE7=xcq@U6@hO~5rSz#B=;po~eqkE5@ zy)t`eW%n^c-*fso&viI*a&uAyM}Ke~19Aoq8hqXm*U+4tVL9gyACWV1)aWr|$Boa+ zapYT5`hOB*4pDHtqe6r(9CYd8=+Z&JfkB7iA@(r;HlpsF7&1R% z7XiD9tz~}juE6DES28as%h+YWeuxL&9%dJ_)$DR`8C#6Fhv8Wnzy%C9M|fBY${eM{k*Eyw_m@Vxy!cKUf9+Fs!d-(~){dVJnWuw#t7E z9Bwn>imu>x*3rMM@Q9MQNn#zzS!r9@P55V}ogE{ov#I~H6lUbUBmZLv8 z_U`DfJrVDP_n%M?&c+DU7b8?ZK00+l?dO8qpA7&u5Mx#j{td=;9><2@m&T?Xj6L)_ z4C6;W>Tx3Kb2{+z*+@2(EkvuCfI1$}e!v#7$!rF@5hF_x+RRp5BY|&WH?YmDo?VX? zb{(q&Z4-1iqCJjeVPNzxgliO11$lwt|(T?UwP@S;C6Z zKGyNpxt6Wrt@8@rGB0DR&>mN?9Ra@e#uEt6NFKX}y@p=arf5AdtUUk6bE1|b2xXJ?I z>QcsjemIeM9oIX!KEy?Tfp`knceuK}l}Pl#H4xVbToZ6j$2Aw%5?q(#^5NQmD~#&~ zToGJ%;d%hqZd^~`dKT9!xZcF|F0M~-{T0_&xEyaM5kpPy1~4P> zHCzS!WOiqn53k68*F?ZeE+~=Gx@uolMTrY=rK^S zn5qfamgg1wN;bHRG{4VY3EqVf@|&$;_Dr3=zq&RYRO0kbi;@jI3q0fBqvxfDV@>6I z(~;kx6Ny`auRM@Q>;WtVJOsEW znn;8IA2^su90wfodLq#!jj_T*iNtWgn*rwm?nGNC2mIt+*a39DpGZ6kI1p!`hX7CD z#QX$cw+|DEUg?ZI16Tm~IPS_60bcS^B2fc)3~(o4<;RJ{r-0ayXp3wOe<0~`-{3*chF`vEHf zp9H)W@DSjmfS&;#0{jy21YqXp(C^Av5O6%;kXGme&IGIkECak15D!%I;J9u%b8O0X z4D8h{V<-GabXvzugMUYo#Jq0V1cu|H`!(xcN+i}nj`hx--#hmQSv@yqY+;uSxM=JJ z!-s*&_16IILVa;XA|jC85U!n|7m>aUl-8}doR__+?nKLm2W*DwYE8vM<~Wz2=^1g;t2ckc#7>AM@!)4%D;g-9kFwp|#< zR=_tF8Mlz3d`^bUrGH8!=x;g6}K%mn)TBs8$NCae>eJWx|yH$PeVT!efSpi z<$SY!KWB@60sb!VkD2*tZ*zfM&{l)L5@W!{W<_t-xT{?zZ$?}zbc6!^FsnoNIbGX2Tmp9ene|Bd`DOY&EOpZh)h z5cqw;Pg#EO)4nJDJ>Y*0-}}w!r>)@`Apaf#e-`u~v+zadApU9aUkCp@Gk;Yw|NSt2 zz6w6gzef4iCHa%Ve+&E}X8vV@Po&P!>48oUbb6rE1Dzh|^gyQvIz7$05cK~FNhYFc8x@W3D)H@*6`%ec-KAizj;CmK8^&V8(4^U8iJXaT> zIGyQGz*3)wy>uRcAOVX>K8~k&xKL&kfB3`$?Exv^ub(YJs&HH=OYy8 zh=Ky&g8`P~j}<5=`Z}3mm2bXJ249NdBv}N$#{sJ3@c21T8Od=H9wX%O0x6J4^0@*0 z*)r$1$%OF|03KK6kjeay0rkFhyTJlk--QwuNw`kJ8VR>ZxKqLhC45}MCJCD*Y>}`{ zLfly5AzMP1gar~7N?0V}ItgnewCDSO7gz7urRrDLg1K`qa*bY99Ig(9T@xqfPtGsM zn;7QNiJK=)$}gBaMv_xoCtF?E7YVxrwGRh4x5^51Ndf9^9m!MsNn_b8TlPmO&RmjS zXro^s>8k%K`Gr6n=zX3VL81InScS`hCk#}7lnJf{sk^K<{L8;GWZib3}ZCWM3ia zEs{>}QK#UObbebLaYZkebeEfpv4^F6K+;?0Tj|$w`T+K*E&sPk`s0$W>gDI4Q+xPZ zfw05R^?*Jr>Bq(i`t1U+W=YQ)Aqf1e7U*Y^K6|8~EB|~Y>HFk>$MmLGOZbjq-VqtS>bz z_vUnqX&xB{y6bE*n+1AD@6o>v9hvSkFOvCG>!-^k{Z2{eXTQkZT1k&eJ8HdlwWN=mB#OZAGXSmQ^s|b^ZUvp{*WRw~ zOCkR#=+r*f+5G$@m(OPTG!Y~4`xk)wCH(`LPqhwyErtCLr2HCb=NPw!duX7$ByI-Z zNcoVopDmdgSU~ql>(4S|K9!CW^p5IxET?C)M{IVckR8$}6c&&i5A&pax}3PwI(T&o z`x~Tuh8%}?N;}u5kf%3BQTyy!AOt^=@(+Wa4gc@8m1{TXR4+x6uJU=O^iPW{w48p} zZ&IZDqO@=C?{9GVZ1yTm5D5HUDd5|Z{*-Kh{2nLh?@D^HYzPmL5<;BQ1#bTR26XCQ z{cQQ~hK&#TVVkTMHLhlJy4ixjho+!U2A$f2%jUO2q9fg0Te?d@cb#pXm2>;qY?vH> zRKE*Jdb_QiZw7r>2X@YNpj>I#Rc2e6_i;N`8pVDk?f*ok`>*|2uc@*&&ig*&l8w%8%MXT~{vePJD9;ht!mX!N~6shJ|Eukf3(aX(H z28hJJ6hla9MX8Y0LQ{&SJNh?9~ddh62*f ztOD(d9xX?^!Iy06>Vkez8KBd1;`Ak+LiI@;{v90qw|xvQKA2gxE1lIrU4=_FK(vSWG>OMd0ZVh95Z3M~7a_%M@&Usp$UL~Vs0=z;(`4x*F> zxk!A%$);g?mryEfo0_f?mov8iu3*=$iU@xiC{_>R)0NFHB%@`mXd zyt+Di@XZ(=cs~^1ow6B#4{3;0EnIw*$|h42sIgkYU`a{vgk=p{RJ`8eTHeotA$;Zv zjv!e+?v+(0vn4)iWl^M(d#l4$#eVATR5&Qpho~%4;-gd+lGnR($z0jjO9GYQs%mA1 z_mvJmFeR!#mjxQU>c_ zmlBlFu75e`cwuosi&R&YG0(%x0nCNQh$y#sO~o?sP0dYKKab9{}5>86J_66Ps??+x(@>p9_;o1AE27` zT~bfMbvB1fwvo(koBkHLK~Yf2i`0|LeMNuVroU6_D`9=(5H8$n*xMm??OZT#x@A}x-qbbxJp;aQg`i0|EZvm7+_PdMcID?#)|>v From 3db61919691010581f55a1de18094cb90d69f60c Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Wed, 12 Mar 2025 10:27:48 -0400 Subject: [PATCH 003/137] fixed symbol_table entries not working --- src/symbol_table.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index fa0e6bb..4369551 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -37,17 +37,18 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { //create entry just for things below top level scope TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id) { -if(table ==NULL || table->Parent_Scope == NULL){ +if(table ==NULL /*|| table->Parent_Scope == NULL*/){ printf("Null reference to table given for create entry or given top level scope which is invalid\n"); return NULL; } -TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); +/*TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); if(topDef == NULL){ printf("This type is not defined at the top level\n"); return NULL; -} +}*/ TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode)); - newEntry->theType = topDef->theName; + //newEntry->theType = topDef->theName; + newEntry->theType=typeOf; newEntry->theName = id; if (table->entries == NULL) { table->entries = newEntry; From f0e03b27247cfe883ef13df699cf177e0dfac2c5 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 04:24:03 -0400 Subject: [PATCH 004/137] save point for tweaking symbol table--note won't be currently working --- src/symbol_table.c | 81 ++++++++++++++++++++++++++++++++++++++++++++-- src/symbol_table.h | 42 +++++++++++++++++++++++- 2 files changed, 120 insertions(+), 3 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 4369551..08de0de 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -8,6 +8,71 @@ #include char * typey = "type"; char * funy = "function"; + +typedef enum { + //First 4 below are primitive types that are all encapsulated in primitive type + //TYPE_INTEGER, + //TYPE_CHARACTER, + //TYPE_BOOLEAN, + //TYPE_ADDRESS, + //Type String is an array of char enclosed in double quotes per lexer + TYPE_STRING, + //Array can be multidimensional. Information should be stored here + TYPE_ARRAY, + //Record is user defined types + TYPE_RECORD, + //Declaring what type a particular function is without as + TYPE_FUNCTION_DECLARATION, + //Declaring what type a particular function is with as + //TYPE_AS_FUNCTION_DECLARATION, + //Declaring what type a function is (what the parameters and output are) + TYPE_FUNCTION_TYPE, + //The Type being pointed to by the first 4 above that only stores the size + TYPE_PRIMITIVE + +} types; + +/* put in symbol_table.h +typedef struct{ + int size; +}primitive_info; + +typedef struct{ + int length; + char* location; +}string_info; + +typedef struct{ + int numofdimensions; + //the above value tells you how long the below array is. For example if num of dimensions is 5, I can store 1,3,2,5,9 to define a multidimensional array of that size + int* arr; +}array_info; + +typedef struct{ + //similar to above we define a record to hold the number of elements and an array of tablenodes (types) that it contains in the order specified by the user + int numofelements; + TableNode* listoftypes; +}record_info; + +typedef struct{ + int startlinenumber; + bool regularoras; +}function_declaration_info; + +typedef struct{ + TableNode* parameter; + TableNode* returntype; +}function_type_info; + +typedef union { + PrimAdInfo* primitive_info; + ArrayAdInfo* array_info; + RecAdInfo* record_info; + StringAdInfo* string_info; + FunDecAdInfo* func_dec_info; + FunTypeAdInfo* func_type_info; + }AdInfo; +*/ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { SymbolTable* table = (SymbolTable*)malloc(sizeof(SymbolTable)); table->Line_Number = Line; @@ -35,10 +100,22 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { } //create entry just for things below top level scope +SymbolTable* init(SymbolTable* start){ + if(start->Parent_Scope == NULL){ + printf("Cannot initialize a scope that is not the parent scope\n"); + return NULL; + } + TableNode* table1 = (TableNode*)malloc(sizeof(SymbolTable)); + table->Line_Number = Line; + table->Column_Number = Column; + table->Parent_Scope = ParentScope; + table->Children_Scope = NULL; + table->entries = NULL; + TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id) { -if(table ==NULL /*|| table->Parent_Scope == NULL*/){ - printf("Null reference to table given for create entry or given top level scope which is invalid\n"); +if(table ==NULL){ + printf("Null reference to table"); return NULL; } /*TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); diff --git a/src/symbol_table.h b/src/symbol_table.h index 03028ad..46caa02 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -3,6 +3,44 @@ #include #include +typedef struct{ + int size; +}primitive_info; + +typedef struct{ + int length; + char* location; +}string_info; + +typedef struct{ + int numofdimensions; + //the above value tells you how long the below array is. For example if num of dimensions is 5, I can store 1,3,2,5,9 to define > int* arr; +}array_info; + +typedef struct{ + //similar to above we define a record to hold the number of elements and an array of tablenodes (types) that it contains in the > int numofelements; + TableNode* listoftypes; +}record_info; + +typedef struct{ + int startlinenumber; + bool regularoras; +}function_declaration_info; + +typedef struct{ + TableNode* parameter; + TableNode* returntype; +}function_type_info; + +typedef union { + PrimAdInfo* primitive_info; + ArrayAdInfo* array_info; + RecAdInfo* record_info; + StringAdInfo* string_info; + FunDecAdInfo* func_dec_info; + FunTypeAdInfo* func_type_info; + }AdInfo; + typedef struct ListOfTable { struct SymbolTable* table; // struct ListOfTable* prev; @@ -10,8 +48,10 @@ typedef struct ListOfTable { } ListOfTable; typedef struct TableNode { - char* theType; + //reference to the type entry that this is + TableNode* theType; char* theName; + AdInfo* additionalinfo; struct TableNode* next; } TableNode; From 392a4b3ba57cfc2e2f3fe90f4a7acad13c8371b0 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 05:32:24 -0400 Subject: [PATCH 005/137] wrote up symbol table structure. Have to correct code and then add type checking grammar rules --- src/runner.c | 2 +- src/symbol_table.c | 124 ++++++++++++++++++++++++++++++++++++++------- src/symbol_table.h | 2 + 3 files changed, 109 insertions(+), 19 deletions(-) diff --git a/src/runner.c b/src/runner.c index 2110d23..f02e2cf 100644 --- a/src/runner.c +++ b/src/runner.c @@ -75,7 +75,7 @@ fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number,tok, yytext); } int run(FILE *alpha) { int token; - top = cur = CreateScope(NULL, 1, 1); + top = cur = init(CreateScope(NULL, 1, 1)); // If file is not found if (alpha == NULL) { diff --git a/src/symbol_table.c b/src/symbol_table.c index 08de0de..c50eac8 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -44,8 +44,9 @@ typedef struct{ typedef struct{ int numofdimensions; - //the above value tells you how long the below array is. For example if num of dimensions is 5, I can store 1,3,2,5,9 to define a multidimensional array of that size - int* arr; + //the above value tells you how long the below array is. For example if num of dimensions is 5, I can store 1,3,2,5,9 to define > + int* sizesofdimensions; + TableNode* typeofarray; }array_info; typedef struct{ @@ -73,6 +74,53 @@ typedef union { FunTypeAdInfo* func_type_info; }AdInfo; */ + +primitive_info* CreatePrimitiveInfo(size){ + primitive_info* prim = (primitive_info*)malloc(sizeof(primitive_info)); + prim.size=size; + return prim; +} + +string_info* CreateStringInfo(int length, char* loc){ + string_info* stringy = (string_info*)malloc(sizeof(string_info)); + stringy.length=length; + char* location = loc; + return stringy; +} + +array_info* CreateArrayInfo(int dim, int* sizes, TableNode* type){ + array_info* arr = (array_info*)malloc(sizeof(array_info)); + arr.numofdimensions=dim; + arr.typeofarray=type; + int* dimensionsizes = loc; + return arr; +} + +record_info* CreateRecordInfo(int length, TableNode* typesarray){ + record_info* reccy = (record_info*)malloc(sizeof(record_info)); + reccy.numofelements=length; + reccy->listoftypes = typesarray; + return reccy; +} + +function_declaration_info* CreateFunctionDeclarationInfo(int line, bool asorregular){ + function_declaration_info* fundec = (function_declaration_info*)malloc(sizeof(function_declaration_info)); + fundec.startlinenumber=line; + fundec.regularoras = asorregular; + return fundec; +} + +function_type_info* CreateFunctionTypeInfo(TableNode* parameter, TableNode* returntype){ + function_type_info* funtype = (function_type_info*)malloc(sizeof(function_type_info)); + funtype->parameter=parameter; + funtype->returntype = returntype; + return funtype; +} + + + + + SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { SymbolTable* table = (SymbolTable*)malloc(sizeof(SymbolTable)); table->Line_Number = Line; @@ -105,28 +153,68 @@ SymbolTable* init(SymbolTable* start){ printf("Cannot initialize a scope that is not the parent scope\n"); return NULL; } - TableNode* table1 = (TableNode*)malloc(sizeof(SymbolTable)); - table->Line_Number = Line; - table->Column_Number = Column; - table->Parent_Scope = ParentScope; - table->Children_Scope = NULL; - table->entries = NULL; + TableNode* integ = (TableNode*)malloc(sizeof(SymbolTable)); + TableNode* addr = (TableNode*)malloc(sizeof(SymbolTable)); + TableNode* chara = (TableNode*)malloc(sizeof(SymbolTable)); + TableNode* stri = (TableNode*)malloc(sizeof(SymbolTable)); + TableNode* boo = (TableNode*)malloc(sizeof(SymbolTable)); + TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); + start->entries = integ; + integ->next = addr; + addr->next = chara; + chara->next = stri; + stri->next = boo; + boo->next = arr; + integ->theName= "integer"; + addr->theName= "address"; + chara->theName= "character"; + boo->theName= "Boolean"; + stri->theName= "string"; + arr->theName= "array" -TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id) { + //root TableNode that all are pointing to but not in table + TableNode* prime = (TableNode*)malloc(sizeof(SymbolTable)); + prime->theName= "primitive"; + prime->theType=NULL; + prime->additionalinfo = NULL; + prime->next = NULL; + + TableNode* striprim = (TableNode*)malloc(sizeof(SymbolTable)); + prime->theName= "1->character"; + prime->theType=NULL; + prime->additionalinfo = NULL; + prime->next = NULL; + + integ->theType=prime; + addr->theType=prime; + chara->theType=prime; + stri->theType=striprim; + boo->theType=prime; + arr->theType=prime; + + start->Line_Number = 1; + start->Column_Number = 1; + start->Parent_Scope = NULL; + start->Children_Scope = NULL; + + return start; +} + +TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id, AdInfo* ad) { if(table ==NULL){ printf("Null reference to table"); return NULL; } -/*TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); +TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); if(topDef == NULL){ printf("This type is not defined at the top level\n"); return NULL; -}*/ +} TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode)); - //newEntry->theType = topDef->theName; - newEntry->theType=typeOf; + newEntry->theType = topDef; newEntry->theName = id; + newEntry->additionalinfo = ad; if (table->entries == NULL) { table->entries = newEntry; return newEntry; @@ -137,7 +225,7 @@ if(topDef == NULL){ return newEntry; } } - +/* //we use false for type defs and true for functions for parameter of typeOf TableNode* Define(SymbolTable* table, bool typeOf, char* id) { if(table ==NULL || table->Parent_Scope != NULL){ @@ -171,7 +259,7 @@ if(table_lookup(table,id) != NULL){ } } - +*/ TableNode* table_lookup(SymbolTable* table, char* x) { TableNode* entrie = table->entries; for (; entrie != NULL; entrie = entrie->next) { @@ -217,11 +305,11 @@ void print_symbol_table(SymbolTable* table, FILE* file_ptr) { for (; entrie != NULL; entrie = entrie->next) { if (parant_scope == 0) { fprintf(file_ptr, "%-17s: %06d : : %-21s: %-28s\n", - entrie->theName, current_scope, entrie->theType, + entrie->theName, current_scope, entrie->theType->theName, "Extra annotation"); } else { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName, - current_scope, parant_scope, entrie->theType, "Extra annotation"); + current_scope, parant_scope, entrie->theType->theName, "Extra annotation"); } } if (table->Children_Scope != NULL) { @@ -254,7 +342,7 @@ SymbolTable* getFirstChild(ListOfTable* lt) { return lt->table; } ListOfTable* getRestOfChildren(ListOfTable* lt) { return lt->next; } TableNode* getFirstEntry(SymbolTable* st) { return st->entries; } TableNode* getNextEntry(TableNode* tn) { return tn->next; } -char* getType(TableNode* tn) { return tn->theType; } +char* getType(TableNode* tn) { return tn->theType->theName; } char* getName(TableNode* tn) { return tn->theName; } int getLine(SymbolTable* st) { return st->Line_Number; } int getColumn(SymbolTable* st) { return st->Column_Number; } diff --git a/src/symbol_table.h b/src/symbol_table.h index 46caa02..497cf3f 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -15,6 +15,8 @@ typedef struct{ typedef struct{ int numofdimensions; //the above value tells you how long the below array is. For example if num of dimensions is 5, I can store 1,3,2,5,9 to define > int* arr; + int* sizesofdimensions; + TableNode* typeofarray; }array_info; typedef struct{ From f0e0d7bdbc3816560e3f9d34062bd53f83a8dffa Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 12:04:53 -0400 Subject: [PATCH 006/137] still working through symbol_table to try and get it to compile soon but fixed issues with storing values and calling the right element of a struct --- src/runner.c | 2 ++ src/symbol_table.c | 50 +++++++++++++++++++++++++++++++++++----------- src/symbol_table.h | 23 ++++++++++++--------- 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/runner.c b/src/runner.c index f02e2cf..238abf1 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,6 +2,8 @@ /* The Translators - Spring 2025 */ #include "runner.h" +extern TableNode* funprime; +extern TableNode* arrayprim; int main(int argc, char *argv[]) { if (argc == 1) { diff --git a/src/symbol_table.c b/src/symbol_table.c index c50eac8..7e8c339 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -8,6 +8,8 @@ #include char * typey = "type"; char * funy = "function"; +TableNode* funprime; +TableNode* arrayprim; typedef enum { //First 4 below are primitive types that are all encapsulated in primitive type @@ -81,18 +83,20 @@ primitive_info* CreatePrimitiveInfo(size){ return prim; } -string_info* CreateStringInfo(int length, char* loc){ +//probably don't need the below structure since can create from an array +/*string_info* CreateStringInfo(int length, char* loc){ string_info* stringy = (string_info*)malloc(sizeof(string_info)); stringy.length=length; char* location = loc; return stringy; } - -array_info* CreateArrayInfo(int dim, int* sizes, TableNode* type){ +*/ +array_info* CreateArrayInfo(int dim, /*int* sizes,*/ TableNode* type){ array_info* arr = (array_info*)malloc(sizeof(array_info)); arr.numofdimensions=dim; - arr.typeofarray=type; - int* dimensionsizes = loc; + arr->typeofarray=type; + //avoiding storing any types like below + //int* dimensionsizes = loc; return arr; } @@ -103,6 +107,7 @@ record_info* CreateRecordInfo(int length, TableNode* typesarray){ return reccy; } +//below function takes a bool to see if parameter should be decomposed or not function_declaration_info* CreateFunctionDeclarationInfo(int line, bool asorregular){ function_declaration_info* fundec = (function_declaration_info*)malloc(sizeof(function_declaration_info)); fundec.startlinenumber=line; @@ -158,19 +163,21 @@ SymbolTable* init(SymbolTable* start){ TableNode* chara = (TableNode*)malloc(sizeof(SymbolTable)); TableNode* stri = (TableNode*)malloc(sizeof(SymbolTable)); TableNode* boo = (TableNode*)malloc(sizeof(SymbolTable)); - TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); + //TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; addr->next = chara; chara->next = stri; stri->next = boo; - boo->next = arr; + //boo->next = arr; + boo->next = NULL; + integ->theName= "integer"; addr->theName= "address"; chara->theName= "character"; boo->theName= "Boolean"; stri->theName= "string"; - arr->theName= "array" + //arr->theName= "array" //root TableNode that all are pointing to but not in table TableNode* prime = (TableNode*)malloc(sizeof(SymbolTable)); @@ -178,19 +185,37 @@ SymbolTable* init(SymbolTable* start){ prime->theType=NULL; prime->additionalinfo = NULL; prime->next = NULL; - - TableNode* striprim = (TableNode*)malloc(sizeof(SymbolTable)); - prime->theName= "1->character"; + + //note sur exatly how to get array types to look right so using a dummy Table Node below and updating the print symbol table function to access the additional information to print for array types, similar to function types + TableNode* arrayprim = (TableNode*)malloc(sizeof(SymbolTable)); + prime->theName= "array"; prime->theType=NULL; prime->additionalinfo = NULL; prime->next = NULL; + //funprime = CreateEntry(NULL,NULL,strdup("function primitive"),NULL); + + //similar workaround to arrays above + TableNode* funprime = (TableNode*)malloc(sizeof(SymbolTable)); + prime->theName= "primitive function"; + prime->theType=NULL; + prime->additionalinfo = NULL; + prime->next = NULL; + integ->theType=prime; addr->theType=prime; chara->theType=prime; stri->theType=striprim; boo->theType=prime; - arr->theType=prime; + arr->theType=arrayprim; + + //filling in all the values for the additional info for initial types + integ->additionalinfo = CreatePrimitiveInfo(4); + addr->additionalinfo = CreatePrimitiveInfo(8); + chara->additionalinfo = CreatePrimitiveInfo(1); + stri->additionalinfo = CreateArrayInfo(1,chara); + boo->additionalinfo = CreatePrimitiveInfo(1); + //addr->additionalinfo = CreatePrimitiveInfo(8); start->Line_Number = 1; start->Column_Number = 1; @@ -304,6 +329,7 @@ void print_symbol_table(SymbolTable* table, FILE* file_ptr) { } for (; entrie != NULL; entrie = entrie->next) { if (parant_scope == 0) { + if(strcmp(entrie->theType->theName,"function primitive")|| strccmp(entrie->theType->theName," fprintf(file_ptr, "%-17s: %06d : : %-21s: %-28s\n", entrie->theName, current_scope, entrie->theType->theName, "Extra annotation"); diff --git a/src/symbol_table.h b/src/symbol_table.h index 497cf3f..42b0304 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -7,15 +7,20 @@ typedef struct{ int size; }primitive_info; +/*This structure can be subsumed into the structure below (1-d array of chars) typedef struct{ - int length; - char* location; + //shouldn't need to store any values since would be compiled at runtime + //int length; + //char* location; }string_info; +*/ typedef struct{ int numofdimensions; //the above value tells you how long the below array is. For example if num of dimensions is 5, I can store 1,3,2,5,9 to define > int* arr; - int* sizesofdimensions; + //shouldn't need to store any values (like sizes of dimenions or the location + //int* sizesofdimensions; + //do have to store type of array TableNode* typeofarray; }array_info; @@ -35,12 +40,12 @@ typedef struct{ }function_type_info; typedef union { - PrimAdInfo* primitive_info; - ArrayAdInfo* array_info; - RecAdInfo* record_info; - StringAdInfo* string_info; - FunDecAdInfo* func_dec_info; - FunTypeAdInfo* func_type_info; + primitive_info* PrimAdInfo; + array_info* ArrayAdInfo; + record_info* RecAdInfo; + //string_info* StringAdInfo; + func_dec_info* FunDecAdInfo; + func_type_info* FunTypeAdInfo; }AdInfo; typedef struct ListOfTable { From 63534d1daf8465574644a2fbcec7817a693fe549 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 13:35:25 -0400 Subject: [PATCH 007/137] restructured table, still have to update print table properly as well as grammar rules --- src/symbol_table.c | 61 ++++++++++++++++++++++++++-------------------- src/symbol_table.h | 23 +++++++++-------- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 7e8c339..a693301 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -77,10 +77,12 @@ typedef union { }AdInfo; */ -primitive_info* CreatePrimitiveInfo(size){ - primitive_info* prim = (primitive_info*)malloc(sizeof(primitive_info)); - prim.size=size; - return prim; +AdInfo* CreatePrimitiveInfo(int size){ + + AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); + info->PrimAdInfo = (primitive_info*)malloc(sizeof(primitive_info)); + info->PrimAdInfo->size=size; + return info; } //probably don't need the below structure since can create from an array @@ -91,35 +93,39 @@ primitive_info* CreatePrimitiveInfo(size){ return stringy; } */ -array_info* CreateArrayInfo(int dim, /*int* sizes,*/ TableNode* type){ - array_info* arr = (array_info*)malloc(sizeof(array_info)); - arr.numofdimensions=dim; - arr->typeofarray=type; +AdInfo* CreateArrayInfo(int dim, /*int* sizes,*/ TableNode* type){ + AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); + info->ArrayAdInfo = (array_info*)malloc(sizeof(array_info)); + info->ArrayAdInfo->numofdimensions=dim; + info->ArrayAdInfo->typeofarray=type; //avoiding storing any types like below //int* dimensionsizes = loc; - return arr; + return info; } -record_info* CreateRecordInfo(int length, TableNode* typesarray){ - record_info* reccy = (record_info*)malloc(sizeof(record_info)); - reccy.numofelements=length; - reccy->listoftypes = typesarray; - return reccy; +AdInfo* CreateRecordInfo(int length, TableNode* typesarray){ + AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); + info->RecAdInfo = (record_info*)malloc(sizeof(record_info)); + info->RecAdInfo->numofelements=length; + info->RecAdInfo->listoftypes = typesarray; + return info; } //below function takes a bool to see if parameter should be decomposed or not -function_declaration_info* CreateFunctionDeclarationInfo(int line, bool asorregular){ - function_declaration_info* fundec = (function_declaration_info*)malloc(sizeof(function_declaration_info)); - fundec.startlinenumber=line; - fundec.regularoras = asorregular; - return fundec; +AdInfo* CreateFunctionDeclarationInfo(int line, bool asorregular){ + AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); + info->FunDecAdInfo = (function_declaration_info*)malloc(sizeof(function_declaration_info)); + info->FunDecAdInfo->startlinenumber=line; + info->FunDecAdInfo->regularoras = asorregular; + return info; } -function_type_info* CreateFunctionTypeInfo(TableNode* parameter, TableNode* returntype){ - function_type_info* funtype = (function_type_info*)malloc(sizeof(function_type_info)); - funtype->parameter=parameter; - funtype->returntype = returntype; - return funtype; +AdInfo* CreateFunctionTypeInfo(TableNode* parameter, TableNode* returntype){ + AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); + info->FunTypeAdInfo = (function_type_info*)malloc(sizeof(function_type_info)); + info->FunTypeAdInfo->parameter=parameter; + info->FunTypeAdInfo->returntype = returntype; + return info; } @@ -205,9 +211,9 @@ SymbolTable* init(SymbolTable* start){ integ->theType=prime; addr->theType=prime; chara->theType=prime; - stri->theType=striprim; + stri->theType=arrayprim; boo->theType=prime; - arr->theType=arrayprim; + //arr->theType=arrayprim; //filling in all the values for the additional info for initial types integ->additionalinfo = CreatePrimitiveInfo(4); @@ -329,7 +335,8 @@ void print_symbol_table(SymbolTable* table, FILE* file_ptr) { } for (; entrie != NULL; entrie = entrie->next) { if (parant_scope == 0) { - if(strcmp(entrie->theType->theName,"function primitive")|| strccmp(entrie->theType->theName," + /*have to update*/ if(strcmp(entrie->theType->theName,"function primitive")|| strcmp(entrie->theType->theName,"array")){ + } fprintf(file_ptr, "%-17s: %06d : : %-21s: %-28s\n", entrie->theName, current_scope, entrie->theType->theName, "Extra annotation"); diff --git a/src/symbol_table.h b/src/symbol_table.h index 42b0304..7639e14 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -3,6 +3,8 @@ #include #include +struct TableNode; + typedef struct{ int size; }primitive_info; @@ -21,12 +23,13 @@ typedef struct{ //shouldn't need to store any values (like sizes of dimenions or the location //int* sizesofdimensions; //do have to store type of array - TableNode* typeofarray; + struct TableNode* typeofarray; }array_info; typedef struct{ - //similar to above we define a record to hold the number of elements and an array of tablenodes (types) that it contains in the > int numofelements; - TableNode* listoftypes; + //similar to above we define a record to hold the number of elements and an array of tablenodes (types) that it contains in the > + int numofelements; + struct TableNode* listoftypes; }record_info; typedef struct{ @@ -35,8 +38,8 @@ typedef struct{ }function_declaration_info; typedef struct{ - TableNode* parameter; - TableNode* returntype; + struct TableNode* parameter; + struct TableNode* returntype; }function_type_info; typedef union { @@ -44,8 +47,8 @@ typedef union { array_info* ArrayAdInfo; record_info* RecAdInfo; //string_info* StringAdInfo; - func_dec_info* FunDecAdInfo; - func_type_info* FunTypeAdInfo; + function_declaration_info* FunDecAdInfo; + function_type_info* FunTypeAdInfo; }AdInfo; typedef struct ListOfTable { @@ -56,11 +59,11 @@ typedef struct ListOfTable { typedef struct TableNode { //reference to the type entry that this is - TableNode* theType; + struct TableNode* theType; char* theName; AdInfo* additionalinfo; struct TableNode* next; -} TableNode; +}TableNode; typedef struct SymbolTable { TableNode* entries; @@ -71,7 +74,6 @@ typedef struct SymbolTable { } SymbolTable; SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column); -TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id); TableNode* table_lookup(SymbolTable* table, char* x); TableNode* look_up(SymbolTable* table, char* x); void print_symbol_table(SymbolTable* table, FILE* file_ptr); @@ -83,6 +85,7 @@ SymbolTable* getFirstChild(ListOfTable* lt); ListOfTable* getRestOfChildren(ListOfTable* lt); TableNode* getFirstEntry(SymbolTable* st); TableNode* getNextEntry(TableNode* tn); +SymbolTable* init(SymbolTable* scope); char* getType(TableNode* tn); char* getName(TableNode* tn); int getLine(SymbolTable* st); From 9361ed62e76a633c2364dc0a7db90265fc86bc45 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 14:46:31 -0400 Subject: [PATCH 008/137] added a type check function in symbol table --- src/symbol_table.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index a693301..5eb94d2 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -10,6 +10,7 @@ char * typey = "type"; char * funy = "function"; TableNode* funprime; TableNode* arrayprim; +extern SymbolTable* cur; typedef enum { //First 4 below are primitive types that are all encapsulated in primitive type @@ -256,6 +257,11 @@ if(topDef == NULL){ return newEntry; } } + +char* getType(TableNode* tn) { return tn->theType->theName; } +char* getName(TableNode* tn) { return tn->theName; } +int getLine(SymbolTable* st) { return st->Line_Number; } +int getColumn(SymbolTable* st) { return st->Column_Number; } /* //we use false for type defs and true for functions for parameter of typeOf TableNode* Define(SymbolTable* table, bool typeOf, char* id) { @@ -368,6 +374,36 @@ SymbolTable* getAncestor(SymbolTable* table) { } } +bool typeCheck(char* firstID, char* secondID){ + + + TableNode* entry1 = look_up(cur,firstID); + TableNode* entry2 = look_up(cur,secondID); + if(entry1==NULL){ + printf("first type not defined\n"); + return false; + } + if(entry2==NULL){ + printf("second type not defined\n"); + return false; + } + if(table_lookup(getAncestor(cur),getType(look_up(cur,firstID))) == + table_lookup(getAncestor(cur),getType(look_up(cur,secondID)))){ + if(strcmp(getType(look_up(cur,firstID)),"array")==0){ + if(look_up(cur,firstID)->additionalinfo->ArrayAdInfo->numofdimensions == + look_up(cur,secondID)->additionalinfo->ArrayAdInfo->numofdimensions && + look_up(cur,firstID)->additionalinfo->ArrayAdInfo->typeofarray == + look_up(cur,secondID)->additionalinfo->ArrayAdInfo->typeofarray){ + return true;} + else{ + return false;} + } + return true; + } + return false; +} + + SymbolTable* getParent(SymbolTable* st) { return st->Parent_Scope; } ListOfTable* getChildren(SymbolTable* st) { return st->Children_Scope; } @@ -375,10 +411,6 @@ SymbolTable* getFirstChild(ListOfTable* lt) { return lt->table; } ListOfTable* getRestOfChildren(ListOfTable* lt) { return lt->next; } TableNode* getFirstEntry(SymbolTable* st) { return st->entries; } TableNode* getNextEntry(TableNode* tn) { return tn->next; } -char* getType(TableNode* tn) { return tn->theType->theName; } -char* getName(TableNode* tn) { return tn->theName; } -int getLine(SymbolTable* st) { return st->Line_Number; } -int getColumn(SymbolTable* st) { return st->Column_Number; } // uncomment the below main function along with the headers above for a simple // standalone test of table and entry creation From 8a1477c04dd1d898ecea9c5fe0d3005687a75ecd Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 15:11:03 -0400 Subject: [PATCH 009/137] started updating values to types --- src/grammar.y | 22 ++++++++++++---------- src/lexicalStructure.lex | 20 ++++++++++---------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 3e9bc44..dba555d 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -21,7 +21,7 @@ //%define api.location.type {location_t} %locations %union { - int integ; + //int integ; char * words; } @@ -34,7 +34,7 @@ %token T_BOOLEAN 203 %token T_CHARACTER 204 %token T_STRING 205 -%token C_INTEGER 301 +%token C_INTEGER 301 %token C_NULL 302 %token C_CHARACTER 303 %token C_STRING 304 @@ -180,8 +180,10 @@ rec_op : expression: - constant {printf("constant expression\n");} - | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");} + constant {printf("constant expression\n");} {$$ = $1;} + | SUB_OR_NEG expression {if(strcmp($2,integer) != 0) {printf("cant negate something not an integer at + line %d and column %d\n",@2.first_line,@2.first_column);}} %prec UMINUS {printf("negative expression\n");} + | NOT expression {printf("not expression\n");} | expression ADD expression {printf("add expression\n");} | expression SUB_OR_NEG expression {printf("subtract expression\n");} @@ -215,12 +217,12 @@ memOp: constant: - C_STRING - | C_INTEGER - | C_NULL - | C_CHARACTER - | C_TRUE - | C_FALSE + C_STRING {$$ = $1;} + | C_INTEGER {$$ = $1;} + | C_NULL {$$ = $1;} + | C_CHARACTER {$$ = $1;} + | C_TRUE {$$ = $1;} + | C_FALSE {$$ = $1;} ; types: diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index eac2840..91fc789 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -36,10 +36,10 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] %% -"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup(yytext);return T_INTEGER;}} -"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {if(tok_flag != NULL){print_tok(T_ADDRESS);}incr(line_number,column_number,T_ADDRESS);yylval.words = strdup(yytext);return T_ADDRESS;}} -"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup(yytext);return T_BOOLEAN;}} -"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {if(tok_flag != NULL){print_tok(T_CHARACTER);}incr(line_number,column_number,T_CHARACTER);yylval.words = strdup(yytext);return T_CHARACTER;}} +"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup("type");return T_INTEGER;}} +"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {if(tok_flag != NULL){print_tok(T_ADDRESS);}incr(line_number,column_number,T_ADDRESS);yylval.words = strdup("type");return T_ADDRESS;}} +"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup("type");return T_BOOLEAN;}} +"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {if(tok_flag != NULL){print_tok(T_CHARACTER);}incr(line_number,column_number,T_CHARACTER);yylval.words = strdup("type");return T_CHARACTER;}} "while" {if(DEBUG) {printf( "WHILE: %s (%d)\n", yytext, WHILE);} else {if(tok_flag != NULL){print_tok(WHILE);}incr(line_number,column_number,WHILE);return WHILE;}} "if" {if(DEBUG) {printf( "IF: %s (%d)\n", yytext, IF);} else {if(tok_flag != NULL){print_tok(IF);}incr(line_number,column_number,IF);return IF;}} @@ -72,9 +72,9 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "," {if(DEBUG) {printf( "COMMA: %s (%d)\n", yytext, COMMA);} else {if(tok_flag != NULL){print_tok(COMMA);}incr(line_number,column_number,COMMA);return COMMA;}} "->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {if(tok_flag != NULL){print_tok(ARROW);}incr(line_number,column_number,ARROW);return ARROW;}} -{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytext);return C_INTEGER;}} -'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);return C_CHARACTER;}} -\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);return C_STRING;}} +{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.words = strdup("integer");return C_INTEGER;}} +'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.words = strdup("character");return C_CHARACTER;}} +\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.words = strdup("string");return C_STRING;}} {COMMENT} {if(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}} "(" {if(DEBUG) {printf( "L_PAREN: %s (%d)\n", yytext, L_PAREN);} else {if(tok_flag != NULL){print_tok(L_PAREN);}incr(line_number,column_number,L_PAREN);return L_PAREN;}} @@ -84,9 +84,9 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "{" {if(DEBUG) {printf( "L_BRACE: %s (%d)\n", yytext, L_BRACE);} else {if(tok_flag != NULL){print_tok(L_BRACE);}incr(line_number,column_number,L_BRACE);return L_BRACE;}} "}" {if(DEBUG) {printf( "R_BRACE: %s (%d)\n", yytext, R_BRACE);} else {if(tok_flag != NULL){print_tok(R_BRACE);}incr(line_number,column_number,R_BRACE);return R_BRACE;}} -"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.words = strdup(yytext);return C_TRUE;}} -"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.words = strdup(yytext);return C_FALSE;}} -"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.words = strdup(yytext);return C_NULL;}} +"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.words = strdup("Boolean");return C_TRUE;}} +"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.words = strdup("Boolean");return C_FALSE;}} +"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.words = strdup("address");return C_NULL;}} {ID} {if(DEBUG) {printf( "ID: %s (%d)\n", yytext, ID);} else {if(tok_flag != NULL){print_tok(ID);}incr(line_number,column_number,ID);yylval.words = strdup(yytext); return ID;}} From ead70170c0caf05c49b2401b8e75ec4fe7c4e5cc Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 19:58:53 -0400 Subject: [PATCH 010/137] added a remove entry function --- src/grammar.y | 16 +++-- src/lexicalStructure.lex | 8 +-- src/runner.c | 5 ++ src/symbol_table.c | 148 ++++++++++++++++++++++++++++++++++----- 4 files changed, 153 insertions(+), 24 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index dba555d..a153f8e 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -17,11 +17,18 @@ extern int line_number; extern int column_number; extern FILE * yyin; + extern TableNode* funprime; + extern TableNode* arrayprim; + extern TableNode* integ; + extern TableNode* addr; + extern TableNode* chara; + extern TableNode* stri; + extern TableNode* boo; %} //%define api.location.type {location_t} %locations %union { - //int integ; + int integ; char * words; } @@ -225,9 +232,10 @@ constant: | C_FALSE {$$ = $1;} ; -types: - T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} - | T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} +types: + // Commented out T_String below + // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} + T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 91fc789..24eaa78 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -36,10 +36,10 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] %% -"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup("type");return T_INTEGER;}} -"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {if(tok_flag != NULL){print_tok(T_ADDRESS);}incr(line_number,column_number,T_ADDRESS);yylval.words = strdup("type");return T_ADDRESS;}} -"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup("type");return T_BOOLEAN;}} -"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {if(tok_flag != NULL){print_tok(T_CHARACTER);}incr(line_number,column_number,T_CHARACTER);yylval.words = strdup("type");return T_CHARACTER;}} +"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup(yytext);return T_INTEGER;}} +"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {if(tok_flag != NULL){print_tok(T_ADDRESS);}incr(line_number,column_number,T_ADDRESS);yylval.words = strdup(yytext);return T_ADDRESS;}} +"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup(yytext);return T_BOOLEAN;}} +"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {if(tok_flag != NULL){print_tok(T_CHARACTER);}incr(line_number,column_number,T_CHARACTER);yylval.words = strdup(yytext);return T_CHARACTER;}} "while" {if(DEBUG) {printf( "WHILE: %s (%d)\n", yytext, WHILE);} else {if(tok_flag != NULL){print_tok(WHILE);}incr(line_number,column_number,WHILE);return WHILE;}} "if" {if(DEBUG) {printf( "IF: %s (%d)\n", yytext, IF);} else {if(tok_flag != NULL){print_tok(IF);}incr(line_number,column_number,IF);return IF;}} diff --git a/src/runner.c b/src/runner.c index 238abf1..f2a96ef 100644 --- a/src/runner.c +++ b/src/runner.c @@ -4,6 +4,11 @@ #include "runner.h" extern TableNode* funprime; extern TableNode* arrayprim; +extern TableNode* integ; +extern TableNode* addr; +extern TableNode* chara; +extern TableNode* stri; +extern TableNode* boo; int main(int argc, char *argv[]) { if (argc == 1) { diff --git a/src/symbol_table.c b/src/symbol_table.c index 5eb94d2..8388578 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -11,6 +11,17 @@ char * funy = "function"; TableNode* funprime; TableNode* arrayprim; extern SymbolTable* cur; +TableNode* integ; +TableNode* addr; +TableNode* chara; +TableNode* stri; +TableNode* boo; +TableNode* recprime; +TableNode* funprime; +TableNode* arrayprime; +TableNode* funtypeprime; + + typedef enum { //First 4 below are primitive types that are all encapsulated in primitive type @@ -86,6 +97,13 @@ AdInfo* CreatePrimitiveInfo(int size){ return info; } +int getPrimSize(TableNode* definition){ + if(strcmp(getType(definition),"primitive")!=0){ + printf("not checking the size of a primitive -- invalid op\n"); + return 0;} + return definition->additionalinfo->PrimAdInfo->size; +} + //probably don't need the below structure since can create from an array /*string_info* CreateStringInfo(int length, char* loc){ string_info* stringy = (string_info*)malloc(sizeof(string_info)); @@ -94,6 +112,7 @@ AdInfo* CreatePrimitiveInfo(int size){ return stringy; } */ + AdInfo* CreateArrayInfo(int dim, /*int* sizes,*/ TableNode* type){ AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); info->ArrayAdInfo = (array_info*)malloc(sizeof(array_info)); @@ -104,6 +123,20 @@ AdInfo* CreateArrayInfo(int dim, /*int* sizes,*/ TableNode* type){ return info; } +int getNumArrDim(TableNode* definition){ + if(strcmp(getType(definition),"array")!=0){ + printf("not checking the dim of an array -- invalid op\n"); + return 0;} + return definition->additionalinfo->ArrayAdInfo->numofdimensions; +} + +TableNode* getArrType(TableNode* definition){ + if(strcmp(getType(definition),"array")!=0){ + printf("not checking the type of an array -- invalid op\n"); + return NULL;} + return definition->additionalinfo->ArrayAdInfo->typeofarray; +} + AdInfo* CreateRecordInfo(int length, TableNode* typesarray){ AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); info->RecAdInfo = (record_info*)malloc(sizeof(record_info)); @@ -112,6 +145,20 @@ AdInfo* CreateRecordInfo(int length, TableNode* typesarray){ return info; } +int getRecLength(TableNode* definition){ + if(strcmp(getType(definition),"record")!=0){ + printf("not checking the length of an record -- invalid op\n"); + return 0;} + return definition->additionalinfo->RecAdInfo->numofelements; +} + +TableNode* getRecList(TableNode* definition){ + if(strcmp(getType(definition),"record")!=0){ + printf("not checking the list of types of a record -- invalid op\n"); + return NULL;} + return definition->additionalinfo->RecAdInfo->listoftypes; +} + //below function takes a bool to see if parameter should be decomposed or not AdInfo* CreateFunctionDeclarationInfo(int line, bool asorregular){ AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); @@ -121,6 +168,20 @@ AdInfo* CreateFunctionDeclarationInfo(int line, bool asorregular){ return info; } +int getStartLine(TableNode* definition){ + if(strcmp(getType(definition),"function primitive")!=0){ + printf("not checking the start line of a function -- invalid op\n"); + return 0;} + return definition->additionalinfo->FunDecAdInfo->startlinenumber; +} + +bool getAsKeyword(TableNode* definition){ + if(strcmp(getType(definition),"function primitive")!=0){ + printf("not checking if a function is called with as or not -- invalid op\n"); + return NULL;} + return definition->additionalinfo->FunDecAdInfo->regularoras; +} + AdInfo* CreateFunctionTypeInfo(TableNode* parameter, TableNode* returntype){ AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); info->FunTypeAdInfo = (function_type_info*)malloc(sizeof(function_type_info)); @@ -129,7 +190,19 @@ AdInfo* CreateFunctionTypeInfo(TableNode* parameter, TableNode* returntype){ return info; } +TableNode* getParameter(TableNode* definition){ + if(strcmp(getType(definition),"function type primitive")!=0){ + printf("not checking the parameter of a function -- invalid op\n"); + return NULL;} + return definition->additionalinfo->FunTypeAdInfo->parameter; +} +TableNode* getReturn(TableNode* definition){ + if(strcmp(getType(definition),"function type primitive")!=0){ + printf("not checking the return of a function -- invalid op\n"); + return NULL;} + return definition->additionalinfo->FunTypeAdInfo->returntype; +} @@ -165,11 +238,11 @@ SymbolTable* init(SymbolTable* start){ printf("Cannot initialize a scope that is not the parent scope\n"); return NULL; } - TableNode* integ = (TableNode*)malloc(sizeof(SymbolTable)); - TableNode* addr = (TableNode*)malloc(sizeof(SymbolTable)); - TableNode* chara = (TableNode*)malloc(sizeof(SymbolTable)); - TableNode* stri = (TableNode*)malloc(sizeof(SymbolTable)); - TableNode* boo = (TableNode*)malloc(sizeof(SymbolTable)); + integ = (TableNode*)malloc(sizeof(TableNode)); + addr = (TableNode*)malloc(sizeof(TableNode)); + chara = (TableNode*)malloc(sizeof(TableNode)); + stri = (TableNode*)malloc(sizeof(TableNode)); + boo = (TableNode*)malloc(sizeof(TableNode)); //TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; @@ -183,31 +256,44 @@ SymbolTable* init(SymbolTable* start){ addr->theName= "address"; chara->theName= "character"; boo->theName= "Boolean"; - stri->theName= "string"; + stri->theName= "string primitive"; //arr->theName= "array" //root TableNode that all are pointing to but not in table - TableNode* prime = (TableNode*)malloc(sizeof(SymbolTable)); + TableNode* prime = (TableNode*)malloc(sizeof(TableNode)); prime->theName= "primitive"; prime->theType=NULL; prime->additionalinfo = NULL; prime->next = NULL; //note sur exatly how to get array types to look right so using a dummy Table Node below and updating the print symbol table function to access the additional information to print for array types, similar to function types - TableNode* arrayprim = (TableNode*)malloc(sizeof(SymbolTable)); - prime->theName= "array"; - prime->theType=NULL; - prime->additionalinfo = NULL; + arrayprim = (TableNode*)malloc(sizeof(TableNode)); + arrayprim->theName= "array"; + arrayprim->theType=NULL; + arrayprim->additionalinfo = NULL; prime->next = NULL; //funprime = CreateEntry(NULL,NULL,strdup("function primitive"),NULL); //similar workaround to arrays above - TableNode* funprime = (TableNode*)malloc(sizeof(SymbolTable)); - prime->theName= "primitive function"; - prime->theType=NULL; - prime->additionalinfo = NULL; - prime->next = NULL; + funprime = (TableNode*)malloc(sizeof(TableNode)); + funprime->theName= "primitive function"; + funprime->theType=NULL; + funprime->additionalinfo = NULL; + funpprime->next = NULL; + + //record + recprime = (TableNode*)malloc(sizeof(TableNode)); + recprime->theName= "record"; + recprime->theType=NULL; + recprime->additionalinfo = NULL; + recprime->next = NULL; + + funtypeprime = (TableNode*)malloc(sizeof(TableNode)); + funtypeprime->theName= "primitive function type"; + funtypeprime->theType=NULL; + funtypeprime->additionalinfo = NULL; + funtypeprime->next = NULL; integ->theType=prime; addr->theType=prime; @@ -374,6 +460,36 @@ SymbolTable* getAncestor(SymbolTable* table) { } } +SymbolTable* removeEntry(SymbolTable* scope, char* search){ + +if(scope == NULL){ + return NULL; +} +if(scope->entries == NULL){ + return scope; +} + +TableNode* prev = NULL; +TableNode* now = scope->entries; + +while(now != NULL){ +if(strcmp(getName(now),search)==0){ + if(prev == NULL){ + scope->entries = getNextEntry(now); + return scope; + } else{ + prev->next = now->next; + return scope; + } +} +prev = now; +now = now->next; +} +return scope; +} + + + bool typeCheck(char* firstID, char* secondID){ From 78f1cd3fbb6b16077de381e0a224bab56943c2f0 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 20:48:11 -0400 Subject: [PATCH 011/137] Got symbol Table largely working (but without certain entries being added like functions or records) --- src/grammar.y | 10 +++++++--- src/symbol_table.c | 6 ++---- src/symbol_table.h | 10 ++++++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index a153f8e..c9136c4 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -19,6 +19,8 @@ extern FILE * yyin; extern TableNode* funprime; extern TableNode* arrayprim; + extern TableNode* recprime; + extern TableNode* funtypeprime; extern TableNode* integ; extern TableNode* addr; extern TableNode* chara; @@ -33,6 +35,9 @@ } + +%type expression +%type constant %type id_or_types %type types %token ID 101 @@ -150,7 +155,7 @@ declaration_list: ; declaration: - id_or_types COLON ID {CreateEntry(cur,$1,$3); } + id_or_types COLON ID {CreateEntry(cur,$1,$3,NULL); } ; id_or_types: @@ -188,8 +193,7 @@ rec_op : expression: constant {printf("constant expression\n");} {$$ = $1;} - | SUB_OR_NEG expression {if(strcmp($2,integer) != 0) {printf("cant negate something not an integer at - line %d and column %d\n",@2.first_line,@2.first_column);}} %prec UMINUS {printf("negative expression\n");} + | SUB_OR_NEG expression {if(strcmp($2,"integer") != 0) {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column);}} %prec UMINUS {printf("negative expression\n");} | NOT expression {printf("not expression\n");} | expression ADD expression {printf("add expression\n");} diff --git a/src/symbol_table.c b/src/symbol_table.c index 8388578..6f26b89 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -17,8 +17,6 @@ TableNode* chara; TableNode* stri; TableNode* boo; TableNode* recprime; -TableNode* funprime; -TableNode* arrayprime; TableNode* funtypeprime; @@ -234,7 +232,7 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { //create entry just for things below top level scope SymbolTable* init(SymbolTable* start){ - if(start->Parent_Scope == NULL){ + if(start->Parent_Scope != NULL){ printf("Cannot initialize a scope that is not the parent scope\n"); return NULL; } @@ -280,7 +278,7 @@ SymbolTable* init(SymbolTable* start){ funprime->theName= "primitive function"; funprime->theType=NULL; funprime->additionalinfo = NULL; - funpprime->next = NULL; + funprime->next = NULL; //record recprime = (TableNode*)malloc(sizeof(TableNode)); diff --git a/src/symbol_table.h b/src/symbol_table.h index 7639e14..7763305 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -86,6 +86,16 @@ ListOfTable* getRestOfChildren(ListOfTable* lt); TableNode* getFirstEntry(SymbolTable* st); TableNode* getNextEntry(TableNode* tn); SymbolTable* init(SymbolTable* scope); +int getPrimSize(TableNode* definition); +int getNumArrDim(TableNode* definition); +TableNode* getArrType(TableNode* definition); +int getRecLength(TableNode* definition); +TableNode* getRecList(TableNode* definition); +int getStartLine(TableNode* definition); +bool getAsKeyword(TableNode* definition); +TableNode* getParameter(TableNode* definition); +TableNode* getReturn(TableNode* definition); + char* getType(TableNode* tn); char* getName(TableNode* tn); int getLine(SymbolTable* st); From 1544f2b728f18c5d03cb763fc0bbee1f003fd3f4 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 22:42:08 -0400 Subject: [PATCH 012/137] all compilation errors are gone. Function Types are properly entering Symbol Table. Some Type checking is taking place among expressions. --- src/grammar.y | 33 +++++++++++++++++++++++---------- src/symbol_table.c | 10 ++++++++-- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index c9136c4..6c3cf9f 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -35,7 +35,7 @@ } - +%type assignable %type expression %type constant %type id_or_types @@ -122,7 +122,8 @@ definition: TYPE ID COLON dblock | TYPE ID COLON constant ARROW ID | function_declaration - | TYPE ID COLON id_or_types ARROW id_or_types + | TYPE ID COLON id_or_types ARROW id_or_types { + CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6)));} | ID parameter ASSIGN sblock ; @@ -155,7 +156,7 @@ declaration_list: ; declaration: - id_or_types COLON ID {CreateEntry(cur,$1,$3,NULL); } + id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } ; id_or_types: @@ -193,21 +194,33 @@ rec_op : expression: constant {printf("constant expression\n");} {$$ = $1;} - | SUB_OR_NEG expression {if(strcmp($2,"integer") != 0) {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column);}} %prec UMINUS {printf("negative expression\n");} + | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) + {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("undefined");}else{$$=$2;}} + + | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); + printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} - | NOT expression {printf("not expression\n");} | expression ADD expression {printf("add expression\n");} | expression SUB_OR_NEG expression {printf("subtract expression\n");} | expression MUL expression {printf("multiply expression\n");} | expression DIV expression {printf("division expression\n");} | expression REM expression {printf("remainder expression\n");} + | expression AND expression {printf("and expression\n");} + | expression OR expression {printf("or expression\n");} - | expression LESS_THAN expression {printf("less than expression\n");} - | expression EQUAL_TO expression {printf("equals check expression\n");} - | assignable {printf("assignable expression\n");} - | L_PAREN expression R_PAREN {printf("paren expression\n");} - | memOp assignable + + | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && + strcmp($1,"integer")==0){$$=strdup("Boolean");}else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} + | expression EQUAL_TO expression {printf("equals check expression\n"); + if(strcmp($1,$3)==0){$$=strdup("Boolean");}else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| +strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} +else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column);$$=strdup("undefined");}} + | assignable {printf("assignable expression\n");$$=$1;} + | L_PAREN expression R_PAREN {printf("paren expression\n");$$=$2;} + | memOp assignable {$$ = strdup("address");} ; diff --git a/src/symbol_table.c b/src/symbol_table.c index 6f26b89..31abdf1 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -316,19 +316,25 @@ SymbolTable* init(SymbolTable* start){ return start; } -TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id, AdInfo* ad) { +TableNode* CreateEntry(SymbolTable* table, TableNode* typeOf, char* id, AdInfo* ad) { if(table ==NULL){ printf("Null reference to table"); return NULL; } +/* TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); if(topDef == NULL){ printf("This type is not defined at the top level\n"); return NULL; +} +*/ +if(typeOf == NULL){ + printf("This is not pointing to a proper definition\n"); + return NULL; } TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode)); - newEntry->theType = topDef; + newEntry->theType = typeOf/*topDef*/; newEntry->theName = id; newEntry->additionalinfo = ad; if (table->entries == NULL) { From 78b3539de60a233bf07da7951b7b634d3fc93c43 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 14 Mar 2025 22:47:29 -0400 Subject: [PATCH 013/137] changed 'string primitive' to 'string' --- src/symbol_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 31abdf1..973ed5e 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -254,7 +254,7 @@ SymbolTable* init(SymbolTable* start){ addr->theName= "address"; chara->theName= "character"; boo->theName= "Boolean"; - stri->theName= "string primitive"; + stri->theName= "string"; //arr->theName= "array" //root TableNode that all are pointing to but not in table From d817ceaf7df0f5bd71eea0add3d9df5f6b00d3d0 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Mon, 24 Mar 2025 11:59:53 -0400 Subject: [PATCH 014/137] added comments to symbol table.c for clarity. Note- we need to add scope reference to record instead of array reference. Additionally, in print symbol table.c we need to update for if an entry is a function, it should print out parameter->return type --- src/symbol_table.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 973ed5e..83901df 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -86,7 +86,7 @@ typedef union { FunTypeAdInfo* func_type_info; }AdInfo; */ - +//primitive additional info only stores the size of that type AdInfo* CreatePrimitiveInfo(int size){ AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); @@ -95,6 +95,7 @@ AdInfo* CreatePrimitiveInfo(int size){ return info; } +//only gets the size of a primitive type int getPrimSize(TableNode* definition){ if(strcmp(getType(definition),"primitive")!=0){ printf("not checking the size of a primitive -- invalid op\n"); @@ -111,6 +112,8 @@ int getPrimSize(TableNode* definition){ } */ +//Only information stored in array info is the number of dimensions and the type stored in the array +//per professor, the actual size of the array is calculated at runtime so bounds checking only needs to be done then AdInfo* CreateArrayInfo(int dim, /*int* sizes,*/ TableNode* type){ AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); info->ArrayAdInfo = (array_info*)malloc(sizeof(array_info)); @@ -120,14 +123,14 @@ AdInfo* CreateArrayInfo(int dim, /*int* sizes,*/ TableNode* type){ //int* dimensionsizes = loc; return info; } - +//This gets the number of dimensions from array info int getNumArrDim(TableNode* definition){ if(strcmp(getType(definition),"array")!=0){ printf("not checking the dim of an array -- invalid op\n"); return 0;} return definition->additionalinfo->ArrayAdInfo->numofdimensions; } - +//This gets the type stored in an array from arrtype. It returns a reference to the entry of that type TableNode* getArrType(TableNode* definition){ if(strcmp(getType(definition),"array")!=0){ printf("not checking the type of an array -- invalid op\n"); @@ -135,21 +138,25 @@ TableNode* getArrType(TableNode* definition){ return definition->additionalinfo->ArrayAdInfo->typeofarray; } +//Record type currently stores the number of elements as well as the types, in order, of what make up that type in an array. +//Unfortunately this second part should probably instead be replaced by a reference to a scope in which those elements are found. AdInfo* CreateRecordInfo(int length, TableNode* typesarray){ AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); info->RecAdInfo = (record_info*)malloc(sizeof(record_info)); info->RecAdInfo->numofelements=length; + //replace below with reference to a scope, not an array info->RecAdInfo->listoftypes = typesarray; return info; } - +//This gets the number of elements that make up a record. +//Perhaps this may not be needed since we need to iterate over all elements anyways. int getRecLength(TableNode* definition){ if(strcmp(getType(definition),"record")!=0){ printf("not checking the length of an record -- invalid op\n"); return 0;} return definition->additionalinfo->RecAdInfo->numofelements; } - +//This gets the array. Needs to up be updated to get the scope instead TableNode* getRecList(TableNode* definition){ if(strcmp(getType(definition),"record")!=0){ printf("not checking the list of types of a record -- invalid op\n"); @@ -158,6 +165,9 @@ TableNode* getRecList(TableNode* definition){ } //below function takes a bool to see if parameter should be decomposed or not +//note that functions only take one input and have one output +//using "as" the input record can be decomposed to give the illusion of multiple inputs +//Below function also has the line number where the function is first defined AdInfo* CreateFunctionDeclarationInfo(int line, bool asorregular){ AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); info->FunDecAdInfo = (function_declaration_info*)malloc(sizeof(function_declaration_info)); @@ -165,21 +175,21 @@ AdInfo* CreateFunctionDeclarationInfo(int line, bool asorregular){ info->FunDecAdInfo->regularoras = asorregular; return info; } - +//gets the line at which the function was first defined. (Can be used to print out in table if needed) int getStartLine(TableNode* definition){ if(strcmp(getType(definition),"function primitive")!=0){ printf("not checking the start line of a function -- invalid op\n"); return 0;} return definition->additionalinfo->FunDecAdInfo->startlinenumber; } - +//checks if "as" keyword was used for function definition. Either 0 or 1 for not used or used. bool getAsKeyword(TableNode* definition){ if(strcmp(getType(definition),"function primitive")!=0){ printf("not checking if a function is called with as or not -- invalid op\n"); return NULL;} return definition->additionalinfo->FunDecAdInfo->regularoras; } - +//stores the type of a function (parameter type and return type) AdInfo* CreateFunctionTypeInfo(TableNode* parameter, TableNode* returntype){ AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); info->FunTypeAdInfo = (function_type_info*)malloc(sizeof(function_type_info)); @@ -187,14 +197,14 @@ AdInfo* CreateFunctionTypeInfo(TableNode* parameter, TableNode* returntype){ info->FunTypeAdInfo->returntype = returntype; return info; } - +//returns parameter type of a function TableNode* getParameter(TableNode* definition){ if(strcmp(getType(definition),"function type primitive")!=0){ printf("not checking the parameter of a function -- invalid op\n"); return NULL;} return definition->additionalinfo->FunTypeAdInfo->parameter; } - +//returns return type of a function TableNode* getReturn(TableNode* definition){ if(strcmp(getType(definition),"function type primitive")!=0){ printf("not checking the return of a function -- invalid op\n"); @@ -203,7 +213,7 @@ TableNode* getReturn(TableNode* definition){ } - +//creates a new scope (not the top scope though) SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { SymbolTable* table = (SymbolTable*)malloc(sizeof(SymbolTable)); table->Line_Number = Line; @@ -231,6 +241,7 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { } //create entry just for things below top level scope +//This function defines the integer, address, character, and bool primitive types SymbolTable* init(SymbolTable* start){ if(start->Parent_Scope != NULL){ printf("Cannot initialize a scope that is not the parent scope\n"); @@ -258,13 +269,18 @@ SymbolTable* init(SymbolTable* start){ //arr->theName= "array" //root TableNode that all are pointing to but not in table + //This is only to solve the issue that all entries must have a name and a type + //and the type must point to an actual table entry + //Again, this primitive table entry isn't in the top scope. It is outside the top scope and is only there + //to facilitate the fact that these are primitive TableNode* prime = (TableNode*)malloc(sizeof(TableNode)); prime->theName= "primitive"; prime->theType=NULL; prime->additionalinfo = NULL; prime->next = NULL; - //note sur exatly how to get array types to look right so using a dummy Table Node below and updating the print symbol table function to access the additional information to print for array types, similar to function types + //not sure exatly how to get array types to look right so using a dummy Table Node below and updating the print symbol table function to access the additional information to print for array types, similar to function types + //when printing symbol table, if array is seen arrayprim = (TableNode*)malloc(sizeof(TableNode)); arrayprim->theName= "array"; arrayprim->theType=NULL; @@ -301,6 +317,9 @@ SymbolTable* init(SymbolTable* start){ //arr->theType=arrayprim; //filling in all the values for the additional info for initial types + //These numbers below for create primitive specifically are supposed to be the size + //of these primitive types. We can change these if needed to not be hard coded numbers + //as a reminder, stri below is defined as a one dimensional array of characters integ->additionalinfo = CreatePrimitiveInfo(4); addr->additionalinfo = CreatePrimitiveInfo(8); chara->additionalinfo = CreatePrimitiveInfo(1); From 94b80b024d4ae9ff8ee97d7629603acc57b27964 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 25 Mar 2025 17:02:14 -0400 Subject: [PATCH 015/137] Quick formatting updates --- src/grammar.y | 106 +++---- src/runner.c | 82 +++--- src/runner.h | 20 +- src/symbol_table.c | 694 ++++++++++++++++++++++++--------------------- src/symbol_table.h | 135 ++++----- 5 files changed, 532 insertions(+), 505 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 6c3cf9f..758b35d 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -2,30 +2,30 @@ /* The Translators - Spring 2025 */ %{ - #include - #include "../src/symbol_table.c" - #include - extern int yylex(void); - void yyerror(const char *err); - extern char* yytext; - extern int yyleng; - extern int yychar; - extern SymbolTable * cur; - //char* cur_value; - //char* cur_type; - int token_tracker; - extern int line_number; - extern int column_number; - extern FILE * yyin; - extern TableNode* funprime; - extern TableNode* arrayprim; - extern TableNode* recprime; - extern TableNode* funtypeprime; - extern TableNode* integ; - extern TableNode* addr; - extern TableNode* chara; - extern TableNode* stri; - extern TableNode* boo; + #include + #include "../src/symbol_table.c" + #include + extern int yylex(void); + void yyerror(const char *err); + extern char* yytext; + extern int yyleng; + extern int yychar; + extern SymbolTable * cur; + //char* cur_value; + //char* cur_type; + int token_tracker; + extern int line_number; + extern int column_number; + extern FILE * yyin; + extern TableNode* funprime; + extern TableNode* arrayprim; + extern TableNode* recprime; + extern TableNode* funtypeprime; + extern TableNode* integ; + extern TableNode* addr; + extern TableNode* chara; + extern TableNode* stri; + extern TableNode* boo; %} //%define api.location.type {location_t} %locations @@ -123,7 +123,8 @@ definition: | TYPE ID COLON constant ARROW ID | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { - CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6)));} + CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); + } | ID parameter ASSIGN sblock ; @@ -192,15 +193,12 @@ rec_op : DOT expression: - constant {printf("constant expression\n");} {$$ = $1;} | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) - {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("undefined");}else{$$=$2;}} - + {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("undefined");}else{$$=$2;}} | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); - printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} - + printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} | expression ADD expression {printf("add expression\n");} | expression SUB_OR_NEG expression {printf("subtract expression\n");} | expression MUL expression {printf("multiply expression\n");} @@ -212,16 +210,16 @@ expression: | expression OR expression {printf("or expression\n");} | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean");}else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + strcmp($1,"integer")==0){$$=strdup("Boolean");}else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression EQUAL_TO expression {printf("equals check expression\n"); - if(strcmp($1,$3)==0){$$=strdup("Boolean");}else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| -strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} -else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column);$$=strdup("undefined");}} + if(strcmp($1,$3)==0){$$=strdup("Boolean");}else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| + strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column);$$=strdup("undefined");}} | assignable {printf("assignable expression\n");$$=$1;} | L_PAREN expression R_PAREN {printf("paren expression\n");$$=$2;} | memOp assignable {$$ = strdup("address");} - ; + ; ablock: @@ -250,9 +248,9 @@ constant: ; types: - // Commented out T_String below - // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} - T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} + // Commented out T_String below + // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} + T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} @@ -261,31 +259,5 @@ types: %% void yyerror(const char *err) { - fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column); + fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column); } -/* -int main(int argc, char * argv[]) { - token_tracker = 1; - cur=CreateScope(NULL,1,1); - //int a; - FILE * fp; - if(argc > 1){ - fp = fopen(argv[1], "r"); - yyin = fp; - } else { - fp = stdin; - yyin = fp; - } - yyparse(); - //while ((a = yyparse() != EOF){ - // token_tracker++; - //printf("%d = a: yytext = %s: yychar = %d, token number: %d\n", a, yytext, yychar,token_tracker); - //if(yytext[0] == '\n'){ - FILE* f = fdopen(1,"w"); - print_symbol_table(getAncestor(cur),f); - fclose(f); - // break; - //} - //} - return 0; -} */ diff --git a/src/runner.c b/src/runner.c index f2a96ef..8722425 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,13 +2,13 @@ /* The Translators - Spring 2025 */ #include "runner.h" -extern TableNode* funprime; -extern TableNode* arrayprim; -extern TableNode* integ; -extern TableNode* addr; -extern TableNode* chara; -extern TableNode* stri; -extern TableNode* boo; +extern TableNode *funprime; +extern TableNode *arrayprim; +extern TableNode *integ; +extern TableNode *addr; +extern TableNode *chara; +extern TableNode *stri; +extern TableNode *boo; int main(int argc, char *argv[]) { if (argc == 1) { @@ -29,13 +29,16 @@ int main(int argc, char *argv[]) { } else { - if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != 0) { + if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != + 0) { fprintf(stderr, INVALID); return -1; } else { for (int i = 1; i < argc - 1; i++) { if (check_flag(argv[i], argv[argc - 1]) != 0) { - fprintf(stderr, "INVALID FLAG(S): Use -help to view valid inputs \n"); + fprintf(stderr, + "INVALID FLAG(S): Use -help to " + "view valid inputs \n"); return -1; } } @@ -64,21 +67,22 @@ int check_flag(char *arg, char *alpha) { } } -void incr(int lnum,int cnum, int tok){ - //if (tok == COMMENT) { - for (int i = 0; i < yyleng; i++) { - if (yytext[i] == '\n') { - line_number++; - column_number = 0; - } - column_number++; - } -// }else{ -// column_number += yyleng; -// } +void incr(int lnum, int cnum, int tok) { + // if (tok == COMMENT) { + for (int i = 0; i < yyleng; i++) { + if (yytext[i] == '\n') { + line_number++; + column_number = 0; + } + column_number++; + } + // }else{ + // column_number += yyleng; + // } } -void print_tok(int tok){ -fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number,tok, yytext); +void print_tok(int tok) { + fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, tok, + yytext); } int run(FILE *alpha) { int token; @@ -94,10 +98,11 @@ int run(FILE *alpha) { // TOK FLAG if (tok_flag != NULL) { while (0 != (token = yylex())) { - //if (tok_flag != NULL) { - // fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, - // token, yytext); - //} + // if (tok_flag != NULL) { + // fprintf(tok_flag, "%d %d %3d \"%s\"\n", + // line_number, column_number, + // token, yytext); + // } /*if (token == COMMENT) { for (int i = 0; i < yyleng; i++) { if (yytext[i] == '\n') { @@ -110,9 +115,10 @@ int run(FILE *alpha) { } if (token == 1999) { printf( - "On line number %d and column number %d we have an invalid " - "character:%s\n", - line_number, column_number, yytext); + "On line number %d and column + number %d we have an invalid " "character:%s\n", + line_number, column_number, + yytext); } column_number += yyleng; */ } @@ -172,14 +178,15 @@ int new_file(char *arg, char *alpha) { } else if (strcmp(arg, "-st") == 0) { type_len = ST_LEN; } else { - fprintf(stderr, "INVALID FLAG: Use -help to view valid inputs\n"); + fprintf(stderr, + "INVALID FLAG: Use -help to view valid inputs\n"); return -1; } // calculate lengths int basename_len = strlen(basename); char *file_name = - calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char)); + calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char)); // coy filename and add extension strncpy(file_name, basename, basename_len - ALPHA_OFFSET); @@ -195,15 +202,14 @@ int new_file(char *arg, char *alpha) { } int is_alpha_file(char *alpha, int file_len) { - if (strcmp(".alpha", alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) { - return -1; // not alpha file + if (strcmp(".alpha", + alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) { + return -1; // not alpha file } - return 0; // is alpha file + return 0; // is alpha file } -void enter_scope(int line, int column) { - cur = CreateScope(cur, line, column); -} +void enter_scope(int line, int column) { cur = CreateScope(cur, line, column); } void exit_scope() { if (cur->Parent_Scope == NULL) { printf("Can't close top"); diff --git a/src/runner.h b/src/runner.h index 9f66407..d378be5 100644 --- a/src/runner.h +++ b/src/runner.h @@ -5,14 +5,18 @@ #define TOK_LEN 3 #define ST_LEN 2 #define HELP \ - "HELP:\nHow to run the alpha compiler:\n./alpha [options] program\nValid " \ - "options:\n-tok output the token number, token, line number, and column " \ - "number for each of the tokens to the .tok file\n-st output the symbol " \ - "table for the program to the .st file\n-help print this message and exit " \ - "the alpha compiler\n" + "HELP:\nHow to run the alpha compiler:\n./alpha [options] " \ + "program\nValid " \ + "options:\n-tok output the token number, token, line number, and " \ + "column " \ + "number for each of the tokens to the .tok file\n-st output the " \ + "symbol " \ + "table for the program to the .st file\n-help print this message " \ + "and exit " \ + "the alpha compiler\n" #define SET_FLAG 1 // Used to set flags for arg types -#define INVALID \ - "INVALID INPUT: Include a .alpha file or use -help for more inputs \n" +#define INVALID \ + "INVALID INPUT: Include a .alpha file or use -help for more inputs \n" #include #include @@ -22,7 +26,7 @@ #include "../tmp/flex.h" #include "symbol_table.h" -//#include "typedefs.h" +// #include "typedefs.h" #include "../tmp/grammar.tab.h" extern int line_number, column_number; diff --git a/src/symbol_table.c b/src/symbol_table.c index 83901df..1c08f27 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -6,42 +6,43 @@ #include #include #include -char * typey = "type"; -char * funy = "function"; -TableNode* funprime; -TableNode* arrayprim; -extern SymbolTable* cur; -TableNode* integ; -TableNode* addr; -TableNode* chara; -TableNode* stri; -TableNode* boo; -TableNode* recprime; -TableNode* funtypeprime; - - +char *typey = "type"; +char *funy = "function"; +TableNode *funprime; +TableNode *arrayprim; +extern SymbolTable *cur; +TableNode *integ; +TableNode *addr; +TableNode *chara; +TableNode *stri; +TableNode *boo; +TableNode *recprime; +TableNode *funtypeprime; typedef enum { - //First 4 below are primitive types that are all encapsulated in primitive type - //TYPE_INTEGER, - //TYPE_CHARACTER, - //TYPE_BOOLEAN, - //TYPE_ADDRESS, - //Type String is an array of char enclosed in double quotes per lexer - TYPE_STRING, - //Array can be multidimensional. Information should be stored here - TYPE_ARRAY, - //Record is user defined types - TYPE_RECORD, - //Declaring what type a particular function is without as - TYPE_FUNCTION_DECLARATION, - //Declaring what type a particular function is with as - //TYPE_AS_FUNCTION_DECLARATION, - //Declaring what type a function is (what the parameters and output are) - TYPE_FUNCTION_TYPE, - //The Type being pointed to by the first 4 above that only stores the size - TYPE_PRIMITIVE - + // First 4 below are primitive types that are all encapsulated in + // primitive type + // TYPE_INTEGER, + // TYPE_CHARACTER, + // TYPE_BOOLEAN, + // TYPE_ADDRESS, + // Type String is an array of char enclosed in double quotes per lexer + TYPE_STRING, + // Array can be multidimensional. Information should be stored here + TYPE_ARRAY, + // Record is user defined types + TYPE_RECORD, + // Declaring what type a particular function is without as + TYPE_FUNCTION_DECLARATION, + // Declaring what type a particular function is with as + // TYPE_AS_FUNCTION_DECLARATION, + // Declaring what type a function is (what the parameters and output + // are) + TYPE_FUNCTION_TYPE, + // The Type being pointed to by the first 4 above that only stores the + // size + TYPE_PRIMITIVE + } types; /* put in symbol_table.h @@ -56,13 +57,14 @@ typedef struct{ typedef struct{ int numofdimensions; - //the above value tells you how long the below array is. For example if num of dimensions is 5, I can store 1,3,2,5,9 to define > - int* sizesofdimensions; + //the above value tells you how long the below array is. For example if num +of dimensions is 5, I can store 1,3,2,5,9 to define > int* sizesofdimensions; TableNode* typeofarray; }array_info; typedef struct{ - //similar to above we define a record to hold the number of elements and an array of tablenodes (types) that it contains in the order specified by the user + //similar to above we define a record to hold the number of elements and an +array of tablenodes (types) that it contains in the order specified by the user int numofelements; TableNode* listoftypes; }record_info; @@ -77,145 +79,167 @@ typedef struct{ TableNode* returntype; }function_type_info; -typedef union { +typedef union { PrimAdInfo* primitive_info; ArrayAdInfo* array_info; RecAdInfo* record_info; - StringAdInfo* string_info; + StringAdInfo* string_info; FunDecAdInfo* func_dec_info; FunTypeAdInfo* func_type_info; }AdInfo; */ -//primitive additional info only stores the size of that type -AdInfo* CreatePrimitiveInfo(int size){ +// primitive additional info only stores the size of that type +AdInfo *CreatePrimitiveInfo(int size) { - AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); - info->PrimAdInfo = (primitive_info*)malloc(sizeof(primitive_info)); - info->PrimAdInfo->size=size; - return info; + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->PrimAdInfo = (primitive_info *)malloc(sizeof(primitive_info)); + info->PrimAdInfo->size = size; + return info; } -//only gets the size of a primitive type -int getPrimSize(TableNode* definition){ - if(strcmp(getType(definition),"primitive")!=0){ - printf("not checking the size of a primitive -- invalid op\n"); - return 0;} - return definition->additionalinfo->PrimAdInfo->size; +// only gets the size of a primitive type +int getPrimSize(TableNode *definition) { + if (strcmp(getType(definition), "primitive") != 0) { + printf("not checking the size of a primitive -- invalid op\n"); + return 0; + } + return definition->additionalinfo->PrimAdInfo->size; } -//probably don't need the below structure since can create from an array +// probably don't need the below structure since can create from an array /*string_info* CreateStringInfo(int length, char* loc){ string_info* stringy = (string_info*)malloc(sizeof(string_info)); stringy.length=length; - char* location = loc; + char* location = loc; return stringy; } */ -//Only information stored in array info is the number of dimensions and the type stored in the array -//per professor, the actual size of the array is calculated at runtime so bounds checking only needs to be done then -AdInfo* CreateArrayInfo(int dim, /*int* sizes,*/ TableNode* type){ - AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); - info->ArrayAdInfo = (array_info*)malloc(sizeof(array_info)); - info->ArrayAdInfo->numofdimensions=dim; - info->ArrayAdInfo->typeofarray=type; - //avoiding storing any types like below - //int* dimensionsizes = loc; +// Only information stored in array info is the number of dimensions and the +// type stored in the array per professor, the actual size of the array is +// calculated at runtime so bounds checking only needs to be done then +AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->ArrayAdInfo = (array_info *)malloc(sizeof(array_info)); + info->ArrayAdInfo->numofdimensions = dim; + info->ArrayAdInfo->typeofarray = type; + // avoiding storing any types like below + // int* dimensionsizes = loc; return info; } -//This gets the number of dimensions from array info -int getNumArrDim(TableNode* definition){ - if(strcmp(getType(definition),"array")!=0){ +// This gets the number of dimensions from array info +int getNumArrDim(TableNode *definition) { + if (strcmp(getType(definition), "array") != 0) { printf("not checking the dim of an array -- invalid op\n"); - return 0;} + return 0; + } return definition->additionalinfo->ArrayAdInfo->numofdimensions; } -//This gets the type stored in an array from arrtype. It returns a reference to the entry of that type -TableNode* getArrType(TableNode* definition){ - if(strcmp(getType(definition),"array")!=0){ +// This gets the type stored in an array from arrtype. It returns a reference to +// the entry of that type +TableNode *getArrType(TableNode *definition) { + if (strcmp(getType(definition), "array") != 0) { printf("not checking the type of an array -- invalid op\n"); - return NULL;} + return NULL; + } return definition->additionalinfo->ArrayAdInfo->typeofarray; } -//Record type currently stores the number of elements as well as the types, in order, of what make up that type in an array. -//Unfortunately this second part should probably instead be replaced by a reference to a scope in which those elements are found. -AdInfo* CreateRecordInfo(int length, TableNode* typesarray){ - AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); - info->RecAdInfo = (record_info*)malloc(sizeof(record_info)); - info->RecAdInfo->numofelements=length; - //replace below with reference to a scope, not an array +// Record type currently stores the number of elements as well as the types, in +// order, of what make up that type in an array. Unfortunately this second part +// should probably instead be replaced by a reference to a scope in which those +// elements are found. +AdInfo *CreateRecordInfo(int length, TableNode *typesarray) { + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->RecAdInfo = (record_info *)malloc(sizeof(record_info)); + info->RecAdInfo->numofelements = length; + // replace below with reference to a scope, not an array info->RecAdInfo->listoftypes = typesarray; return info; } -//This gets the number of elements that make up a record. -//Perhaps this may not be needed since we need to iterate over all elements anyways. -int getRecLength(TableNode* definition){ - if(strcmp(getType(definition),"record")!=0){ +// This gets the number of elements that make up a record. +// Perhaps this may not be needed since we need to iterate over all elements +// anyways. +int getRecLength(TableNode *definition) { + if (strcmp(getType(definition), "record") != 0) { printf("not checking the length of an record -- invalid op\n"); - return 0;} + return 0; + } return definition->additionalinfo->RecAdInfo->numofelements; } -//This gets the array. Needs to up be updated to get the scope instead -TableNode* getRecList(TableNode* definition){ - if(strcmp(getType(definition),"record")!=0){ - printf("not checking the list of types of a record -- invalid op\n"); - return NULL;} +// This gets the array. Needs to up be updated to get the scope instead +TableNode *getRecList(TableNode *definition) { + if (strcmp(getType(definition), "record") != 0) { + printf("not checking the list of types of a record -- invalid " + "op\n"); + return NULL; + } return definition->additionalinfo->RecAdInfo->listoftypes; } -//below function takes a bool to see if parameter should be decomposed or not -//note that functions only take one input and have one output -//using "as" the input record can be decomposed to give the illusion of multiple inputs -//Below function also has the line number where the function is first defined -AdInfo* CreateFunctionDeclarationInfo(int line, bool asorregular){ - AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); - info->FunDecAdInfo = (function_declaration_info*)malloc(sizeof(function_declaration_info)); - info->FunDecAdInfo->startlinenumber=line; +// below function takes a bool to see if parameter should be decomposed or not +// note that functions only take one input and have one output +// using "as" the input record can be decomposed to give the illusion of +// multiple inputs Below function also has the line number where the function is +// first defined +AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->FunDecAdInfo = (function_declaration_info *)malloc( + sizeof(function_declaration_info)); + info->FunDecAdInfo->startlinenumber = line; info->FunDecAdInfo->regularoras = asorregular; return info; } -//gets the line at which the function was first defined. (Can be used to print out in table if needed) -int getStartLine(TableNode* definition){ - if(strcmp(getType(definition),"function primitive")!=0){ - printf("not checking the start line of a function -- invalid op\n"); - return 0;} +// gets the line at which the function was first defined. (Can be used to print +// out in table if needed) +int getStartLine(TableNode *definition) { + if (strcmp(getType(definition), "function primitive") != 0) { + printf("not checking the start line of a function -- invalid " + "op\n"); + return 0; + } return definition->additionalinfo->FunDecAdInfo->startlinenumber; } -//checks if "as" keyword was used for function definition. Either 0 or 1 for not used or used. -bool getAsKeyword(TableNode* definition){ - if(strcmp(getType(definition),"function primitive")!=0){ - printf("not checking if a function is called with as or not -- invalid op\n"); - return NULL;} +// checks if "as" keyword was used for function definition. Either 0 or 1 for +// not used or used. +bool getAsKeyword(TableNode *definition) { + if (strcmp(getType(definition), "function primitive") != 0) { + printf("not checking if a function is called with as or not -- " + "invalid op\n"); + return NULL; + } return definition->additionalinfo->FunDecAdInfo->regularoras; } -//stores the type of a function (parameter type and return type) -AdInfo* CreateFunctionTypeInfo(TableNode* parameter, TableNode* returntype){ - AdInfo* info = (AdInfo*)malloc(sizeof(AdInfo)); - info->FunTypeAdInfo = (function_type_info*)malloc(sizeof(function_type_info)); - info->FunTypeAdInfo->parameter=parameter; +// stores the type of a function (parameter type and return type) +AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->FunTypeAdInfo = + (function_type_info *)malloc(sizeof(function_type_info)); + info->FunTypeAdInfo->parameter = parameter; info->FunTypeAdInfo->returntype = returntype; return info; } -//returns parameter type of a function -TableNode* getParameter(TableNode* definition){ - if(strcmp(getType(definition),"function type primitive")!=0){ - printf("not checking the parameter of a function -- invalid op\n"); - return NULL;} +// returns parameter type of a function +TableNode *getParameter(TableNode *definition) { + if (strcmp(getType(definition), "function type primitive") != 0) { + printf( + "not checking the parameter of a function -- invalid op\n"); + return NULL; + } return definition->additionalinfo->FunTypeAdInfo->parameter; } -//returns return type of a function -TableNode* getReturn(TableNode* definition){ - if(strcmp(getType(definition),"function type primitive")!=0){ +// returns return type of a function +TableNode *getReturn(TableNode *definition) { + if (strcmp(getType(definition), "function type primitive") != 0) { printf("not checking the return of a function -- invalid op\n"); - return NULL;} + return NULL; + } return definition->additionalinfo->FunTypeAdInfo->returntype; } - -//creates a new scope (not the top scope though) -SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { - SymbolTable* table = (SymbolTable*)malloc(sizeof(SymbolTable)); +// creates a new scope (not the top scope though) +SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) { + SymbolTable *table = (SymbolTable *)malloc(sizeof(SymbolTable)); table->Line_Number = Line; table->Column_Number = Column; table->Parent_Scope = ParentScope; @@ -223,16 +247,18 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { table->entries = NULL; if (ParentScope != NULL) { if (ParentScope->Children_Scope == NULL) { - ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable)); + ListOfTable *newEntry = + (ListOfTable *)malloc(sizeof(ListOfTable)); newEntry->next = NULL; // newEntry->prev = NULL; newEntry->table = table; ParentScope->Children_Scope = newEntry; } else { - ListOfTable* newEntry = (ListOfTable*)malloc(sizeof(ListOfTable)); + ListOfTable *newEntry = + (ListOfTable *)malloc(sizeof(ListOfTable)); // newEntry->prev = NULL; newEntry->table = table; - ListOfTable* oldEntry = ParentScope->Children_Scope; + ListOfTable *oldEntry = ParentScope->Children_Scope; ParentScope->Children_Scope = newEntry; newEntry->next = oldEntry; } @@ -240,143 +266,150 @@ SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column) { return table; } -//create entry just for things below top level scope -//This function defines the integer, address, character, and bool primitive types -SymbolTable* init(SymbolTable* start){ - if(start->Parent_Scope != NULL){ - printf("Cannot initialize a scope that is not the parent scope\n"); - return NULL; - } - integ = (TableNode*)malloc(sizeof(TableNode)); - addr = (TableNode*)malloc(sizeof(TableNode)); - chara = (TableNode*)malloc(sizeof(TableNode)); - stri = (TableNode*)malloc(sizeof(TableNode)); - boo = (TableNode*)malloc(sizeof(TableNode)); - //TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); - start->entries = integ; - integ->next = addr; - addr->next = chara; - chara->next = stri; - stri->next = boo; - //boo->next = arr; - boo->next = NULL; +// create entry just for things below top level scope +// This function defines the integer, address, character, and bool primitive +// types +SymbolTable *init(SymbolTable *start) { + if (start->Parent_Scope != NULL) { + printf( + "Cannot initialize a scope that is not the parent scope\n"); + return NULL; + } + integ = (TableNode *)malloc(sizeof(TableNode)); + addr = (TableNode *)malloc(sizeof(TableNode)); + chara = (TableNode *)malloc(sizeof(TableNode)); + stri = (TableNode *)malloc(sizeof(TableNode)); + boo = (TableNode *)malloc(sizeof(TableNode)); + // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); + start->entries = integ; + integ->next = addr; + addr->next = chara; + chara->next = stri; + stri->next = boo; + // boo->next = arr; + boo->next = NULL; - integ->theName= "integer"; - addr->theName= "address"; - chara->theName= "character"; - boo->theName= "Boolean"; - stri->theName= "string"; - //arr->theName= "array" - - //root TableNode that all are pointing to but not in table - //This is only to solve the issue that all entries must have a name and a type - //and the type must point to an actual table entry - //Again, this primitive table entry isn't in the top scope. It is outside the top scope and is only there - //to facilitate the fact that these are primitive - TableNode* prime = (TableNode*)malloc(sizeof(TableNode)); - prime->theName= "primitive"; - prime->theType=NULL; - prime->additionalinfo = NULL; - prime->next = NULL; - - //not sure exatly how to get array types to look right so using a dummy Table Node below and updating the print symbol table function to access the additional information to print for array types, similar to function types - //when printing symbol table, if array is seen - arrayprim = (TableNode*)malloc(sizeof(TableNode)); - arrayprim->theName= "array"; - arrayprim->theType=NULL; + integ->theName = "integer"; + addr->theName = "address"; + chara->theName = "character"; + boo->theName = "Boolean"; + stri->theName = "string"; + // arr->theName= "array" + + // root TableNode that all are pointing to but not in table + // This is only to solve the issue that all entries must have a name and + // a type and the type must point to an actual table entry Again, this + // primitive table entry isn't in the top scope. It is outside the top + // scope and is only there to facilitate the fact that these are + // primitive + TableNode *prime = (TableNode *)malloc(sizeof(TableNode)); + prime->theName = "primitive"; + prime->theType = NULL; + prime->additionalinfo = NULL; + prime->next = NULL; + + // not sure exatly how to get array types to look right so using a dummy + // Table Node below and updating the print symbol table function to + // access the additional information to print for array types, similar + // to function types when printing symbol table, if array is seen + arrayprim = (TableNode *)malloc(sizeof(TableNode)); + arrayprim->theName = "array"; + arrayprim->theType = NULL; arrayprim->additionalinfo = NULL; prime->next = NULL; - - //funprime = CreateEntry(NULL,NULL,strdup("function primitive"),NULL); - - //similar workaround to arrays above - funprime = (TableNode*)malloc(sizeof(TableNode)); - funprime->theName= "primitive function"; - funprime->theType=NULL; + + // funprime = CreateEntry(NULL,NULL,strdup("function primitive"),NULL); + + // similar workaround to arrays above + funprime = (TableNode *)malloc(sizeof(TableNode)); + funprime->theName = "primitive function"; + funprime->theType = NULL; funprime->additionalinfo = NULL; funprime->next = NULL; - //record - recprime = (TableNode*)malloc(sizeof(TableNode)); - recprime->theName= "record"; - recprime->theType=NULL; + // record + recprime = (TableNode *)malloc(sizeof(TableNode)); + recprime->theName = "record"; + recprime->theType = NULL; recprime->additionalinfo = NULL; recprime->next = NULL; - funtypeprime = (TableNode*)malloc(sizeof(TableNode)); - funtypeprime->theName= "primitive function type"; - funtypeprime->theType=NULL; + funtypeprime = (TableNode *)malloc(sizeof(TableNode)); + funtypeprime->theName = "primitive function type"; + funtypeprime->theType = NULL; funtypeprime->additionalinfo = NULL; funtypeprime->next = NULL; - integ->theType=prime; - addr->theType=prime; - chara->theType=prime; - stri->theType=arrayprim; - boo->theType=prime; - //arr->theType=arrayprim; - - //filling in all the values for the additional info for initial types - //These numbers below for create primitive specifically are supposed to be the size - //of these primitive types. We can change these if needed to not be hard coded numbers - //as a reminder, stri below is defined as a one dimensional array of characters - integ->additionalinfo = CreatePrimitiveInfo(4); - addr->additionalinfo = CreatePrimitiveInfo(8); + integ->theType = prime; + addr->theType = prime; + chara->theType = prime; + stri->theType = arrayprim; + boo->theType = prime; + // arr->theType=arrayprim; + + // filling in all the values for the additional info for initial types + // These numbers below for create primitive specifically are supposed to + // be the size of these primitive types. We can change these if needed + // to not be hard coded numbers as a reminder, stri below is defined as + // a one dimensional array of characters + integ->additionalinfo = CreatePrimitiveInfo(4); + addr->additionalinfo = CreatePrimitiveInfo(8); chara->additionalinfo = CreatePrimitiveInfo(1); - stri->additionalinfo = CreateArrayInfo(1,chara); + stri->additionalinfo = CreateArrayInfo(1, chara); boo->additionalinfo = CreatePrimitiveInfo(1); - //addr->additionalinfo = CreatePrimitiveInfo(8); + // addr->additionalinfo = CreatePrimitiveInfo(8); start->Line_Number = 1; start->Column_Number = 1; start->Parent_Scope = NULL; start->Children_Scope = NULL; - - return start; -} - -TableNode* CreateEntry(SymbolTable* table, TableNode* typeOf, char* id, AdInfo* ad) { -if(table ==NULL){ - printf("Null reference to table"); - return NULL; -} -/* -TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); -if(topDef == NULL){ - printf("This type is not defined at the top level\n"); - return NULL; -} -*/ -if(typeOf == NULL){ - printf("This is not pointing to a proper definition\n"); - return NULL; -} - TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode)); - newEntry->theType = typeOf/*topDef*/; - newEntry->theName = id; - newEntry->additionalinfo = ad; - if (table->entries == NULL) { - table->entries = newEntry; - return newEntry; - } else { - TableNode* oldEntry = table->entries; - table->entries = newEntry; - newEntry->next = oldEntry; - return newEntry; - } + return start; } -char* getType(TableNode* tn) { return tn->theType->theName; } -char* getName(TableNode* tn) { return tn->theName; } -int getLine(SymbolTable* st) { return st->Line_Number; } -int getColumn(SymbolTable* st) { return st->Column_Number; } +TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, + AdInfo *ad) { + + if (table == NULL) { + printf("Null reference to table"); + return NULL; + } + /* + TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); + if(topDef == NULL){ + printf("This type is not defined at the top level\n"); + return NULL; + } + */ + if (typeOf == NULL) { + printf("This is not pointing to a proper definition\n"); + return NULL; + } + TableNode *newEntry = (TableNode *)malloc(sizeof(TableNode)); + newEntry->theType = typeOf /*topDef*/; + newEntry->theName = id; + newEntry->additionalinfo = ad; + if (table->entries == NULL) { + table->entries = newEntry; + return newEntry; + } else { + TableNode *oldEntry = table->entries; + table->entries = newEntry; + newEntry->next = oldEntry; + return newEntry; + } +} + +char *getType(TableNode *tn) { return tn->theType->theName; } +char *getName(TableNode *tn) { return tn->theName; } +int getLine(SymbolTable *st) { return st->Line_Number; } +int getColumn(SymbolTable *st) { return st->Column_Number; } /* //we use false for type defs and true for functions for parameter of typeOf TableNode* Define(SymbolTable* table, bool typeOf, char* id) { if(table ==NULL || table->Parent_Scope != NULL){ - printf("No valid table given for header defs\n"); - return NULL; + printf("No valid table given for header defs\n"); + return NULL; } @@ -384,14 +417,14 @@ if(table ==NULL || table->Parent_Scope != NULL){ //possible issues with referencing text instead of heap if(typeOf == 0){ - newEntry->theType = typey; + newEntry->theType = typey; } if (typeOf == 1){ - newEntry->theType = funy; + newEntry->theType = funy; } if(table_lookup(table,id) != NULL){ - printf("already defined at the top level, can't define duplicate names\n"); - return NULL; + printf("already defined at the top level, can't define duplicate +names\n"); return NULL; } newEntry->theName = id; if (table->entries == NULL) { @@ -406,8 +439,8 @@ if(table_lookup(table,id) != NULL){ } */ -TableNode* table_lookup(SymbolTable* table, char* x) { - TableNode* entrie = table->entries; +TableNode *table_lookup(SymbolTable *table, char *x) { + TableNode *entrie = table->entries; for (; entrie != NULL; entrie = entrie->next) { if (!strcmp(entrie->theName, x)) { return entrie; @@ -415,65 +448,71 @@ TableNode* table_lookup(SymbolTable* table, char* x) { } return NULL; } -TableNode* look_up(SymbolTable* table, char* x) { +TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { return NULL; } - TableNode* ret = table_lookup(table, x); + TableNode *ret = table_lookup(table, x); if (ret != NULL) { return ret; } return look_up(table->Parent_Scope, x); } -void print_symbol_table(SymbolTable* table, FILE* file_ptr) { +void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", - "PARENT", "TYPE", "Extra annotation"); + fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", + "SCOPE", "PARENT", "TYPE", "Extra annotation"); } - TableNode* entrie = table->entries; - fprintf(file_ptr, - "-----------------:--------:--------:----------------------:---------" - "--------------------\n"); + TableNode *entrie = table->entries; + fprintf(file_ptr, "-----------------:--------:--------:----------------" + "------:---------" + "--------------------\n"); int parant_scope = 0; int current_scope = 0; if (table->Parent_Scope != NULL) { parant_scope = table->Parent_Scope->Line_Number * 1000 + - table->Parent_Scope->Column_Number; - current_scope = table->Line_Number * 1000 + table->Column_Number; + table->Parent_Scope->Column_Number; + current_scope = + table->Line_Number * 1000 + table->Column_Number; } else { current_scope = 1001; } - if ( entrie == NULL ) { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", - current_scope, parant_scope, "", "Empty Scope"); + if (entrie == NULL) { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", + current_scope, parant_scope, "", "Empty Scope"); } for (; entrie != NULL; entrie = entrie->next) { if (parant_scope == 0) { - /*have to update*/ if(strcmp(entrie->theType->theName,"function primitive")|| strcmp(entrie->theType->theName,"array")){ - } - fprintf(file_ptr, "%-17s: %06d : : %-21s: %-28s\n", - entrie->theName, current_scope, entrie->theType->theName, - "Extra annotation"); + /*have to update*/ if (strcmp(entrie->theType->theName, + "function primitive") || + strcmp(entrie->theType->theName, + "array")) { + } + fprintf(file_ptr, + "%-17s: %06d : : %-21s: %-28s\n", + entrie->theName, current_scope, + entrie->theType->theName, "Extra annotation"); } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName, - current_scope, parant_scope, entrie->theType->theName, "Extra annotation"); + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + entrie->theType->theName, "Extra annotation"); } } if (table->Children_Scope != NULL) { - ListOfTable* node = table->Children_Scope; + ListOfTable *node = table->Children_Scope; for (; node != NULL; node = node->next) { print_symbol_table(node->table, file_ptr); } } if (table->Parent_Scope == NULL) { - fprintf(file_ptr, - "-----------------:--------:--------:----------------------:-------" - "----------------------\n"); + fprintf(file_ptr, "-----------------:--------:--------:--------" + "--------------:-------" + "----------------------\n"); } } -SymbolTable* getAncestor(SymbolTable* table) { +SymbolTable *getAncestor(SymbolTable *table) { if (table->Parent_Scope == NULL) { // if table has no parent, return itself return table; @@ -483,73 +522,78 @@ SymbolTable* getAncestor(SymbolTable* table) { } } -SymbolTable* removeEntry(SymbolTable* scope, char* search){ +SymbolTable *removeEntry(SymbolTable *scope, char *search) { -if(scope == NULL){ - return NULL; -} -if(scope->entries == NULL){ - return scope; + if (scope == NULL) { + return NULL; + } + if (scope->entries == NULL) { + return scope; + } + + TableNode *prev = NULL; + TableNode *now = scope->entries; + + while (now != NULL) { + if (strcmp(getName(now), search) == 0) { + if (prev == NULL) { + scope->entries = getNextEntry(now); + return scope; + } else { + prev->next = now->next; + return scope; + } + } + prev = now; + now = now->next; + } + return scope; } -TableNode* prev = NULL; -TableNode* now = scope->entries; +bool typeCheck(char *firstID, char *secondID) { -while(now != NULL){ -if(strcmp(getName(now),search)==0){ - if(prev == NULL){ - scope->entries = getNextEntry(now); - return scope; - } else{ - prev->next = now->next; - return scope; - } -} -prev = now; -now = now->next; -} -return scope; -} - - - -bool typeCheck(char* firstID, char* secondID){ - - - TableNode* entry1 = look_up(cur,firstID); - TableNode* entry2 = look_up(cur,secondID); - if(entry1==NULL){ - printf("first type not defined\n"); - return false; - } - if(entry2==NULL){ + TableNode *entry1 = look_up(cur, firstID); + TableNode *entry2 = look_up(cur, secondID); + if (entry1 == NULL) { + printf("first type not defined\n"); + return false; + } + if (entry2 == NULL) { printf("second type not defined\n"); return false; } - if(table_lookup(getAncestor(cur),getType(look_up(cur,firstID))) == - table_lookup(getAncestor(cur),getType(look_up(cur,secondID)))){ - if(strcmp(getType(look_up(cur,firstID)),"array")==0){ - if(look_up(cur,firstID)->additionalinfo->ArrayAdInfo->numofdimensions == - look_up(cur,secondID)->additionalinfo->ArrayAdInfo->numofdimensions && - look_up(cur,firstID)->additionalinfo->ArrayAdInfo->typeofarray == - look_up(cur,secondID)->additionalinfo->ArrayAdInfo->typeofarray){ - return true;} - else{ - return false;} + if (table_lookup(getAncestor(cur), getType(look_up(cur, firstID))) == + table_lookup(getAncestor(cur), getType(look_up(cur, secondID)))) { + if (strcmp(getType(look_up(cur, firstID)), "array") == 0) { + if (look_up(cur, firstID) + ->additionalinfo->ArrayAdInfo + ->numofdimensions == + look_up(cur, secondID) + ->additionalinfo->ArrayAdInfo + ->numofdimensions && + look_up(cur, firstID) + ->additionalinfo->ArrayAdInfo + ->typeofarray == + look_up(cur, secondID) + ->additionalinfo->ArrayAdInfo + ->typeofarray) { + return true; + } else { + return false; + } } - return true; - } - return false; + return true; + } + return false; } +SymbolTable *getParent(SymbolTable *st) { return st->Parent_Scope; } -SymbolTable* getParent(SymbolTable* st) { return st->Parent_Scope; } - -ListOfTable* getChildren(SymbolTable* st) { return st->Children_Scope; } -SymbolTable* getFirstChild(ListOfTable* lt) { return lt->table; } -ListOfTable* getRestOfChildren(ListOfTable* lt) { return lt->next; } -TableNode* getFirstEntry(SymbolTable* st) { return st->entries; } -TableNode* getNextEntry(TableNode* tn) { return tn->next; } +ListOfTable *getChildren(SymbolTable *st) { return st->Children_Scope; } +SymbolTable *getFirstChild(ListOfTable *lt) { return lt->table; } +ListOfTable *getRestOfChildren(ListOfTable *lt) { return lt->next; } +TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } +TableNode *getNextEntry(TableNode *tn) { return tn->next; } // uncomment the below main function along with the headers above for a simple // standalone test of table and entry creation diff --git a/src/symbol_table.h b/src/symbol_table.h index 7763305..84b3e5a 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -5,9 +5,9 @@ struct TableNode; -typedef struct{ - int size; -}primitive_info; +typedef struct { + int size; +} primitive_info; /*This structure can be subsumed into the structure below (1-d array of chars) typedef struct{ @@ -17,86 +17,87 @@ typedef struct{ }string_info; */ -typedef struct{ - int numofdimensions; - //the above value tells you how long the below array is. For example if num of dimensions is 5, I can store 1,3,2,5,9 to define > int* arr; - //shouldn't need to store any values (like sizes of dimenions or the location - //int* sizesofdimensions; - //do have to store type of array - struct TableNode* typeofarray; -}array_info; +typedef struct { + int numofdimensions; + // the above value tells you how long the below array is. For example if + // num of dimensions is 5, I can store 1,3,2,5,9 to define > int* + // arr; shouldn't need to store any values (like sizes of dimenions or + // the location int* sizesofdimensions; do have to store type of array + struct TableNode *typeofarray; +} array_info; -typedef struct{ - //similar to above we define a record to hold the number of elements and an array of tablenodes (types) that it contains in the > - int numofelements; - struct TableNode* listoftypes; -}record_info; +typedef struct { + // similar to above we define a record to hold the number of elements + // and an array of tablenodes (types) that it contains in the > + int numofelements; + struct TableNode *listoftypes; +} record_info; -typedef struct{ - int startlinenumber; - bool regularoras; -}function_declaration_info; +typedef struct { + int startlinenumber; + bool regularoras; +} function_declaration_info; -typedef struct{ - struct TableNode* parameter; - struct TableNode* returntype; -}function_type_info; +typedef struct { + struct TableNode *parameter; + struct TableNode *returntype; +} function_type_info; typedef union { - primitive_info* PrimAdInfo; - array_info* ArrayAdInfo; - record_info* RecAdInfo; - //string_info* StringAdInfo; - function_declaration_info* FunDecAdInfo; - function_type_info* FunTypeAdInfo; - }AdInfo; + primitive_info *PrimAdInfo; + array_info *ArrayAdInfo; + record_info *RecAdInfo; + // string_info* StringAdInfo; + function_declaration_info *FunDecAdInfo; + function_type_info *FunTypeAdInfo; +} AdInfo; typedef struct ListOfTable { - struct SymbolTable* table; + struct SymbolTable *table; // struct ListOfTable* prev; - struct ListOfTable* next; + struct ListOfTable *next; } ListOfTable; typedef struct TableNode { - //reference to the type entry that this is - struct TableNode* theType; - char* theName; - AdInfo* additionalinfo; - struct TableNode* next; -}TableNode; + // reference to the type entry that this is + struct TableNode *theType; + char *theName; + AdInfo *additionalinfo; + struct TableNode *next; +} TableNode; typedef struct SymbolTable { - TableNode* entries; - struct SymbolTable* Parent_Scope; - struct ListOfTable* Children_Scope; + TableNode *entries; + struct SymbolTable *Parent_Scope; + struct ListOfTable *Children_Scope; int Line_Number; int Column_Number; } SymbolTable; -SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column); -TableNode* table_lookup(SymbolTable* table, char* x); -TableNode* look_up(SymbolTable* table, char* x); -void print_symbol_table(SymbolTable* table, FILE* file_ptr); +SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column); +TableNode *table_lookup(SymbolTable *table, char *x); +TableNode *look_up(SymbolTable *table, char *x); +void print_symbol_table(SymbolTable *table, FILE *file_ptr); -SymbolTable* getAncestor(SymbolTable* table); -SymbolTable* getParent(SymbolTable* st); -ListOfTable* getChildren(SymbolTable* st); -SymbolTable* getFirstChild(ListOfTable* lt); -ListOfTable* getRestOfChildren(ListOfTable* lt); -TableNode* getFirstEntry(SymbolTable* st); -TableNode* getNextEntry(TableNode* tn); -SymbolTable* init(SymbolTable* scope); -int getPrimSize(TableNode* definition); -int getNumArrDim(TableNode* definition); -TableNode* getArrType(TableNode* definition); -int getRecLength(TableNode* definition); -TableNode* getRecList(TableNode* definition); -int getStartLine(TableNode* definition); -bool getAsKeyword(TableNode* definition); -TableNode* getParameter(TableNode* definition); -TableNode* getReturn(TableNode* definition); +SymbolTable *getAncestor(SymbolTable *table); +SymbolTable *getParent(SymbolTable *st); +ListOfTable *getChildren(SymbolTable *st); +SymbolTable *getFirstChild(ListOfTable *lt); +ListOfTable *getRestOfChildren(ListOfTable *lt); +TableNode *getFirstEntry(SymbolTable *st); +TableNode *getNextEntry(TableNode *tn); +SymbolTable *init(SymbolTable *scope); +int getPrimSize(TableNode *definition); +int getNumArrDim(TableNode *definition); +TableNode *getArrType(TableNode *definition); +int getRecLength(TableNode *definition); +TableNode *getRecList(TableNode *definition); +int getStartLine(TableNode *definition); +bool getAsKeyword(TableNode *definition); +TableNode *getParameter(TableNode *definition); +TableNode *getReturn(TableNode *definition); -char* getType(TableNode* tn); -char* getName(TableNode* tn); -int getLine(SymbolTable* st); -int getColumn(SymbolTable* st); +char *getType(TableNode *tn); +char *getName(TableNode *tn); +int getLine(SymbolTable *st); +int getColumn(SymbolTable *st); From d1f7041c31c6c1334cdb7173898d54f850de4d23 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Wed, 26 Mar 2025 10:54:04 -0400 Subject: [PATCH 016/137] added enum return function --- src/symbol_table.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 83901df..a01d467 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -40,13 +40,17 @@ typedef enum { //Declaring what type a function is (what the parameters and output are) TYPE_FUNCTION_TYPE, //The Type being pointed to by the first 4 above that only stores the size - TYPE_PRIMITIVE + TYPE_PRIMITIVE, + //All else (NULL case likely) + TYPE_ALL_ELSE } types; /* put in symbol_table.h typedef struct{ - int size; + int size; if(strcmp(getType(tn),getName(integ))==0){ + return + } }primitive_info; typedef struct{ @@ -366,8 +370,46 @@ if(typeOf == NULL){ return newEntry; } } +/* +TableNode* integ; +TableNode* addr; +TableNode* chara; +TableNode* stri; +TableNode* boo; +TableNode* recprime; +TableNode* funtypeprime; +*/ char* getType(TableNode* tn) { return tn->theType->theName; } + int getAdInfoType(TableNode* tn){ + if(strcmp(getType(tn),getName(integ))==0){ + return TYPE_PRIMITIVE; + } + if(strcmp(getType(tn),getName(addr))==0){ + return TYPE_PRIMITIVE; + } + if(strcmp(getType(tn),getName(chara))==0){ + return TYPE_PRIMITIVE; + } + if(strcmp(getType(tn),getName(stri))==0){ + return TYPE_ARRAY; + } + if(strcmp(getType(tn),getName(boo))==0){ + return TYPE_PRIMITIVE; + } + if(strcmp(getType(tn),getName(recprime))==0){ + return TYPE_RECORD; + } + if(strcmp(getType(tn),getName(funtypeprime))==0){ + return TYPE_FUNCTION_TYPE; + } + if(strcmp(getType(tn),getName(arrayprim))==0){ + return TYPE_ARRAY; + } + else{ + return TYPE_FUNCTION_DECLARATION; + } +} char* getName(TableNode* tn) { return tn->theName; } int getLine(SymbolTable* st) { return st->Line_Number; } int getColumn(SymbolTable* st) { return st->Column_Number; } From 5aefd319ae51b59542b823bc909b113d1549e6cf Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 26 Mar 2025 12:45:05 -0400 Subject: [PATCH 017/137] Testing suite updated --- Makefile | 3 +- check.sh | 19 ++- src/runner.c | 9 +- .../expected/sp1_comment_fix1.expected | 2 +- .../expected/sp1_comment_fix2.expected | 3 + .../expected/sp1_comment_issues.expected | 22 +++ tests/sprint1/expected/sp1_comments.expected | 9 ++ .../expected/sp1_general_token.expected | 68 ++++++++ tests/sprint1/expected/sp1_keywords.expected | 29 ++++ tests/sprint1/expected/sp1_operators.expected | 22 +++ .../sprint1/expected/sp1_other_punc.expected | 7 + .../expected/sp1_punc_grouping.expected | 59 +++++++ .../expected/sp1_real_alpha_file1.expected | 145 ++++++++++++++++++ .../expected/sp1_real_alpha_file2.expected | 100 ++++++++++++ .../sprint1/expected/sp1_simple_int.expected | 8 + .../expected/sp1_simple_literals.expected | 64 ++++++++ tests/sprint1/expected/sp1_variables.expected | 13 ++ tests/sprint2/other/calc.h | 48 ------ tests/sprint2/other/test.c | 74 --------- tests/sprint2/other/testGrammar.y | 41 ----- 20 files changed, 573 insertions(+), 172 deletions(-) create mode 100644 tests/sprint1/expected/sp1_comment_fix2.expected create mode 100644 tests/sprint1/expected/sp1_comment_issues.expected create mode 100644 tests/sprint1/expected/sp1_comments.expected create mode 100644 tests/sprint1/expected/sp1_general_token.expected create mode 100644 tests/sprint1/expected/sp1_keywords.expected create mode 100644 tests/sprint1/expected/sp1_operators.expected create mode 100644 tests/sprint1/expected/sp1_other_punc.expected create mode 100644 tests/sprint1/expected/sp1_punc_grouping.expected create mode 100644 tests/sprint1/expected/sp1_real_alpha_file1.expected create mode 100644 tests/sprint1/expected/sp1_real_alpha_file2.expected create mode 100644 tests/sprint1/expected/sp1_simple_int.expected create mode 100644 tests/sprint1/expected/sp1_simple_literals.expected create mode 100644 tests/sprint1/expected/sp1_variables.expected delete mode 100644 tests/sprint2/other/calc.h delete mode 100644 tests/sprint2/other/test.c delete mode 100644 tests/sprint2/other/testGrammar.y diff --git a/Makefile b/Makefile index fe8f769..8649a5c 100644 --- a/Makefile +++ b/Makefile @@ -41,9 +41,8 @@ test-s1: test-s2: chmod +x ./check.sh - $(foreach test, $(TESTS-S2), ./$(EXE) -tok $(test);) + $(foreach test, $(TESTS-S2), ./$(EXE) -st $(test);) ./check.sh - $(foreach test, $(TESTS-S2), ./$(EXE) $(test);) clean: rm -f *.o diff --git a/check.sh b/check.sh index b8b138c..f325421 100755 --- a/check.sh +++ b/check.sh @@ -5,6 +5,11 @@ # The Translators - Spring 2025 # TOK_DIR="out" +RED='\033[0;31m' +GREEN='\033[0;32m' +WHITE='\033[0m' +PURPLE='\033[0;35m' +ORANGE='\033[0;33m' if [[ ! -d "$TOK_DIR" ]]; then echo "Directory $TOK_DIR does not exist." @@ -19,9 +24,15 @@ for file in "$TOK_DIR"/*; do exp="./tests/sprint$num/expected/$filename.expected" if [[ -f "$exp" ]]; then - echo -e "--------------------------------------------" - echo -e "Checking $file...\n" - diff --color=always "$file" "$exp" - echo -e "--------------------------------------------\n" + diff -q "$file" "$exp" > /dev/null + if [[ $? -eq 0 ]]; then + echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed." + else + echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value..." + diff --color=always "$file" "$exp" + echo -e "" + fi + else + echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value." fi done \ No newline at end of file diff --git a/src/runner.c b/src/runner.c index 8722425..68198f8 100644 --- a/src/runner.c +++ b/src/runner.c @@ -131,8 +131,13 @@ int run(FILE *alpha) { } if (st_flag != NULL) { - // output symbol table, file pointer is - // print_symbol_table(top,st_flag); + yyparse(); + print_symbol_table(getAncestor(cur), st_flag); + fclose(st_flag); + if (yyin != NULL) { + fclose(yyin); + } + return 0; } yyparse(); diff --git a/tests/sprint1/expected/sp1_comment_fix1.expected b/tests/sprint1/expected/sp1_comment_fix1.expected index 07d66e1..de45b77 100644 --- a/tests/sprint1/expected/sp1_comment_fix1.expected +++ b/tests/sprint1/expected/sp1_comment_fix1.expected @@ -1 +1 @@ - daskmskdfm \ No newline at end of file +1 1 700 "(***)" diff --git a/tests/sprint1/expected/sp1_comment_fix2.expected b/tests/sprint1/expected/sp1_comment_fix2.expected new file mode 100644 index 0000000..e094e9b --- /dev/null +++ b/tests/sprint1/expected/sp1_comment_fix2.expected @@ -0,0 +1,3 @@ +1 1 700 "(*(**)" +1 7 603 "*" +1 8 502 ")" diff --git a/tests/sprint1/expected/sp1_comment_issues.expected b/tests/sprint1/expected/sp1_comment_issues.expected new file mode 100644 index 0000000..0e3c0b8 --- /dev/null +++ b/tests/sprint1/expected/sp1_comment_issues.expected @@ -0,0 +1,22 @@ +1 1 700 "(*(**)" +1 7 603 "*" +1 8 502 ")" +2 1 700 "(***)" +3 1 700 "(******)" +3 9 700 "(*\kpp*********)" +4 1 501 "(" +4 2 700 "(*((*)" +4 8 502 ")" +5 1 700 "(***)" +5 6 700 "(*) +(* *)" +7 1 700 "(***)" +7 6 502 ")" +7 7 502 ")" +7 8 502 ")" +7 9 502 ")" +7 10 502 ")" +7 11 502 ")" +7 12 603 "*" +7 13 700 "(*))))))))*)" +7 25 502 ")" diff --git a/tests/sprint1/expected/sp1_comments.expected b/tests/sprint1/expected/sp1_comments.expected new file mode 100644 index 0000000..0486ed9 --- /dev/null +++ b/tests/sprint1/expected/sp1_comments.expected @@ -0,0 +1,9 @@ +1 1 700 "(* hello *)" +2 1 700 "(* hello *)" +3 1 700 "(* I'd think this is a legal "string" that contains several \n \t +escaped characters, isn't it? *)" +5 1 700 "(* \ *)" +6 1 700 "(* *)" +7 1 700 "(*{COMMENT}+ *)" +8 1 700 "(* * *)" +9 1 700 "(* (hello) *)" diff --git a/tests/sprint1/expected/sp1_general_token.expected b/tests/sprint1/expected/sp1_general_token.expected new file mode 100644 index 0000000..d50bac7 --- /dev/null +++ b/tests/sprint1/expected/sp1_general_token.expected @@ -0,0 +1,68 @@ +1 1 101 "This" +1 6 101 "is" +1 9 101 "a" +1 11 101 "test" +2 1 301 "9" +2 2 101 "combined" +2 11 301 "7" +2 12 101 "okens" +3 1 301 "12345" +4 1 301 "893247892" +5 1 101 "combined" +5 10 101 "DueToUnknownChar" +5 27 101 "_validtoken" +5 39 101 "__validtoken1" +5 53 101 "_valid_token2" +5 67 101 "validToken3_" +6 1 305 "true" +6 6 306 "false" +7 1 302 "null" +7 6 401 "while" +7 12 609 "!" +7 13 101 "wrong" +7 19 402 "if" +7 22 101 "when" +8 1 404 "else" +8 6 405 "type" +8 11 406 "function" +9 1 407 "return" +9 9 408 "external" +9 25 409 "as" +10 1 101 "string" +10 8 101 "_NOte_that_was_not_reserved" +11 1 501 "(" +11 2 503 "[" +11 3 502 ")" +11 4 504 "]" +11 5 505 "{" +11 6 506 "}" +11 7 508 ":" +11 8 507 ";" +11 9 509 "," +11 10 510 "->" +12 1 601 "+" +12 2 602 "-" +12 3 603 "*" +12 4 604 "/" +12 5 605 "%" +13 1 606 "<" +13 2 607 "=" +14 1 608 ":=" +15 2 101 "This" +15 7 101 "is" +15 10 101 "not" +15 14 101 "a" +15 16 101 "valid" +16 1 101 "String" +17 1 304 ""This is a valid String"" +18 1 609 "!" +18 2 611 "|" +19 1 612 "." +19 2 612 "." +20 1 700 "(* this is a comment *)" +21 1 501 "(" +21 2 603 "*" +21 3 101 "Not" +21 7 101 "a" +21 9 101 "comment" +22 3 610 "&" diff --git a/tests/sprint1/expected/sp1_keywords.expected b/tests/sprint1/expected/sp1_keywords.expected new file mode 100644 index 0000000..9e70321 --- /dev/null +++ b/tests/sprint1/expected/sp1_keywords.expected @@ -0,0 +1,29 @@ +1 1 401 "while" +2 1 101 "While" +3 1 101 "whiLe" +4 1 402 "if" +5 1 101 "IF" +6 1 101 "If" +7 1 101 "iF" +8 1 403 "then" +9 1 101 "Then" +10 1 101 "theN" +11 1 404 "else" +12 1 101 "eLse" +13 1 101 "elSe" +14 1 101 "Else" +15 1 405 "type" +16 1 101 "Type" +17 1 101 "tyPe" +18 1 406 "function" +19 1 101 "Function" +20 1 101 "functioN" +21 1 407 "return" +22 1 101 "Return" +23 1 101 "returN" +24 1 408 "external" +25 1 101 "External" +26 1 101 "exteRnal" +27 1 409 "as" +28 1 101 "As" +29 1 101 "aS" diff --git a/tests/sprint1/expected/sp1_operators.expected b/tests/sprint1/expected/sp1_operators.expected new file mode 100644 index 0000000..dd3eaab --- /dev/null +++ b/tests/sprint1/expected/sp1_operators.expected @@ -0,0 +1,22 @@ +1 1 601 "+" +2 1 602 "-" +3 1 603 "*" +4 1 604 "/" +6 1 605 "%" +7 1 606 "<" +9 1 607 "=" +10 1 608 ":=" +11 1 607 "=" +11 2 508 ":" +12 1 508 ":" +13 1 607 "=" +14 1 609 "!" +15 1 610 "&" +16 1 611 "|" +17 1 612 "." +18 1 101 "relEASE" +19 1 614 "release" +20 1 101 "RELEASE" +21 1 613 "reserve" +22 1 101 "RESERVE" +23 1 101 "reSERVe" diff --git a/tests/sprint1/expected/sp1_other_punc.expected b/tests/sprint1/expected/sp1_other_punc.expected new file mode 100644 index 0000000..7500378 --- /dev/null +++ b/tests/sprint1/expected/sp1_other_punc.expected @@ -0,0 +1,7 @@ +1 1 507 ";" +2 1 508 ":" +3 1 509 "," +4 1 510 "->" +5 1 510 "->" +6 1 602 "-" +6 2 510 "->" diff --git a/tests/sprint1/expected/sp1_punc_grouping.expected b/tests/sprint1/expected/sp1_punc_grouping.expected new file mode 100644 index 0000000..c58a316 --- /dev/null +++ b/tests/sprint1/expected/sp1_punc_grouping.expected @@ -0,0 +1,59 @@ +1 1 502 ")" +2 1 101 "a" +2 2 502 ")" +3 1 502 ")" +3 2 101 "a" +4 1 502 ")" +4 2 603 "*" +5 1 603 "*" +5 2 502 ")" +7 1 700 "(* jellsls + well this seems to work + + + *)" +13 1 501 "(" +14 1 101 "a" +14 2 501 "(" +15 1 501 "(" +15 2 101 "a" +16 1 501 "(" +16 2 603 "*" +17 1 603 "*" +17 2 501 "(" +20 1 505 "{" +21 1 101 "a" +21 2 505 "{" +22 1 505 "{" +22 2 101 "a" +23 1 505 "{" +23 2 603 "*" +24 1 603 "*" +24 2 505 "{" +25 1 506 "}" +26 1 101 "a" +26 2 506 "}" +27 1 506 "}" +27 2 101 "a" +28 1 506 "}" +28 2 603 "*" +29 1 603 "*" +29 2 506 "}" +33 1 503 "[" +34 1 101 "a" +34 2 503 "[" +35 1 503 "[" +35 2 101 "a" +36 1 503 "[" +36 2 603 "*" +37 1 603 "*" +37 2 503 "[" +38 1 504 "]" +39 1 101 "a" +39 2 504 "]" +40 1 504 "]" +40 2 101 "a" +41 1 504 "]" +41 2 603 "*" +42 1 603 "*" +42 2 504 "]" diff --git a/tests/sprint1/expected/sp1_real_alpha_file1.expected b/tests/sprint1/expected/sp1_real_alpha_file1.expected new file mode 100644 index 0000000..cc3f2c9 --- /dev/null +++ b/tests/sprint1/expected/sp1_real_alpha_file1.expected @@ -0,0 +1,145 @@ +1 1 405 "type" +1 6 101 "rec" +1 9 508 ":" +1 11 503 "[" +1 12 201 "integer" +1 19 508 ":" +1 21 101 "x" +1 22 507 ";" +1 24 201 "integer" +1 31 508 ":" +1 33 101 "y" +1 34 504 "]" +2 1 405 "type" +2 6 101 "T1" +2 8 508 ":" +2 10 201 "integer" +2 18 510 "->" +2 21 201 "integer" +3 1 405 "type" +3 6 101 "T2" +3 8 508 ":" +3 10 101 "rec" +3 14 510 "->" +3 17 201 "integer" +4 1 406 "function" +4 10 101 "foo" +4 14 508 ":" +4 16 101 "T1" +5 1 406 "function" +5 10 101 "bar1" +5 15 508 ":" +5 17 101 "T2" +6 1 406 "function" +6 10 101 "bar2" +6 15 508 ":" +6 17 101 "T2" +7 1 101 "foo" +7 4 501 "(" +7 5 101 "x" +7 6 502 ")" +7 8 608 ":=" +7 11 505 "{" +8 2 407 "return" +8 9 101 "x" +8 11 603 "*" +8 13 101 "x" +8 14 507 ";" +9 9 506 "}" +10 1 101 "bar1" +10 5 501 "(" +10 6 101 "a" +10 7 502 ")" +10 9 608 ":=" +10 12 505 "{" +11 9 407 "return" +11 16 101 "a" +11 17 612 "." +11 18 101 "x" +11 20 603 "*" +11 22 101 "a" +11 23 612 "." +11 24 101 "y" +11 25 507 ";" +12 9 506 "}" +13 1 101 "bar2" +13 6 409 "as" +13 9 501 "(" +13 10 101 "r" +13 11 509 "," +13 12 101 "s" +13 13 502 ")" +13 15 608 ":=" +13 18 505 "{" +14 9 407 "return" +14 16 101 "r" +14 18 603 "*" +14 20 101 "s" +14 21 507 ";" +15 9 506 "}" +16 1 101 "entry" +16 6 501 "(" +16 7 101 "arg" +16 10 502 ")" +16 12 608 ":=" +16 15 505 "{" +17 9 503 "[" +17 11 201 "integer" +17 18 508 ":" +17 20 101 "result" +17 27 507 ";" +17 29 101 "rec" +17 32 508 ":" +17 34 101 "w" +17 35 504 "]" +18 9 101 "result" +18 16 608 ":=" +18 19 101 "foo" +18 22 501 "(" +18 23 301 "5" +18 24 502 ")" +18 25 507 ";" +19 9 101 "w" +19 11 608 ":=" +19 14 613 "reserve" +19 21 501 "(" +19 22 101 "w" +19 23 502 ")" +19 24 507 ";" +19 26 700 "(* see types.alpha – reserve returns a value of type address, + which can be assigned to array and record variables + *)" +22 9 101 "w" +22 10 612 "." +22 11 101 "x" +22 13 608 ":=" +22 16 301 "5" +22 17 507 ";" +23 9 101 "w" +23 10 612 "." +23 11 101 "y" +23 13 608 ":=" +23 16 301 "7" +23 17 507 ";" +24 9 101 "result" +24 16 608 ":=" +24 19 101 "bar1" +24 23 501 "(" +24 24 101 "w" +24 25 502 ")" +24 26 507 ";" +24 28 700 "(* pass w (a rec type value) to bar1 *)" +25 9 101 "result" +25 16 608 ":=" +25 19 101 "bar2" +25 23 501 "(" +25 24 301 "5" +25 25 509 "," +25 26 301 "7" +25 27 502 ")" +25 28 507 ";" +25 30 700 "(* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *)" +27 9 407 "return" +27 16 301 "0" +27 17 507 ";" +28 1 506 "}" diff --git a/tests/sprint1/expected/sp1_real_alpha_file2.expected b/tests/sprint1/expected/sp1_real_alpha_file2.expected new file mode 100644 index 0000000..90c34a2 --- /dev/null +++ b/tests/sprint1/expected/sp1_real_alpha_file2.expected @@ -0,0 +1,100 @@ +1 1 700 "(* Type definitions *)" +2 1 405 "type" +2 6 101 "string" +2 12 508 ":" +2 14 301 "1" +2 16 510 "->" +2 19 204 "character" +3 1 405 "type" +3 6 101 "int2int" +3 13 508 ":" +3 15 201 "integer" +3 23 510 "->" +3 26 201 "integer" +4 1 405 "type" +4 6 101 "string2int" +4 16 508 ":" +4 18 101 "string" +4 25 510 "->" +4 28 201 "integer" +5 1 700 "(* Function prototypes +They use the above type definitions +*)" +8 1 406 "function" +8 10 101 "square" +8 17 508 ":" +8 19 101 "int2int" +9 1 406 "function" +9 10 101 "entry" +9 16 508 ":" +9 18 101 "string2int" +10 1 700 "(* Function definition +Functions must be declared before they are defined +*)" +13 1 101 "square" +13 7 501 "(" +13 8 101 "x" +13 9 502 ")" +13 11 608 ":=" +13 14 505 "{" +14 1 407 "return" +14 8 101 "x" +14 10 603 "*" +14 12 101 "x" +14 13 507 ";" +15 1 506 "}" +16 1 700 "(* Function definition +entry is the first function called +*)" +19 1 101 "entry" +19 6 501 "(" +19 7 101 "arg" +19 10 502 ")" +19 12 608 ":=" +19 15 505 "{" +20 1 101 "input" +20 7 607 "=" +20 9 301 "7" +20 10 507 ";" +21 1 101 "expected" +21 10 607 "=" +21 12 301 "49" +21 14 507 ";" +22 1 101 "actual" +22 8 608 ":=" +22 11 101 "square" +22 17 501 "(" +22 18 101 "input" +22 23 502 ")" +22 24 507 ";" +23 1 101 "rseult" +23 8 608 ":=" +23 11 101 "expected" +23 20 607 "=" +23 22 101 "actual" +23 28 507 ";" +24 1 407 "return" +24 8 301 "0" +24 9 507 ";" +25 1 503 "[" +25 3 201 "integer" +25 10 508 ":" +25 12 101 "input" +25 17 507 ";" +25 19 201 "integer" +25 26 508 ":" +25 28 101 "expected" +25 36 507 ";" +25 38 201 "integer" +25 45 508 ":" +25 47 101 "actual" +25 53 507 ";" +25 55 101 "boolean" +25 62 508 ":" +25 64 101 "result" +25 70 507 ";" +25 72 101 "string" +25 78 508 ":" +25 80 101 "input" +25 86 504 "]" +26 1 506 "}" diff --git a/tests/sprint1/expected/sp1_simple_int.expected b/tests/sprint1/expected/sp1_simple_int.expected new file mode 100644 index 0000000..0bcbefb --- /dev/null +++ b/tests/sprint1/expected/sp1_simple_int.expected @@ -0,0 +1,8 @@ +1 1 301 "45" +2 1 301 "123" +3 1 301 "8392" +4 1 301 "40" +4 4 301 "40" +5 2 301 "200" +5 6 301 "50" +5 9 301 "21783" diff --git a/tests/sprint1/expected/sp1_simple_literals.expected b/tests/sprint1/expected/sp1_simple_literals.expected new file mode 100644 index 0000000..788adc2 --- /dev/null +++ b/tests/sprint1/expected/sp1_simple_literals.expected @@ -0,0 +1,64 @@ +1 1 304 ""this is a string"" +1 20 301 "721398" +1 27 303 "'g'" +1 32 604 "/" +1 33 101 "n" +1 36 700 "(* should print 3 tokens before this *)" +4 1 301 "12893" +4 8 101 "this" +4 13 101 "is" +4 16 101 "not" +4 20 101 "a" +4 22 101 "string" +4 29 700 "(*one valid token before this*)" +5 1 700 "(* spacey comment here +over multiple lines +will it work? *)" +7 18 306 "false" +11 1 306 "false" +12 1 700 "(**)" +14 1 101 "nullfalse" +15 2 101 "nulltrue" +16 1 302 "null" +17 1 303 "'7'" +18 1 305 "true" +19 2 301 "189" +20 1 303 "'\t'" +21 1 303 "'"'" +22 1 303 "'/'" +23 1 303 "'\n'" +24 1 303 "'\''" +25 1 303 "'\t'" +26 1 303 "'\\'" +27 1 303 "'n'" +29 2 101 "fdsf" +30 1 700 "(*/jnewjno2893u86^ Lots of random characters /n /t '") *)" +35 1 304 ""STRINGwithnotSPaces"" +36 1 303 "' '" +38 1 304 ""J"" +39 1 304 """" +40 1 304 "" "" +42 1 304 ""{SCHAR}"" +43 1 304 ""SCHAR"" +44 1 304 ""[SCHAR]"" +45 1 304 ""FINAL: I'd think this is a legal \"string\" that contains \n \t several escaped characters, isn't it?"" +46 2 101 "I" +46 4 101 "d" +46 6 101 "think" +46 12 101 "this" +46 17 101 "is" +46 20 101 "a" +46 22 101 "legal" +46 30 101 "string" +46 39 101 "that" +46 44 101 "contains" +46 53 101 "several" +46 63 101 "n" +46 66 101 "t" +46 68 101 "escaped" +46 76 101 "characters" +46 86 509 "," +46 88 101 "isn" +46 92 101 "t" +46 94 101 "it" +47 1 101 "nullLike" diff --git a/tests/sprint1/expected/sp1_variables.expected b/tests/sprint1/expected/sp1_variables.expected new file mode 100644 index 0000000..223288a --- /dev/null +++ b/tests/sprint1/expected/sp1_variables.expected @@ -0,0 +1,13 @@ +1 1 101 "valid1" +2 1 101 "Valid2" +3 1 101 "_valid3" +4 1 101 "_valid_name_4" +5 1 101 "VALID" +6 1 301 "0" +6 2 101 "Invalid" +7 1 301 "1" +7 2 101 "invalid" +8 2 101 "invalid" +9 1 101 "invalid" +9 8 607 "=" +10 1 101 "String" diff --git a/tests/sprint2/other/calc.h b/tests/sprint2/other/calc.h deleted file mode 100644 index 2580e93..0000000 --- a/tests/sprint2/other/calc.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Function type. */ -typedef double (func_t) (double); -/* Data type for links in the chain of symbols. */ -struct symrec -{ - char *name; /* name of symbol */ - int type; /* type of symbol: either VAR or FUN */ - union - { - double var; /* value of a VAR */ - func_t *fun; /* value of a FUN */ - } value; - struct symrec *next; /* link field */ -}; -typedef struct symrec symrec; - -/* The symbol table: a chain of 'struct symrec'. */ -extern symrec *sym_table; - -symrec *putsym (char const *name, int sym_type); -symrec *getsym (char const *name); -struct init -{ - char const *name; - func_t *fun; -}; -struct init const funs[] = -{ - { "atan", atan }, - { "cos", cos }, - { "exp", exp }, - { "ln", log }, - { "sin", sin }, - { "sqrt", sqrt }, - { 0, 0 }, -}; -/* The symbol table: a chain of 'struct symrec'. */ -symrec *sym_table; -/* Put functions in table. */ -static void -init_table (void) -{ - for (int i = 0; funs[i].name; i++) - { - symrec *ptr = putsym (funs[i].name, FUN); - ptr->value.fun = funs[i].fun; - } -} diff --git a/tests/sprint2/other/test.c b/tests/sprint2/other/test.c deleted file mode 100644 index 0d9b343..0000000 --- a/tests/sprint2/other/test.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include "symbol_table.h" - -int main(void){ - char *prim = strdup("primitive"); - char *inte = strdup("integer"); - SymbolTable * parant = CreateScope(NULL, 1,1); - char *boole = strdup("Boolean"); - char *chare = strdup("character"); - char *str = strdup("string"); - char *arg = strdup("arg"); - char *one_to_char = strdup("1 -> character"); - char *int_to_int = strdup("integer -> integer"); - char *int2int = strdup("int2int"); - char *str_to_int = strdup("string -> integer"); - char *str2int = strdup("string2int"); - char *square = strdup("square"); - char *string2int = strdup("string2int"); - char *entry = strdup("entry"); - char *x = strdup("x"); - char *input = strdup("input"); - char *expected = strdup("expected"); - char *actual = strdup("actual"); - char *$_und_type = strdup("$_undefined_type"); - char *result = strdup("result"); - char *BOO = strdup("BOO"); - char *YAZOO = strdup("YAZOO"); - - CreateEntry(parant, prim, boole); - CreateEntry(parant, prim, chare); - CreateEntry(parant, prim, inte); - CreateEntry(parant, one_to_char, str); - CreateEntry(parant, int_to_int, int2int); - CreateEntry(parant, str_to_int, str2int); - CreateEntry(parant, int2int, square); - CreateEntry(parant, string2int, entry); - SymbolTable * child = CreateScope(parant, 14,14); - CreateEntry(child, inte, x); - SymbolTable * second = CreateScope(parant, 21,15); - CreateEntry(second, str, arg); - CreateEntry(second, inte, input); - CreateEntry(second, inte, expected); - CreateEntry(second, inte, actual); - CreateEntry(second, $_und_type, result); - SymbolTable * third = CreateScope(second, 33,44); - CreateEntry(third, BOO, arg); - CreateEntry(third, YAZOO, input); - - TableNode *ret = table_lookup(third, "arg"); - printf("%s == %s\n", ret->theName, "arg"); - - ret = table_lookup(third, "hello"); - printf("This should be nil %p != %s\n", ret, "BOO"); - - ret = look_up(second, "input"); - printf("%s == %s\n", ret->theName, "input"); - - ret = look_up(second, "square"); - printf("%s == %s\n", ret->theName, "square"); - - ret = look_up(second, "spuare"); - printf("This should be nil %p == %s\n", ret, "square"); - - print_symbol_table(parant, stderr); - free(inte); - free(boole); - free(prim); - free(str); - free(chare); - free(arg); - return 0; -} - diff --git a/tests/sprint2/other/testGrammar.y b/tests/sprint2/other/testGrammar.y deleted file mode 100644 index 04f8f17..0000000 --- a/tests/sprint2/other/testGrammar.y +++ /dev/null @@ -1,41 +0,0 @@ -%{ - #include /* For printf, etc. */ - #include /* For pow, used in the grammar. */ - #include "calc.h" /* Contains definition of 'symrec'. */ - int yylex (void); - void yyerror (char const *); -%} -%define api.value.type union /* Generate YYSTYPE from these types: */ -%token NUM /* Double precision number. */ -%token VAR FUN /* Symbol table pointer: variable/function. */ -%nterm exp -%precedence '=' -%left '-' '+' -%left '*' '/' -%precedence NEG /* negation--unary minus */ -%right '^' /* exponentiation */ -%% /* The grammar follows. */ -input: - %empty -| input line -; -line: - '\n' -| exp '\n' { printf ("%.10g\n", $1); } -| error '\n' { yyerrok; } -; -exp: - NUM -| VAR { $$ = $1->value.var; } -| VAR '=' exp { $$ = $3; $1->value.var = $3; } -| FUN '(' exp ')' { $$ = $1->value.fun ($3); } -| exp '+' exp { $$ = $1 + $3; } -| exp '-' exp { $$ = $1 - $3; } -| exp '*' exp { $$ = $1 * $3; } -| exp '/' exp { $$ = $1 / $3; } -| '-' exp %prec NEG { $$ = -$2; } -| exp '^' exp { $$ = pow ($1, $3); } -| '(' exp ')' { $$ = $2; } -; -/* End of grammar. */ -%% From 0ff894d571e25e09a3a23ed13ff1e91a2176ee11 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Wed, 26 Mar 2025 15:21:42 -0400 Subject: [PATCH 018/137] fixed most things in the symbol table structure. Seeing core dumps and have to fix the print symbol table function --- src/symbol_table.c | 68 ++++++++++++++++++++++++++++++++++++---------- src/symbol_table.h | 4 +-- 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 205bcbe..cb6a311 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -27,23 +27,23 @@ typedef enum { // TYPE_BOOLEAN, // TYPE_ADDRESS, // Type String is an array of char enclosed in double quotes per lexer - TYPE_STRING, + TYPE_STRING = 1, // Array can be multidimensional. Information should be stored here - TYPE_ARRAY, + TYPE_ARRAY = 2, // Record is user defined types - TYPE_RECORD, + TYPE_RECORD = 3, // Declaring what type a particular function is without as - TYPE_FUNCTION_DECLARATION, + TYPE_FUNCTION_DECLARATION = 4, // Declaring what type a particular function is with as // TYPE_AS_FUNCTION_DECLARATION, // Declaring what type a function is (what the parameters and output // are) - TYPE_FUNCTION_TYPE, + TYPE_FUNCTION_TYPE = 5, // The Type being pointed to by the first 4 above that only stores the // size - TYPE_PRIMITIVE, + TYPE_PRIMITIVE = 6, //likely NULL - TYPE_ALL_ELSE + TYPE_ALL_ELSE = 7 } types; @@ -153,12 +153,12 @@ TableNode *getArrType(TableNode *definition) { // order, of what make up that type in an array. Unfortunately this second part // should probably instead be replaced by a reference to a scope in which those // elements are found. -AdInfo *CreateRecordInfo(int length, TableNode *typesarray) { +AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); info->RecAdInfo = (record_info *)malloc(sizeof(record_info)); info->RecAdInfo->numofelements = length; // replace below with reference to a scope, not an array - info->RecAdInfo->listoftypes = typesarray; + info->RecAdInfo->recordScope = recordScope; return info; } // This gets the number of elements that make up a record. @@ -172,13 +172,13 @@ int getRecLength(TableNode *definition) { return definition->additionalinfo->RecAdInfo->numofelements; } // This gets the array. Needs to up be updated to get the scope instead -TableNode *getRecList(TableNode *definition) { +SymbolTable *getRecList(TableNode *definition) { if (strcmp(getType(definition), "record") != 0) { printf("not checking the list of types of a record -- invalid " "op\n"); return NULL; } - return definition->additionalinfo->RecAdInfo->listoftypes; + return definition->additionalinfo->RecAdInfo->recordScope; } // below function takes a bool to see if parameter should be decomposed or not @@ -379,8 +379,34 @@ TableNode* boo; TableNode* recprime; TableNode* funtypeprime; */ +TableNode* populateTypeAndInfo(TableNode* tn, TableNode* type, AdInfo* info){ + if(tn == NULL){ + printf("passed in an invalid table node to modify (NULL).\n"); + return NULL; + } + if(type == NULL){ + printf("passed in a NULL type reference to populate a table node. Invalid.\n"); + return NULL; + } + if(info == NULL){ + printf("passed in a NULL info reference to populate a table node. Invalid.\n"); + return NULL; + } + tn->theType = type; + tn->additionalinfo = info; + //returning reference to modified table node + return tn; + } int getAdInfoType(TableNode* tn){ + if(tn == NULL){ + printf("passing in NULL table entry. Invalid\n"); + return -1; + } + if(tn->theType == NULL){ + printf("Entry being passed in has a null reference for theType. Invalid.\n"); + return -1; + } if(strcmp(getType(tn),getName(integ))==0){ return TYPE_PRIMITIVE; } @@ -443,7 +469,16 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } } -char *getType(TableNode *tn) { return tn->theType->theName; } +char *getType(TableNode *tn) { + if(tn == NULL){ + printf("passed a NULL table entry to getType\n"); + return NULL; + } + if(tn->theType == NULL){ + printf("type of entry is currently NULL, undefined type \n"); + return NULL; + } + return tn->theType->theName; } char *getName(TableNode *tn) { return tn->theName; } int getLine(SymbolTable *st) { return st->Line_Number; } int getColumn(SymbolTable *st) { return st->Column_Number; } @@ -483,6 +518,7 @@ names\n"); return NULL; } */ +//only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { TableNode *entrie = table->entries; for (; entrie != NULL; entrie = entrie->next) { @@ -492,6 +528,7 @@ TableNode *table_lookup(SymbolTable *table, char *x) { } return NULL; } +//check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { return NULL; @@ -504,6 +541,8 @@ TableNode *look_up(SymbolTable *table, char *x) { } void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + + return; if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -526,7 +565,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (; entrie != NULL; entrie = entrie->next) { + for (entrie != NULL; entrie = entrie->next;) { if (parant_scope == 0) { /*have to update*/ if (strcmp(entrie->theType->theName, "function primitive") || @@ -555,7 +594,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "----------------------\n"); } } - +//get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { if (table->Parent_Scope == NULL) { // if table has no parent, return itself @@ -594,6 +633,7 @@ SymbolTable *removeEntry(SymbolTable *scope, char *search) { return scope; } +//almost certainly don't need to use the below function since type checking happens by passing types up the grammar bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); diff --git a/src/symbol_table.h b/src/symbol_table.h index 84b3e5a..de37098 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -30,7 +30,7 @@ typedef struct { // similar to above we define a record to hold the number of elements // and an array of tablenodes (types) that it contains in the > int numofelements; - struct TableNode *listoftypes; + struct SymbolTable *recordScope; } record_info; typedef struct { @@ -91,7 +91,7 @@ int getPrimSize(TableNode *definition); int getNumArrDim(TableNode *definition); TableNode *getArrType(TableNode *definition); int getRecLength(TableNode *definition); -TableNode *getRecList(TableNode *definition); +SymbolTable *getRecList(TableNode *definition); int getStartLine(TableNode *definition); bool getAsKeyword(TableNode *definition); TableNode *getParameter(TableNode *definition); From 27fb88f866d3b242c7e7aba7a4886356c1252f6e Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Wed, 26 Mar 2025 16:21:57 -0400 Subject: [PATCH 019/137] updated branch to not crash due to getType issue --- src/symbol_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index cb6a311..35e99de 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -472,11 +472,11 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, char *getType(TableNode *tn) { if(tn == NULL){ printf("passed a NULL table entry to getType\n"); - return NULL; + return tn; } if(tn->theType == NULL){ printf("type of entry is currently NULL, undefined type \n"); - return NULL; + return tn; } return tn->theType->theName; } char *getName(TableNode *tn) { return tn->theName; } From 22c1a79e0323b2fb5062b984978304146568caa4 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Wed, 26 Mar 2025 18:42:09 -0400 Subject: [PATCH 020/137] added more helper functions. still have to update print symbol table function --- src/symbol_table.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 35e99de..208eb69 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -472,17 +472,38 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, char *getType(TableNode *tn) { if(tn == NULL){ printf("passed a NULL table entry to getType\n"); - return tn; + return ""; } if(tn->theType == NULL){ printf("type of entry is currently NULL, undefined type \n"); - return tn; + return ""; } return tn->theType->theName; } char *getName(TableNode *tn) { return tn->theName; } int getLine(SymbolTable *st) { return st->Line_Number; } int getColumn(SymbolTable *st) { return st->Column_Number; } +TableNode* addName(TableNode *tn, char* str){ + if(tn == NULL){ + printf("passed a Null table node to the addName function. Invalid./n"); + return tn; + } +} +SymbolTable* setLineNumber(SymbolTable *st,int line){ + if(st == NULL){ + printf("passed a Null Symbol Table to the setLineNumber function. Invalid./n"); + return st; + } + st->Line_Number = line; + } + +SymbolTable* setColumnNumber(SymbolTable *st,int column){ + if(st == NULL){ + printf("passed a Null Symbol Table to the setColumnNumber function. Invalid./n"); + return st; + } + st->Line_Number = column; + } /* //we use false for type defs and true for functions for parameter of typeOf TableNode* Define(SymbolTable* table, bool typeOf, char* id) { From 04418cc75db6483aaedab72b9ab26c824155d6c7 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 03:06:58 -0400 Subject: [PATCH 021/137] added testing suite for binary and unary operations typechecking --- test-s1 | 0 test-s2 | 0 tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha | 6 ++++++ tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha | 5 +++++ tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha | 9 +++++++++ tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha | 6 ++++++ 6 files changed, 26 insertions(+) create mode 100644 test-s1 create mode 100644 test-s2 create mode 100644 tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha create mode 100644 tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha create mode 100644 tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha create mode 100644 tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha diff --git a/test-s1 b/test-s1 new file mode 100644 index 0000000..e69de29 diff --git a/test-s2 b/test-s2 new file mode 100644 index 0000000..e69de29 diff --git a/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha new file mode 100644 index 0000000..5952129 --- /dev/null +++ b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha @@ -0,0 +1,6 @@ +entry(arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + b2 := 3 < x; + b1 := arr = 2; + b1 := 6<7 & arr2=7; +} diff --git a/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha new file mode 100644 index 0000000..12db768 --- /dev/null +++ b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha @@ -0,0 +1,5 @@ +entry(arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + b2 := !(3 < 2); + b1 := !5; +} diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha new file mode 100644 index 0000000..5b13147 --- /dev/null +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -0,0 +1,9 @@ +entry(arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a] + x := 3 + 2 * 8; + x := 3 - 2 / 8; + x := a * 2 % 8; + b2 := 3 * 2 % 8; + x := 3 % 2 * 8; + x := 3 + arr - 8; +} diff --git a/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha new file mode 100644 index 0000000..31e01a7 --- /dev/null +++ b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha @@ -0,0 +1,6 @@ +entry(arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + x := -8; + x := -b1; + b2 := -x; +} From c4ad1547bf6ff6a208f11e6a77c674fb4f6413fc Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 04:00:30 -0400 Subject: [PATCH 022/137] fixed most symbol table structure issues. Working on print symbol table --- Makefile | 2 +- src/symbol_table.c | 32 ++++++++++++++++++++++---------- test-s1 | 0 test-s2 | 0 4 files changed, 23 insertions(+), 11 deletions(-) delete mode 100644 test-s1 delete mode 100644 test-s2 diff --git a/Makefile b/Makefile index 8649a5c..815aec5 100644 --- a/Makefile +++ b/Makefile @@ -55,4 +55,4 @@ clean: rm -f *.st rm -rf out rm -rf tmp - rm -f parser \ No newline at end of file + rm -f parser diff --git a/src/symbol_table.c b/src/symbol_table.c index 208eb69..ba57818 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -479,7 +479,17 @@ char *getType(TableNode *tn) { return ""; } return tn->theType->theName; } -char *getName(TableNode *tn) { return tn->theName; } +char *getName(TableNode *tn) { + if(tn == NULL){ + printf("passed a NULL table entry to getName\n"); + return ""; + } + if(tn->theType == NULL){ + printf("name of entry is currently NULL, undefined \n"); + return ""; + } + return tn->theName; +} int getLine(SymbolTable *st) { return st->Line_Number; } int getColumn(SymbolTable *st) { return st->Column_Number; } TableNode* addName(TableNode *tn, char* str){ @@ -563,7 +573,6 @@ TableNode *look_up(SymbolTable *table, char *x) { void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - return; if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -586,17 +595,16 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (entrie != NULL; entrie = entrie->next;) { + for (;entrie != NULL; entrie = entrie->next) { + if (getAdInfoType(entrie) == TYPE_ARRAY){ if (parant_scope == 0) { - /*have to update*/ if (strcmp(entrie->theType->theName, - "function primitive") || - strcmp(entrie->theType->theName, - "array")) { - } + fprintf(file_ptr, - "%-17s: %06d : : %-21s: %-28s\n", + "%-17s: %06d : : %-21d -> %-21s: %-28s\n", entrie->theName, current_scope, - entrie->theType->theName, "Extra annotation"); + entrie->additionalinfo->ArrayAdInfo->numofdimensions, + entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, + "Type of Array"); } else { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName, current_scope, parant_scope, @@ -617,6 +625,10 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } //get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { + if(table == NULL){ + printf("passing a NULL reference to getAncestor. Invalid.\n"); + return NULL; + } if (table->Parent_Scope == NULL) { // if table has no parent, return itself return table; diff --git a/test-s1 b/test-s1 deleted file mode 100644 index e69de29..0000000 diff --git a/test-s2 b/test-s2 deleted file mode 100644 index e69de29..0000000 From 3686a64948d8453370bae0199c672a97fce669e9 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 04:44:13 -0400 Subject: [PATCH 023/137] symbol_table print almost done but have to figure out seg fault --- src/symbol_table.c | 71 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index ba57818..9ba911f 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -505,6 +505,7 @@ SymbolTable* setLineNumber(SymbolTable *st,int line){ return st; } st->Line_Number = line; + return st; } SymbolTable* setColumnNumber(SymbolTable *st,int column){ @@ -513,6 +514,7 @@ SymbolTable* setColumnNumber(SymbolTable *st,int column){ return st; } st->Line_Number = column; + return st; } /* //we use false for type defs and true for functions for parameter of typeOf @@ -606,11 +608,76 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, "Type of Array"); } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", + fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", entrie->theName, current_scope, parant_scope, - entrie->theType->theName, "Extra annotation"); + entrie->additionalinfo->ArrayAdInfo->numofdimensions, + entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, + "Type of Array"); } } + if (getAdInfoType(entrie) == TYPE_RECORD){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: elements-%-28d\n", + entrie->theName, current_scope, + "record", + entrie->additionalinfo->RecAdInfo->numofelements); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", + entrie->theName, current_scope, parant_scope, + "record", + entrie->additionalinfo->RecAdInfo->numofelements); + } + } + if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: size-%-28d bytes\n", + entrie->theName, current_scope, + "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", + entrie->theName, current_scope, parant_scope, + "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : : %-21s -> %-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->FunTypeAdInfo->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo->returntype->theName, + "Type of Function"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + entrie->additionalinfo->FunTypeAdInfo->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo->returntype->theName, + "Type of Function"); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + getType(entrie), + "Function"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + getType(entrie), + "Function"); + } + } +} if (table->Children_Scope != NULL) { ListOfTable *node = table->Children_Scope; for (; node != NULL; node = node->next) { From fd39afc9e0db6327c9b461265c89fa97a4e15579 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 27 Mar 2025 15:28:30 -0400 Subject: [PATCH 024/137] Added the files to the repo #t51 --- src/intermediate_code.c | 0 src/intermediate_code.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/intermediate_code.c create mode 100644 src/intermediate_code.h diff --git a/src/intermediate_code.c b/src/intermediate_code.c new file mode 100644 index 0000000..e69de29 diff --git a/src/intermediate_code.h b/src/intermediate_code.h new file mode 100644 index 0000000..e69de29 From 03be62dc1946e5951256fd99b14af6bc50fba783 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 27 Mar 2025 16:08:31 -0400 Subject: [PATCH 025/137] Added structs enums and stubs #t51 --- src/intermediate_code.c | 13 +++++++++++++ src/intermediate_code.h | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index e69de29..f32b966 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -0,0 +1,13 @@ + + void emit_binary_op(char* result, char* op, char* arg1, char* arg2){ + return; + } + void emit_unary_op(char* result, char* op, char* arg){ + return; + } + void emit_assignment(char* target, char* source){ + return; + } +void emit_as_file(FILE * out_file, Instruction * instr_arr){ + return; +} diff --git a/src/intermediate_code.h b/src/intermediate_code.h index e69de29..c2aa796 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -0,0 +1,37 @@ +// Track 1: Core Infrastructure & Basic Expressions +// * Create intermediate_code.h/.c defining the instruction structure: +// - Struct with fields for: opcode, result, operand1, operand2, label +// - Enum for all operation types (ADD, SUB, MUL, DIV, etc.) +// * Implement temp variable generator function that produces unique names (t1, t2, etc.) +// * Create specific code emission functions: +// - emit_binary_op(char* result, char* op, char* arg1, char* arg2) +// - emit_unary_op(char* result, char* op, char* arg) +// - emit_assignment(char* target, char* source) +// * Add Bison actions for arithmetic expressions: +// - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); +// - Subtraction, multiplication, division, modulo +#include "symbol_table.h" + +typedef enum {ADD, SUB, MUL, DIV} Op; // TODO: add all the instructions +typedef struct { + Op opcode; + TableNode * result; + TableNode * operand1; + TableNode * operand2; + int label; +} Instruction; + +void emit_binary_op(char* result, char* op, char* arg1, char* arg2); +void emit_unary_op(char* result, char* op, char* arg); +void emit_assignment(char* target, char* source); +// TODO: Find out what these are suposed to do. Guess is create an entry in +// the list of instructions + + +// * Implement integer/boolean/character specific operation handling +// TODO: Find out what this means + +// * Create output function to write instructions to file with line formatting +void emit_as_file(FILE * out_file, Instruction * instr_arr); + +// * Implement instruction array storage for backpatching From 666e0a4159249676b4490e378e481c15f873b007 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 27 Mar 2025 17:28:16 -0400 Subject: [PATCH 026/137] No change #t51 --- src/intermediate_code.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/intermediate_code.h b/src/intermediate_code.h index c2aa796..446f4c4 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -25,11 +25,11 @@ void emit_binary_op(char* result, char* op, char* arg1, char* arg2); void emit_unary_op(char* result, char* op, char* arg); void emit_assignment(char* target, char* source); // TODO: Find out what these are suposed to do. Guess is create an entry in -// the list of instructions +// the list of instructions. Guess is that its suposed to ret a struct ptr // * Implement integer/boolean/character specific operation handling -// TODO: Find out what this means +// TODO: Find out what this means. // * Create output function to write instructions to file with line formatting void emit_as_file(FILE * out_file, Instruction * instr_arr); From 8f1c7590bd4fd64c9b781523a040e1664bff9769 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 19:23:05 -0400 Subject: [PATCH 027/137] added get number of entries function --- src/grammar.y | 84 +++++++++++++++++++++++++++++++++++++++++++--- src/symbol_table.c | 25 +++++++++++++- 2 files changed, 104 insertions(+), 5 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 758b35d..2a02f11 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -157,8 +157,66 @@ declaration_list: ; declaration: - id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } - ; + id_or_types COLON ID { + TableNode* type = table_lookup(getAncestor(cur), $1); + AdInfo* info = NULL; + + // Check for NULL type + if (type == NULL) { + printf("Error: Type '%s' not found\n", $1); + } else { + // Create appropriate AdInfo based on the type + if (type == integ) { + // Integer type + info = CreatePrimitiveInfo(4); // 4 bytes for integer + } + else if (type == addr) { + // Address type + info = CreatePrimitiveInfo(8); // 8 bytes for address + } + else if (type == chara) { + // Character type + info = CreatePrimitiveInfo(1); // 1 byte for character + } + else if (type == boo) { + // Boolean type + info = CreatePrimitiveInfo(1); // 1 byte for boolean + } + else if (type == stri) { + // String type (array of characters) + info = CreateArrayInfo(1, chara); // 1-dimensional array of characters + } + else if (type == arrayprim) { + // Array type + // Need to determine dimensions and element type from context + // This is a placeholder - you'll need to adjust based on your grammar + info = CreateArrayInfo(1, NULL); // Default to 1D array of unknown type + } + else if (type == recprime) { + // Record type + // Need to determine elements from context + // This is a placeholder - you'll need to adjust based on your grammar + info = CreateRecordInfo(0, NULL); // Default to empty record + } + else if (type == funprime) { + // Function declaration + info = CreateFunctionDeclarationInfo(0, false); // Start at line 0, regular function + } + else if (type == funtypeprime) { + // Function type + // Need parameter and return types from context + // This is a placeholder - you'll need to adjust based on your grammar + info = CreateFunctionTypeInfo(NULL, NULL); // Default to no parameter/return type + } + // Add additional type cases as needed + } + + // Create the entry with the appropriate AdInfo + CreateEntry(cur, type, $3, info); + } +; +// id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } +// ; id_or_types: ID {printf("string of id in id_or_type is %s\n",$1);} {$$ = $1;} @@ -200,17 +258,35 @@ expression: | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} | expression ADD expression {printf("add expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression SUB_OR_NEG expression {printf("subtract expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression MUL expression {printf("multiply expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression DIV expression {printf("division expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression REM expression {printf("remainder expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression AND expression {printf("and expression\n");} + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression OR expression {printf("or expression\n");} +{printf("less than expression\n");if(strcmp($1,$3)==0 && + strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} - | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean");}else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + | expression LESS_THAN expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && + strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression EQUAL_TO expression {printf("equals check expression\n"); if(strcmp($1,$3)==0){$$=strdup("Boolean");}else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| diff --git a/src/symbol_table.c b/src/symbol_table.c index 9ba911f..b453c6b 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -103,6 +103,14 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { + if (definition == NULL){ + printf("passed an NULL entry to getPrimSize function. Invalid.\n"); + return -1; + } + if (definition->additionalinfo == NULL){ + printf("node has NULL additionalinfo. Invalid.\n"); + return -1; + } if (strcmp(getType(definition), "primitive") != 0) { printf("not checking the size of a primitive -- invalid op\n"); return 0; @@ -133,6 +141,11 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { } // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { + if (definition == NULL){ + printf("passed an NULL entry to getNumArrDim function. Invalid.\n"); + return -1; + } + if( if (strcmp(getType(definition), "array") != 0) { printf("not checking the dim of an array -- invalid op\n"); return 0; @@ -181,6 +194,16 @@ SymbolTable *getRecList(TableNode *definition) { return definition->additionalinfo->RecAdInfo->recordScope; } +int getRecSize(SymbolTable* tn){ + int s = 0; + TableNode* cur = getFirstEntry(tn); + while(getNextEntry(cur) != NULL){ + s++; + cur = getNextEntry(cur); + } + return s; + } + // below function takes a bool to see if parameter should be decomposed or not // note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of @@ -484,7 +507,7 @@ char *getName(TableNode *tn) { printf("passed a NULL table entry to getName\n"); return ""; } - if(tn->theType == NULL){ + if(tn->theName == NULL){ printf("name of entry is currently NULL, undefined \n"); return ""; } From c93534e9d486fdc2423999b1459e08a814ea2e2d Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 20:10:14 -0400 Subject: [PATCH 028/137] added setRecSize --- src/symbol_table.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/symbol_table.c b/src/symbol_table.c index b453c6b..2457042 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -194,6 +194,15 @@ SymbolTable *getRecList(TableNode *definition) { return definition->additionalinfo->RecAdInfo->recordScope; } +TableNode* setRecSize(TableNode* tn, int n){ + if(tn == NULL){ + printf("passed in NULL entry for setRecSize. Invalid\n"); + return NULL; + } + tn->AdInfo->RecAdInfo->numofelements = n; + return tn; + } + int getRecSize(SymbolTable* tn){ int s = 0; TableNode* cur = getFirstEntry(tn); From d7f6272d371daae47055f277f113cdeb92c6d0b4 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Thu, 27 Mar 2025 23:37:04 -0400 Subject: [PATCH 029/137] still editing grammar --- src/grammar.y | 88 +++++++++------------------------------- src/lexicalStructure.lex | 2 +- src/symbol_table.c | 2 +- 3 files changed, 22 insertions(+), 70 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 2a02f11..05fee0c 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -46,7 +46,7 @@ %token T_BOOLEAN 203 %token T_CHARACTER 204 %token T_STRING 205 -%token C_INTEGER 301 +%token C_INTEGER 301 %token C_NULL 302 %token C_CHARACTER 303 %token C_STRING 304 @@ -120,7 +120,7 @@ prototype: definition: TYPE ID COLON dblock - | TYPE ID COLON constant ARROW ID + | TYPE ID COLON C_INTEGER ARROW ID | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); @@ -160,63 +160,8 @@ declaration: id_or_types COLON ID { TableNode* type = table_lookup(getAncestor(cur), $1); AdInfo* info = NULL; - - // Check for NULL type - if (type == NULL) { - printf("Error: Type '%s' not found\n", $1); - } else { - // Create appropriate AdInfo based on the type - if (type == integ) { - // Integer type - info = CreatePrimitiveInfo(4); // 4 bytes for integer - } - else if (type == addr) { - // Address type - info = CreatePrimitiveInfo(8); // 8 bytes for address - } - else if (type == chara) { - // Character type - info = CreatePrimitiveInfo(1); // 1 byte for character - } - else if (type == boo) { - // Boolean type - info = CreatePrimitiveInfo(1); // 1 byte for boolean - } - else if (type == stri) { - // String type (array of characters) - info = CreateArrayInfo(1, chara); // 1-dimensional array of characters - } - else if (type == arrayprim) { - // Array type - // Need to determine dimensions and element type from context - // This is a placeholder - you'll need to adjust based on your grammar - info = CreateArrayInfo(1, NULL); // Default to 1D array of unknown type - } - else if (type == recprime) { - // Record type - // Need to determine elements from context - // This is a placeholder - you'll need to adjust based on your grammar - info = CreateRecordInfo(0, NULL); // Default to empty record - } - else if (type == funprime) { - // Function declaration - info = CreateFunctionDeclarationInfo(0, false); // Start at line 0, regular function - } - else if (type == funtypeprime) { - // Function type - // Need parameter and return types from context - // This is a placeholder - you'll need to adjust based on your grammar - info = CreateFunctionTypeInfo(NULL, NULL); // Default to no parameter/return type - } - // Add additional type cases as needed - } - - // Create the entry with the appropriate AdInfo - CreateEntry(cur, type, $3, info); - } -; -// id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } -// ; + id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + ; id_or_types: ID {printf("string of id in id_or_type is %s\n",$1);} {$$ = $1;} @@ -258,27 +203,34 @@ expression: | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} | expression ADD expression {printf("add expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression SUB_OR_NEG expression {printf("subtract expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("Boolean");$$=strdup("undefined");}} | expression MUL expression {printf("multiply expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression DIV expression {printf("division expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression REM expression {printf("remainder expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression AND expression {printf("and expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression OR expression {printf("or expression\n");} -{printf("less than expression\n");if(strcmp($1,$3)==0 && + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} @@ -316,7 +268,7 @@ memOp: constant: C_STRING {$$ = $1;} - | C_INTEGER {$$ = $1;} + | C_INTEGER {$$ = "integer";} | C_NULL {$$ = $1;} | C_CHARACTER {$$ = $1;} | C_TRUE {$$ = $1;} diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 24eaa78..2fab3b4 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -72,7 +72,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "," {if(DEBUG) {printf( "COMMA: %s (%d)\n", yytext, COMMA);} else {if(tok_flag != NULL){print_tok(COMMA);}incr(line_number,column_number,COMMA);return COMMA;}} "->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {if(tok_flag != NULL){print_tok(ARROW);}incr(line_number,column_number,ARROW);return ARROW;}} -{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.words = strdup("integer");return C_INTEGER;}} +{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytex)/*words = strdup("integer")*/;return C_INTEGER;}} '{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.words = strdup("character");return C_CHARACTER;}} \"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.words = strdup("string");return C_STRING;}} {COMMENT} {if(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}} diff --git a/src/symbol_table.c b/src/symbol_table.c index 2457042..8b0b99c 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -199,7 +199,7 @@ TableNode* setRecSize(TableNode* tn, int n){ printf("passed in NULL entry for setRecSize. Invalid\n"); return NULL; } - tn->AdInfo->RecAdInfo->numofelements = n; + tn->additionalinfo->RecAdInfo->numofelements = n; return tn; } From 38a1d0b0911ffa99809191616e99a94bac783a23 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 02:02:44 -0400 Subject: [PATCH 030/137] added more helper functions --- src/grammar.y | 45 ++++++++++++++++++++-------------------- src/lexicalStructure.lex | 2 +- src/symbol_table.c | 20 +++++++++++++++++- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 05fee0c..faaabae 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -145,7 +145,8 @@ idlist: sblock: L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE - | L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE + | L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} + dblock {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE ; dblock: @@ -157,10 +158,7 @@ declaration_list: ; declaration: - id_or_types COLON ID { - TableNode* type = table_lookup(getAncestor(cur), $1); - AdInfo* info = NULL; - id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL);} ; id_or_types: @@ -202,46 +200,49 @@ expression: $$=strdup("undefined");}else{$$=$2;}} | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} - | expression ADD expression {printf("add expression\n");} - {printf("less than expression\n"); - if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression ADD expression + {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression SUB_OR_NEG expression {printf("subtract expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean"); + + | expression SUB_OR_NEG expression + {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression MUL expression {printf("multiply expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression MUL expression + {printf("multiply expression\n"); + printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression DIV expression {printf("division expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression DIV expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression REM expression {printf("remainder expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression REM expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression AND expression {printf("and expression\n");} - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean"); + | expression AND expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} - | expression OR expression {printf("or expression\n");} + | expression OR expression {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean"); + strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean"); + strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("Boolean");$$=strdup("undefined");}} + | expression EQUAL_TO expression {printf("equals check expression\n"); - if(strcmp($1,$3)==0){$$=strdup("Boolean");}else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| + if(strcmp($1,$3)==0){$$=strdup("Boolean");} + else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column);$$=strdup("undefined");}} | assignable {printf("assignable expression\n");$$=$1;} diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 2fab3b4..b43c979 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -72,7 +72,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "," {if(DEBUG) {printf( "COMMA: %s (%d)\n", yytext, COMMA);} else {if(tok_flag != NULL){print_tok(COMMA);}incr(line_number,column_number,COMMA);return COMMA;}} "->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {if(tok_flag != NULL){print_tok(ARROW);}incr(line_number,column_number,ARROW);return ARROW;}} -{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytex)/*words = strdup("integer")*/;return C_INTEGER;}} +{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytext)/*words = strdup("integer")*/;return C_INTEGER;}} '{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.words = strdup("character");return C_CHARACTER;}} \"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.words = strdup("string");return C_STRING;}} {COMMENT} {if(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}} diff --git a/src/symbol_table.c b/src/symbol_table.c index 8b0b99c..59a27c9 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -145,7 +145,6 @@ int getNumArrDim(TableNode *definition) { printf("passed an NULL entry to getNumArrDim function. Invalid.\n"); return -1; } - if( if (strcmp(getType(definition), "array") != 0) { printf("not checking the dim of an array -- invalid op\n"); return 0; @@ -236,6 +235,15 @@ int getStartLine(TableNode *definition) { } return definition->additionalinfo->FunDecAdInfo->startlinenumber; } + +TableNode* setStartLine(TableNode* tn, int start){ + if(tn == NULL){ + printf("passing in a NULL entry to setStartLine. invalid\n"); + return NULL; + } + tn->additionalinfo->FunDecAdInfo->startlinenumber = start; + return tn; + } // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { @@ -246,6 +254,16 @@ bool getAsKeyword(TableNode *definition) { } return definition->additionalinfo->FunDecAdInfo->regularoras; } + +TableNode* setAsKeyword(TableNode* tn, bool as){ + if(tn == NULL){ + printf("passing in a NULL entry to setAsKeyword. invalid\n"); + return NULL; + } + tn->additionalinfo->FunDecAdInfo->regularoras = as; + return tn; + } + // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); From 2654308396f4066d36c7f3954d65ac7ebd7709b1 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 02:14:50 -0400 Subject: [PATCH 031/137] fixed expression rules --- src/grammar.y | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index faaabae..6b2b70b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -195,58 +195,67 @@ rec_op : expression: constant {printf("constant expression\n");} {$$ = $1;} + | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); $$=strdup("undefined");}else{$$=$2;}} + | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} + | expression ADD expression - {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression SUB_OR_NEG expression - {printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} + | expression MUL expression {printf("multiply expression\n"); - printf("less than expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("Boolean");} + if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} + | expression DIV expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} + | expression REM expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression AND expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression OR expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean");} + {printf("OR\n");if(strcmp($1,$3)==0 && + strcmp($1,"Boolean")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("Boolean");$$=strdup("undefined");}} + $$=strdup("undefined");}} | expression EQUAL_TO expression {printf("equals check expression\n"); if(strcmp($1,$3)==0){$$=strdup("Boolean");} else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column);$$=strdup("undefined");}} + | assignable {printf("assignable expression\n");$$=$1;} + | L_PAREN expression R_PAREN {printf("paren expression\n");$$=$2;} + | memOp assignable {$$ = strdup("address");} ; From 24caa0e9a7217ad7272ef1828e9e4176dae1c63c Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Fri, 28 Mar 2025 10:18:18 -0400 Subject: [PATCH 032/137] Updeated the contents of st to Dev #t51 --- src/symbol_table.c | 89 ++++++++++++++++++++++++++++++++++++++-------- src/symbol_table.h | 4 +-- 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 205bcbe..4ce220b 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -27,23 +27,23 @@ typedef enum { // TYPE_BOOLEAN, // TYPE_ADDRESS, // Type String is an array of char enclosed in double quotes per lexer - TYPE_STRING, + TYPE_STRING = 1, // Array can be multidimensional. Information should be stored here - TYPE_ARRAY, + TYPE_ARRAY = 2, // Record is user defined types - TYPE_RECORD, + TYPE_RECORD = 3, // Declaring what type a particular function is without as - TYPE_FUNCTION_DECLARATION, + TYPE_FUNCTION_DECLARATION = 4, // Declaring what type a particular function is with as // TYPE_AS_FUNCTION_DECLARATION, // Declaring what type a function is (what the parameters and output // are) - TYPE_FUNCTION_TYPE, + TYPE_FUNCTION_TYPE = 5, // The Type being pointed to by the first 4 above that only stores the // size - TYPE_PRIMITIVE, + TYPE_PRIMITIVE = 6, //likely NULL - TYPE_ALL_ELSE + TYPE_ALL_ELSE = 7 } types; @@ -153,12 +153,12 @@ TableNode *getArrType(TableNode *definition) { // order, of what make up that type in an array. Unfortunately this second part // should probably instead be replaced by a reference to a scope in which those // elements are found. -AdInfo *CreateRecordInfo(int length, TableNode *typesarray) { +AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); info->RecAdInfo = (record_info *)malloc(sizeof(record_info)); info->RecAdInfo->numofelements = length; // replace below with reference to a scope, not an array - info->RecAdInfo->listoftypes = typesarray; + info->RecAdInfo->recordScope = recordScope; return info; } // This gets the number of elements that make up a record. @@ -172,13 +172,13 @@ int getRecLength(TableNode *definition) { return definition->additionalinfo->RecAdInfo->numofelements; } // This gets the array. Needs to up be updated to get the scope instead -TableNode *getRecList(TableNode *definition) { +SymbolTable *getRecList(TableNode *definition) { if (strcmp(getType(definition), "record") != 0) { printf("not checking the list of types of a record -- invalid " "op\n"); return NULL; } - return definition->additionalinfo->RecAdInfo->listoftypes; + return definition->additionalinfo->RecAdInfo->recordScope; } // below function takes a bool to see if parameter should be decomposed or not @@ -379,8 +379,34 @@ TableNode* boo; TableNode* recprime; TableNode* funtypeprime; */ +TableNode* populateTypeAndInfo(TableNode* tn, TableNode* type, AdInfo* info){ + if(tn == NULL){ + printf("passed in an invalid table node to modify (NULL).\n"); + return NULL; + } + if(type == NULL){ + printf("passed in a NULL type reference to populate a table node. Invalid.\n"); + return NULL; + } + if(info == NULL){ + printf("passed in a NULL info reference to populate a table node. Invalid.\n"); + return NULL; + } + tn->theType = type; + tn->additionalinfo = info; + //returning reference to modified table node + return tn; + } int getAdInfoType(TableNode* tn){ + if(tn == NULL){ + printf("passing in NULL table entry. Invalid\n"); + return -1; + } + if(tn->theType == NULL){ + printf("Entry being passed in has a null reference for theType. Invalid.\n"); + return -1; + } if(strcmp(getType(tn),getName(integ))==0){ return TYPE_PRIMITIVE; } @@ -443,11 +469,41 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } } -char *getType(TableNode *tn) { return tn->theType->theName; } +char *getType(TableNode *tn) { + if(tn == NULL){ + printf("passed a NULL table entry to getType\n"); + return ""; + } + if(tn->theType == NULL){ + printf("type of entry is currently NULL, undefined type \n"); + return ""; + } + return tn->theType->theName; } char *getName(TableNode *tn) { return tn->theName; } int getLine(SymbolTable *st) { return st->Line_Number; } int getColumn(SymbolTable *st) { return st->Column_Number; } +TableNode* addName(TableNode *tn, char* str){ + if(tn == NULL){ + printf("passed a Null table node to the addName function. Invalid./n"); + return tn; + } +} +SymbolTable* setLineNumber(SymbolTable *st,int line){ + if(st == NULL){ + printf("passed a Null Symbol Table to the setLineNumber function. Invalid./n"); + return st; + } + st->Line_Number = line; + } + +SymbolTable* setColumnNumber(SymbolTable *st,int column){ + if(st == NULL){ + printf("passed a Null Symbol Table to the setColumnNumber function. Invalid./n"); + return st; + } + st->Line_Number = column; + } /* //we use false for type defs and true for functions for parameter of typeOf TableNode* Define(SymbolTable* table, bool typeOf, char* id) { @@ -483,6 +539,7 @@ names\n"); return NULL; } */ +//only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { TableNode *entrie = table->entries; for (; entrie != NULL; entrie = entrie->next) { @@ -492,6 +549,7 @@ TableNode *table_lookup(SymbolTable *table, char *x) { } return NULL; } +//check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { return NULL; @@ -504,6 +562,8 @@ TableNode *look_up(SymbolTable *table, char *x) { } void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + + return; if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -526,7 +586,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (; entrie != NULL; entrie = entrie->next) { + for (entrie != NULL; entrie = entrie->next;) { if (parant_scope == 0) { /*have to update*/ if (strcmp(entrie->theType->theName, "function primitive") || @@ -555,7 +615,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "----------------------\n"); } } - +//get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { if (table->Parent_Scope == NULL) { // if table has no parent, return itself @@ -594,6 +654,7 @@ SymbolTable *removeEntry(SymbolTable *scope, char *search) { return scope; } +//almost certainly don't need to use the below function since type checking happens by passing types up the grammar bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); diff --git a/src/symbol_table.h b/src/symbol_table.h index 84b3e5a..de37098 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -30,7 +30,7 @@ typedef struct { // similar to above we define a record to hold the number of elements // and an array of tablenodes (types) that it contains in the > int numofelements; - struct TableNode *listoftypes; + struct SymbolTable *recordScope; } record_info; typedef struct { @@ -91,7 +91,7 @@ int getPrimSize(TableNode *definition); int getNumArrDim(TableNode *definition); TableNode *getArrType(TableNode *definition); int getRecLength(TableNode *definition); -TableNode *getRecList(TableNode *definition); +SymbolTable *getRecList(TableNode *definition); int getStartLine(TableNode *definition); bool getAsKeyword(TableNode *definition); TableNode *getParameter(TableNode *definition); From 36694a2f4ae815e0bb2827fd198aab4272b79a4c Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 13:47:53 -0400 Subject: [PATCH 033/137] updated lookups to return undefined entry if invalid --- src/grammar.y | 34 +++++++++++++-------- src/symbol_table.c | 34 ++++++++++++++------- tests/sprint2/test/test_carls_mistake.alpha | 4 +-- 3 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 6b2b70b..7ff44da 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -201,60 +201,70 @@ expression: $$=strdup("undefined");}else{$$=$2;}} | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); - printf("mismatch at line %d and column %d\n",@1.first_line,@1.first_column);}} + printf("mismatch at line %d and column %d. Invalid type being negated is %s\n", + @1.first_line,@1.first_column,$2);}} | expression ADD expression {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression SUB_OR_NEG expression {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression MUL expression {printf("multiply expression\n"); if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression DIV expression {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression REM expression {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression AND expression {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression OR expression {printf("OR\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression LESS_THAN expression {printf("less than expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column); + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression EQUAL_TO expression {printf("equals check expression\n"); if(strcmp($1,$3)==0){$$=strdup("Boolean");} else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d\n",@2.first_line,@2.first_column);$$=strdup("undefined");}} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s\n", + @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} - | assignable {printf("assignable expression\n");$$=$1;} + | assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;} - | L_PAREN expression R_PAREN {printf("paren expression\n");$$=$2;} + | L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;} | memOp assignable {$$ = strdup("address");} ; diff --git a/src/symbol_table.c b/src/symbol_table.c index 59a27c9..dabcafa 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -18,6 +18,7 @@ TableNode *stri; TableNode *boo; TableNode *recprime; TableNode *funtypeprime; +TableNode *undefined; typedef enum { // First 4 below are primitive types that are all encapsulated in @@ -228,7 +229,7 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // gets the line at which the function was first defined. (Can be used to print // out in table if needed) int getStartLine(TableNode *definition) { - if (strcmp(getType(definition), "function primitive") != 0) { + if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking the start line of a function -- invalid " "op\n"); return 0; @@ -247,7 +248,7 @@ TableNode* setStartLine(TableNode* tn, int start){ // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { - if (strcmp(getType(definition), "function primitive") != 0) { + if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking if a function is called with as or not -- " "invalid op\n"); return NULL; @@ -275,7 +276,7 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { } // returns parameter type of a function TableNode *getParameter(TableNode *definition) { - if (strcmp(getType(definition), "function type primitive") != 0) { + if (strcmp(getType(definition), "primitive function type") != 0) { printf( "not checking the parameter of a function -- invalid op\n"); return NULL; @@ -284,7 +285,7 @@ TableNode *getParameter(TableNode *definition) { } // returns return type of a function TableNode *getReturn(TableNode *definition) { - if (strcmp(getType(definition), "function type primitive") != 0) { + if (strcmp(getType(definition), "primitive function type") != 0) { printf("not checking the return of a function -- invalid op\n"); return NULL; } @@ -394,6 +395,12 @@ SymbolTable *init(SymbolTable *start) { funtypeprime->additionalinfo = NULL; funtypeprime->next = NULL; + undefined = (TableNode *)malloc(sizeof(TableNode)); + undefined->theName = "undefined"; + undefined->theType = NULL; + undefined->additionalinfo = NULL; + undefined->next = NULL; + integ->theType = prime; addr->theType = prime; chara->theType = prime; @@ -522,24 +529,26 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, char *getType(TableNode *tn) { if(tn == NULL){ printf("passed a NULL table entry to getType\n"); - return ""; + return getName(undefined); } if(tn->theType == NULL){ printf("type of entry is currently NULL, undefined type \n"); - return ""; + return getName(undefined); } return tn->theType->theName; } + char *getName(TableNode *tn) { if(tn == NULL){ printf("passed a NULL table entry to getName\n"); - return ""; + return undefined->theName; } if(tn->theName == NULL){ printf("name of entry is currently NULL, undefined \n"); - return ""; + return undefined->theName; } return tn->theName; } + int getLine(SymbolTable *st) { return st->Line_Number; } int getColumn(SymbolTable *st) { return st->Column_Number; } TableNode* addName(TableNode *tn, char* str){ @@ -609,17 +618,20 @@ TableNode *table_lookup(SymbolTable *table, char *x) { return entrie; } } - return NULL; + return undefined; } //check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { - return NULL; + printf("passed in empty scope. error.\n"); + return undefined; } TableNode *ret = table_lookup(table, x); - if (ret != NULL) { + if (ret != NULL && ret != undefined) { return ret; } + printf("could not find %s in scope that started at line %d and column %d so moving up a scope\n" + ,x,getLine(table),getColumn(table)); return look_up(table->Parent_Scope, x); } diff --git a/tests/sprint2/test/test_carls_mistake.alpha b/tests/sprint2/test/test_carls_mistake.alpha index fb75ca3..f2b3703 100644 --- a/tests/sprint2/test/test_carls_mistake.alpha +++ b/tests/sprint2/test/test_carls_mistake.alpha @@ -18,10 +18,10 @@ bar2 as (r,s) := { entry(arg) := { [ integer: result ; rec: w] result := foo(5); - w := reserve(w); (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*) + w := reserve w; (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*) w.x := 5; w.y := 7; result := bar1(w); (* pass w (a rec type value) to bar1 *) result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) return 0; -} \ No newline at end of file +} From d0a00c86841469434bc9cf302d4a687403223cac Mon Sep 17 00:00:00 2001 From: Moroseui <157774170+Moroseui@users.noreply.github.com> Date: Fri, 28 Mar 2025 13:58:45 -0400 Subject: [PATCH 034/137] Update grammar.y with Annie's changes --- src/grammar.y | 131 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 20 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 7ff44da..c9da70b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -119,18 +119,58 @@ prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; definition: - TYPE ID COLON dblock - | TYPE ID COLON C_INTEGER ARROW ID +definition: +TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); + if (table_lookup(getAncestor(cur), $2) == NULL) { + printf("rec not found \n"); + } + }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); + cur = getParent(cur);} + | TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); - } - | ID parameter ASSIGN sblock + } + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + } L_PAREN ID { + CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + }R_PAREN ASSIGN sblock + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL) { + printf("null check\n"); + } + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + }AS L_PAREN { + TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) { + printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ + CreateEntry(cur, entry, NULL, NULL); + } + } + } idlist R_PAREN ASSIGN sblock ; + function_declaration: - FUNCTION ID COLON ID - | EXTERNAL FUNCTION ID COLON ID +FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} + | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} ; parameter: @@ -139,14 +179,34 @@ parameter: ; idlist: - ID COMMA idlist - | ID + ID { + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) == NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $1); + } COMMA idlist + | ID { + + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) != NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $1); + } ; + sblock: - L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE - | L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} - dblock {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE +L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE + | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock + {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE ; dblock: @@ -158,8 +218,8 @@ declaration_list: ; declaration: - id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL);} - ; + id_or_types COLON ID {printf("ID/TYPE: %s, ID: %s\n", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + ; id_or_types: ID {printf("string of id in id_or_type is %s\n",$1);} {$$ = $1;} @@ -180,14 +240,45 @@ compound_statement: ; simple_statement: - assignable ASSIGN expression + assignable ASSIGN expression {if(strcmp($1, $3) == 0){ + } else { + printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column); + }} + | RETURN expression ; assignable: - ID - | assignable ablock - | assignable rec_op ID +ID {TableNode *node = table_lookup(cur, $1); + printf("%s\n", $1); + if (node == NULL) { + printf("could not find %s in current scope\n", $1); + node = table_lookup(getAncestor(cur), $1); + if (node != NULL && getAdInfoType(node) == TYPE_FUNCTION_DECLARATION) { + if (getAsKeyword(node)) { + node = table_lookup(getAncestor(cur), getType(node)); + $$ = getRecLength(getParameter(node)); + } else { + $$ = 1; + } + } + else { + printf("assignable not defined as correct type at line %d, column %d\n", @1.first_line, @1.first_column); + } + } else if (getAdInfoType(node) == TYPE_ARRAY) { + $$ = getNumArrDim(node); + } else { + $$ = getName(node); + } +} +| assignable ablock {if ($1 != $2) { + printf("invalid number of expressions in ablock at line %d, column %d\n", @1.first_line, @1.first_column); + } + $$ = getName(getReturn(look_up(cur, $1))); +} +| assignable rec_op ID {TableNode * tn; printf("this is assignable.id %s\n", getType(look_up(cur, $1)));if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) + {$$ = "test";} +} ; rec_op : @@ -271,12 +362,12 @@ expression: ablock: - L_PAREN argument_list R_PAREN +L_PAREN argument_list {$$ = $2;} R_PAREN ; argument_list: - expression COMMA argument_list - | expression +expression COMMA argument_list {$$ = $3 + 1;} +| expression {$$ = 1;} ; From 37dedf181832c17d73a3260de89663cf1bb3b8b5 Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 14:16:49 -0400 Subject: [PATCH 035/137] fixed some grammar rules --- src/grammar.y | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index c9da70b..9e765e2 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -26,6 +26,7 @@ extern TableNode* chara; extern TableNode* stri; extern TableNode* boo; + TableNode * tn; %} //%define api.location.type {location_t} %locations @@ -118,7 +119,6 @@ prototype_or_definition_list: prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; -definition: definition: TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == NULL) { @@ -169,14 +169,10 @@ TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo function_declaration: -FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} + FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} ; -parameter: - L_PAREN ID R_PAREN - | AS L_PAREN idlist R_PAREN - ; idlist: ID { @@ -222,7 +218,7 @@ declaration: ; id_or_types: - ID {printf("string of id in id_or_type is %s\n",$1);} {$$ = $1;} + ID {printf("string of id in id_or_type is %s\n",$1); $$ = getType(look_up(cur,$1));} | types {printf("string of type in id_or_type is %s\n",$1);} {$$ = $1;} ; @@ -276,7 +272,8 @@ ID {TableNode *node = table_lookup(cur, $1); } $$ = getName(getReturn(look_up(cur, $1))); } -| assignable rec_op ID {TableNode * tn; printf("this is assignable.id %s\n", getType(look_up(cur, $1)));if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) +| assignable rec_op ID {TableNode * tn; printf("this is assignable.id %s\n", getType(look_up(cur, $1))); + if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) {$$ = "test";} } ; From cca01eb0b5a4588a02c981d21b052889d2e3f0bc Mon Sep 17 00:00:00 2001 From: Partho Bhattacharya Date: Fri, 28 Mar 2025 14:49:17 -0400 Subject: [PATCH 036/137] working on tabel --- src/grammar.y | 36 +++++------------------------------- src/symbol_table.c | 17 ++++++++++++++--- 2 files changed, 19 insertions(+), 34 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 9e765e2..b464641 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1,3 +1,4 @@ + /* Syntax Analyzer with Bison (3.8.2) */ /* The Translators - Spring 2025 */ @@ -245,37 +246,10 @@ simple_statement: ; assignable: -ID {TableNode *node = table_lookup(cur, $1); - printf("%s\n", $1); - if (node == NULL) { - printf("could not find %s in current scope\n", $1); - node = table_lookup(getAncestor(cur), $1); - if (node != NULL && getAdInfoType(node) == TYPE_FUNCTION_DECLARATION) { - if (getAsKeyword(node)) { - node = table_lookup(getAncestor(cur), getType(node)); - $$ = getRecLength(getParameter(node)); - } else { - $$ = 1; - } - } - else { - printf("assignable not defined as correct type at line %d, column %d\n", @1.first_line, @1.first_column); - } - } else if (getAdInfoType(node) == TYPE_ARRAY) { - $$ = getNumArrDim(node); - } else { - $$ = getName(node); - } -} -| assignable ablock {if ($1 != $2) { - printf("invalid number of expressions in ablock at line %d, column %d\n", @1.first_line, @1.first_column); - } - $$ = getName(getReturn(look_up(cur, $1))); -} -| assignable rec_op ID {TableNode * tn; printf("this is assignable.id %s\n", getType(look_up(cur, $1))); - if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) - {$$ = "test";} -} + ID {$$ = $1; } + | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} + | assignable rec_op ID {if(undefined != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) + {$$ = getType(tn);}} ; rec_op : diff --git a/src/symbol_table.c b/src/symbol_table.c index dabcafa..123c6a8 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -44,7 +44,8 @@ typedef enum { // size TYPE_PRIMITIVE = 6, //likely NULL - TYPE_ALL_ELSE = 7 + TYPE_ALL_ELSE = 7, + TYPE_UNDEFINED = 8 } types; @@ -214,7 +215,13 @@ int getRecSize(SymbolTable* tn){ } // below function takes a bool to see if parameter should be decomposed or not -// note that functions only take one input and have one output +assignable: + ID {$$ = $1; } + | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} + | assignable rec_op ID {TableNode * tn; if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) + {$$ = getType(tn);} + } + ;// note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of // multiple inputs Below function also has the line number where the function is // first defined @@ -488,7 +495,10 @@ int getAdInfoType(TableNode* tn){ if(strcmp(getType(tn),getName(arrayprim))==0){ return TYPE_ARRAY; } - else{ + if(strcmp(getType(tn),getName(undefined))==0){ + return TYPE_UNDEFINED; + } + else{ return TYPE_FUNCTION_DECLARATION; } } @@ -637,6 +647,7 @@ TableNode *look_up(SymbolTable *table, char *x) { void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + return; if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); From f217500b5517a92e532d01fbdc49cdad9976f521 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 28 Mar 2025 16:11:42 -0400 Subject: [PATCH 037/137] removed most seg faults --- Makefile | 9 +++- src/grammar.y | 6 +-- src/symbol_table.c | 101 +++++++++++++++++++++++---------------------- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/Makefile b/Makefile index 815aec5..729ca3d 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ CFLAGS := YACC := bison TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha) +TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha) TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha) compiler: clean runner @@ -32,13 +33,19 @@ runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o debug: CFLAGS += -DDEBUG=1 debug: clean compiler -test: test-s1 test-s2 +test: test-s1 test-s3 test-s2 test-s1: chmod +x ./check.sh $(foreach test, $(TESTS-S1), ./$(EXE) -tok $(test);) ./check.sh + +test-s3: + chmod +x ./check.sh + $(foreach test, $(TESTS-S3), ./$(EXE) -st $(test);) + ./check.sh + test-s2: chmod +x ./check.sh $(foreach test, $(TESTS-S2), ./$(EXE) -st $(test);) diff --git a/src/grammar.y b/src/grammar.y index b464641..5238aac 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -246,10 +246,10 @@ simple_statement: ; assignable: - ID {$$ = $1; } + ID {$$ = getType(look_up(cur,$1));} | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} - | assignable rec_op ID {if(undefined != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) - {$$ = getType(tn);}} + | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ + {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} ; rec_op : diff --git a/src/symbol_table.c b/src/symbol_table.c index 123c6a8..4b31b1e 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -105,7 +105,7 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { - if (definition == NULL){ + if (definition == NULL || definition == undefined){ printf("passed an NULL entry to getPrimSize function. Invalid.\n"); return -1; } @@ -143,7 +143,7 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { } // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { - if (definition == NULL){ + if (definition == NULL|| definition == undefined){ printf("passed an NULL entry to getNumArrDim function. Invalid.\n"); return -1; } @@ -158,7 +158,7 @@ int getNumArrDim(TableNode *definition) { TableNode *getArrType(TableNode *definition) { if (strcmp(getType(definition), "array") != 0) { printf("not checking the type of an array -- invalid op\n"); - return NULL; + return undefined; } return definition->additionalinfo->ArrayAdInfo->typeofarray; } @@ -196,9 +196,9 @@ SymbolTable *getRecList(TableNode *definition) { } TableNode* setRecSize(TableNode* tn, int n){ - if(tn == NULL){ + if(tn == NULL||tn==undefined){ printf("passed in NULL entry for setRecSize. Invalid\n"); - return NULL; + return undefined; } tn->additionalinfo->RecAdInfo->numofelements = n; return tn; @@ -215,12 +215,6 @@ int getRecSize(SymbolTable* tn){ } // below function takes a bool to see if parameter should be decomposed or not -assignable: - ID {$$ = $1; } - | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} - | assignable rec_op ID {TableNode * tn; if(NULL != (tn = table_lookup(getRecList(look_up(cur, $1)), $3))) - {$$ = getType(tn);} - } ;// note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of // multiple inputs Below function also has the line number where the function is @@ -245,9 +239,9 @@ int getStartLine(TableNode *definition) { } TableNode* setStartLine(TableNode* tn, int start){ - if(tn == NULL){ - printf("passing in a NULL entry to setStartLine. invalid\n"); - return NULL; + if(tn == NULL||tn==undefined){ + printf("passing in a NULL or undefined entry to setStartLine. invalid\n"); + return undefined; } tn->additionalinfo->FunDecAdInfo->startlinenumber = start; return tn; @@ -258,15 +252,15 @@ bool getAsKeyword(TableNode *definition) { if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking if a function is called with as or not -- " "invalid op\n"); - return NULL; + return 0; } return definition->additionalinfo->FunDecAdInfo->regularoras; } TableNode* setAsKeyword(TableNode* tn, bool as){ - if(tn == NULL){ - printf("passing in a NULL entry to setAsKeyword. invalid\n"); - return NULL; + if(tn == NULL||tn==undefined){ + printf("passing in a NULL or undefined entry to setAsKeyword. invalid\n"); + return undefined; } tn->additionalinfo->FunDecAdInfo->regularoras = as; return tn; @@ -286,7 +280,7 @@ TableNode *getParameter(TableNode *definition) { if (strcmp(getType(definition), "primitive function type") != 0) { printf( "not checking the parameter of a function -- invalid op\n"); - return NULL; + return undefined; } return definition->additionalinfo->FunTypeAdInfo->parameter; } @@ -294,7 +288,7 @@ TableNode *getParameter(TableNode *definition) { TableNode *getReturn(TableNode *definition) { if (strcmp(getType(definition), "primitive function type") != 0) { printf("not checking the return of a function -- invalid op\n"); - return NULL; + return undefined; } return definition->additionalinfo->FunTypeAdInfo->returntype; } @@ -444,17 +438,17 @@ TableNode* recprime; TableNode* funtypeprime; */ TableNode* populateTypeAndInfo(TableNode* tn, TableNode* type, AdInfo* info){ - if(tn == NULL){ - printf("passed in an invalid table node to modify (NULL).\n"); - return NULL; + if(tn == NULL||tn==undefined){ + printf("passed in an invalid table node to modify (NULL or undefined).\n"); + return undefined; } - if(type == NULL){ - printf("passed in a NULL type reference to populate a table node. Invalid.\n"); - return NULL; + if(type == NULL||type==undefined){ + printf("passed in a NULL or undefined type reference to populate a table node. Invalid.\n"); + return undefined; } if(info == NULL){ printf("passed in a NULL info reference to populate a table node. Invalid.\n"); - return NULL; + return undefined; } tn->theType = type; tn->additionalinfo = info; @@ -463,12 +457,12 @@ TableNode* populateTypeAndInfo(TableNode* tn, TableNode* type, AdInfo* info){ } int getAdInfoType(TableNode* tn){ - if(tn == NULL){ - printf("passing in NULL table entry. Invalid\n"); + if(tn == NULL||tn==undefined){ + printf("passing in NULL or undefined table entry. Invalid\n"); return -1; } - if(tn->theType == NULL){ - printf("Entry being passed in has a null reference for theType. Invalid.\n"); + if(tn->theType == NULL|| tn->theType == undefined){ + printf("Entry being passed in has a null or undefined reference for theType. Invalid.\n"); return -1; } if(strcmp(getType(tn),getName(integ))==0){ @@ -508,7 +502,7 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, if (table == NULL) { printf("Null reference to table"); - return NULL; + return undefined; } /* TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); @@ -517,11 +511,11 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, return NULL; } */ - if (typeOf == NULL) { - printf("This is not pointing to a proper definition\n"); - return NULL; + if (typeOf == NULL||typeOf == undefined) { + printf("This is not pointing to a proper definition (either NULL or undefined)\n"); + return undefined; } - TableNode *newEntry = (TableNode *)malloc(sizeof(TableNode)); + TableNode *newEntry = (TableNode *)calloc(1,sizeof(TableNode)); newEntry->theType = typeOf /*topDef*/; newEntry->theName = id; newEntry->additionalinfo = ad; @@ -537,23 +531,23 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } char *getType(TableNode *tn) { - if(tn == NULL){ - printf("passed a NULL table entry to getType\n"); + if(tn == NULL||tn==undefined){ + printf("passed a NULL or undefined table entry to getType\n"); return getName(undefined); } - if(tn->theType == NULL){ - printf("type of entry is currently NULL, undefined type \n"); + if(tn->theType == NULL|| tn->theType == undefined){ + printf("type of entry is currently NULL or undefined type \n"); return getName(undefined); } return tn->theType->theName; } char *getName(TableNode *tn) { - if(tn == NULL){ - printf("passed a NULL table entry to getName\n"); + if(tn == NULL||tn==undefined){ + //printf("passed a NULL or undefined table entry to getName\n"); return undefined->theName; } if(tn->theName == NULL){ - printf("name of entry is currently NULL, undefined \n"); + //printf("name of entry is currently NULL, undefined \n"); return undefined->theName; } return tn->theName; @@ -562,10 +556,20 @@ char *getName(TableNode *tn) { int getLine(SymbolTable *st) { return st->Line_Number; } int getColumn(SymbolTable *st) { return st->Column_Number; } TableNode* addName(TableNode *tn, char* str){ - if(tn == NULL){ - printf("passed a Null table node to the addName function. Invalid./n"); - return tn; + if(tn == NULL||tn==undefined){ + printf("passed a Null or undefined table node to the addName function. Invalid./n"); + return undefined; } + if(tn->theName != NULL){ + printf("Name doesn't look like it is empty before you change. Are you sure you need to update name?/n"); + return undefined; + } + if(str == NULL){ + printf("passed a NULL string to the addName function. Invalid./n"); + return undefined; + } + tn->theName = str; + return tn; } SymbolTable* setLineNumber(SymbolTable *st,int line){ @@ -647,7 +651,6 @@ TableNode *look_up(SymbolTable *table, char *x) { void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - return; if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -811,11 +814,11 @@ bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); TableNode *entry2 = look_up(cur, secondID); - if (entry1 == NULL) { + if (entry1 == NULL|| entry1 == undefined) { printf("first type not defined\n"); return false; } - if (entry2 == NULL) { + if (entry2 == NULL|| entry2 == undefined) { printf("second type not defined\n"); return false; } From 227cec0b7341f222745c6054252fe369773f60b0 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 28 Mar 2025 18:02:40 -0400 Subject: [PATCH 038/137] continuing. need fix of makefile --- Makefile | 17 ++-- src/grammar.y | 17 ++-- src/symbol_table.c | 200 ++++++++++++++++++++++++++++----------------- 3 files changed, 144 insertions(+), 90 deletions(-) diff --git a/Makefile b/Makefile index 729ca3d..c58b895 100644 --- a/Makefile +++ b/Makefile @@ -33,22 +33,21 @@ runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o debug: CFLAGS += -DDEBUG=1 debug: clean compiler -test: test-s1 test-s3 test-s2 +test: test-s1 test-s2 test-s3 test-s1: chmod +x ./check.sh - $(foreach test, $(TESTS-S1), ./$(EXE) -tok $(test);) - ./check.sh - - -test-s3: - chmod +x ./check.sh - $(foreach test, $(TESTS-S3), ./$(EXE) -st $(test);) + for test in $(TESTS-S1); do ./$(EXE) -tok $$test || echo "Test $$test failed but continuing"; done ./check.sh test-s2: chmod +x ./check.sh - $(foreach test, $(TESTS-S2), ./$(EXE) -st $(test);) + for test in $(TESTS-S2); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done + ./check.sh + +test-s3: + chmod +x ./check.sh + for test in $(TESTS-S3); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done ./check.sh clean: diff --git a/src/grammar.y b/src/grammar.y index 5238aac..fcb06b8 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -219,8 +219,11 @@ declaration: ; id_or_types: - ID {printf("string of id in id_or_type is %s\n",$1); $$ = getType(look_up(cur,$1));} - | types {printf("string of type in id_or_type is %s\n",$1);} {$$ = $1;} + ID {printf("string of id is %s in ID pattern of id_or_type rule.\n"); $$ = $1;} + //{printf("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.\n",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} + | types {printf("string of type is %s in types pattern of id_or_type rule.\n",$1);} {$$ = $1;} + //{printf("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.\n",$1);} {$$ = $1;} + ; ; statement_list: @@ -247,7 +250,7 @@ simple_statement: assignable: ID {$$ = getType(look_up(cur,$1));} - | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} + | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} //add array case here | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} ; @@ -360,10 +363,10 @@ constant: types: // Commented out T_String below // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} - T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} - | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} - | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} - | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} + T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} + | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} + | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} + | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} ; %% diff --git a/src/symbol_table.c b/src/symbol_table.c index 4b31b1e..7f8849b 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -650,7 +650,6 @@ TableNode *look_up(SymbolTable *table, char *x) { } void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -673,87 +672,23 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (;entrie != NULL; entrie = entrie->next) { - if (getAdInfoType(entrie) == TYPE_ARRAY){ + for (; entrie != NULL; entrie = entrie->next) { if (parant_scope == 0) { - + /*have to update*/ if (strcmp(entrie->theType->theName, + "function primitive") || + strcmp(entrie->theType->theName, + "array")) { + } fprintf(file_ptr, - "%-17s: %06d : : %-21d -> %-21s: %-28s\n", + "%-17s: %06d : : %-21s: %-28s\n", entrie->theName, current_scope, - entrie->additionalinfo->ArrayAdInfo->numofdimensions, - entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, - "Type of Array"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->additionalinfo->ArrayAdInfo->numofdimensions, - entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, - "Type of Array"); - } - } - if (getAdInfoType(entrie) == TYPE_RECORD){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : :%-21s: elements-%-28d\n", - entrie->theName, current_scope, - "record", - entrie->additionalinfo->RecAdInfo->numofelements); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", - entrie->theName, current_scope, parant_scope, - "record", - entrie->additionalinfo->RecAdInfo->numofelements); - } - } - if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : :%-21s: size-%-28d bytes\n", - entrie->theName, current_scope, - "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", - entrie->theName, current_scope, parant_scope, - "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : : %-21s -> %-21s: %-28s\n", - entrie->theName, current_scope, - entrie->additionalinfo->FunTypeAdInfo->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo->returntype->theName, - "Type of Function"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->additionalinfo->FunTypeAdInfo->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo->returntype->theName, - "Type of Function"); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", - entrie->theName, current_scope, - getType(entrie), - "Function"); + entrie->theType->theName, "Extra annotation"); } else { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName, current_scope, parant_scope, - getType(entrie), - "Function"); + entrie->theType->theName, "Extra annotation"); } } -} if (table->Children_Scope != NULL) { ListOfTable *node = table->Children_Scope; for (; node != NULL; node = node->next) { @@ -766,6 +701,123 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "----------------------\n"); } } +// void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + +// if (table->Parent_Scope == NULL) { +// fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", +// "SCOPE", "PARENT", "TYPE", "Extra annotation"); +// } +// TableNode *entrie = table->entries; +// fprintf(file_ptr, "-----------------:--------:--------:----------------" +// "------:---------" +// "--------------------\n"); +// int parant_scope = 0; +// int current_scope = 0; +// if (table->Parent_Scope != NULL) { +// parant_scope = table->Parent_Scope->Line_Number * 1000 + +// table->Parent_Scope->Column_Number; +// current_scope = +// table->Line_Number * 1000 + table->Column_Number; +// } else { +// current_scope = 1001; +// } +// if (entrie == NULL) { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", +// current_scope, parant_scope, "", "Empty Scope"); +// } +// for (;entrie != NULL; entrie = entrie->next) { +// if (getAdInfoType(entrie) == TYPE_ARRAY){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : : %-21d -> %-21s: %-28s\n", +// entrie->theName, current_scope, +// entrie->additionalinfo->ArrayAdInfo->numofdimensions, +// entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, +// "Type of Array"); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", +// entrie->theName, current_scope, parant_scope, +// entrie->additionalinfo->ArrayAdInfo->numofdimensions, +// entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, +// "Type of Array"); +// } +// } +// if (getAdInfoType(entrie) == TYPE_RECORD){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : :%-21s: elements-%-28d\n", +// entrie->theName, current_scope, +// "record", +// entrie->additionalinfo->RecAdInfo->numofelements); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", +// entrie->theName, current_scope, parant_scope, +// "record", +// entrie->additionalinfo->RecAdInfo->numofelements); +// } +// } +// if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : :%-21s: size-%-28d bytes\n", +// entrie->theName, current_scope, +// "Primitive", +// entrie->additionalinfo->PrimAdInfo->size); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", +// entrie->theName, current_scope, parant_scope, +// "Primitive", +// entrie->additionalinfo->PrimAdInfo->size); +// } +// } +// if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : : %-21s -> %-21s: %-28s\n", +// entrie->theName, current_scope, +// entrie->additionalinfo->FunTypeAdInfo->parameter->theName, +// entrie->additionalinfo->FunTypeAdInfo->returntype->theName, +// "Type of Function"); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", +// entrie->theName, current_scope, parant_scope, +// entrie->additionalinfo->FunTypeAdInfo->parameter->theName, +// entrie->additionalinfo->FunTypeAdInfo->returntype->theName, +// "Type of Function"); +// } +// } +// if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ +// if (parant_scope == 0) { + +// fprintf(file_ptr, +// "%-17s: %06d : :%-21s: %-28s\n", +// entrie->theName, current_scope, +// getType(entrie), +// "Function"); +// } else { +// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", +// entrie->theName, current_scope, parant_scope, +// getType(entrie), +// "Function"); +// } +// } +// } +// if (table->Children_Scope != NULL) { +// ListOfTable *node = table->Children_Scope; +// for (; node != NULL; node = node->next) { +// print_symbol_table(node->table, file_ptr); +// } +// } +// if (table->Parent_Scope == NULL) { +// fprintf(file_ptr, "-----------------:--------:--------:--------" +// "--------------:-------" +// "----------------------\n"); +// } +// } //get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { if(table == NULL){ From 982a8a045424cd402ff78aff152513f991100ead Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 28 Mar 2025 18:22:05 -0400 Subject: [PATCH 039/137] init --- src/grammar.y~ | 373 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 373 insertions(+) create mode 100644 src/grammar.y~ diff --git a/src/grammar.y~ b/src/grammar.y~ new file mode 100644 index 0000000..5238aac --- /dev/null +++ b/src/grammar.y~ @@ -0,0 +1,373 @@ + +/* Syntax Analyzer with Bison (3.8.2) */ +/* The Translators - Spring 2025 */ + +%{ + #include + #include "../src/symbol_table.c" + #include + extern int yylex(void); + void yyerror(const char *err); + extern char* yytext; + extern int yyleng; + extern int yychar; + extern SymbolTable * cur; + //char* cur_value; + //char* cur_type; + int token_tracker; + extern int line_number; + extern int column_number; + extern FILE * yyin; + extern TableNode* funprime; + extern TableNode* arrayprim; + extern TableNode* recprime; + extern TableNode* funtypeprime; + extern TableNode* integ; + extern TableNode* addr; + extern TableNode* chara; + extern TableNode* stri; + extern TableNode* boo; + TableNode * tn; +%} +//%define api.location.type {location_t} +%locations +%union { + int integ; + char * words; +} + + +%type assignable +%type expression +%type constant +%type id_or_types +%type types +%token ID 101 +%token T_INTEGER 201 +%token T_ADDRESS 202 +%token T_BOOLEAN 203 +%token T_CHARACTER 204 +%token T_STRING 205 +%token C_INTEGER 301 +%token C_NULL 302 +%token C_CHARACTER 303 +%token C_STRING 304 +%token C_TRUE 305 +%token C_FALSE 306 +%token WHILE 401 +%token IF 402 +%token THEN 403 +%token ELSE 404 +%token TYPE 405 +%token FUNCTION 406 +%token RETURN 407 +%token EXTERNAL 408 +%token AS 409 +%token L_PAREN 501 +%token R_PAREN 502 +%token L_BRACKET 503 +%token R_BRACKET 504 +%token L_BRACE 505 +%token R_BRACE 506 +%token SEMI_COLON 507 +%token COLON 508 +%token COMMA 509 +%token ARROW 510 +%token MUL 603 +%token DIV 604 +%token REM 605 +%token ADD 601 +%token LESS_THAN 606 +%token EQUAL_TO 607 +%token AND 610 +%token OR 611 +%token ASSIGN 608 +%token SUB_OR_NEG 602 +%token NOT 609 +%token DOT 612 +%token RESERVE 613 +%token RELEASE 614 +%token COMMENT 700 + +//precedence order +%left ASSIGN +%left OR +%left AND +%left EQUAL_TO +%left LESS_THAN +%left ADD SUB_OR_NEG +%left MUL DIV REM +%precedence NOT +%precedence UMINUS +%precedence DOT +%precedence RESERVE RELEASE + + + +%% + +program: + prototype_or_definition_list + ; + +prototype_or_definition_list: + prototype prototype_or_definition_list + | definition prototype_or_definition_list + | prototype + | definition + ; + +prototype: + L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; + +definition: +TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); + if (table_lookup(getAncestor(cur), $2) == NULL) { + printf("rec not found \n"); + } + }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); + cur = getParent(cur);} + | TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} + | function_declaration + | TYPE ID COLON id_or_types ARROW id_or_types { + CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); + } + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + } L_PAREN ID { + CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + }R_PAREN ASSIGN sblock + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == NULL) { + printf("null check\n"); + } + if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + }AS L_PAREN { + TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) { + printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + } else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ + CreateEntry(cur, entry, NULL, NULL); + } + } + } idlist R_PAREN ASSIGN sblock + ; + + +function_declaration: + FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} + | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} + ; + + +idlist: + ID { + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) == NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $1); + } COMMA idlist + | ID { + + TableNode *entry = getFirstEntry(cur); + while (getName(entry) != NULL) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) != NULL) { + printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + } + addName(entry, $1); + } + ; + + +sblock: +L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE + | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock + {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE + ; + +dblock: + L_BRACKET declaration_list R_BRACKET; + +declaration_list: + declaration SEMI_COLON declaration_list + | declaration + ; + +declaration: + id_or_types COLON ID {printf("ID/TYPE: %s, ID: %s\n", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + ; + +id_or_types: + ID {printf("string of id in id_or_type is %s\n",$1); $$ = getType(look_up(cur,$1));} + | types {printf("string of type in id_or_type is %s\n",$1);} {$$ = $1;} + ; + +statement_list: + compound_statement statement_list + | compound_statement + | simple_statement SEMI_COLON statement_list + | simple_statement SEMI_COLON + ; + +compound_statement: + WHILE L_PAREN expression R_PAREN sblock + | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock + | sblock //{printf("seen a compound statement rule\n");} + ; + +simple_statement: + assignable ASSIGN expression {if(strcmp($1, $3) == 0){ + } else { + printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column); + }} + + | RETURN expression + ; + +assignable: + ID {$$ = getType(look_up(cur,$1));} + | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} + | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ + {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} + ; + +rec_op : + DOT + +expression: + constant {printf("constant expression\n");} {$$ = $1;} + + | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) + {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); + $$=strdup("undefined");}else{$$=$2;}} + + | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); + printf("mismatch at line %d and column %d. Invalid type being negated is %s\n", + @1.first_line,@1.first_column,$2);}} + + | expression ADD expression + {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression SUB_OR_NEG expression + {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression MUL expression + {printf("multiply expression\n"); + if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression DIV expression + {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression REM expression + {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression AND expression + {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression OR expression + {printf("OR\n");if(strcmp($1,$3)==0 && + strcmp($1,"Boolean")==0){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression LESS_THAN expression + {printf("less than expression\n");if(strcmp($1,$3)==0 && + strcmp($1,"integer")==0){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined");}} + + | expression EQUAL_TO expression {printf("equals check expression\n"); + if(strcmp($1,$3)==0){$$=strdup("Boolean");} + else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| + strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} + else{printf("mismatch at line %d and column %d. Invalid types %s and %s\n", + @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} + + | assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;} + + | L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;} + + | memOp assignable {$$ = strdup("address");} + ; + + +ablock: +L_PAREN argument_list {$$ = $2;} R_PAREN + ; + +argument_list: +expression COMMA argument_list {$$ = $3 + 1;} +| expression {$$ = 1;} + ; + + +memOp: + RESERVE {printf("reserve expression\n");} + | RELEASE {printf("release expression\n");} + ; + + +constant: + C_STRING {$$ = $1;} + | C_INTEGER {$$ = "integer";} + | C_NULL {$$ = $1;} + | C_CHARACTER {$$ = $1;} + | C_TRUE {$$ = $1;} + | C_FALSE {$$ = $1;} + ; + +types: + // Commented out T_String below + // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} + T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} + | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} + | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} + | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} + ; + +%% + +void yyerror(const char *err) { + fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column); +} From ad4f55c2bf5005d7bc38655d0573d0f572b0c98d Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 28 Mar 2025 20:38:21 -0400 Subject: [PATCH 040/137] HUGE Makefile updates! --- Makefile | 33 +- check.sh | 73 ++-- src/grammar.y~ | 373 ------------------ src/symbol_table.c | 2 +- test.sh | 166 ++++++++ ..._mistake.alpha => sp2_carls_mistake.alpha} | 0 ...id_recop.alpha => sp2_invalid_recop.alpha} | 0 ...elease.alpha => sp2_invalid_release.alpha} | 0 ...pha => sp2_valid_assignable_and_mem.alpha} | 0 9 files changed, 242 insertions(+), 405 deletions(-) delete mode 100644 src/grammar.y~ create mode 100755 test.sh rename tests/sprint2/test/{test_carls_mistake.alpha => sp2_carls_mistake.alpha} (100%) rename tests/sprint2/test/{test_invalid_recop.alpha => sp2_invalid_recop.alpha} (100%) rename tests/sprint2/test/{test_invalid_release.alpha => sp2_invalid_release.alpha} (100%) rename tests/sprint2/test/{test_valid_assignable_and_mem.alpha => sp2_valid_assignable_and_mem.alpha} (100%) diff --git a/Makefile b/Makefile index c58b895..0f04da9 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,9 @@ CFLAGS := YACC := bison TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha) -TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha) TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha) +TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha) +TESTS-S4 := $(wildcard tests/sprint4/test/*.alpha) compiler: clean runner @@ -33,22 +34,38 @@ runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o debug: CFLAGS += -DDEBUG=1 debug: clean compiler -test: test-s1 test-s2 test-s3 +test: + chmod +x ./check.sh + chmod +x ./test.sh + $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);) + ./test.sh sp2 + ./test.sh sp3 + ./test.sh sp4 + ./check.sh test-s1: chmod +x ./check.sh - for test in $(TESTS-S1); do ./$(EXE) -tok $$test || echo "Test $$test failed but continuing"; done - ./check.sh + chmod +x ./test.sh + $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);) + ./check.sh sp1 test-s2: chmod +x ./check.sh - for test in $(TESTS-S2); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done - ./check.sh + chmod +x ./test.sh + ./test.sh sp2 + ./check.sh sp2 test-s3: chmod +x ./check.sh - for test in $(TESTS-S3); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done - ./check.sh + chmod +x ./test.sh + ./test.sh sp3 + ./check.sh sp3 + +test-s4: + chmod +x ./check.sh + chmod +x ./test.sh + ./test.sh sp4 + ./check.sh sp4 clean: rm -f *.o diff --git a/check.sh b/check.sh index f325421..bac18ec 100755 --- a/check.sh +++ b/check.sh @@ -5,34 +5,61 @@ # The Translators - Spring 2025 # TOK_DIR="out" +NOCOLOR='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' -WHITE='\033[0m' -PURPLE='\033[0;35m' ORANGE='\033[0;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +LIGHTGRAY='\033[0;37m' +DARKGRAY='\033[1;30m' +LIGHTRED='\033[1;31m' +LIGHTGREEN='\033[1;32m' +YELLOW='\033[1;33m' +LIGHTBLUE='\033[1;34m' +LIGHTPURPLE='\033[1;35m' +LIGHTCYAN='\033[1;36m' +WHITE='\033[1;37m' + +compare_files() { + local file="$1" + local filename=$(basename -- "$file") + filename="${filename%.*}" + local num=${filename:2:1} + local exp="./tests/sprint$num/expected/$filename.expected" + + if [[ -f "$exp" ]]; then + diff -q "$file" "$exp" > /dev/null + if [[ $? -eq 0 ]]; then + echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed.${NOCOLOR}" + else + echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value...${NOCOLOR}" + diff --color=always "$file" "$exp" + echo -e "" + fi + else + echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value.${NOCOLOR}" + fi +} if [[ ! -d "$TOK_DIR" ]]; then - echo "Directory $TOK_DIR does not exist." + echo -e "${RED}[ERROR] ${YELLOW}Directory $TOK_DIR does not exist.${NOCOLOR}" exit 1 fi -echo -e "\n" -for file in "$TOK_DIR"/*; do - filename=$(basename -- "$file") - filename="${filename%.*}" - num=${filename:2:1} - exp="./tests/sprint$num/expected/$filename.expected" - - if [[ -f "$exp" ]]; then - diff -q "$file" "$exp" > /dev/null - if [[ $? -eq 0 ]]; then - echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed." - else - echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value..." - diff --color=always "$file" "$exp" - echo -e "" - fi - else - echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value." - fi -done \ No newline at end of file +if [[ $# -eq 0 ]]; then + for file in "$TOK_DIR"/*; do + compare_files "$file" + done +elif [[ $# -eq 1 ]]; then + prefix="$1" + for file in "$TOK_DIR"/"$prefix"*; do + if [[ -f "$file" ]]; then + compare_files "$file" + fi + done +else + echo -e "${LIGHTBLUE}Usage: $0 [sp#]${NOCOLOR}" + exit 1 +fi \ No newline at end of file diff --git a/src/grammar.y~ b/src/grammar.y~ deleted file mode 100644 index 5238aac..0000000 --- a/src/grammar.y~ +++ /dev/null @@ -1,373 +0,0 @@ - -/* Syntax Analyzer with Bison (3.8.2) */ -/* The Translators - Spring 2025 */ - -%{ - #include - #include "../src/symbol_table.c" - #include - extern int yylex(void); - void yyerror(const char *err); - extern char* yytext; - extern int yyleng; - extern int yychar; - extern SymbolTable * cur; - //char* cur_value; - //char* cur_type; - int token_tracker; - extern int line_number; - extern int column_number; - extern FILE * yyin; - extern TableNode* funprime; - extern TableNode* arrayprim; - extern TableNode* recprime; - extern TableNode* funtypeprime; - extern TableNode* integ; - extern TableNode* addr; - extern TableNode* chara; - extern TableNode* stri; - extern TableNode* boo; - TableNode * tn; -%} -//%define api.location.type {location_t} -%locations -%union { - int integ; - char * words; -} - - -%type assignable -%type expression -%type constant -%type id_or_types -%type types -%token ID 101 -%token T_INTEGER 201 -%token T_ADDRESS 202 -%token T_BOOLEAN 203 -%token T_CHARACTER 204 -%token T_STRING 205 -%token C_INTEGER 301 -%token C_NULL 302 -%token C_CHARACTER 303 -%token C_STRING 304 -%token C_TRUE 305 -%token C_FALSE 306 -%token WHILE 401 -%token IF 402 -%token THEN 403 -%token ELSE 404 -%token TYPE 405 -%token FUNCTION 406 -%token RETURN 407 -%token EXTERNAL 408 -%token AS 409 -%token L_PAREN 501 -%token R_PAREN 502 -%token L_BRACKET 503 -%token R_BRACKET 504 -%token L_BRACE 505 -%token R_BRACE 506 -%token SEMI_COLON 507 -%token COLON 508 -%token COMMA 509 -%token ARROW 510 -%token MUL 603 -%token DIV 604 -%token REM 605 -%token ADD 601 -%token LESS_THAN 606 -%token EQUAL_TO 607 -%token AND 610 -%token OR 611 -%token ASSIGN 608 -%token SUB_OR_NEG 602 -%token NOT 609 -%token DOT 612 -%token RESERVE 613 -%token RELEASE 614 -%token COMMENT 700 - -//precedence order -%left ASSIGN -%left OR -%left AND -%left EQUAL_TO -%left LESS_THAN -%left ADD SUB_OR_NEG -%left MUL DIV REM -%precedence NOT -%precedence UMINUS -%precedence DOT -%precedence RESERVE RELEASE - - - -%% - -program: - prototype_or_definition_list - ; - -prototype_or_definition_list: - prototype prototype_or_definition_list - | definition prototype_or_definition_list - | prototype - | definition - ; - -prototype: - L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; - -definition: -TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); - if (table_lookup(getAncestor(cur), $2) == NULL) { - printf("rec not found \n"); - } - }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); - cur = getParent(cur);} - | TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} - | function_declaration - | TYPE ID COLON id_or_types ARROW id_or_types { - CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); - } - | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); - } else { - setStartLine(node, @1.first_line); - setAsKeyword(node, false); - } - cur = CreateScope(cur, 0, 0); - } L_PAREN ID { - CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); - }R_PAREN ASSIGN sblock - | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL) { - printf("null check\n"); - } - if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); - } else { - setStartLine(node, @1.first_line); - setAsKeyword(node, false); - } - cur = CreateScope(cur, 0, 0); - }AS L_PAREN { - TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) { - printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); - } else { - for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ - CreateEntry(cur, entry, NULL, NULL); - } - } - } idlist R_PAREN ASSIGN sblock - ; - - -function_declaration: - FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} - | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} - ; - - -idlist: - ID { - TableNode *entry = getFirstEntry(cur); - while (getName(entry) != NULL) { - entry = getNextEntry(entry); - } - if (getNextEntry(entry) == NULL) { - printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); - } - addName(entry, $1); - } COMMA idlist - | ID { - - TableNode *entry = getFirstEntry(cur); - while (getName(entry) != NULL) { - entry = getNextEntry(entry); - } - if (getNextEntry(entry) != NULL) { - printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); - } - addName(entry, $1); - } - ; - - -sblock: -L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE - | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock - {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE - ; - -dblock: - L_BRACKET declaration_list R_BRACKET; - -declaration_list: - declaration SEMI_COLON declaration_list - | declaration - ; - -declaration: - id_or_types COLON ID {printf("ID/TYPE: %s, ID: %s\n", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } - ; - -id_or_types: - ID {printf("string of id in id_or_type is %s\n",$1); $$ = getType(look_up(cur,$1));} - | types {printf("string of type in id_or_type is %s\n",$1);} {$$ = $1;} - ; - -statement_list: - compound_statement statement_list - | compound_statement - | simple_statement SEMI_COLON statement_list - | simple_statement SEMI_COLON - ; - -compound_statement: - WHILE L_PAREN expression R_PAREN sblock - | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock - | sblock //{printf("seen a compound statement rule\n");} - ; - -simple_statement: - assignable ASSIGN expression {if(strcmp($1, $3) == 0){ - } else { - printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column); - }} - - | RETURN expression - ; - -assignable: - ID {$$ = getType(look_up(cur,$1));} - | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} - | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ - {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} - ; - -rec_op : - DOT - -expression: - constant {printf("constant expression\n");} {$$ = $1;} - - | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) - {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); - $$=strdup("undefined");}else{$$=$2;}} - - | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); - printf("mismatch at line %d and column %d. Invalid type being negated is %s\n", - @1.first_line,@1.first_column,$2);}} - - | expression ADD expression - {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression SUB_OR_NEG expression - {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression MUL expression - {printf("multiply expression\n"); - if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression DIV expression - {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression REM expression - {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression AND expression - {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression OR expression - {printf("OR\n");if(strcmp($1,$3)==0 && - strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression LESS_THAN expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} - - | expression EQUAL_TO expression {printf("equals check expression\n"); - if(strcmp($1,$3)==0){$$=strdup("Boolean");} - else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| - strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s\n", - @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} - - | assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;} - - | L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;} - - | memOp assignable {$$ = strdup("address");} - ; - - -ablock: -L_PAREN argument_list {$$ = $2;} R_PAREN - ; - -argument_list: -expression COMMA argument_list {$$ = $3 + 1;} -| expression {$$ = 1;} - ; - - -memOp: - RESERVE {printf("reserve expression\n");} - | RELEASE {printf("release expression\n");} - ; - - -constant: - C_STRING {$$ = $1;} - | C_INTEGER {$$ = "integer";} - | C_NULL {$$ = $1;} - | C_CHARACTER {$$ = $1;} - | C_TRUE {$$ = $1;} - | C_FALSE {$$ = $1;} - ; - -types: - // Commented out T_String below - // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} - T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} - | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} - | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} - | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} - ; - -%% - -void yyerror(const char *err) { - fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column); -} diff --git a/src/symbol_table.c b/src/symbol_table.c index 7f8849b..cdcbd30 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -921,4 +921,4 @@ TableNode *getNextEntry(TableNode *tn) { return tn->next; } printf("The type of the first entry is %s\n",First_Entry->theType); return 0; } - */ + */ \ No newline at end of file diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..e35809e --- /dev/null +++ b/test.sh @@ -0,0 +1,166 @@ +#!/bin/bash + +# Test Tool # +# The Translators - Spring 2025 # + +RED='\033[0;31m' +GREEN='\033[0;32m' +ORANGE='\033[0;33m' +BLUE='\033[0;34m' +PURPLE='\033[0;35m' +CYAN='\033[0;36m' +LIGHTGRAY='\033[0;37m' +DARKGRAY='\033[1;30m' +LIGHTRED='\033[1;31m' +LIGHTGREEN='\033[1;32m' +YELLOW='\033[1;33m' +LIGHTBLUE='\033[1;34m' +LIGHTPURPLE='\033[1;35m' +LIGHTCYAN='\033[1;36m' +WHITE='\033[1;37m' + +if [ ! -f "./alpha" ]; then + echo -e "${RED}[ERROR] ${YELLOW}File ./alpha not found!${WHITE}" + exit 1 +fi + +if [ ! -d "./out" ]; then + mkdir -p out +fi + +SWITCH=${YELLOW} +count=0 + +switchfunc() { + if [ $count -eq 0 ]; then + count=1 + SWITCH=${YELLOW} + else + count=0 + SWITCH='\033[0;35m' + fi +} + +if [ $# -eq 0 ]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running all tests...${WHITE}" + echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-1 ---------------------------\n${WHITE}" + for file in ./tests/sprint1/test/*; do + if [ -f "$file" ]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + echo -e "" + + echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-2 ---------------------------\n${WHITE}" + for file in ./tests/sprint2/test/*; do + if [ -f "$file" ]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + echo -e "" + + echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-3 ---------------------------\n${WHITE}" + for file in ./tests/sprint3/test/*; do + if [ -f "$file" ]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + echo -e "" + + echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-4 ---------------------------\n${WHITE}" + for file in ./tests/sprint4/test/*; do + if [ -f "$file" ]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n${WHITE}" + switchfunc + fi + done + +else + if [ "$1" == "--help" ]; then + echo -e "${YELLOW}[INFO] ${WHITE}Usage: ./test.sh [prefix]" + echo -e "${YELLOW}[INFO] ${WHITE}--help: show this help message" + echo -e "${YELLOW}[INFO] ${WHITE}--file : run test with file" + exit 0 + fi + if [[ "$1" == "--file" ]]; then + shift + if [ $# -eq 0 ]; then + echo -e "${RED}[ERROR] ${YELLOW}No file specified!${WHITE}" + exit 1 + fi + if [ -f "$1" ]; then + filename=$(basename -- "$1") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$1" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}" + exit 1 + else + echo -e "${RED}[ERROR] ${YELLOW}File $1 not found!${WHITE}" + exit 1 + fi + fi + + if [[ "$1" == "sp1" ]]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." + for file in ./tests/sprint1/test/*; do + if [[ "$file" == *"$1"* ]]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + elif [[ "$1" == "sp2" ]]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." + for file in ./tests/sprint2/test/*; do + if [[ "$file" == *"$1"* ]]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + elif [[ "$1" == "sp3" ]]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." + for file in ./tests/sprint3/test/*; do + if [[ "$file" == *"$1"* ]]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + elif [[ "$1" == "sp4" ]]; then + echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..." + for file in ./tests/sprint4/test/*; do + if [[ "$file" == *"$1"* ]]; then + filename=$(basename -- "$file") + echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" + ./alpha -st "$file" + echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" + switchfunc + fi + done + else + echo -e "${RED}[ERROR] ${YELLOW}Invalid prefix $1!${WHITE}" + exit 1 + fi +fi \ No newline at end of file diff --git a/tests/sprint2/test/test_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha similarity index 100% rename from tests/sprint2/test/test_carls_mistake.alpha rename to tests/sprint2/test/sp2_carls_mistake.alpha diff --git a/tests/sprint2/test/test_invalid_recop.alpha b/tests/sprint2/test/sp2_invalid_recop.alpha similarity index 100% rename from tests/sprint2/test/test_invalid_recop.alpha rename to tests/sprint2/test/sp2_invalid_recop.alpha diff --git a/tests/sprint2/test/test_invalid_release.alpha b/tests/sprint2/test/sp2_invalid_release.alpha similarity index 100% rename from tests/sprint2/test/test_invalid_release.alpha rename to tests/sprint2/test/sp2_invalid_release.alpha diff --git a/tests/sprint2/test/test_valid_assignable_and_mem.alpha b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha similarity index 100% rename from tests/sprint2/test/test_valid_assignable_and_mem.alpha rename to tests/sprint2/test/sp2_valid_assignable_and_mem.alpha From 57ba34ab37ccb716b60e9079a366cfd34f049762 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 28 Mar 2025 22:22:58 -0400 Subject: [PATCH 041/137] added a bunch of NULL checks --- src/grammar.y | 41 ++- src/symbol_table.c | 346 +++++++++++++++---------- tests/sprint2/sp2_function_types.alpha | 17 ++ 3 files changed, 260 insertions(+), 144 deletions(-) create mode 100644 tests/sprint2/sp2_function_types.alpha diff --git a/src/grammar.y b/src/grammar.y index fcb06b8..b7438bd 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -36,7 +36,7 @@ char * words; } - +%type idlist %type assignable %type expression %type constant @@ -121,27 +121,39 @@ prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; definition: -TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); +TYPE ID COLON { + printf("Currently see a record definition for %s\n", $2); + tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == NULL) { printf("rec not found \n"); } }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); cur = getParent(cur);} - | TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} + | TYPE ID COLON C_INTEGER ARROW id_or_types + {printf("Currently see a array definition of name %s,storing type %s, of dimensions %d\n", + $2, $6, $4); + CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { + printf("Currently see a function type definition of name %s,parameter type %s, of return type %s\n", + $2, $4, $6); CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); } | ID { TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + if (node == NULL) { printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); - } else { + }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } + else { setStartLine(node, @1.first_line); setAsKeyword(node, false); } cur = CreateScope(cur, 0, 0); } L_PAREN ID { + printf("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s\n", + $1,$4); CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); }R_PAREN ASSIGN sblock | ID { @@ -149,23 +161,29 @@ TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo if (node == NULL) { printf("null check\n"); } - if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + if (node == NULL) { printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); - } else { + }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ + printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + } + else { setStartLine(node, @1.first_line); setAsKeyword(node, false); } cur = CreateScope(cur, 0, 0); }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) { + if (parameter == NULL) { printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); - } else { + }else if(getAdInfoType(parameter) != TYPE_RECORD){ + printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + }else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ CreateEntry(cur, entry, NULL, NULL); } } - } idlist R_PAREN ASSIGN sblock + } idlist {printf("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d\n", + $1,$6);} R_PAREN ASSIGN sblock ; @@ -185,7 +203,7 @@ idlist: printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); } addName(entry, $1); - } COMMA idlist + } COMMA idlist {$$ = $3 + 1;} | ID { TableNode *entry = getFirstEntry(cur); @@ -196,6 +214,7 @@ idlist: printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); } addName(entry, $1); + $$ = 1; } ; diff --git a/src/symbol_table.c b/src/symbol_table.c index 7f8849b..e8e1868 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -19,6 +19,7 @@ TableNode *boo; TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; +//AdInfo *Undefined_function_type_info; typedef enum { // First 4 below are primitive types that are all encapsulated in @@ -133,6 +134,10 @@ int getPrimSize(TableNode *definition) { // type stored in the array per professor, the actual size of the array is // calculated at runtime so bounds checking only needs to be done then AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { + if(type == NULL || type == undefined){ + printf("passed a NULL or undefined type reference to CreateArrayInfo. Invalid.\n"); + return NULL; + } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); info->ArrayAdInfo = (array_info *)malloc(sizeof(array_info)); info->ArrayAdInfo->numofdimensions = dim; @@ -144,7 +149,7 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { if (definition == NULL|| definition == undefined){ - printf("passed an NULL entry to getNumArrDim function. Invalid.\n"); + printf("passed an NULL or undefined entry to getNumArrDim function. Invalid.\n"); return -1; } if (strcmp(getType(definition), "array") != 0) { @@ -156,6 +161,10 @@ int getNumArrDim(TableNode *definition) { // This gets the type stored in an array from arrtype. It returns a reference to // the entry of that type TableNode *getArrType(TableNode *definition) { + if(definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getArrType function. Invalid.\n"); + return NULL; + } if (strcmp(getType(definition), "array") != 0) { printf("not checking the type of an array -- invalid op\n"); return undefined; @@ -179,6 +188,10 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // Perhaps this may not be needed since we need to iterate over all elements // anyways. int getRecLength(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getRecLength function. Invalid.\n"); + return -1; + } if (strcmp(getType(definition), "record") != 0) { printf("not checking the length of an record -- invalid op\n"); return 0; @@ -187,6 +200,10 @@ int getRecLength(TableNode *definition) { } // This gets the array. Needs to up be updated to get the scope instead SymbolTable *getRecList(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getRecList function. Invalid.\n"); + return NULL; + } if (strcmp(getType(definition), "record") != 0) { printf("not checking the list of types of a record -- invalid " "op\n"); @@ -205,13 +222,20 @@ TableNode* setRecSize(TableNode* tn, int n){ } int getRecSize(SymbolTable* tn){ + if(tn == NULL){ + printf("passed in NULL SymbolTable for getRecSize. Invalid\n"); + return -1; + } int s = 0; TableNode* cur = getFirstEntry(tn); + if (cur != NULL){ while(getNextEntry(cur) != NULL){ s++; cur = getNextEntry(cur); } return s; + } +return -1; } // below function takes a bool to see if parameter should be decomposed or not @@ -230,6 +254,10 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // gets the line at which the function was first defined. (Can be used to print // out in table if needed) int getStartLine(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getStartLine function. Invalid.\n"); + return -1; + } if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking the start line of a function -- invalid " "op\n"); @@ -249,6 +277,10 @@ TableNode* setStartLine(TableNode* tn, int start){ // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getAsKeyword function. Invalid.\n"); + return false; + } if (strcmp(getType(definition), "primitive function") != 0) { printf("not checking if a function is called with as or not -- " "invalid op\n"); @@ -268,6 +300,14 @@ TableNode* setAsKeyword(TableNode* tn, bool as){ // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { + if(parameter == NULL||parameter == undefined){ + printf("passed a NULL or undefined parameter to CreateFunctionTypeInfo. Invalid.\n"); + return NULL; + } + if(returntype == NULL||returntype == undefined){ + printf("passed a NULL or undefined return type to CreateFunctionTypeInfo. Invalid.\n"); + return NULL; + } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); info->FunTypeAdInfo = (function_type_info *)malloc(sizeof(function_type_info)); @@ -277,6 +317,10 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { } // returns parameter type of a function TableNode *getParameter(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getParameter function. Invalid.\n"); + return undefined; + } if (strcmp(getType(definition), "primitive function type") != 0) { printf( "not checking the parameter of a function -- invalid op\n"); @@ -286,6 +330,10 @@ TableNode *getParameter(TableNode *definition) { } // returns return type of a function TableNode *getReturn(TableNode *definition) { + if (definition == NULL|| definition == undefined){ + printf("passed an NULL or undefined entry to getReturn function. Invalid.\n"); + return NULL; + } if (strcmp(getType(definition), "primitive function type") != 0) { printf("not checking the return of a function -- invalid op\n"); return undefined; @@ -331,11 +379,11 @@ SymbolTable *init(SymbolTable *start) { "Cannot initialize a scope that is not the parent scope\n"); return NULL; } - integ = (TableNode *)malloc(sizeof(TableNode)); - addr = (TableNode *)malloc(sizeof(TableNode)); - chara = (TableNode *)malloc(sizeof(TableNode)); - stri = (TableNode *)malloc(sizeof(TableNode)); - boo = (TableNode *)malloc(sizeof(TableNode)); + integ = (TableNode *)calloc(1,sizeof(TableNode)); + addr = (TableNode *)calloc(1,sizeof(TableNode)); + chara = (TableNode *)calloc(1,sizeof(TableNode)); + stri = (TableNode *)calloc(1,sizeof(TableNode)); + boo = (TableNode *)calloc(1,sizeof(TableNode)); // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; @@ -402,6 +450,8 @@ SymbolTable *init(SymbolTable *start) { undefined->additionalinfo = NULL; undefined->next = NULL; + //Undefined_function_type_info = CreateFunctionTypeInfo(undefined, undefined); + integ->theType = prime; addr->theType = prime; chara->theType = prime; @@ -465,31 +515,31 @@ int getAdInfoType(TableNode* tn){ printf("Entry being passed in has a null or undefined reference for theType. Invalid.\n"); return -1; } - if(strcmp(getType(tn),getName(integ))==0){ + if(strcmp(getName(tn),getName(integ))==0){ return TYPE_PRIMITIVE; } - if(strcmp(getType(tn),getName(addr))==0){ + if(strcmp(getName(tn),getName(addr))==0){ return TYPE_PRIMITIVE; } - if(strcmp(getType(tn),getName(chara))==0){ + if(strcmp(getName(tn),getName(chara))==0){ return TYPE_PRIMITIVE; } - if(strcmp(getType(tn),getName(stri))==0){ + if(strcmp(getName(tn),getName(stri))==0){ return TYPE_ARRAY; } - if(strcmp(getType(tn),getName(boo))==0){ + if(strcmp(getName(tn),getName(boo))==0){ return TYPE_PRIMITIVE; } - if(strcmp(getType(tn),getName(recprime))==0){ + if(strcmp(getName(tn),getName(recprime))==0){ return TYPE_RECORD; } - if(strcmp(getType(tn),getName(funtypeprime))==0){ + if(strcmp(getName(tn),getName(funtypeprime))==0){ return TYPE_FUNCTION_TYPE; } - if(strcmp(getType(tn),getName(arrayprim))==0){ + if(strcmp(getName(tn),getName(arrayprim))==0){ return TYPE_ARRAY; } - if(strcmp(getType(tn),getName(undefined))==0){ + if(strcmp(getName(tn),getName(undefined))==0){ return TYPE_UNDEFINED; } else{ @@ -497,13 +547,13 @@ int getAdInfoType(TableNode* tn){ } } -TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, - AdInfo *ad) { +TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo *ad) { if (table == NULL) { printf("Null reference to table"); return undefined; } + /* TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); if(topDef == NULL){ @@ -553,8 +603,18 @@ char *getName(TableNode *tn) { return tn->theName; } -int getLine(SymbolTable *st) { return st->Line_Number; } -int getColumn(SymbolTable *st) { return st->Column_Number; } +int getLine(SymbolTable *st) { + if(st == NULL){ + printf("passed a NULL symbol table to getLine function. Invalid.\n"); + return -1; + } + return st->Line_Number; } +int getColumn(SymbolTable *st) { + if(st == NULL){ + printf("passed a NULL symbol table to getColumn function. Invalid.\n"); + return -1; + } + return st->Column_Number; } TableNode* addName(TableNode *tn, char* str){ if(tn == NULL||tn==undefined){ printf("passed a Null or undefined table node to the addName function. Invalid./n"); @@ -626,6 +686,10 @@ names\n"); return NULL; */ //only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { + if(table == NULL) { + printf("passed in empty scope. error.\n"); + return undefined; + } TableNode *entrie = table->entries; for (; entrie != NULL; entrie = entrie->next) { if (!strcmp(entrie->theName, x)) { @@ -648,8 +712,9 @@ TableNode *look_up(SymbolTable *table, char *x) { ,x,getLine(table),getColumn(table)); return look_up(table->Parent_Scope, x); } - +/* void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -674,7 +739,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } for (; entrie != NULL; entrie = entrie->next) { if (parant_scope == 0) { - /*have to update*/ if (strcmp(entrie->theType->theName, + /*have to update if (strcmp(entrie->theType->theName, "function primitive") || strcmp(entrie->theType->theName, "array")) { @@ -700,124 +765,139 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "--------------:-------" "----------------------\n"); } -} -// void print_symbol_table(SymbolTable *table, FILE *file_ptr) { +}*/ +void print_symbol_table(SymbolTable *table, FILE *file_ptr) { -// if (table->Parent_Scope == NULL) { -// fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", -// "SCOPE", "PARENT", "TYPE", "Extra annotation"); -// } -// TableNode *entrie = table->entries; -// fprintf(file_ptr, "-----------------:--------:--------:----------------" -// "------:---------" -// "--------------------\n"); -// int parant_scope = 0; -// int current_scope = 0; -// if (table->Parent_Scope != NULL) { -// parant_scope = table->Parent_Scope->Line_Number * 1000 + -// table->Parent_Scope->Column_Number; -// current_scope = -// table->Line_Number * 1000 + table->Column_Number; -// } else { -// current_scope = 1001; -// } -// if (entrie == NULL) { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", -// current_scope, parant_scope, "", "Empty Scope"); -// } -// for (;entrie != NULL; entrie = entrie->next) { -// if (getAdInfoType(entrie) == TYPE_ARRAY){ -// if (parant_scope == 0) { + if (table->Parent_Scope == NULL) { + fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", + "SCOPE", "PARENT", "TYPE", "Extra annotation"); + } + TableNode *entrie = table->entries; + fprintf(file_ptr, "-----------------:--------:--------:----------------" + "------:---------" + "--------------------\n"); + int parant_scope = 0; + int current_scope = 0; + if (table->Parent_Scope != NULL) { + parant_scope = table->Parent_Scope->Line_Number * 1000 + + table->Parent_Scope->Column_Number; + current_scope = + table->Line_Number * 1000 + table->Column_Number; + } else { + current_scope = 1001; + } + if (entrie == NULL) { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", + current_scope, parant_scope, "", "Empty Scope"); + } + for (;entrie != NULL; entrie = entrie->next) { + if (getAdInfoType(entrie) == TYPE_ARRAY){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : : %-21d -> %-21s: %-28s\n", -// entrie->theName, current_scope, -// entrie->additionalinfo->ArrayAdInfo->numofdimensions, -// entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, -// "Type of Array"); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", -// entrie->theName, current_scope, parant_scope, -// entrie->additionalinfo->ArrayAdInfo->numofdimensions, -// entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, -// "Type of Array"); -// } -// } -// if (getAdInfoType(entrie) == TYPE_RECORD){ -// if (parant_scope == 0) { + fprintf(file_ptr, + "%-17s: %06d : : %-21d -> %-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->ArrayAdInfo->numofdimensions, + entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, + "Type of Array"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + entrie->additionalinfo->ArrayAdInfo->numofdimensions, + entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, + "Type of Array"); + } + } + if (getAdInfoType(entrie) == TYPE_RECORD){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : :%-21s: elements-%-28d\n", -// entrie->theName, current_scope, -// "record", -// entrie->additionalinfo->RecAdInfo->numofelements); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", -// entrie->theName, current_scope, parant_scope, -// "record", -// entrie->additionalinfo->RecAdInfo->numofelements); -// } -// } -// if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ -// if (parant_scope == 0) { + fprintf(file_ptr, + "%-17s: %06d : :%-21s: elements-%-28d\n", + entrie->theName, current_scope, + "record", + entrie->additionalinfo->RecAdInfo->numofelements); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", + entrie->theName, current_scope, parant_scope, + "record", + entrie->additionalinfo->RecAdInfo->numofelements); + } + } + if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : :%-21s: size-%-28d bytes\n", -// entrie->theName, current_scope, -// "Primitive", -// entrie->additionalinfo->PrimAdInfo->size); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", -// entrie->theName, current_scope, parant_scope, -// "Primitive", -// entrie->additionalinfo->PrimAdInfo->size); -// } -// } -// if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ -// if (parant_scope == 0) { + fprintf(file_ptr, + "%-17s: %06d : :%-21s: size-%-28d bytes\n", + entrie->theName, current_scope, + "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", + entrie->theName, current_scope, parant_scope, + "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : : %-21s -> %-21s: %-28s\n", -// entrie->theName, current_scope, -// entrie->additionalinfo->FunTypeAdInfo->parameter->theName, -// entrie->additionalinfo->FunTypeAdInfo->returntype->theName, -// "Type of Function"); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", -// entrie->theName, current_scope, parant_scope, -// entrie->additionalinfo->FunTypeAdInfo->parameter->theName, -// entrie->additionalinfo->FunTypeAdInfo->returntype->theName, -// "Type of Function"); -// } -// } -// if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ -// if (parant_scope == 0) { + fprintf(file_ptr, + "%-17s: %06d : : %-21s -> %-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->FunTypeAdInfo->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo->returntype->theName, + "Type of Function"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + entrie->additionalinfo->FunTypeAdInfo->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo->returntype->theName, + "Type of Function"); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ + if (parant_scope == 0) { -// fprintf(file_ptr, -// "%-17s: %06d : :%-21s: %-28s\n", -// entrie->theName, current_scope, -// getType(entrie), -// "Function"); -// } else { -// fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", -// entrie->theName, current_scope, parant_scope, -// getType(entrie), -// "Function"); -// } -// } -// } -// if (table->Children_Scope != NULL) { -// ListOfTable *node = table->Children_Scope; -// for (; node != NULL; node = node->next) { -// print_symbol_table(node->table, file_ptr); -// } -// } -// if (table->Parent_Scope == NULL) { -// fprintf(file_ptr, "-----------------:--------:--------:--------" -// "--------------:-------" -// "----------------------\n"); -// } -// } + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + getType(entrie), + "Function"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + getType(entrie), + "Function"); + } + } + if (getAdInfoType(entrie) == TYPE_UNDEFINED){ + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + "undefined", + "undefined entry"); + } else { + fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, parant_scope, + "undefined", + "undefined entry"); + } + } +} + if (table->Children_Scope != NULL) { + ListOfTable *node = table->Children_Scope; + for (; node != NULL; node = node->next) { + print_symbol_table(node->table, file_ptr); + } + } + if (table->Parent_Scope == NULL) { + fprintf(file_ptr, "-----------------:--------:--------:--------" + "--------------:-------" + "----------------------\n"); + } +} //get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { if(table == NULL){ diff --git a/tests/sprint2/sp2_function_types.alpha b/tests/sprint2/sp2_function_types.alpha new file mode 100644 index 0000000..509de78 --- /dev/null +++ b/tests/sprint2/sp2_function_types.alpha @@ -0,0 +1,17 @@ +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer +function integerXinteger2integer: integerXinteger (*-> integer +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +type integer2address: integer -> address +type address2integer: address -> integer +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer +external function reserve: integer2address +external function release: address2integer +function entry: string2integer*) \ No newline at end of file From d587ed9f3bc7639ca5435363ecf80e2cd81774cd Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 28 Mar 2025 23:33:08 -0400 Subject: [PATCH 042/137] Updated --- Makefile | 4 +- src/grammar.y | 2 +- src/runner.c | 13 +- src/symbol_table.c | 635 ++++++++++-------- test.sh | 18 +- .../{ => test}/sp2_function_types.alpha | 0 6 files changed, 383 insertions(+), 289 deletions(-) rename tests/sprint2/{ => test}/sp2_function_types.alpha (100%) diff --git a/Makefile b/Makefile index 0f04da9..4b92e65 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ debug: clean compiler test: chmod +x ./check.sh chmod +x ./test.sh - $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);) + $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) -debug || true);) ./test.sh sp2 ./test.sh sp3 ./test.sh sp4 @@ -46,7 +46,7 @@ test: test-s1: chmod +x ./check.sh chmod +x ./test.sh - $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);) + $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) -debug || true);) ./check.sh sp1 test-s2: diff --git a/src/grammar.y b/src/grammar.y index b7438bd..8ff8a8f 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -122,7 +122,7 @@ prototype: definition: TYPE ID COLON { - printf("Currently see a record definition for %s\n", $2); + printf("Currently see a record definition for %s\n", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == NULL) { printf("rec not found \n"); diff --git a/src/runner.c b/src/runner.c index 68198f8..a87b527 100644 --- a/src/runner.c +++ b/src/runner.c @@ -9,8 +9,19 @@ extern TableNode *addr; extern TableNode *chara; extern TableNode *stri; extern TableNode *boo; +extern bool DEBUG; +extern char * COLOR_YELLOW; +extern char * COLOR_BLUE; +extern char * COLOR_WHITE; int main(int argc, char *argv[]) { + // if last argument is debug then set to true and ignore it for the rest of this file + if (argc > 1 && strcmp(argv[argc - 1], "-debug") == 0) { + DEBUG = true; + argc--; + } + + if (argc == 1) { fprintf(stderr, INVALID); return -1; @@ -221,4 +232,4 @@ void exit_scope() { return; } cur = cur->Parent_Scope; -} +} \ No newline at end of file diff --git a/src/symbol_table.c b/src/symbol_table.c index 26d8798..8fa87d2 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -19,7 +19,7 @@ TableNode *boo; TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; -//AdInfo *Undefined_function_type_info; +// AdInfo *Undefined_function_type_info; typedef enum { // First 4 below are primitive types that are all encapsulated in @@ -44,9 +44,9 @@ typedef enum { // The Type being pointed to by the first 4 above that only stores the // size TYPE_PRIMITIVE = 6, - //likely NULL - TYPE_ALL_ELSE = 7, - TYPE_UNDEFINED = 8 + // likely NULL + TYPE_ALL_ELSE = 7, + TYPE_UNDEFINED = 8 } types; @@ -106,14 +106,15 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { - if (definition == NULL || definition == undefined){ - printf("passed an NULL entry to getPrimSize function. Invalid.\n"); - return -1; - } - if (definition->additionalinfo == NULL){ - printf("node has NULL additionalinfo. Invalid.\n"); - return -1; - } + if (definition == NULL || definition == undefined) { + printf( + "passed an NULL entry to getPrimSize function. Invalid.\n"); + return -1; + } + if (definition->additionalinfo == NULL) { + printf("node has NULL additionalinfo. Invalid.\n"); + return -1; + } if (strcmp(getType(definition), "primitive") != 0) { printf("not checking the size of a primitive -- invalid op\n"); return 0; @@ -134,8 +135,9 @@ int getPrimSize(TableNode *definition) { // type stored in the array per professor, the actual size of the array is // calculated at runtime so bounds checking only needs to be done then AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { - if(type == NULL || type == undefined){ - printf("passed a NULL or undefined type reference to CreateArrayInfo. Invalid.\n"); + if (type == NULL || type == undefined) { + printf("passed a NULL or undefined type reference to " + "CreateArrayInfo. Invalid.\n"); return NULL; } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); @@ -148,8 +150,9 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { } // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getNumArrDim function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getNumArrDim " + "function. Invalid.\n"); return -1; } if (strcmp(getType(definition), "array") != 0) { @@ -161,8 +164,9 @@ int getNumArrDim(TableNode *definition) { // This gets the type stored in an array from arrtype. It returns a reference to // the entry of that type TableNode *getArrType(TableNode *definition) { - if(definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getArrType function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getArrType " + "function. Invalid.\n"); return NULL; } if (strcmp(getType(definition), "array") != 0) { @@ -188,8 +192,9 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // Perhaps this may not be needed since we need to iterate over all elements // anyways. int getRecLength(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getRecLength function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getRecLength " + "function. Invalid.\n"); return -1; } if (strcmp(getType(definition), "record") != 0) { @@ -200,8 +205,9 @@ int getRecLength(TableNode *definition) { } // This gets the array. Needs to up be updated to get the scope instead SymbolTable *getRecList(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getRecList function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getRecList " + "function. Invalid.\n"); return NULL; } if (strcmp(getType(definition), "record") != 0) { @@ -212,34 +218,34 @@ SymbolTable *getRecList(TableNode *definition) { return definition->additionalinfo->RecAdInfo->recordScope; } -TableNode* setRecSize(TableNode* tn, int n){ - if(tn == NULL||tn==undefined){ - printf("passed in NULL entry for setRecSize. Invalid\n"); - return undefined; - } - tn->additionalinfo->RecAdInfo->numofelements = n; - return tn; - } - -int getRecSize(SymbolTable* tn){ - if(tn == NULL){ +TableNode *setRecSize(TableNode *tn, int n) { + if (tn == NULL || tn == undefined) { + printf("passed in NULL entry for setRecSize. Invalid\n"); + return undefined; + } + tn->additionalinfo->RecAdInfo->numofelements = n; + return tn; +} + +int getRecSize(SymbolTable *tn) { + if (tn == NULL) { printf("passed in NULL SymbolTable for getRecSize. Invalid\n"); return -1; } - int s = 0; - TableNode* cur = getFirstEntry(tn); - if (cur != NULL){ - while(getNextEntry(cur) != NULL){ - s++; - cur = getNextEntry(cur); - } - return s; + int s = 0; + TableNode *cur = getFirstEntry(tn); + if (cur != NULL) { + while (getNextEntry(cur) != NULL) { + s++; + cur = getNextEntry(cur); + } + return s; } -return -1; - } + return -1; +} // below function takes a bool to see if parameter should be decomposed or not - ;// note that functions only take one input and have one output +; // note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of // multiple inputs Below function also has the line number where the function is // first defined @@ -254,8 +260,9 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // gets the line at which the function was first defined. (Can be used to print // out in table if needed) int getStartLine(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getStartLine function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getStartLine " + "function. Invalid.\n"); return -1; } if (strcmp(getType(definition), "primitive function") != 0) { @@ -266,19 +273,21 @@ int getStartLine(TableNode *definition) { return definition->additionalinfo->FunDecAdInfo->startlinenumber; } -TableNode* setStartLine(TableNode* tn, int start){ - if(tn == NULL||tn==undefined){ - printf("passing in a NULL or undefined entry to setStartLine. invalid\n"); - return undefined; - } - tn->additionalinfo->FunDecAdInfo->startlinenumber = start; - return tn; - } +TableNode *setStartLine(TableNode *tn, int start) { + if (tn == NULL || tn == undefined) { + printf("passing in a NULL or undefined entry to setStartLine. " + "invalid\n"); + return undefined; + } + tn->additionalinfo->FunDecAdInfo->startlinenumber = start; + return tn; +} // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getAsKeyword function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getAsKeyword " + "function. Invalid.\n"); return false; } if (strcmp(getType(definition), "primitive function") != 0) { @@ -289,23 +298,26 @@ bool getAsKeyword(TableNode *definition) { return definition->additionalinfo->FunDecAdInfo->regularoras; } -TableNode* setAsKeyword(TableNode* tn, bool as){ - if(tn == NULL||tn==undefined){ - printf("passing in a NULL or undefined entry to setAsKeyword. invalid\n"); +TableNode *setAsKeyword(TableNode *tn, bool as) { + if (tn == NULL || tn == undefined) { + printf("passing in a NULL or undefined entry to setAsKeyword. " + "invalid\n"); return undefined; } - tn->additionalinfo->FunDecAdInfo->regularoras = as; - return tn; - } - + tn->additionalinfo->FunDecAdInfo->regularoras = as; + return tn; +} + // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { - if(parameter == NULL||parameter == undefined){ - printf("passed a NULL or undefined parameter to CreateFunctionTypeInfo. Invalid.\n"); + if (parameter == NULL || parameter == undefined) { + printf("passed a NULL or undefined parameter to " + "CreateFunctionTypeInfo. Invalid.\n"); return NULL; } - if(returntype == NULL||returntype == undefined){ - printf("passed a NULL or undefined return type to CreateFunctionTypeInfo. Invalid.\n"); + if (returntype == NULL || returntype == undefined) { + printf("passed a NULL or undefined return type to " + "CreateFunctionTypeInfo. Invalid.\n"); return NULL; } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); @@ -317,8 +329,9 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { } // returns parameter type of a function TableNode *getParameter(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getParameter function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getParameter " + "function. Invalid.\n"); return undefined; } if (strcmp(getType(definition), "primitive function type") != 0) { @@ -330,8 +343,9 @@ TableNode *getParameter(TableNode *definition) { } // returns return type of a function TableNode *getReturn(TableNode *definition) { - if (definition == NULL|| definition == undefined){ - printf("passed an NULL or undefined entry to getReturn function. Invalid.\n"); + if (definition == NULL || definition == undefined) { + printf("passed an NULL or undefined entry to getReturn " + "function. Invalid.\n"); return NULL; } if (strcmp(getType(definition), "primitive function type") != 0) { @@ -379,11 +393,11 @@ SymbolTable *init(SymbolTable *start) { "Cannot initialize a scope that is not the parent scope\n"); return NULL; } - integ = (TableNode *)calloc(1,sizeof(TableNode)); - addr = (TableNode *)calloc(1,sizeof(TableNode)); - chara = (TableNode *)calloc(1,sizeof(TableNode)); - stri = (TableNode *)calloc(1,sizeof(TableNode)); - boo = (TableNode *)calloc(1,sizeof(TableNode)); + integ = (TableNode *)calloc(1, sizeof(TableNode)); + addr = (TableNode *)calloc(1, sizeof(TableNode)); + chara = (TableNode *)calloc(1, sizeof(TableNode)); + stri = (TableNode *)calloc(1, sizeof(TableNode)); + boo = (TableNode *)calloc(1, sizeof(TableNode)); // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; @@ -450,7 +464,8 @@ SymbolTable *init(SymbolTable *start) { undefined->additionalinfo = NULL; undefined->next = NULL; - //Undefined_function_type_info = CreateFunctionTypeInfo(undefined, undefined); + // Undefined_function_type_info = CreateFunctionTypeInfo(undefined, + // undefined); integ->theType = prime; addr->theType = prime; @@ -487,67 +502,71 @@ TableNode* boo; TableNode* recprime; TableNode* funtypeprime; */ -TableNode* populateTypeAndInfo(TableNode* tn, TableNode* type, AdInfo* info){ - if(tn == NULL||tn==undefined){ - printf("passed in an invalid table node to modify (NULL or undefined).\n"); - return undefined; - } - if(type == NULL||type==undefined){ - printf("passed in a NULL or undefined type reference to populate a table node. Invalid.\n"); - return undefined; - } - if(info == NULL){ - printf("passed in a NULL info reference to populate a table node. Invalid.\n"); - return undefined; - } - tn->theType = type; - tn->additionalinfo = info; - //returning reference to modified table node - return tn; - } +TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { + if (tn == NULL || tn == undefined) { + printf("passed in an invalid table node to modify (NULL or " + "undefined).\n"); + return undefined; + } + if (type == NULL || type == undefined) { + printf("passed in a NULL or undefined type reference to " + "populate a table node. Invalid.\n"); + return undefined; + } + if (info == NULL) { + printf("passed in a NULL info reference to populate a table " + "node. Invalid.\n"); + return undefined; + } + tn->theType = type; + tn->additionalinfo = info; + // returning reference to modified table node + return tn; +} -int getAdInfoType(TableNode* tn){ - if(tn == NULL||tn==undefined){ - printf("passing in NULL or undefined table entry. Invalid\n"); - return -1; - } - if(tn->theType == NULL|| tn->theType == undefined){ - printf("Entry being passed in has a null or undefined reference for theType. Invalid.\n"); - return -1; - } - if(strcmp(getName(tn),getName(integ))==0){ - return TYPE_PRIMITIVE; - } - if(strcmp(getName(tn),getName(addr))==0){ +int getAdInfoType(TableNode *tn) { + if (tn == NULL || tn == undefined) { + printf("passing in NULL or undefined table entry. Invalid\n"); + return -1; + } + if (tn->theType == NULL || tn->theType == undefined) { + printf("Entry being passed in has a null or undefined " + "reference for theType. Invalid.\n"); + return -1; + } + if (strcmp(getName(tn), getName(integ)) == 0) { return TYPE_PRIMITIVE; } - if(strcmp(getName(tn),getName(chara))==0){ + if (strcmp(getName(tn), getName(addr)) == 0) { return TYPE_PRIMITIVE; } - if(strcmp(getName(tn),getName(stri))==0){ + if (strcmp(getName(tn), getName(chara)) == 0) { + return TYPE_PRIMITIVE; + } + if (strcmp(getName(tn), getName(stri)) == 0) { return TYPE_ARRAY; } - if(strcmp(getName(tn),getName(boo))==0){ + if (strcmp(getName(tn), getName(boo)) == 0) { return TYPE_PRIMITIVE; } - if(strcmp(getName(tn),getName(recprime))==0){ + if (strcmp(getName(tn), getName(recprime)) == 0) { return TYPE_RECORD; } - if(strcmp(getName(tn),getName(funtypeprime))==0){ + if (strcmp(getName(tn), getName(funtypeprime)) == 0) { return TYPE_FUNCTION_TYPE; } - if(strcmp(getName(tn),getName(arrayprim))==0){ + if (strcmp(getName(tn), getName(arrayprim)) == 0) { return TYPE_ARRAY; } - if(strcmp(getName(tn),getName(undefined))==0){ - return TYPE_UNDEFINED; - } - else{ + if (strcmp(getName(tn), getName(undefined)) == 0) { + return TYPE_UNDEFINED; + } else { return TYPE_FUNCTION_DECLARATION; } } -TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo *ad) { +TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, + AdInfo *ad) { if (table == NULL) { printf("Null reference to table"); @@ -561,11 +580,12 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo * return NULL; } */ - if (typeOf == NULL||typeOf == undefined) { - printf("This is not pointing to a proper definition (either NULL or undefined)\n"); + if (typeOf == NULL || typeOf == undefined) { + printf("This is not pointing to a proper definition (either " + "NULL or undefined)\n"); return undefined; } - TableNode *newEntry = (TableNode *)calloc(1,sizeof(TableNode)); + TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); newEntry->theType = typeOf /*topDef*/; newEntry->theName = id; newEntry->additionalinfo = ad; @@ -581,74 +601,85 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo * } char *getType(TableNode *tn) { - if(tn == NULL||tn==undefined){ - printf("passed a NULL or undefined table entry to getType\n"); - return getName(undefined); - } - if(tn->theType == NULL|| tn->theType == undefined){ - printf("type of entry is currently NULL or undefined type \n"); - return getName(undefined); - } - return tn->theType->theName; } - -char *getName(TableNode *tn) { - if(tn == NULL||tn==undefined){ - //printf("passed a NULL or undefined table entry to getName\n"); - return undefined->theName; + if (tn == NULL || tn == undefined) { + printf("passed a NULL or undefined table entry to getType\n"); + return getName(undefined); } - if(tn->theName == NULL){ - //printf("name of entry is currently NULL, undefined \n"); - return undefined->theName; + if (tn->theType == NULL || tn->theType == undefined) { + printf("type of entry is currently NULL or undefined type \n"); + return getName(undefined); } - return tn->theName; + return tn->theType->theName; } -int getLine(SymbolTable *st) { - if(st == NULL){ - printf("passed a NULL symbol table to getLine function. Invalid.\n"); +char *getName(TableNode *tn) { + if (tn == NULL || tn == undefined) { + // printf("passed a NULL or undefined table entry to + // getName\n"); + return undefined->theName; + } + if (tn->theName == NULL) { + // printf("name of entry is currently NULL, undefined \n"); + return undefined->theName; + } + return tn->theName; +} + +int getLine(SymbolTable *st) { + if (st == NULL) { + printf("passed a NULL symbol table to getLine function. " + "Invalid.\n"); return -1; } - return st->Line_Number; } -int getColumn(SymbolTable *st) { - if(st == NULL){ - printf("passed a NULL symbol table to getColumn function. Invalid.\n"); + return st->Line_Number; +} +int getColumn(SymbolTable *st) { + if (st == NULL) { + printf("passed a NULL symbol table to getColumn function. " + "Invalid.\n"); return -1; } - return st->Column_Number; } -TableNode* addName(TableNode *tn, char* str){ - if(tn == NULL||tn==undefined){ - printf("passed a Null or undefined table node to the addName function. Invalid./n"); - return undefined; - } - if(tn->theName != NULL){ - printf("Name doesn't look like it is empty before you change. Are you sure you need to update name?/n"); + return st->Column_Number; +} +TableNode *addName(TableNode *tn, char *str) { + if (tn == NULL || tn == undefined) { + printf("passed a Null or undefined table node to the addName " + "function. Invalid./n"); return undefined; - } - if(str == NULL){ - printf("passed a NULL string to the addName function. Invalid./n"); + } + if (tn->theName != NULL) { + printf("Name doesn't look like it is empty before you change. " + "Are you sure you need to update name?/n"); return undefined; - } + } + if (str == NULL) { + printf( + "passed a NULL string to the addName function. Invalid./n"); + return undefined; + } tn->theName = str; return tn; } -SymbolTable* setLineNumber(SymbolTable *st,int line){ - if(st == NULL){ - printf("passed a Null Symbol Table to the setLineNumber function. Invalid./n"); - return st; - } - st->Line_Number = line; - return st; - } - -SymbolTable* setColumnNumber(SymbolTable *st,int column){ - if(st == NULL){ - printf("passed a Null Symbol Table to the setColumnNumber function. Invalid./n"); +SymbolTable *setLineNumber(SymbolTable *st, int line) { + if (st == NULL) { + printf("passed a Null Symbol Table to the setLineNumber " + "function. Invalid./n"); return st; - } - st->Line_Number = column; - return st; } + st->Line_Number = line; + return st; +} + +SymbolTable *setColumnNumber(SymbolTable *st, int column) { + if (st == NULL) { + printf("passed a Null Symbol Table to the setColumnNumber " + "function. Invalid./n"); + return st; + } + st->Line_Number = column; + return st; +} /* //we use false for type defs and true for functions for parameter of typeOf TableNode* Define(SymbolTable* table, bool typeOf, char* id) { @@ -684,9 +715,9 @@ names\n"); return NULL; } */ -//only check table that is given +// only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { - if(table == NULL) { + if (table == NULL) { printf("passed in empty scope. error.\n"); return undefined; } @@ -698,23 +729,24 @@ TableNode *table_lookup(SymbolTable *table, char *x) { } return undefined; } -//check current table and all parents +// check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { - printf("passed in empty scope. error.\n"); + printf("passed in empty scope. error.\n"); return undefined; } TableNode *ret = table_lookup(table, x); if (ret != NULL && ret != undefined) { return ret; } - printf("could not find %s in scope that started at line %d and column %d so moving up a scope\n" - ,x,getLine(table),getColumn(table)); + printf("could not find %s in scope that started at line %d and column " + "%d so moving up a scope\n", + x, getLine(table), getColumn(table)); return look_up(table->Parent_Scope, x); } /* void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - + if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -767,7 +799,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } }*/ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - + if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); @@ -790,102 +822,127 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (;entrie != NULL; entrie = entrie->next) { - if (getAdInfoType(entrie) == TYPE_ARRAY){ - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : : %-21d -> %-21s: %-28s\n", - entrie->theName, current_scope, - entrie->additionalinfo->ArrayAdInfo->numofdimensions, - entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, - "Type of Array"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21d -> %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->additionalinfo->ArrayAdInfo->numofdimensions, - entrie->additionalinfo->ArrayAdInfo->typeofarray->theName, - "Type of Array"); - } - } - if (getAdInfoType(entrie) == TYPE_RECORD){ - if (parant_scope == 0) { + for (; entrie != NULL; entrie = entrie->next) { + if (getAdInfoType(entrie) == TYPE_ARRAY) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: elements-%-28d\n", - entrie->theName, current_scope, - "record", - entrie->additionalinfo->RecAdInfo->numofelements); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: elements-%-28d\n", - entrie->theName, current_scope, parant_scope, - "record", - entrie->additionalinfo->RecAdInfo->numofelements); + fprintf(file_ptr, + "%-17s: %06d : : %-21d -> " + "%-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->ArrayAdInfo + ->numofdimensions, + entrie->additionalinfo->ArrayAdInfo + ->typeofarray->theName, + "Type of Array"); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21d -> %-21s: " + "%-28s\n", + entrie->theName, current_scope, + parant_scope, + entrie->additionalinfo->ArrayAdInfo + ->numofdimensions, + entrie->additionalinfo->ArrayAdInfo + ->typeofarray->theName, + "Type of Array"); + } } - } - if (getAdInfoType(entrie) == TYPE_PRIMITIVE){ - if (parant_scope == 0) { + if (getAdInfoType(entrie) == TYPE_RECORD) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: size-%-28d bytes\n", - entrie->theName, current_scope, - "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: size-%-28d bytes\n", - entrie->theName, current_scope, parant_scope, - "Primitive", - entrie->additionalinfo->PrimAdInfo->size); + fprintf(file_ptr, + "%-17s: %06d : :%-21s: " + "elements-%-28d\n", + entrie->theName, current_scope, + "record", + entrie->additionalinfo->RecAdInfo + ->numofelements); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21s: " + "elements-%-28d\n", + entrie->theName, current_scope, + parant_scope, "record", + entrie->additionalinfo->RecAdInfo + ->numofelements); + } } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE){ - if (parant_scope == 0) { + if (getAdInfoType(entrie) == TYPE_PRIMITIVE) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : : %-21s -> %-21s: %-28s\n", - entrie->theName, current_scope, - entrie->additionalinfo->FunTypeAdInfo->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo->returntype->theName, - "Type of Function"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s -> %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->additionalinfo->FunTypeAdInfo->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo->returntype->theName, - "Type of Function"); + fprintf( + file_ptr, + "%-17s: %06d : :%-21s: size-%-28d " + "bytes\n", + entrie->theName, current_scope, "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } else { + fprintf( + file_ptr, + "%-17s: %06d : %06d : %-21s: size-%-28d " + "bytes\n", + entrie->theName, current_scope, + parant_scope, "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION){ - if (parant_scope == 0) { + if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", - entrie->theName, current_scope, - getType(entrie), - "Function"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - getType(entrie), - "Function"); + fprintf(file_ptr, + "%-17s: %06d : : %-21s -> " + "%-21s: %-28s\n", + entrie->theName, current_scope, + entrie->additionalinfo->FunTypeAdInfo + ->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo + ->returntype->theName, + "Type of Function"); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21s -> %-21s: " + "%-28s\n", + entrie->theName, current_scope, + parant_scope, + entrie->additionalinfo->FunTypeAdInfo + ->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo + ->returntype->theName, + "Type of Function"); + } } - } - if (getAdInfoType(entrie) == TYPE_UNDEFINED){ - if (parant_scope == 0) { + if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", - entrie->theName, current_scope, - "undefined", - "undefined entry"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - "undefined", - "undefined entry"); + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + getType(entrie), "Function"); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, + parant_scope, getType(entrie), + "Function"); + } + } + if (getAdInfoType(entrie) == TYPE_UNDEFINED) { + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-17s: %06d : :%-21s: %-28s\n", + entrie->theName, current_scope, + "undefined", "undefined entry"); + } else { + fprintf(file_ptr, + "%-17s: %06d : %06d : %-21s: %-28s\n", + entrie->theName, current_scope, + parant_scope, "undefined", + "undefined entry"); + } } } -} if (table->Children_Scope != NULL) { ListOfTable *node = table->Children_Scope; for (; node != NULL; node = node->next) { @@ -898,12 +955,12 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "----------------------\n"); } } -//get top most symbol table +// get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { - if(table == NULL){ - printf("passing a NULL reference to getAncestor. Invalid.\n"); - return NULL; - } + if (table == NULL) { + printf("passing a NULL reference to getAncestor. Invalid.\n"); + return NULL; + } if (table->Parent_Scope == NULL) { // if table has no parent, return itself return table; @@ -941,16 +998,17 @@ SymbolTable *removeEntry(SymbolTable *scope, char *search) { return scope; } -//almost certainly don't need to use the below function since type checking happens by passing types up the grammar +// almost certainly don't need to use the below function since type checking +// happens by passing types up the grammar bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); TableNode *entry2 = look_up(cur, secondID); - if (entry1 == NULL|| entry1 == undefined) { + if (entry1 == NULL || entry1 == undefined) { printf("first type not defined\n"); return false; } - if (entry2 == NULL|| entry2 == undefined) { + if (entry2 == NULL || entry2 == undefined) { printf("second type not defined\n"); return false; } @@ -1001,4 +1059,29 @@ TableNode *getNextEntry(TableNode *tn) { return tn->next; } printf("The type of the first entry is %s\n",First_Entry->theType); return 0; } - */ \ No newline at end of file + */ + +char *getLineStr(); +char *COLOR_RED = "\033[0;31m"; +char *COLOR_GREEN = "\033[0;32m"; +char *COLOR_ORANGE = "\033[0;33m"; +char *COLOR_BLUE = "\033[0;34m"; +char *COLOR_PURPLE = "\033[0;35m"; +char *COLOR_CYAN = "\033[0;36m"; +char *COLOR_LIGHTGRAY = "\033[0;37m"; +char *COLOR_DARKGRAY = "\033[1;30m"; +char *COLOR_LIGHTRED = "\033[1;31m"; +char *COLOR_LIGHTGREEN = "\033[1;32m"; +char *COLOR_YELLOW = "\033[1;33m"; +char *COLOR_LIGHTBLUE = "\033[1;34m"; +char *COLOR_LIGHTPURPLE = "\033[1;35m"; +char *COLOR_LIGHTCYAN = "\033[1;36m"; +char *COLOR_WHITE = "\033[1;37m"; + +bool DEBUG = false; + +char *getLineStr(int d) { + char *new_text = malloc(100); + sprintf(new_text, "%s[%d]%s ", COLOR_DARKGRAY, d, COLOR_WHITE); + return new_text; +} \ No newline at end of file diff --git a/test.sh b/test.sh index e35809e..9c32bed 100755 --- a/test.sh +++ b/test.sh @@ -48,7 +48,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -60,7 +60,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -72,7 +72,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -84,7 +84,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n${WHITE}" switchfunc fi @@ -106,7 +106,7 @@ else if [ -f "$1" ]; then filename=$(basename -- "$1") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$1" + ./alpha -st "$1" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}" exit 1 else @@ -121,7 +121,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -132,7 +132,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -143,7 +143,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -154,7 +154,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" + ./alpha -st "$file" -debug echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi diff --git a/tests/sprint2/sp2_function_types.alpha b/tests/sprint2/test/sp2_function_types.alpha similarity index 100% rename from tests/sprint2/sp2_function_types.alpha rename to tests/sprint2/test/sp2_function_types.alpha From be311c7418218c4f8ea8aa3c1ce7578b877d9251 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 31 Mar 2025 11:43:30 -0400 Subject: [PATCH 043/137] printdebug function with line and file names --- src/grammar.y | 114 ++++++++++---------- src/runner.c | 10 +- src/symbol_table.c | 263 +++++++++++++++++++++++++-------------------- 3 files changed, 206 insertions(+), 181 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 8ff8a8f..6421c42 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -27,7 +27,7 @@ extern TableNode* chara; extern TableNode* stri; extern TableNode* boo; - TableNode * tn; + TableNode * tn; %} //%define api.location.type {location_t} %locations @@ -122,29 +122,29 @@ prototype: definition: TYPE ID COLON { - printf("Currently see a record definition for %s\n", $2); + printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == NULL) { - printf("rec not found \n"); + printdebug("rec not found "); } }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); cur = getParent(cur);} | TYPE ID COLON C_INTEGER ARROW id_or_types - {printf("Currently see a array definition of name %s,storing type %s, of dimensions %d\n", + {printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, $6, $4); CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { - printf("Currently see a function type definition of name %s,parameter type %s, of return type %s\n", + printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, $4, $6); CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); } | ID { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == NULL) { - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); @@ -152,19 +152,19 @@ TYPE ID COLON { } cur = CreateScope(cur, 0, 0); } L_PAREN ID { - printf("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s\n", + printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4); CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); }R_PAREN ASSIGN sblock | ID { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == NULL) { - printf("null check\n"); + printdebug("null check"); } if (node == NULL) { - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); @@ -174,15 +174,15 @@ TYPE ID COLON { }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); if (parameter == NULL) { - printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function defined with as, but parameter is not a record at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(parameter) != TYPE_RECORD){ - printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column); + printdebug("function defined with as, but parameter is not a record at line %d, column %d", @1.first_line, @1.first_column); }else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ CreateEntry(cur, entry, NULL, NULL); } } - } idlist {printf("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d\n", + } idlist {printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$6);} R_PAREN ASSIGN sblock ; @@ -200,7 +200,7 @@ idlist: entry = getNextEntry(entry); } if (getNextEntry(entry) == NULL) { - printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); } addName(entry, $1); } COMMA idlist {$$ = $3 + 1;} @@ -211,7 +211,7 @@ idlist: entry = getNextEntry(entry); } if (getNextEntry(entry) != NULL) { - printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column); + printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); } addName(entry, $1); $$ = 1; @@ -222,7 +222,7 @@ idlist: sblock: L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock - {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE + {printdebug("seen sblock with dblock");} statement_list {cur = getParent(cur);} R_BRACE ; dblock: @@ -234,14 +234,14 @@ declaration_list: ; declaration: - id_or_types COLON ID {printf("ID/TYPE: %s, ID: %s\n", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } + id_or_types COLON ID {printdebug("ID/TYPE: %s, ID: %s", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } ; id_or_types: - ID {printf("string of id is %s in ID pattern of id_or_type rule.\n"); $$ = $1;} - //{printf("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.\n",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} - | types {printf("string of type is %s in types pattern of id_or_type rule.\n",$1);} {$$ = $1;} - //{printf("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.\n",$1);} {$$ = $1;} + ID {printdebug("string of id is %s in ID pattern of id_or_type rule."); $$ = $1;} + //{printdebug("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} + | types {printdebug("string of type is %s in types pattern of id_or_type rule.",$1);} {$$ = $1;} + //{printdebug("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.",$1);} {$$ = $1;} ; ; @@ -255,13 +255,13 @@ statement_list: compound_statement: WHILE L_PAREN expression R_PAREN sblock | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock - | sblock //{printf("seen a compound statement rule\n");} + | sblock //{printdebug("seen a compound statement rule");} ; simple_statement: assignable ASSIGN expression {if(strcmp($1, $3) == 0){ } else { - printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column); + printdebug("Mismatch at line %d and column%d", @2.first_line, @2.first_column); }} | RETURN expression @@ -278,77 +278,77 @@ rec_op : DOT expression: - constant {printf("constant expression\n");} {$$ = $1;} + constant {printdebug("constant expression");} {$$ = $1;} - | SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0) - {printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column); + | SUB_OR_NEG expression %prec UMINUS {printdebug("negative expression");if(strcmp($2,"integer") != 0) + {printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); $$=strdup("undefined");}else{$$=$2;}} - | NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); - printf("mismatch at line %d and column %d. Invalid type being negated is %s\n", + | NOT expression {printdebug("not expression"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,$2);}} | expression ADD expression - {printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("add expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression SUB_OR_NEG expression - {printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("sub or neg expression");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression MUL expression - {printf("multiply expression\n"); + {printdebug("multiply expression"); if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression DIV expression - {printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("divide expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression REM expression - {printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("remainder expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression AND expression - {printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + {printdebug("AND expression");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression OR expression - {printf("OR\n");if(strcmp($1,$3)==0 && + {printdebug("OR");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} | expression LESS_THAN expression - {printf("less than expression\n");if(strcmp($1,$3)==0 && + {printdebug("less than expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n", + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); $$=strdup("undefined");}} - | expression EQUAL_TO expression {printf("equals check expression\n"); + | expression EQUAL_TO expression {printdebug("equals check expression"); if(strcmp($1,$3)==0){$$=strdup("Boolean");} else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} - else{printf("mismatch at line %d and column %d. Invalid types %s and %s\n", + else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} - | assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;} + | assignable {printdebug("assignable expression. current type is %s",$1);$$=$1;} - | L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;} + | L_PAREN expression R_PAREN {printdebug("paren expression. current type is %s",$2);$$=$2;} | memOp assignable {$$ = strdup("address");} ; @@ -365,8 +365,8 @@ expression COMMA argument_list {$$ = $3 + 1;} memOp: - RESERVE {printf("reserve expression\n");} - | RELEASE {printf("release expression\n");} + RESERVE {printdebug("reserve expression");} + | RELEASE {printdebug("release expression");} ; @@ -381,15 +381,15 @@ constant: types: // Commented out T_String below - // T_STRING {printf("string of T_STRING in types is %s\n",$1);} {$$ = $1;} - T_INTEGER {printf("string of T_INTEGER in types is %s\n",$1);} {$$ = $1;} - | T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$1);} {$$ = $1;} - | T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$1);} {$$ = $1;} - | T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$1);} {$$ = $1;} + // T_STRING {printdebug("string of T_STRING in types is %s",$1);} {$$ = $1;} + T_INTEGER {printdebug("string of T_INTEGER in types is %s",$1);} {$$ = $1;} + | T_ADDRESS {printdebug("string of T_ADDRESS in types is %s",$1);} {$$ = $1;} + | T_CHARACTER {printdebug("string of T_CHARACTER in types is %s",$1);} {$$ = $1;} + | T_BOOLEAN {printdebug("string of T_BOOLEAN in types is %s",$1);} {$$ = $1;} ; %% void yyerror(const char *err) { - fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column); + fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column); } diff --git a/src/runner.c b/src/runner.c index a87b527..7c053a4 100644 --- a/src/runner.c +++ b/src/runner.c @@ -10,18 +10,18 @@ extern TableNode *chara; extern TableNode *stri; extern TableNode *boo; extern bool DEBUG; -extern char * COLOR_YELLOW; -extern char * COLOR_BLUE; -extern char * COLOR_WHITE; +extern char *COLOR_YELLOW; +extern char *COLOR_BLUE; +extern char *COLOR_WHITE; int main(int argc, char *argv[]) { - // if last argument is debug then set to true and ignore it for the rest of this file + // if last argument is debug then set to true and ignore it for the rest + // of this file if (argc > 1 && strcmp(argv[argc - 1], "-debug") == 0) { DEBUG = true; argc--; } - if (argc == 1) { fprintf(stderr, INVALID); return -1; diff --git a/src/symbol_table.c b/src/symbol_table.c index 8fa87d2..4531f1d 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -3,6 +3,7 @@ #include "symbol_table.h" +#include #include #include #include @@ -19,8 +20,43 @@ TableNode *boo; TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; -// AdInfo *Undefined_function_type_info; +char *COLOR_RED = "\033[0;31m"; +char *COLOR_GREEN = "\033[0;32m"; +char *COLOR_ORANGE = "\033[0;33m"; +char *COLOR_BLUE = "\033[0;34m"; +char *COLOR_PURPLE = "\033[0;35m"; +char *COLOR_CYAN = "\033[0;36m"; +char *COLOR_LIGHTGRAY = "\033[0;37m"; +char *COLOR_DARKGRAY = "\033[1;30m"; +char *COLOR_LIGHTRED = "\033[1;31m"; +char *COLOR_LIGHTGREEN = "\033[1;32m"; +char *COLOR_YELLOW = "\033[1;33m"; +char *COLOR_LIGHTBLUE = "\033[1;34m"; +char *COLOR_LIGHTPURPLE = "\033[1;35m"; +char *COLOR_LIGHTCYAN = "\033[1;36m"; +char *COLOR_WHITE = "\033[1;37m"; + +bool DEBUG = true; + +void printdebug_impl(char *file, int line, const char *format, ...); + +void printdebug_impl(char *file, int line, const char *format, ...) { + if (DEBUG) { + printf("%s<%s> [%d]%s ", COLOR_DARKGRAY, file, line, + COLOR_WHITE); + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); + } +} + +#define printdebug(format, ...) \ + printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) + +// AdInfo *Undefined_function_type_info; typedef enum { // First 4 below are primitive types that are all encapsulated in // primitive type @@ -107,16 +143,17 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf( - "passed an NULL entry to getPrimSize function. Invalid.\n"); + printdebug( + "passed an NULL entry to getPrimSize function. Invalid."); return -1; } if (definition->additionalinfo == NULL) { - printf("node has NULL additionalinfo. Invalid.\n"); + printdebug("node has NULL additionalinfo. Invalid."); return -1; } if (strcmp(getType(definition), "primitive") != 0) { - printf("not checking the size of a primitive -- invalid op\n"); + printdebug( + "not checking the size of a primitive -- invalid op"); return 0; } return definition->additionalinfo->PrimAdInfo->size; @@ -136,8 +173,8 @@ int getPrimSize(TableNode *definition) { // calculated at runtime so bounds checking only needs to be done then AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { if (type == NULL || type == undefined) { - printf("passed a NULL or undefined type reference to " - "CreateArrayInfo. Invalid.\n"); + printdebug("passed a NULL or undefined type reference to " + "CreateArrayInfo. Invalid."); return NULL; } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); @@ -151,12 +188,12 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getNumArrDim " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getNumArrDim " + "function. Invalid."); return -1; } if (strcmp(getType(definition), "array") != 0) { - printf("not checking the dim of an array -- invalid op\n"); + printdebug("not checking the dim of an array -- invalid op"); return 0; } return definition->additionalinfo->ArrayAdInfo->numofdimensions; @@ -165,12 +202,12 @@ int getNumArrDim(TableNode *definition) { // the entry of that type TableNode *getArrType(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getArrType " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getArrType " + "function. Invalid."); return NULL; } if (strcmp(getType(definition), "array") != 0) { - printf("not checking the type of an array -- invalid op\n"); + printdebug("not checking the type of an array -- invalid op"); return undefined; } return definition->additionalinfo->ArrayAdInfo->typeofarray; @@ -193,12 +230,13 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // anyways. int getRecLength(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getRecLength " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getRecLength " + "function. Invalid."); return -1; } if (strcmp(getType(definition), "record") != 0) { - printf("not checking the length of an record -- invalid op\n"); + printdebug( + "not checking the length of an record -- invalid op"); return 0; } return definition->additionalinfo->RecAdInfo->numofelements; @@ -206,13 +244,14 @@ int getRecLength(TableNode *definition) { // This gets the array. Needs to up be updated to get the scope instead SymbolTable *getRecList(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getRecList " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getRecList " + "function. Invalid."); return NULL; } if (strcmp(getType(definition), "record") != 0) { - printf("not checking the list of types of a record -- invalid " - "op\n"); + printdebug( + "not checking the list of types of a record -- invalid " + "op"); return NULL; } return definition->additionalinfo->RecAdInfo->recordScope; @@ -220,7 +259,7 @@ SymbolTable *getRecList(TableNode *definition) { TableNode *setRecSize(TableNode *tn, int n) { if (tn == NULL || tn == undefined) { - printf("passed in NULL entry for setRecSize. Invalid\n"); + printdebug("passed in NULL entry for setRecSize. Invalid"); return undefined; } tn->additionalinfo->RecAdInfo->numofelements = n; @@ -229,7 +268,8 @@ TableNode *setRecSize(TableNode *tn, int n) { int getRecSize(SymbolTable *tn) { if (tn == NULL) { - printf("passed in NULL SymbolTable for getRecSize. Invalid\n"); + printdebug( + "passed in NULL SymbolTable for getRecSize. Invalid"); return -1; } int s = 0; @@ -261,13 +301,14 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // out in table if needed) int getStartLine(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getStartLine " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getStartLine " + "function. Invalid."); return -1; } if (strcmp(getType(definition), "primitive function") != 0) { - printf("not checking the start line of a function -- invalid " - "op\n"); + printdebug( + "not checking the start line of a function -- invalid " + "op"); return 0; } return definition->additionalinfo->FunDecAdInfo->startlinenumber; @@ -275,8 +316,9 @@ int getStartLine(TableNode *definition) { TableNode *setStartLine(TableNode *tn, int start) { if (tn == NULL || tn == undefined) { - printf("passing in a NULL or undefined entry to setStartLine. " - "invalid\n"); + printdebug( + "passing in a NULL or undefined entry to setStartLine. " + "invalid"); return undefined; } tn->additionalinfo->FunDecAdInfo->startlinenumber = start; @@ -286,13 +328,14 @@ TableNode *setStartLine(TableNode *tn, int start) { // not used or used. bool getAsKeyword(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getAsKeyword " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getAsKeyword " + "function. Invalid."); return false; } if (strcmp(getType(definition), "primitive function") != 0) { - printf("not checking if a function is called with as or not -- " - "invalid op\n"); + printdebug( + "not checking if a function is called with as or not -- " + "invalid op"); return 0; } return definition->additionalinfo->FunDecAdInfo->regularoras; @@ -300,8 +343,9 @@ bool getAsKeyword(TableNode *definition) { TableNode *setAsKeyword(TableNode *tn, bool as) { if (tn == NULL || tn == undefined) { - printf("passing in a NULL or undefined entry to setAsKeyword. " - "invalid\n"); + printdebug( + "passing in a NULL or undefined entry to setAsKeyword. " + "invalid"); return undefined; } tn->additionalinfo->FunDecAdInfo->regularoras = as; @@ -311,13 +355,13 @@ TableNode *setAsKeyword(TableNode *tn, bool as) { // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { if (parameter == NULL || parameter == undefined) { - printf("passed a NULL or undefined parameter to " - "CreateFunctionTypeInfo. Invalid.\n"); + printdebug("passed a NULL or undefined parameter to " + "CreateFunctionTypeInfo. Invalid."); return NULL; } if (returntype == NULL || returntype == undefined) { - printf("passed a NULL or undefined return type to " - "CreateFunctionTypeInfo. Invalid.\n"); + printdebug("passed a NULL or undefined return type to " + "CreateFunctionTypeInfo. Invalid."); return NULL; } AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); @@ -330,13 +374,13 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { // returns parameter type of a function TableNode *getParameter(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getParameter " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getParameter " + "function. Invalid."); return undefined; } if (strcmp(getType(definition), "primitive function type") != 0) { - printf( - "not checking the parameter of a function -- invalid op\n"); + printdebug( + "not checking the parameter of a function -- invalid op"); return undefined; } return definition->additionalinfo->FunTypeAdInfo->parameter; @@ -344,12 +388,13 @@ TableNode *getParameter(TableNode *definition) { // returns return type of a function TableNode *getReturn(TableNode *definition) { if (definition == NULL || definition == undefined) { - printf("passed an NULL or undefined entry to getReturn " - "function. Invalid.\n"); + printdebug("passed an NULL or undefined entry to getReturn " + "function. Invalid."); return NULL; } if (strcmp(getType(definition), "primitive function type") != 0) { - printf("not checking the return of a function -- invalid op\n"); + printdebug( + "not checking the return of a function -- invalid op"); return undefined; } return definition->additionalinfo->FunTypeAdInfo->returntype; @@ -389,8 +434,8 @@ SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) { // types SymbolTable *init(SymbolTable *start) { if (start->Parent_Scope != NULL) { - printf( - "Cannot initialize a scope that is not the parent scope\n"); + printdebug( + "Cannot initialize a scope that is not the parent scope"); return NULL; } integ = (TableNode *)calloc(1, sizeof(TableNode)); @@ -504,18 +549,19 @@ TableNode* funtypeprime; */ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { if (tn == NULL || tn == undefined) { - printf("passed in an invalid table node to modify (NULL or " - "undefined).\n"); + printdebug("passed in an invalid table node to modify (NULL or " + "undefined)."); return undefined; } if (type == NULL || type == undefined) { - printf("passed in a NULL or undefined type reference to " - "populate a table node. Invalid.\n"); + printdebug("passed in a NULL or undefined type reference to " + "populate a table node. Invalid."); return undefined; } if (info == NULL) { - printf("passed in a NULL info reference to populate a table " - "node. Invalid.\n"); + printdebug( + "passed in a NULL info reference to populate a table " + "node. Invalid."); return undefined; } tn->theType = type; @@ -526,12 +572,12 @@ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { int getAdInfoType(TableNode *tn) { if (tn == NULL || tn == undefined) { - printf("passing in NULL or undefined table entry. Invalid\n"); + printdebug("passing in NULL or undefined table entry. Invalid"); return -1; } if (tn->theType == NULL || tn->theType == undefined) { - printf("Entry being passed in has a null or undefined " - "reference for theType. Invalid.\n"); + printdebug("Entry being passed in has a null or undefined " + "reference for theType. Invalid."); return -1; } if (strcmp(getName(tn), getName(integ)) == 0) { @@ -569,20 +615,21 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, AdInfo *ad) { if (table == NULL) { - printf("Null reference to table"); + printdebug("Null reference to table"); return undefined; } /* TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); if(topDef == NULL){ - printf("This type is not defined at the top level\n"); + printdebug("This type is not defined at the top level"); return NULL; } */ if (typeOf == NULL || typeOf == undefined) { - printf("This is not pointing to a proper definition (either " - "NULL or undefined)\n"); + printdebug( + "This is not pointing to a proper definition (either " + "NULL or undefined)"); return undefined; } TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); @@ -602,11 +649,11 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, char *getType(TableNode *tn) { if (tn == NULL || tn == undefined) { - printf("passed a NULL or undefined table entry to getType\n"); + printdebug("passed a NULL or undefined table entry to getType"); return getName(undefined); } if (tn->theType == NULL || tn->theType == undefined) { - printf("type of entry is currently NULL or undefined type \n"); + printdebug("type of entry is currently NULL or undefined type"); return getName(undefined); } return tn->theType->theName; @@ -614,12 +661,12 @@ char *getType(TableNode *tn) { char *getName(TableNode *tn) { if (tn == NULL || tn == undefined) { - // printf("passed a NULL or undefined table entry to - // getName\n"); + // printdebug("passed a NULL or undefined table entry to + // getName"); return undefined->theName; } if (tn->theName == NULL) { - // printf("name of entry is currently NULL, undefined \n"); + // printdebug("name of entry is currently NULL, undefined"); return undefined->theName; } return tn->theName; @@ -627,34 +674,36 @@ char *getName(TableNode *tn) { int getLine(SymbolTable *st) { if (st == NULL) { - printf("passed a NULL symbol table to getLine function. " - "Invalid.\n"); + printdebug("passed a NULL symbol table to getLine function. " + "Invalid."); return -1; } return st->Line_Number; } int getColumn(SymbolTable *st) { if (st == NULL) { - printf("passed a NULL symbol table to getColumn function. " - "Invalid.\n"); + printdebug("passed a NULL symbol table to getColumn function. " + "Invalid."); return -1; } return st->Column_Number; } TableNode *addName(TableNode *tn, char *str) { if (tn == NULL || tn == undefined) { - printf("passed a Null or undefined table node to the addName " - "function. Invalid./n"); + printdebug( + "passed a Null or undefined table node to the addName " + "function. Invalid."); return undefined; } if (tn->theName != NULL) { - printf("Name doesn't look like it is empty before you change. " - "Are you sure you need to update name?/n"); + printdebug( + "Name doesn't look like it is empty before you change. " + "Are you sure you need to update name?"); return undefined; } if (str == NULL) { - printf( - "passed a NULL string to the addName function. Invalid./n"); + printdebug( + "passed a NULL string to the addName function. Invalid."); return undefined; } tn->theName = str; @@ -663,8 +712,8 @@ TableNode *addName(TableNode *tn, char *str) { SymbolTable *setLineNumber(SymbolTable *st, int line) { if (st == NULL) { - printf("passed a Null Symbol Table to the setLineNumber " - "function. Invalid./n"); + printdebug("passed a Null Symbol Table to the setLineNumber " + "function. Invalid."); return st; } st->Line_Number = line; @@ -673,8 +722,8 @@ SymbolTable *setLineNumber(SymbolTable *st, int line) { SymbolTable *setColumnNumber(SymbolTable *st, int column) { if (st == NULL) { - printf("passed a Null Symbol Table to the setColumnNumber " - "function. Invalid./n"); + printdebug("passed a Null Symbol Table to the setColumnNumber " + "function. Invalid."); return st; } st->Line_Number = column; @@ -684,7 +733,7 @@ SymbolTable *setColumnNumber(SymbolTable *st, int column) { //we use false for type defs and true for functions for parameter of typeOf TableNode* Define(SymbolTable* table, bool typeOf, char* id) { if(table ==NULL || table->Parent_Scope != NULL){ - printf("No valid table given for header defs\n"); + printdebug("No valid table given for header defs"); return NULL; } @@ -699,8 +748,8 @@ if (typeOf == 1){ newEntry->theType = funy; } if(table_lookup(table,id) != NULL){ - printf("already defined at the top level, can't define duplicate -names\n"); return NULL; + printdebug("already defined at the top level, can't define duplicate +names"); return NULL; } newEntry->theName = id; if (table->entries == NULL) { @@ -718,7 +767,7 @@ names\n"); return NULL; // only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { if (table == NULL) { - printf("passed in empty scope. error.\n"); + printdebug("passed in empty scope. error."); return undefined; } TableNode *entrie = table->entries; @@ -732,16 +781,17 @@ TableNode *table_lookup(SymbolTable *table, char *x) { // check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { - printf("passed in empty scope. error.\n"); + printdebug("passed in empty scope. error."); return undefined; } TableNode *ret = table_lookup(table, x); if (ret != NULL && ret != undefined) { return ret; } - printf("could not find %s in scope that started at line %d and column " - "%d so moving up a scope\n", - x, getLine(table), getColumn(table)); + printdebug( + "could not find %s in scope that started at line %d and column " + "%d so moving up a scope", + x, getLine(table), getColumn(table)); return look_up(table->Parent_Scope, x); } /* @@ -958,7 +1008,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { // get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { if (table == NULL) { - printf("passing a NULL reference to getAncestor. Invalid.\n"); + printdebug("passing a NULL reference to getAncestor. Invalid."); return NULL; } if (table->Parent_Scope == NULL) { @@ -1005,11 +1055,11 @@ bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); TableNode *entry2 = look_up(cur, secondID); if (entry1 == NULL || entry1 == undefined) { - printf("first type not defined\n"); + printdebug("first type not defined"); return false; } if (entry2 == NULL || entry2 == undefined) { - printf("second type not defined\n"); + printdebug("second type not defined"); return false; } if (table_lookup(getAncestor(cur), getType(look_up(cur, firstID))) == @@ -1052,36 +1102,11 @@ TableNode *getNextEntry(TableNode *tn) { return tn->next; } char* String = "STRING"; char* X = "X"; SymbolTable* Second = CreateScope(NULL, 2,2); - printf("Line number is %d, Column number of scope is - %d\n",Second->Line_Number,Second->Column_Number); TableNode* First_Entry = + printdebug("Line number is %d, Column number of scope is + %d",Second->Line_Number,Second->Column_Number); TableNode* First_Entry = CreateEntry(Second,String,X); - printf("The type of the first entry is %s\n",First_Entry->theType); + printdebug("The type of the first entry is %s",First_Entry->theType); return 0; } - */ - -char *getLineStr(); -char *COLOR_RED = "\033[0;31m"; -char *COLOR_GREEN = "\033[0;32m"; -char *COLOR_ORANGE = "\033[0;33m"; -char *COLOR_BLUE = "\033[0;34m"; -char *COLOR_PURPLE = "\033[0;35m"; -char *COLOR_CYAN = "\033[0;36m"; -char *COLOR_LIGHTGRAY = "\033[0;37m"; -char *COLOR_DARKGRAY = "\033[1;30m"; -char *COLOR_LIGHTRED = "\033[1;31m"; -char *COLOR_LIGHTGREEN = "\033[1;32m"; -char *COLOR_YELLOW = "\033[1;33m"; -char *COLOR_LIGHTBLUE = "\033[1;34m"; -char *COLOR_LIGHTPURPLE = "\033[1;35m"; -char *COLOR_LIGHTCYAN = "\033[1;36m"; -char *COLOR_WHITE = "\033[1;37m"; - -bool DEBUG = false; - -char *getLineStr(int d) { - char *new_text = malloc(100); - sprintf(new_text, "%s[%d]%s ", COLOR_DARKGRAY, d, COLOR_WHITE); - return new_text; -} \ No newline at end of file + */ \ No newline at end of file From 0593673d89c0419be1e2843d4ee3e17c6fb39c08 Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 31 Mar 2025 12:32:36 -0400 Subject: [PATCH 044/137] fixed the NULL checks for the incorrect ORs --- src/grammar.y | 2 +- src/symbol_table.c | 237 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 183 insertions(+), 56 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 6421c42..b44f502 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -124,7 +124,7 @@ definition: TYPE ID COLON { printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); - if (table_lookup(getAncestor(cur), $2) == NULL) { + if (table_lookup(getAncestor(cur), $2) == undefined) { printdebug("rec not found "); } }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); diff --git a/src/symbol_table.c b/src/symbol_table.c index 4531f1d..e1efdfb 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -37,7 +37,7 @@ char *COLOR_LIGHTPURPLE = "\033[1;35m"; char *COLOR_LIGHTCYAN = "\033[1;36m"; char *COLOR_WHITE = "\033[1;37m"; -bool DEBUG = true; +bool DEBUG = false; void printdebug_impl(char *file, int line, const char *format, ...); @@ -142,11 +142,16 @@ AdInfo *CreatePrimitiveInfo(int size) { // only gets the size of a primitive type int getPrimSize(TableNode *definition) { - if (definition == NULL || definition == undefined) { + if (definition == NULL) { printdebug( "passed an NULL entry to getPrimSize function. Invalid."); return -1; } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getPrimSize function. Invalid."); + return -1; + } if (definition->additionalinfo == NULL) { printdebug("node has NULL additionalinfo. Invalid."); return -1; @@ -172,8 +177,18 @@ int getPrimSize(TableNode *definition) { // type stored in the array per professor, the actual size of the array is // calculated at runtime so bounds checking only needs to be done then AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { - if (type == NULL || type == undefined) { - printdebug("passed a NULL or undefined type reference to " + if (type == NULL) { + printdebug("passed a NULL reference to " + "CreateArrayInfo. Invalid."); + return NULL; + } + if (type == undefined) { + printdebug("passed an undefined reference to " + "CreateArrayInfo. Invalid."); + return NULL; + } + if (type == undefined) { + printdebug("passed a undefined type reference to " "CreateArrayInfo. Invalid."); return NULL; } @@ -187,8 +202,13 @@ AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { } // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getNumArrDim " + if (definition == NULL) { + printdebug("passed an NULL entry to getNumArrDim " + "function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getNumArrDim " "function. Invalid."); return -1; } @@ -201,8 +221,13 @@ int getNumArrDim(TableNode *definition) { // This gets the type stored in an array from arrtype. It returns a reference to // the entry of that type TableNode *getArrType(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getArrType " + if (definition == NULL) { + printdebug("passed an NULL entry to getArrType " + "function. Invalid."); + return NULL; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getArrType " "function. Invalid."); return NULL; } @@ -229,8 +254,13 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // Perhaps this may not be needed since we need to iterate over all elements // anyways. int getRecLength(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getRecLength " + if (definition == NULL) { + printdebug("passed an NULL entry to getRecLength " + "function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getRecLength " "function. Invalid."); return -1; } @@ -243,8 +273,13 @@ int getRecLength(TableNode *definition) { } // This gets the array. Needs to up be updated to get the scope instead SymbolTable *getRecList(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getRecList " + if (definition == NULL) { + printdebug("passed a NULL entry to getRecList " + "function. Invalid."); + return NULL; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getRecList " "function. Invalid."); return NULL; } @@ -258,10 +293,14 @@ SymbolTable *getRecList(TableNode *definition) { } TableNode *setRecSize(TableNode *tn, int n) { - if (tn == NULL || tn == undefined) { + if (tn == NULL) { printdebug("passed in NULL entry for setRecSize. Invalid"); return undefined; } + if (tn == undefined) { + printdebug("passed in undefined entry for setRecSize. Invalid"); + return undefined; + } tn->additionalinfo->RecAdInfo->numofelements = n; return tn; } @@ -300,8 +339,13 @@ AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { // gets the line at which the function was first defined. (Can be used to print // out in table if needed) int getStartLine(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getStartLine " + if (definition == NULL) { + printdebug("passed a NULL entry to getStartLine " + "function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getStartLine " "function. Invalid."); return -1; } @@ -315,9 +359,15 @@ int getStartLine(TableNode *definition) { } TableNode *setStartLine(TableNode *tn, int start) { - if (tn == NULL || tn == undefined) { + if (tn == NULL) { printdebug( - "passing in a NULL or undefined entry to setStartLine. " + "passing in a NULL entry to setStartLine. " + "invalid"); + return undefined; + } + if (tn == undefined) { + printdebug( + "passing in an undefined entry to setStartLine. " "invalid"); return undefined; } @@ -327,8 +377,13 @@ TableNode *setStartLine(TableNode *tn, int start) { // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getAsKeyword " + if (definition == NULL) { + printdebug("passed a NULL entry to getAsKeyword " + "function. Invalid."); + return false; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getAsKeyword " "function. Invalid."); return false; } @@ -342,9 +397,15 @@ bool getAsKeyword(TableNode *definition) { } TableNode *setAsKeyword(TableNode *tn, bool as) { - if (tn == NULL || tn == undefined) { + if (tn == NULL) { printdebug( - "passing in a NULL or undefined entry to setAsKeyword. " + "passing in a NULL entry to setAsKeyword. " + "invalid"); + return undefined; + } + if (tn == undefined) { + printdebug( + "passing in an undefined entry to setAsKeyword. " "invalid"); return undefined; } @@ -354,13 +415,23 @@ TableNode *setAsKeyword(TableNode *tn, bool as) { // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { - if (parameter == NULL || parameter == undefined) { - printdebug("passed a NULL or undefined parameter to " + if (parameter == NULL) { + printdebug("passed a NULL parameter to " "CreateFunctionTypeInfo. Invalid."); return NULL; } - if (returntype == NULL || returntype == undefined) { - printdebug("passed a NULL or undefined return type to " + if (parameter == undefined) { + printdebug("passed an undefined parameter to " + "CreateFunctionTypeInfo. Invalid."); + return NULL; + } + if (returntype == NULL) { + printdebug("passed a NULL return type to " + "CreateFunctionTypeInfo. Invalid."); + return NULL; + } + if (returntype == undefined) { + printdebug("passed an undefined return type to " "CreateFunctionTypeInfo. Invalid."); return NULL; } @@ -373,8 +444,13 @@ AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { } // returns parameter type of a function TableNode *getParameter(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getParameter " + if (definition == NULL) { + printdebug("passed a NULL entry to getParameter " + "function. Invalid."); + return undefined; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getParameter " "function. Invalid."); return undefined; } @@ -387,8 +463,13 @@ TableNode *getParameter(TableNode *definition) { } // returns return type of a function TableNode *getReturn(TableNode *definition) { - if (definition == NULL || definition == undefined) { - printdebug("passed an NULL or undefined entry to getReturn " + if (definition == NULL) { + printdebug("passed a NULL entry to getReturn " + "function. Invalid."); + return NULL; + } + if (definition == undefined) { + printdebug("passed an undefined entry to getReturn " "function. Invalid."); return NULL; } @@ -548,13 +629,21 @@ TableNode* recprime; TableNode* funtypeprime; */ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { - if (tn == NULL || tn == undefined) { - printdebug("passed in an invalid table node to modify (NULL or " - "undefined)."); + if (tn == NULL) { + printdebug("passed in an NULL table node to populateTypeAndInfo."); return undefined; } - if (type == NULL || type == undefined) { - printdebug("passed in a NULL or undefined type reference to " + if (tn == undefined) { + printdebug("passed in an undefined table node to populateTypeAndInfo"); + return undefined; + } + if (type == NULL) { + printdebug("passed in a NULL type reference to " + "populate a table node. Invalid."); + return undefined; + } + if (type == undefined) { + printdebug("passed in an undefined type reference to " "populate a table node. Invalid."); return undefined; } @@ -571,13 +660,22 @@ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { } int getAdInfoType(TableNode *tn) { - if (tn == NULL || tn == undefined) { - printdebug("passing in NULL or undefined table entry. Invalid"); + if (tn == NULL) { + printdebug("passing in NULL table entry to getAdInfoType. Invalid"); return -1; } - if (tn->theType == NULL || tn->theType == undefined) { - printdebug("Entry being passed in has a null or undefined " - "reference for theType. Invalid."); + if (tn == undefined) { + printdebug("passing in undefined table entry to getAdInfoType. Invalid"); + return -1; + } + if (tn->theType == NULL) { + printdebug("Entry being passed in has a null" + "reference for theType to getAdInfoType. Invalid."); + return -1; + } + if (tn->theType == undefined) { + printdebug("Entry being passed in an undefined " + "reference for theType to getAdInfoType. Invalid."); return -1; } if (strcmp(getName(tn), getName(integ)) == 0) { @@ -626,10 +724,14 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, return NULL; } */ - if (typeOf == NULL || typeOf == undefined) { + if (typeOf == NULL) { printdebug( - "This is not pointing to a proper definition (either " - "NULL or undefined)"); + "Passing an NULL Type Node to Create Entry"); + return undefined; + } + if (typeOf == undefined) { + printdebug( + "Passing an undefined Type Node to Create Entry"); return undefined; } TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); @@ -648,21 +750,32 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } char *getType(TableNode *tn) { - if (tn == NULL || tn == undefined) { - printdebug("passed a NULL or undefined table entry to getType"); + if (tn == NULL) { + printdebug("passed a NULL table entry to getType"); return getName(undefined); } - if (tn->theType == NULL || tn->theType == undefined) { - printdebug("type of entry is currently NULL or undefined type"); + if (tn == undefined) { + printdebug("passed an undefined table entry to getType"); + return getName(undefined); + } + if (tn->theType == NULL) { + printdebug("type of entry is currently NULL type"); + return getName(undefined); + } + if (tn->theType == undefined) { + printdebug("type of entry is currently undefined type"); return getName(undefined); } return tn->theType->theName; } char *getName(TableNode *tn) { - if (tn == NULL || tn == undefined) { - // printdebug("passed a NULL or undefined table entry to - // getName"); + if (tn == NULL) { + printdebug("passed a NULL table entry to getName"); + return undefined->theName; + } + if (tn == undefined) { + printdebug("passed an undefined table entry to getName"); return undefined->theName; } if (tn->theName == NULL) { @@ -689,9 +802,15 @@ int getColumn(SymbolTable *st) { return st->Column_Number; } TableNode *addName(TableNode *tn, char *str) { - if (tn == NULL || tn == undefined) { + if (tn == NULL) { printdebug( - "passed a Null or undefined table node to the addName " + "passed a Null table node to the addName " + "function. Invalid."); + return undefined; + } + if (tn == undefined) { + printdebug( + "passed an undefined table node to the addName " "function. Invalid."); return undefined; } @@ -1054,12 +1173,20 @@ bool typeCheck(char *firstID, char *secondID) { TableNode *entry1 = look_up(cur, firstID); TableNode *entry2 = look_up(cur, secondID); - if (entry1 == NULL || entry1 == undefined) { - printdebug("first type not defined"); + if (entry1 == NULL) { + printdebug("first type is NULL in type check. Invalid."); return false; } - if (entry2 == NULL || entry2 == undefined) { - printdebug("second type not defined"); + if (entry1 == undefined) { + printdebug("first type is undefined in type check. Invalid."); + return false; + } + if (entry2 == NULL) { + printdebug("second type is NULL in type check. Invalid."); + return false; + } + if (entry2 == undefined) { + printdebug("second type is undefined in type check. Invalid."); return false; } if (table_lookup(getAncestor(cur), getType(look_up(cur, firstID))) == From 188c7344655ea4d9495004e9eb848a1e8e6eaca6 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 31 Mar 2025 17:38:37 -0400 Subject: [PATCH 045/137] small changes, segfault issue found --- src/grammar.y | 4 +-- src/symbol_table.c | 63 ++++++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index b44f502..94fd0a9 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -121,7 +121,7 @@ prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; definition: -TYPE ID COLON { + TYPE ID COLON { printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == undefined) { @@ -238,7 +238,7 @@ declaration: ; id_or_types: - ID {printdebug("string of id is %s in ID pattern of id_or_type rule."); $$ = $1;} + ID {printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;} //{printdebug("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} | types {printdebug("string of type is %s in types pattern of id_or_type rule.",$1);} {$$ = $1;} //{printdebug("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.",$1);} {$$ = $1;} diff --git a/src/symbol_table.c b/src/symbol_table.c index e1efdfb..6421002 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -148,8 +148,8 @@ int getPrimSize(TableNode *definition) { return -1; } if (definition == undefined) { - printdebug( - "passed an undefined entry to getPrimSize function. Invalid."); + printdebug("passed an undefined entry to getPrimSize function. " + "Invalid."); return -1; } if (definition->additionalinfo == NULL) { @@ -360,15 +360,13 @@ int getStartLine(TableNode *definition) { TableNode *setStartLine(TableNode *tn, int start) { if (tn == NULL) { - printdebug( - "passing in a NULL entry to setStartLine. " - "invalid"); + printdebug("passing in a NULL entry to setStartLine. " + "invalid"); return undefined; } if (tn == undefined) { - printdebug( - "passing in an undefined entry to setStartLine. " - "invalid"); + printdebug("passing in an undefined entry to setStartLine. " + "invalid"); return undefined; } tn->additionalinfo->FunDecAdInfo->startlinenumber = start; @@ -398,15 +396,13 @@ bool getAsKeyword(TableNode *definition) { TableNode *setAsKeyword(TableNode *tn, bool as) { if (tn == NULL) { - printdebug( - "passing in a NULL entry to setAsKeyword. " - "invalid"); + printdebug("passing in a NULL entry to setAsKeyword. " + "invalid"); return undefined; } if (tn == undefined) { - printdebug( - "passing in an undefined entry to setAsKeyword. " - "invalid"); + printdebug("passing in an undefined entry to setAsKeyword. " + "invalid"); return undefined; } tn->additionalinfo->FunDecAdInfo->regularoras = as; @@ -630,11 +626,13 @@ TableNode* funtypeprime; */ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { if (tn == NULL) { - printdebug("passed in an NULL table node to populateTypeAndInfo."); + printdebug( + "passed in an NULL table node to populateTypeAndInfo."); return undefined; } if (tn == undefined) { - printdebug("passed in an undefined table node to populateTypeAndInfo"); + printdebug( + "passed in an undefined table node to populateTypeAndInfo"); return undefined; } if (type == NULL) { @@ -661,11 +659,13 @@ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { int getAdInfoType(TableNode *tn) { if (tn == NULL) { - printdebug("passing in NULL table entry to getAdInfoType. Invalid"); + printdebug( + "passing in NULL table entry to getAdInfoType. Invalid"); return -1; } if (tn == undefined) { - printdebug("passing in undefined table entry to getAdInfoType. Invalid"); + printdebug("passing in undefined table entry to getAdInfoType. " + "Invalid"); return -1; } if (tn->theType == NULL) { @@ -725,26 +725,27 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } */ if (typeOf == NULL) { - printdebug( - "Passing an NULL Type Node to Create Entry"); + printdebug("Passing an NULL Type Node to Create Entry"); return undefined; } if (typeOf == undefined) { - printdebug( - "Passing an undefined Type Node to Create Entry"); + printdebug("Passing an undefined Type Node to Create Entry"); return undefined; } + TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); newEntry->theType = typeOf /*topDef*/; newEntry->theName = id; newEntry->additionalinfo = ad; if (table->entries == NULL) { table->entries = newEntry; + printdebug("[CreateEntry] Adding %s to the symbol table", id); return newEntry; } else { TableNode *oldEntry = table->entries; table->entries = newEntry; newEntry->next = oldEntry; + printdebug("[CreateEntry] Adding %s to the symbol table", id); return newEntry; } } @@ -779,7 +780,7 @@ char *getName(TableNode *tn) { return undefined->theName; } if (tn->theName == NULL) { - // printdebug("name of entry is currently NULL, undefined"); + printdebug("name of entry is currently NULL, undefined"); return undefined->theName; } return tn->theName; @@ -803,15 +804,13 @@ int getColumn(SymbolTable *st) { } TableNode *addName(TableNode *tn, char *str) { if (tn == NULL) { - printdebug( - "passed a Null table node to the addName " - "function. Invalid."); + printdebug("passed a Null table node to the addName " + "function. Invalid."); return undefined; } if (tn == undefined) { - printdebug( - "passed an undefined table node to the addName " - "function. Invalid."); + printdebug("passed an undefined table node to the addName " + "function. Invalid."); return undefined; } if (tn->theName != NULL) { @@ -1220,7 +1219,11 @@ ListOfTable *getChildren(SymbolTable *st) { return st->Children_Scope; } SymbolTable *getFirstChild(ListOfTable *lt) { return lt->table; } ListOfTable *getRestOfChildren(ListOfTable *lt) { return lt->next; } TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } -TableNode *getNextEntry(TableNode *tn) { return tn->next; } + +// Segfaults when passed an invalid table node! +TableNode *getNextEntry(TableNode *tn) { return tn; } + + // uncomment the below main function along with the headers above for a simple // standalone test of table and entry creation From c61a87634c452ae09aef3a1b68b50f404cdab3ed Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 31 Mar 2025 20:31:53 -0400 Subject: [PATCH 046/137] fixed NULL check from getNextEntry --- src/symbol_table.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 6421002..a4cee49 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1221,7 +1221,17 @@ ListOfTable *getRestOfChildren(ListOfTable *lt) { return lt->next; } TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } // Segfaults when passed an invalid table node! -TableNode *getNextEntry(TableNode *tn) { return tn; } +TableNode *getNextEntry(TableNode *tn) { + if (tn == NULL) { + printdebug("passed a NULL table node to getNextEntry"); + return undefined; + } + if (tn == undefined) { + printdebug("passed an undefined table node to getNextEntry"); + return undefined; + } + return tn->next; + } // uncomment the below main function along with the headers above for a simple From 5e01b93af835f7a20d345419d6b57cf415f5418a Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 31 Mar 2025 20:42:17 -0400 Subject: [PATCH 047/137] edited while loops in grammar to not look for comparison to NULL. Undefined instead --- src/grammar.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 94fd0a9..352c2ea 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -196,7 +196,7 @@ function_declaration: idlist: ID { TableNode *entry = getFirstEntry(cur); - while (getName(entry) != NULL) { + while (strcmp(getName(entry),"undefined") != 0) { entry = getNextEntry(entry); } if (getNextEntry(entry) == NULL) { @@ -207,7 +207,7 @@ idlist: | ID { TableNode *entry = getFirstEntry(cur); - while (getName(entry) != NULL) { + while (strcmp(getName(entry),"undefined") != 0) { entry = getNextEntry(entry); } if (getNextEntry(entry) != NULL) { From fac92f62f731f7fa5a4f10d5dcfd384be1c4fb64 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 31 Mar 2025 21:18:21 -0400 Subject: [PATCH 048/137] segfaults fixed. need to verify what is being passed to functions. --- src/symbol_table.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index a4cee49..e68c886 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -968,10 +968,24 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { }*/ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + if (table == NULL) { + printdebug( + "%s[FATAL] passed in NULL table to print_symbol_table", + COLOR_RED); + return; + } + + if (table->Parent_Scope != NULL) { + printdebug("%s[WARNING] passed in a non-top level scope to " + "print_symbol_table", + COLOR_ORANGE); + } + if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); } + TableNode *entrie = table->entries; fprintf(file_ptr, "-----------------:--------:--------:----------------" "------:---------" @@ -1213,7 +1227,19 @@ bool typeCheck(char *firstID, char *secondID) { return false; } -SymbolTable *getParent(SymbolTable *st) { return st->Parent_Scope; } +SymbolTable *getParent(SymbolTable *st) { + if (st == NULL) { + printdebug("passed a NULL symbol table to getParent function. " + "Invalid."); + return NULL; + } + if (st->Parent_Scope == NULL) { + printdebug("passed a top level scope to getParent function. " + "Invalid."); + return NULL; + } + return st->Parent_Scope; +} ListOfTable *getChildren(SymbolTable *st) { return st->Children_Scope; } SymbolTable *getFirstChild(ListOfTable *lt) { return lt->table; } @@ -1222,17 +1248,16 @@ TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } // Segfaults when passed an invalid table node! TableNode *getNextEntry(TableNode *tn) { - if (tn == NULL) { + if (tn == NULL) { printdebug("passed a NULL table node to getNextEntry"); return undefined; - } - if (tn == undefined) { + } + if (tn == undefined) { printdebug("passed an undefined table node to getNextEntry"); return undefined; - } - return tn->next; } - + return tn->next; +} // uncomment the below main function along with the headers above for a simple // standalone test of table and entry creation From 05b641a32e52d2dca43570cc8256ede128bea551 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 1 Apr 2025 12:53:31 -0400 Subject: [PATCH 049/137] Added stubs for all emit funcs and added the 3 fields discussed in the library t#51 --- src/intermediate_code.c | 51 +++++++++++++++++++++++++++++++++++++++++ src/intermediate_code.h | 22 ++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index f32b966..2d50a34 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -1,4 +1,12 @@ + + +// TODO: this is here to bring your attention to the comment bellow. +// check if start is NULL if it is assign it to the start globle variable +// otherwise make it next of current and set cur to your instruction. + + + void emit_binary_op(char* result, char* op, char* arg1, char* arg2){ return; } @@ -11,3 +19,46 @@ void emit_as_file(FILE * out_file, Instruction * instr_arr){ return; } + + +void emit_label(char* label){ + return; +} +void emit_jump(char* label){ + return; +} +void emit_conditional_jump(char* condition, char* label){ + return; +} + + + +void emit_function_start(char* name){ + return; +} +void emit_parameter(char* param){ + return; +} +void emit_function_call(char* result, char* name){ + return; +} +void emit_return(char* value){ + return; +} +void emit_reserve(char* result, char* type_name, int size){ + return; +} +void emit_release(char* pointer){ + return; +} + + +void emit_field_access(char* result, char* record, char* field){ + return; +} +void emit_array_access(char* result, char* array, char* index, char* dimension){ + return; +} +void emit_bounds_check(char* index, char* size, char* error_label){ + return; +} diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 446f4c4..1ccd389 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -19,8 +19,14 @@ typedef struct { TableNode * operand1; TableNode * operand2; int label; + int instruction; + Instruction * prev; + Instruction * next; } Instruction; +Instruction * start = NULL; +Instruction * current = NULL; + void emit_binary_op(char* result, char* op, char* arg1, char* arg2); void emit_unary_op(char* result, char* op, char* arg); void emit_assignment(char* target, char* source); @@ -35,3 +41,19 @@ void emit_assignment(char* target, char* source); void emit_as_file(FILE * out_file, Instruction * instr_arr); // * Implement instruction array storage for backpatching + +void emit_label(char* label); +void emit_jump(char* label); +void emit_conditional_jump(char* condition, char* label); + +void emit_function_start(char* name); +void emit_parameter(char* param); +void emit_function_call(char* result, char* name); +void emit_return(char* value); +void emit_reserve(char* result, char* type_name, int size); +void emit_release(char* pointer); + + +void emit_field_access(char* result, char* record, char* field); +void emit_array_access(char* result, char* array, char* index, char* dimension); +void emit_bounds_check(char* index, char* size, char* error_label); From 5bd68ddb85bb114106865876cad69d3c04a502ee Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 1 Apr 2025 17:02:24 -0400 Subject: [PATCH 050/137] verifying grammar --- src/grammar.y | 61 +++++++++++++++++----------- src/runner.c | 9 ---- src/runner.h | 2 - src/symbol_table.c | 15 +++++-- tests/sprint2/test/sp2_library.alpha | 8 ++-- 5 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 352c2ea..4b36a61 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -267,16 +267,30 @@ simple_statement: | RETURN expression ; -assignable: - ID {$$ = getType(look_up(cur,$1));} - | assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));} //add array case here - | assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){ - {$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};} - ; - rec_op : DOT + + + +/////////// VERIFIED UP UNTIL THIS POINT + +// assignable needs more code- specifically for arrays, records and ablock checks + + + + + +ablock: + L_PAREN argument_list {$$ = $2;} R_PAREN + ; + +argument_list: + expression COMMA argument_list {$$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} + | expression {$$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} + ; + +// will ALWAYS be a TYPE expression: constant {printdebug("constant expression");} {$$ = $1;} @@ -341,8 +355,8 @@ expression: | expression EQUAL_TO expression {printdebug("equals check expression"); if(strcmp($1,$3)==0){$$=strdup("Boolean");} - else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| - strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} + //else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| + // strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} @@ -353,17 +367,16 @@ expression: | memOp assignable {$$ = strdup("address");} ; - -ablock: -L_PAREN argument_list {$$ = $2;} R_PAREN +// prolly right, check back with me later +// add array case +// include type check for ablock in arrays - ablock is always the int of the elements in array/rec +assignable: + ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} + | assignable ablock {$$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1);} // add array case + | assignable rec_op ID {if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)){ + {$$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3));}}; printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);} ; -argument_list: -expression COMMA argument_list {$$ = $3 + 1;} -| expression {$$ = 1;} - ; - - memOp: RESERVE {printdebug("reserve expression");} | RELEASE {printdebug("release expression");} @@ -371,12 +384,12 @@ memOp: constant: - C_STRING {$$ = $1;} - | C_INTEGER {$$ = "integer";} - | C_NULL {$$ = $1;} - | C_CHARACTER {$$ = $1;} - | C_TRUE {$$ = $1;} - | C_FALSE {$$ = $1;} + C_STRING {$$ = $1; printdebug("string of C_STRING in constant is %s",$1);} + | C_INTEGER {$$ = "integer"; printdebug("string of C_INTEGER in constant is integer");} + | C_NULL {$$ = $1; printdebug("string of C_NULL in constant is %s",$1);} + | C_CHARACTER {$$ = $1; printdebug("string of C_CHARACTER in constant is %s",$1);} + | C_TRUE {$$ = $1; printdebug("string of C_TRUE in constant is %s",$1);} + | C_FALSE {$$ = $1; printdebug("string of C_FALSE in constant is %s",$1);} ; types: diff --git a/src/runner.c b/src/runner.c index 7c053a4..c6f94a3 100644 --- a/src/runner.c +++ b/src/runner.c @@ -223,13 +223,4 @@ int is_alpha_file(char *alpha, int file_len) { return -1; // not alpha file } return 0; // is alpha file -} - -void enter_scope(int line, int column) { cur = CreateScope(cur, line, column); } -void exit_scope() { - if (cur->Parent_Scope == NULL) { - printf("Can't close top"); - return; - } - cur = cur->Parent_Scope; } \ No newline at end of file diff --git a/src/runner.h b/src/runner.h index d378be5..9678609 100644 --- a/src/runner.h +++ b/src/runner.h @@ -40,8 +40,6 @@ SymbolTable *cur; // int main(int argc, char* argv[]); char *is_tok(int argc, char *argv[]); // int is_alpha_file(char *file, int file_len); -void enter_scope(int, int); -void exit_scope(void); FILE *alpha_file; FILE *tok_flag = NULL; diff --git a/src/symbol_table.c b/src/symbol_table.c index e68c886..29d34a1 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -512,7 +512,7 @@ SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) { SymbolTable *init(SymbolTable *start) { if (start->Parent_Scope != NULL) { printdebug( - "Cannot initialize a scope that is not the parent scope"); + "%s[FATAL] Cannot initialize a scope that is not the parent scope", COLOR_RED); return NULL; } integ = (TableNode *)calloc(1, sizeof(TableNode)); @@ -979,6 +979,9 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { printdebug("%s[WARNING] passed in a non-top level scope to " "print_symbol_table", COLOR_ORANGE); + printdebug("%sParent of's: line %d, column %d", + COLOR_ORANGE, table->Parent_Scope->Line_Number, table->Parent_Scope->Column_Number); + return; } if (table->Parent_Scope == NULL) { @@ -1100,13 +1103,13 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : :%-21s: %-28s\n", entrie->theName, current_scope, - getType(entrie), "Function"); + getType(entrie), "User Defined"); } else { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", entrie->theName, current_scope, parant_scope, getType(entrie), - "Function"); + "User Defined"); } } if (getAdInfoType(entrie) == TYPE_UNDEFINED) { @@ -1145,6 +1148,12 @@ SymbolTable *getAncestor(SymbolTable *table) { } if (table->Parent_Scope == NULL) { // if table has no parent, return itself + printdebug("already at top scope!"); + if (table == cur) { + printdebug("passed in the current scope"); + } else { + printdebug("passed in a different scope"); + } return table; } else { // call function recursively to grab ancestor diff --git a/tests/sprint2/test/sp2_library.alpha b/tests/sprint2/test/sp2_library.alpha index 9bacd6c..866857c 100644 --- a/tests/sprint2/test/sp2_library.alpha +++ b/tests/sprint2/test/sp2_library.alpha @@ -7,9 +7,9 @@ You should #include this file at the start of your alpha file. Some useful types are defined below. *) type string: 1 -> character -type BooleanXBoolean: [Boolean: x, y] -type characterXcharacter: [character: x, y] -type integerXinteger: [integer: x, y] +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] type Boolean2Boolean: Boolean -> Boolean type integer2integer: integer -> integer @@ -25,6 +25,4 @@ type address2integer: address -> integer external function printInteger: integer2integer external function printCharacter: character2integer external function printBoolean: Boolean2integer -external function reserve: integer2address -external function release: address2integer function entry: string2integer From d56d836b8bdb577929df8ae6ba8880a0470c41c3 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 1 Apr 2025 21:08:16 -0400 Subject: [PATCH 051/137] checking number of args in array ablock --- src/grammar.y | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 4b36a61..8eff344 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -282,7 +282,7 @@ rec_op : ablock: - L_PAREN argument_list {$$ = $2;} R_PAREN +L_PAREN argument_list R_PAREN {$$ = $2; printdebug("ablock is %d", $$);} ; argument_list: @@ -372,7 +372,19 @@ expression: // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} - | assignable ablock {$$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1);} // add array case + | assignable ablock { + int type = getAdInfoType(look_up(cur, $1)); + if (type == TYPE_FUNCTION_TYPE) { + $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + } else if (type == TYPE_ARRAY) { + if (getNumArrDim(look_up(cur, $1)) != $2) { + printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); + } + $$ = $1; + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + } + } | assignable rec_op ID {if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)){ {$$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3));}}; printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);} ; From db2268284bd59a838a7003825d142bc5332a94c8 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 2 Apr 2025 11:05:45 -0400 Subject: [PATCH 052/137] more debug messages, new type check for array and rec --- src/grammar.y | 17 +++++++++++++---- src/symbol_table.c | 9 --------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 8eff344..e4185c8 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -259,10 +259,19 @@ compound_statement: ; simple_statement: - assignable ASSIGN expression {if(strcmp($1, $3) == 0){ - } else { - printdebug("Mismatch at line %d and column%d", @2.first_line, @2.first_column); - }} + assignable ASSIGN expression + { + if(strcmp($1, $3) == 0) { + printdebug("Passed standard type check; assignable = expression"); + } else if((strcmp($1, "rec") == 0) && (strcmp($3, "address") == 0)) { + printdebug("Passed rec type check; rec = address"); + } else if((strcmp($1, "array") == 0) && (strcmp($3, "address") == 0)) { + printdebug("Passed array type check; array = address"); + } else { + printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); + printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); + } + } | RETURN expression ; diff --git a/src/symbol_table.c b/src/symbol_table.c index 29d34a1..6551c1d 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -975,15 +975,6 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { return; } - if (table->Parent_Scope != NULL) { - printdebug("%s[WARNING] passed in a non-top level scope to " - "print_symbol_table", - COLOR_ORANGE); - printdebug("%sParent of's: line %d, column %d", - COLOR_ORANGE, table->Parent_Scope->Line_Number, table->Parent_Scope->Column_Number); - return; - } - if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); From a81e3e410f0cf770f99d23ae85fdd488cf2103dd Mon Sep 17 00:00:00 2001 From: Annie Date: Wed, 2 Apr 2025 11:15:53 -0400 Subject: [PATCH 053/137] need to test function call and array type checking --- src/grammar.y | 95 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 30 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index e4185c8..ba66d6b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -141,7 +141,7 @@ definition: } | ID { TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL) { + if (node == undefined) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); @@ -158,25 +158,26 @@ definition: }R_PAREN ASSIGN sblock | ID { TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == NULL) { + if (node == undefined) { printdebug("null check"); } - if (node == NULL) { + if (node == undefined) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); - setAsKeyword(node, false); + setAsKeyword(node, true); } cur = CreateScope(cur, 0, 0); }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - if (parameter == NULL) { - printdebug("function defined with as, but parameter is not a record at line %d, column %d", @1.first_line, @1.first_column); + if (parameter == undefined) { + printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(parameter) != TYPE_RECORD){ - printdebug("function defined with as, but parameter is not a record at line %d, column %d", @1.first_line, @1.first_column); + printdebug("record: %s., primitive: %s.", getName(parameter), getName(recprime)); + printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); }else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ CreateEntry(cur, entry, NULL, NULL); @@ -187,6 +188,7 @@ definition: ; + function_declaration: FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} @@ -203,7 +205,7 @@ idlist: printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); } addName(entry, $1); - } COMMA idlist {$$ = $3 + 1;} + } COMMA idlist {$$ = $4 + 1;} | ID { TableNode *entry = getFirstEntry(cur); @@ -259,19 +261,10 @@ compound_statement: ; simple_statement: - assignable ASSIGN expression - { - if(strcmp($1, $3) == 0) { - printdebug("Passed standard type check; assignable = expression"); - } else if((strcmp($1, "rec") == 0) && (strcmp($3, "address") == 0)) { - printdebug("Passed rec type check; rec = address"); - } else if((strcmp($1, "array") == 0) && (strcmp($3, "address") == 0)) { - printdebug("Passed array type check; array = address"); - } else { - printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); - printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); - } - } + assignable ASSIGN expression {if(strcmp($1, $3) == 0){ + } else { + printdebug("Mismatch at line %d and column%d", @2.first_line, @2.first_column); + }} | RETURN expression ; @@ -295,8 +288,13 @@ L_PAREN argument_list R_PAREN {$$ = $2; printdebug("ablock is %d", ; argument_list: - expression COMMA argument_list {$$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} - | expression {$$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} + expression COMMA argument_list { + CreateEntry(cur, NULL, $1, NULL); + $$ = $3 + 1; + printdebug("[ARGUMENT_LIST] argument list is %d", $$);} + | expression { + CreateEntry(cur, NULL, $1, NULL); + $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} ; // will ALWAYS be a TYPE @@ -381,19 +379,56 @@ expression: // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} - | assignable ablock { - int type = getAdInfoType(look_up(cur, $1)); - if (type == TYPE_FUNCTION_TYPE) { + | assignable { + cur = CreateScope(cur, -1,-1); + }ablock { + int type = getAdInfoType(look_up(getParent(cur), $1)); + if (type == TYPE_FUNCTION_DECLARATION) { + if (getAsKeyword(look_up(getParent(cur), $1))) { + TableNode *param = getParameter(look_up(getParent(cur), $1)); + SymbolTable *recList = getRecList(param); + TableNode *lastCheckedRef = getFirstEntry(recList); + TableNode *lastCheckedAct = getFirstEntry(cur); + while (getNextEntry(lastCheckedRef) != NULL) { + lastCheckedRef = getNextEntry(lastCheckedRef); + } + //this isn't very efficient, but will hopefully work + while (lastCheckedAct != NULL && lastCheckedRef != NULL) { + if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { + printdebug("expected %s expression in function call but got %s at line %d and column %d",getName(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + } + lastCheckedAct = getNextEntry(lastCheckedAct); + TableNode *tn = getFirstEntry(recList); + while (getNextEntry(tn) != lastCheckedRef) { + tn = getNextEntry(tn); + } + lastCheckedRef = tn; + } + + } else { + char *expected = getName(getParameter(look_up(getParent(cur), $1))); + char *actual = getName(getFirstEntry(cur)); + if (strcmp(expected, actual) != 0) { + printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); + } + } + $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); } else if (type == TYPE_ARRAY) { - if (getNumArrDim(look_up(cur, $1)) != $2) { - printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); - } + if (getNumArrDim(look_up(getParent(cur), $1)) != $2) { + printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); + } + for (TableNode *tn = getFirstEntry(cur); tn != NULL; tn = getNextEntry(tn)) { + if (strcmp(getName(tn), "integer") != 0) { + printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); + } + } $$ = $1; printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); } - } + cur = getParent(cur); + } | assignable rec_op ID {if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)){ {$$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3));}}; printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);} ; From 53a4d060b6d31ad6f11848497a6364fd4d3fd018 Mon Sep 17 00:00:00 2001 From: Annie Date: Wed, 2 Apr 2025 11:23:00 -0400 Subject: [PATCH 054/137] added back scarlett's simple statement work --- src/grammar.y | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index ba66d6b..6edd68f 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -261,14 +261,22 @@ compound_statement: ; simple_statement: - assignable ASSIGN expression {if(strcmp($1, $3) == 0){ - } else { - printdebug("Mismatch at line %d and column%d", @2.first_line, @2.first_column); - }} + assignable ASSIGN expression + { + if(strcmp($1, $3) == 0) { + printdebug("Passed standard type check; assignable = expression"); + } else if((strcmp($1, "rec") == 0) && (strcmp($3, "address") == 0)) { + printdebug("Passed rec type check; rec = address"); + } else if((strcmp($1, "array") == 0) && (strcmp($3, "address") == 0)) { + printdebug("Passed array type check; array = address"); + } else { + printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); + printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); + } + } | RETURN expression ; - rec_op : DOT From 1c7cdbb4daa923d15e2fe9b63618214dad8e4e62 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Wed, 2 Apr 2025 11:28:23 -0400 Subject: [PATCH 055/137] Implemented the 2 operation functions #t51 --- src/intermediate_code.c | 39 +++++++++++++++++++++++++++++++++++---- src/intermediate_code.h | 7 ++++--- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 2d50a34..24f370c 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -1,3 +1,7 @@ +#include "intermediate_code.h" + + +start = current = NULL; @@ -7,11 +11,38 @@ - void emit_binary_op(char* result, char* op, char* arg1, char* arg2){ - return; + void emit_binary_op(char* result, Op op, char* arg1, char* arg2){ + Instruction * inst = calloc(1, sizeof(*inst)); + if(start == NULL){ + start = current = inst; + current->index = 1; + } else { + current->next = inst; + inst->prev = current; + inst->index = current->index++; + current = inst; + } + current->opcode = op; + current->result = look_up(result); + current->operand1 = look_up(arg1); + current->operand2 = look_up(arg2); + return; } - void emit_unary_op(char* result, char* op, char* arg){ - return; + void emit_unary_op(char* result, Oo op, char* arg){ + Instruction * inst = calloc(1, sizeof(*inst)); + if(start == NULL){ + start = current = inst; + current->index = 1; + } else { + current->next = inst; + inst->prev = current; + inst->index = current->index++; + current = inst; + } + current->opcode = op; + current->result = look_up(result); + current->operand1 = look_up(arg); + return; } void emit_assignment(char* target, char* source){ return; diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 1ccd389..fdd0aff 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -19,13 +19,14 @@ typedef struct { TableNode * operand1; TableNode * operand2; int label; - int instruction; + int index; Instruction * prev; Instruction * next; } Instruction; -Instruction * start = NULL; -Instruction * current = NULL; +Instruction * start; +Instruction * current; + void emit_binary_op(char* result, char* op, char* arg1, char* arg2); void emit_unary_op(char* result, char* op, char* arg); From d05b6f456c45d45c6d91ee4d20e98cf2cf231269 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 2 Apr 2025 11:54:13 -0400 Subject: [PATCH 056/137] rebase --- tests/sprint2/test/sp2_carls_mistake.alpha | 2 ++ .../test/sp3_carls_second_mistake.alpha | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/sprint3/test/sp3_carls_second_mistake.alpha diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index f2b3703..75fa12f 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -1,6 +1,7 @@ type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer +type arr : 1 -> integer function foo : T1 function bar1 : T2 @@ -23,5 +24,6 @@ entry(arg) := { w.y := 7; result := bar1(w); (* pass w (a rec type value) to bar1 *) result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) + arr(3); return 0; } diff --git a/tests/sprint3/test/sp3_carls_second_mistake.alpha b/tests/sprint3/test/sp3_carls_second_mistake.alpha new file mode 100644 index 0000000..9eb4864 --- /dev/null +++ b/tests/sprint3/test/sp3_carls_second_mistake.alpha @@ -0,0 +1,25 @@ +type string: 1 -> character +type a_of_s: 1 -> string + +(* maybe some other type definitions *) + +entry(arg) := { + [ string: one_name; string: another_name; a_of_s: many_names ] + one_name := "a string literal"; + another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) + another_name(0) := 'C'; + another_name(1) := 'a'; + another_name(2) := 'r'; + another_name(3) := 'l'; + a_of_s := reserve a_of_s(3); + a_of_s(0) := one_name; + a_of_s(1) := another_name; + many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) + many_names(2)(0) := "P"; + many_names(2)(1) := "a"; + many_names(2)(2) := "r"; + many_names(2)(3) := "t"; + many_names(2)(4) := "h"; + many_names(2)(5) := "o"; + return 0; +} \ No newline at end of file From f4b31ee835c854680997f80916a1a2321c14d7b4 Mon Sep 17 00:00:00 2001 From: Annie Date: Wed, 2 Apr 2025 12:59:38 -0400 Subject: [PATCH 057/137] type checking for non as function calls might be working --- src/grammar.y | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 6edd68f..2db7495 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -173,10 +173,11 @@ definition: cur = CreateScope(cur, 0, 0); }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + printdebug("%s", getType(parameter)); if (parameter == undefined) { printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(parameter) != TYPE_RECORD){ - printdebug("record: %s., primitive: %s.", getName(parameter), getName(recprime)); + printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); }else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ @@ -297,11 +298,11 @@ L_PAREN argument_list R_PAREN {$$ = $2; printdebug("ablock is %d", argument_list: expression COMMA argument_list { - CreateEntry(cur, NULL, $1, NULL); + CreateEntry(cur, look_up(cur, $1), "", NULL); $$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} | expression { - CreateEntry(cur, NULL, $1, NULL); + CreateEntry(cur, look_up(cur, $1), "", NULL); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} ; @@ -402,8 +403,8 @@ assignable: } //this isn't very efficient, but will hopefully work while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",getName(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + if (strcmp(getType(lastCheckedAct), getName(lastCheckedRef)) != 0) { + printdebug("expected %s expression in function call but got %s at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); } lastCheckedAct = getNextEntry(lastCheckedAct); TableNode *tn = getFirstEntry(recList); @@ -415,7 +416,7 @@ assignable: } else { char *expected = getName(getParameter(look_up(getParent(cur), $1))); - char *actual = getName(getFirstEntry(cur)); + char *actual = getType(getFirstEntry(cur)); if (strcmp(expected, actual) != 0) { printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); } From 692025412e7877fdfe1578b85afe54238532f3d5 Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 2 Apr 2025 13:16:56 -0400 Subject: [PATCH 058/137] fixed getAdInfo function --- src/symbol_table.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 6551c1d..b896306 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -66,10 +66,10 @@ typedef enum { // TYPE_ADDRESS, // Type String is an array of char enclosed in double quotes per lexer TYPE_STRING = 1, - // Array can be multidimensional. Information should be stored here - TYPE_ARRAY = 2, + // Array can be multidimensional. Information should be stored here. This is the type of the array + TYPE_ARRAY_TYPE = 2, // Record is user defined types - TYPE_RECORD = 3, + TYPE_RECORD_TYPE = 3, // Declaring what type a particular function is without as TYPE_FUNCTION_DECLARATION = 4, // Declaring what type a particular function is with as @@ -82,7 +82,9 @@ typedef enum { TYPE_PRIMITIVE = 6, // likely NULL TYPE_ALL_ELSE = 7, - TYPE_UNDEFINED = 8 + TYPE_UNDEFINED = 8, + TYPE_RECORD = 9, + TYPE_ARRAY = 10 } types; @@ -688,13 +690,13 @@ int getAdInfoType(TableNode *tn) { return TYPE_PRIMITIVE; } if (strcmp(getName(tn), getName(stri)) == 0) { - return TYPE_ARRAY; + return TYPE_ARRAY_TYPE; } if (strcmp(getName(tn), getName(boo)) == 0) { return TYPE_PRIMITIVE; } if (strcmp(getName(tn), getName(recprime)) == 0) { - return TYPE_RECORD; + return TYPE_RECORD_TYPE; } if (strcmp(getName(tn), getName(funtypeprime)) == 0) { return TYPE_FUNCTION_TYPE; @@ -705,6 +707,21 @@ int getAdInfoType(TableNode *tn) { if (strcmp(getName(tn), getName(undefined)) == 0) { return TYPE_UNDEFINED; } else { + if(strcmp(getType(tn), getName(funtypeprime))==0){ + printdebug("passed in a function to getAdInfoType"); + return TYPE_FUNCTION_DECLARATION; + } + if(strcmp(getType(tn), getName(arrayprim))==0){ + printdebug("passed in an array to getAdInfoType"); + return TYPE_ARRAY; + } + if(strcmp(getType(tn), getName(recprime))==0){ + printdebug("passed in a record to getAdInfoType"); + return TYPE_RECORD; + } + printdebug( + "passed in an entry that is not a primitive type, array, " + "or record. Invalid."); return TYPE_FUNCTION_DECLARATION; } } From 20c372f134ac2846121fc844db115145b6ac44d5 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 2 Apr 2025 13:19:37 -0400 Subject: [PATCH 059/137] more type check fixes --- src/grammar.y | 72 +++++++++++-------- .../test/sp3_carls_second_mistake.alpha | 18 ++--- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 2db7495..4ac0f0d 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -266,13 +266,20 @@ simple_statement: { if(strcmp($1, $3) == 0) { printdebug("Passed standard type check; assignable = expression"); - } else if((strcmp($1, "rec") == 0) && (strcmp($3, "address") == 0)) { - printdebug("Passed rec type check; rec = address"); - } else if((strcmp($1, "array") == 0) && (strcmp($3, "address") == 0)) { - printdebug("Passed array type check; array = address"); + } else if((strcmp(getType(look_up(cur, $1)), "array") == 0) && (strcmp($3, "address") == 0)) { + printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, $1, $3); + } else if((strcmp(getType(look_up(cur, $1)), "record") == 0) && (strcmp($3, "address") == 0)) { + printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, $1, $3); + } else if((strcmp(getType(look_up(cur, $1)), "function type primitive") == 0) && (strcmp($3, "address") == 0)) { + printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, $1, $3); + // } else if () { + + // } else if(strcmp(getType(table_lookup(cur, $1)), getType(table_lookup(cur, $3))) == 0) { + // printdebug("%s[] Passed double lookup type check; %s = %s", COLOR_GREEN, $1, $3); } else { printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); + printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(look_up(cur, $1))); } } @@ -387,32 +394,35 @@ expression: // add array case // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: - ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} - | assignable { - cur = CreateScope(cur, -1,-1); - }ablock { - int type = getAdInfoType(look_up(getParent(cur), $1)); - if (type == TYPE_FUNCTION_DECLARATION) { - if (getAsKeyword(look_up(getParent(cur), $1))) { - TableNode *param = getParameter(look_up(getParent(cur), $1)); - SymbolTable *recList = getRecList(param); - TableNode *lastCheckedRef = getFirstEntry(recList); - TableNode *lastCheckedAct = getFirstEntry(cur); - while (getNextEntry(lastCheckedRef) != NULL) { - lastCheckedRef = getNextEntry(lastCheckedRef); - } - //this isn't very efficient, but will hopefully work - while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (strcmp(getType(lastCheckedAct), getName(lastCheckedRef)) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); - } - lastCheckedAct = getNextEntry(lastCheckedAct); - TableNode *tn = getFirstEntry(recList); - while (getNextEntry(tn) != lastCheckedRef) { - tn = getNextEntry(tn); - } - lastCheckedRef = tn; - } + ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} + | assignable + { + cur = CreateScope(cur, -1,-1); + } + ablock + { + int type = getAdInfoType(look_up(getParent(cur), $1)); + if (type == TYPE_FUNCTION_DECLARATION) { + if (getAsKeyword(look_up(getParent(cur), $1))) { + TableNode *param = getParameter(look_up(getParent(cur), $1)); + SymbolTable *recList = getRecList(param); + TableNode *lastCheckedRef = getFirstEntry(recList); + TableNode *lastCheckedAct = getFirstEntry(cur); + while (getNextEntry(lastCheckedRef) != NULL) { + lastCheckedRef = getNextEntry(lastCheckedRef); + } + //this isn't very efficient, but will hopefully work + while (lastCheckedAct != NULL && lastCheckedRef != NULL) { + if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { + printdebug("expected %s expression in function call but got %s at line %d and column %d",getName(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + } + lastCheckedAct = getNextEntry(lastCheckedAct); + TableNode *tn = getFirstEntry(recList); + while (getNextEntry(tn) != lastCheckedRef) { + tn = getNextEntry(tn); + } + lastCheckedRef = tn; + } } else { char *expected = getName(getParameter(look_up(getParent(cur), $1))); @@ -433,7 +443,7 @@ assignable: printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); } } - $$ = $1; + $$ = getName(getArrType(look_up(getParent(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); } cur = getParent(cur); diff --git a/tests/sprint3/test/sp3_carls_second_mistake.alpha b/tests/sprint3/test/sp3_carls_second_mistake.alpha index 9eb4864..26c64d2 100644 --- a/tests/sprint3/test/sp3_carls_second_mistake.alpha +++ b/tests/sprint3/test/sp3_carls_second_mistake.alpha @@ -11,15 +11,15 @@ entry(arg) := { another_name(1) := 'a'; another_name(2) := 'r'; another_name(3) := 'l'; - a_of_s := reserve a_of_s(3); - a_of_s(0) := one_name; - a_of_s(1) := another_name; + many_names := reserve many_names(3); + many_names(0) := one_name; + many_names(1) := another_name; many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) - many_names(2)(0) := "P"; - many_names(2)(1) := "a"; - many_names(2)(2) := "r"; - many_names(2)(3) := "t"; - many_names(2)(4) := "h"; - many_names(2)(5) := "o"; + many_names(2)(0) := 'P'; + many_names(2)(1) := 'a'; + many_names(2)(2) := 'r'; + many_names(2)(3) := 't'; + many_names(2)(4) := 'h'; + many_names(2)(5) := 'o'; return 0; } \ No newline at end of file From 77c4106b1b3faeb6b58eadb0eb5e50a81d9f14c7 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 2 Apr 2025 15:03:29 -0400 Subject: [PATCH 060/137] latest --- src/grammar.y | 88 +++++++++++-------- src/symbol_table.c | 18 ++-- .../test/sp3_carls_second_mistake.alpha | 2 +- 3 files changed, 63 insertions(+), 45 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 4ac0f0d..0ad9cea 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -132,7 +132,9 @@ definition: | TYPE ID COLON C_INTEGER ARROW id_or_types {printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, $6, $4); - CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));} + CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6))); + printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6); + } | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", @@ -237,8 +239,12 @@ declaration_list: ; declaration: - id_or_types COLON ID {printdebug("ID/TYPE: %s, ID: %s", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } - ; + id_or_types COLON ID + { + printdebug("ID/TYPE: %s, ID: %s", $1, $3) ; + CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); + } + ; id_or_types: ID {printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;} @@ -394,15 +400,21 @@ expression: // add array case // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: - ID {$$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} - | assignable + ID { + $$ = getType(look_up(cur,$1)); + printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} + | assignable + { + printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); cur = CreateScope(cur, -1,-1); } - ablock - { + ablock { int type = getAdInfoType(look_up(getParent(cur), $1)); + printdebug("%stype is %d", COLOR_PURPLE, type); + if (type == TYPE_FUNCTION_DECLARATION) { + printdebug("%sEntering function call", COLOR_LIGHTGREEN); if (getAsKeyword(look_up(getParent(cur), $1))) { TableNode *param = getParameter(look_up(getParent(cur), $1)); SymbolTable *recList = getRecList(param); @@ -414,7 +426,7 @@ assignable: //this isn't very efficient, but will hopefully work while (lastCheckedAct != NULL && lastCheckedRef != NULL) { if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",getName(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + printdebug("expected %s expression in function call but got %s at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); } lastCheckedAct = getNextEntry(lastCheckedAct); TableNode *tn = getFirstEntry(recList); @@ -424,33 +436,39 @@ assignable: lastCheckedRef = tn; } - } else { - char *expected = getName(getParameter(look_up(getParent(cur), $1))); - char *actual = getType(getFirstEntry(cur)); - if (strcmp(expected, actual) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); - } - } - - $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); - } else if (type == TYPE_ARRAY) { - if (getNumArrDim(look_up(getParent(cur), $1)) != $2) { - printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); - } - for (TableNode *tn = getFirstEntry(cur); tn != NULL; tn = getNextEntry(tn)) { - if (strcmp(getName(tn), "integer") != 0) { - printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); - } - } - $$ = getName(getArrType(look_up(getParent(cur), $1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); - } - cur = getParent(cur); - } - | assignable rec_op ID {if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)){ - {$$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3));}}; printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);} - ; + } else { + char *expected = getName(getParameter(look_up(getParent(cur), $1))); + char *actual = getType(getFirstEntry(cur)); + if (strcmp(expected, actual) != 0) { + printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); + } + } + $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + + } else if (type == TYPE_ARRAY_TYPE) { + printdebug("%sEntering array call", COLOR_LIGHTGREEN); + if (getNumArrDim(look_up(getParent(cur), $1)) != $2) { + printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); + } + // for (TableNode *tn = getFirstEntry(cur); tn != NULL; tn = getNextEntry(tn)) { + // if (strcmp(getName(tn), "integer") != 0) { + // printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); + // } + // } + $$ = getName(getArrType(look_up(getParent(cur), $1))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + } + cur = getParent(cur); + } + | assignable rec_op ID + { + if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)) { + $$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)); + } + printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1); + } + ; memOp: RESERVE {printdebug("reserve expression");} diff --git a/src/symbol_table.c b/src/symbol_table.c index b896306..1dc6e31 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -702,7 +702,7 @@ int getAdInfoType(TableNode *tn) { return TYPE_FUNCTION_TYPE; } if (strcmp(getName(tn), getName(arrayprim)) == 0) { - return TYPE_ARRAY; + return TYPE_ARRAY_TYPE; // changed from TYPE_ARRAY cuz } if (strcmp(getName(tn), getName(undefined)) == 0) { return TYPE_UNDEFINED; @@ -713,7 +713,7 @@ int getAdInfoType(TableNode *tn) { } if(strcmp(getType(tn), getName(arrayprim))==0){ printdebug("passed in an array to getAdInfoType"); - return TYPE_ARRAY; + return TYPE_ARRAY_TYPE; } if(strcmp(getType(tn), getName(recprime))==0){ printdebug("passed in a record to getAdInfoType"); @@ -1004,8 +1004,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { int parant_scope = 0; int current_scope = 0; if (table->Parent_Scope != NULL) { - parant_scope = table->Parent_Scope->Line_Number * 1000 + - table->Parent_Scope->Column_Number; + parant_scope = getParent(table)->Line_Number * 1000 + + getParent(table)->Column_Number; current_scope = table->Line_Number * 1000 + table->Column_Number; } else { @@ -1015,8 +1015,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", current_scope, parant_scope, "", "Empty Scope"); } - for (; entrie != NULL; entrie = entrie->next) { - if (getAdInfoType(entrie) == TYPE_ARRAY) { + for (; entrie != NULL; entrie = getNextEntry(entrie)) { + if (getAdInfoType(entrie) == TYPE_ARRAY_TYPE) { if (parant_scope == 0) { fprintf(file_ptr, @@ -1136,13 +1136,13 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } } } - if (table->Children_Scope != NULL) { - ListOfTable *node = table->Children_Scope; + if (getChildren(table) != NULL) { + ListOfTable *node = getChildren(table); for (; node != NULL; node = node->next) { print_symbol_table(node->table, file_ptr); } } - if (table->Parent_Scope == NULL) { + if (getParent(table) == NULL) { fprintf(file_ptr, "-----------------:--------:--------:--------" "--------------:-------" "----------------------\n"); diff --git a/tests/sprint3/test/sp3_carls_second_mistake.alpha b/tests/sprint3/test/sp3_carls_second_mistake.alpha index 26c64d2..6d1d614 100644 --- a/tests/sprint3/test/sp3_carls_second_mistake.alpha +++ b/tests/sprint3/test/sp3_carls_second_mistake.alpha @@ -20,6 +20,6 @@ entry(arg) := { many_names(2)(2) := 'r'; many_names(2)(3) := 't'; many_names(2)(4) := 'h'; - many_names(2)(5) := 'o'; + 0(2)(5) := 'o'; return 0; } \ No newline at end of file From 3186d363ed65dd275a0622f96e49cbda83ae7e6f Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 2 Apr 2025 20:31:00 -0400 Subject: [PATCH 061/137] fixed print symbol table to not print scopes used as flags --- src/symbol_table.c | 8 ++++++++ test | 0 tests/sprint2/test/sp2_carls_mistake.alpha | 1 - 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 test diff --git a/src/symbol_table.c b/src/symbol_table.c index 1dc6e31..1a879cd 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1139,7 +1139,15 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getChildren(table) != NULL) { ListOfTable *node = getChildren(table); for (; node != NULL; node = node->next) { + if((node->table) == NULL){ print_symbol_table(node->table, file_ptr); + }else{ + if ((node->table)->Line_Number == -1){ + continue; + }else{ + print_symbol_table(node->table, file_ptr); + } + } } } if (getParent(table) == NULL) { diff --git a/test b/test new file mode 100644 index 0000000..e69de29 diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index 75fa12f..2f4c1ef 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -24,6 +24,5 @@ entry(arg) := { w.y := 7; result := bar1(w); (* pass w (a rec type value) to bar1 *) result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) - arr(3); return 0; } From 3d063525105eca49c1c49fa743747bd90a2ed92c Mon Sep 17 00:00:00 2001 From: Scarlett Date: Thu, 3 Apr 2025 16:37:53 -0400 Subject: [PATCH 062/137] New grammar formatting rules applied. --- src/grammar.y | 761 +++++++++++++++++++++++++-------------- src/lexicalStructure.lex | 38 +- src/symbol_table.c | 33 +- test | 0 4 files changed, 535 insertions(+), 297 deletions(-) delete mode 100644 test diff --git a/src/grammar.y b/src/grammar.y index 0ad9cea..b3f2334 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -2,38 +2,52 @@ /* Syntax Analyzer with Bison (3.8.2) */ /* The Translators - Spring 2025 */ +// ----- THIS FILE MUST BE FORMATTED CORRECTLY FOR READABILITY ----- // + +// ✏️ FORMATTING RULES: +// 1️⃣ Use 4 spaces for indentation. +// 2️⃣ Grammar rules (terminals and nonterminals) should always be on their own line. +// 3️⃣ Grammar rules and C-blocks should always begin 8 spaces in. +// 4️⃣ Rule end-markers (;, |) should always be 4 spaces in. +// 5️⃣ C-blocks should always be clearly defined and follow clang formatting rules. +// 6️⃣ 1-line if/for/while statements must be wrapped in curly braces. +// 7️⃣ DO NOT USE TABS. EVER. + +// Please ask Scarlett if you are unsure of how to format something. Thanks! 😀 + %{ - #include - #include "../src/symbol_table.c" - #include - extern int yylex(void); - void yyerror(const char *err); - extern char* yytext; - extern int yyleng; - extern int yychar; - extern SymbolTable * cur; - //char* cur_value; - //char* cur_type; - int token_tracker; - extern int line_number; - extern int column_number; - extern FILE * yyin; - extern TableNode* funprime; - extern TableNode* arrayprim; - extern TableNode* recprime; - extern TableNode* funtypeprime; - extern TableNode* integ; - extern TableNode* addr; - extern TableNode* chara; - extern TableNode* stri; - extern TableNode* boo; - TableNode * tn; + #include + #include "../src/symbol_table.c" + #include + extern int yylex(void); + void yyerror(const char *err); + extern char* yytext; + extern int yyleng; + extern int yychar; + extern SymbolTable * cur; + //char* cur_value; + //char* cur_type; + int token_tracker; + extern int line_number; + extern int column_number; + extern FILE * yyin; + extern TableNode* funprime; + extern TableNode* arrayprim; + extern TableNode* recprime; + extern TableNode* funtypeprime; + extern TableNode* integ; + extern TableNode* addr; + extern TableNode* chara; + extern TableNode* stri; + extern TableNode* boo; + TableNode * tn; %} -//%define api.location.type {location_t} + %locations + %union { - int integ; - char * words; + int integ; + char * words; } %type idlist @@ -102,174 +116,253 @@ %precedence DOT %precedence RESERVE RELEASE - - %% program: - prototype_or_definition_list - ; + prototype_or_definition_list + ; + + prototype_or_definition_list: - prototype prototype_or_definition_list - | definition prototype_or_definition_list - | prototype - | definition - ; + prototype prototype_or_definition_list + | definition prototype_or_definition_list + | prototype + | definition + ; + + prototype: - L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; + L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; + + definition: - TYPE ID COLON { - printdebug("Currently see a record definition for %s", $2); - tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); - if (table_lookup(getAncestor(cur), $2) == undefined) { - printdebug("rec not found "); - } - }dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); - cur = getParent(cur);} - | TYPE ID COLON C_INTEGER ARROW id_or_types - {printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", - $2, $6, $4); - CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6))); - printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6); + TYPE ID COLON + { + printdebug("Currently see a record definition for %s", $2); + tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); + if (table_lookup(getAncestor(cur), $2) == undefined) { + printdebug("rec not found "); + } } - | function_declaration - | TYPE ID COLON id_or_types ARROW id_or_types { - printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", - $2, $4, $6); - CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); + dblock + { + setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); + cur = getParent(cur); + } + + | TYPE ID COLON C_INTEGER ARROW id_or_types + { + printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, $6, $4); + CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6))); + printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6); + } + + | function_declaration + + | TYPE ID COLON id_or_types ARROW id_or_types + { + printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, $4, $6); + CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); } - | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == undefined) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + + | ID + { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == undefined) { + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + } + L_PAREN ID + { + printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4); + CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + } + R_PAREN ASSIGN sblock + + | ID + { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == undefined) { + printdebug("null check"); + } + if (node == undefined) { + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, true); + } + cur = CreateScope(cur, 0, 0); + } + AS L_PAREN + { + TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + printdebug("%s", getType(parameter)); + if (parameter == undefined) { + printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); + } else if(getAdInfoType(parameter) != TYPE_RECORD) { + printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); + printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); + } else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)) { + CreateEntry(cur, entry, NULL, NULL); } - else { - setStartLine(node, @1.first_line); - setAsKeyword(node, false); - } - cur = CreateScope(cur, 0, 0); - } L_PAREN ID { - printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", - $1,$4); - CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); - }R_PAREN ASSIGN sblock - | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == undefined) { - printdebug("null check"); - } - if (node == undefined) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - } - else { - setStartLine(node, @1.first_line); - setAsKeyword(node, true); - } - cur = CreateScope(cur, 0, 0); - }AS L_PAREN { - TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - printdebug("%s", getType(parameter)); - if (parameter == undefined) { - printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); - }else if(getAdInfoType(parameter) != TYPE_RECORD){ - printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); - printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); - }else { - for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ - CreateEntry(cur, entry, NULL, NULL); - } - } - } idlist {printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", - $1,$6);} R_PAREN ASSIGN sblock - ; + } + } + idlist + { + printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$6); + } + R_PAREN ASSIGN sblock + ; function_declaration: - FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));} - | EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);} - ; + FUNCTION ID COLON ID + { + CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + } + + | EXTERNAL FUNCTION ID COLON ID + { + CreateEntry(cur, look_up(cur, $5), $3, NULL); + } + ; + idlist: - ID { - TableNode *entry = getFirstEntry(cur); - while (strcmp(getName(entry),"undefined") != 0) { - entry = getNextEntry(entry); - } - if (getNextEntry(entry) == NULL) { - printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); - } - addName(entry, $1); - } COMMA idlist {$$ = $4 + 1;} - | ID { - - TableNode *entry = getFirstEntry(cur); - while (strcmp(getName(entry),"undefined") != 0) { - entry = getNextEntry(entry); - } - if (getNextEntry(entry) != NULL) { - printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); - } - addName(entry, $1); - $$ = 1; - } - ; + ID + { + TableNode *entry = getFirstEntry(cur); + while (strcmp(getName(entry),"undefined") != 0) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) == NULL) { + printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); + } + addName(entry, $1); + } + COMMA idlist + { + $$ = $4 + 1; + } + + | ID + { + TableNode *entry = getFirstEntry(cur); + while (strcmp(getName(entry),"undefined") != 0) { + entry = getNextEntry(entry); + } + if (getNextEntry(entry) != NULL) { + printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); + } + addName(entry, $1); + $$ = 1; + } + ; sblock: -L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE - | L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock - {printdebug("seen sblock with dblock");} statement_list {cur = getParent(cur);} R_BRACE - ; + L_BRACE + { + if (getLine(cur) != 0 && getColumn(cur)) { + cur = CreateScope(cur,@1.first_line,@1.first_column); + } + } + statement_list + { + cur = getParent(cur); + } + R_BRACE + + | L_BRACE + { + if (getLine(cur) != 0 && getColumn(cur)) { + cur = CreateScope(cur,@1.first_line,@1.first_column); + } + } + dblock + { + printdebug("seen sblock with dblock"); + } + statement_list + { + cur = getParent(cur); + } + R_BRACE + ; + + dblock: - L_BRACKET declaration_list R_BRACKET; + L_BRACKET declaration_list R_BRACKET; + + declaration_list: - declaration SEMI_COLON declaration_list - | declaration - ; + declaration SEMI_COLON declaration_list + | declaration + ; + + declaration: - id_or_types COLON ID + id_or_types COLON ID { printdebug("ID/TYPE: %s, ID: %s", $1, $3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); } ; + + id_or_types: - ID {printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;} - //{printdebug("string of id is %s in ID pattern of id_or_type rule. Type passed up the tree is %s.",$1,getType(look_up(cur,$1))); $$ = getType(look_up(cur,$1));} - | types {printdebug("string of type is %s in types pattern of id_or_type rule.",$1);} {$$ = $1;} - //{printdebug("string of type is %s in types pattern of id_or_type rule. That is passed up the tree.",$1);} {$$ = $1;} - ; - ; + ID + { + printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1; + } + + | types + { + printdebug("string of type is %s in types pattern of id_or_type rule.",$1); + $$ = $1; + } + ; + + statement_list: - compound_statement statement_list - | compound_statement - | simple_statement SEMI_COLON statement_list - | simple_statement SEMI_COLON - ; + compound_statement statement_list + | compound_statement + | simple_statement SEMI_COLON statement_list + | simple_statement SEMI_COLON + ; + + compound_statement: - WHILE L_PAREN expression R_PAREN sblock - | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock - | sblock //{printdebug("seen a compound statement rule");} - ; + WHILE L_PAREN expression R_PAREN sblock + | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock + | sblock + ; + + simple_statement: - assignable ASSIGN expression - { + assignable ASSIGN expression + { if(strcmp($1, $3) == 0) { printdebug("Passed standard type check; assignable = expression"); } else if((strcmp(getType(look_up(cur, $1)), "array") == 0) && (strcmp($3, "address") == 0)) { @@ -287,114 +380,194 @@ simple_statement: printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(look_up(cur, $1))); } - } + } - | RETURN expression - ; -rec_op : - DOT + | RETURN expression + ; - -/////////// VERIFIED UP UNTIL THIS POINT - -// assignable needs more code- specifically for arrays, records and ablock checks - - +rec_op: + DOT ablock: -L_PAREN argument_list R_PAREN {$$ = $2; printdebug("ablock is %d", $$);} - ; + L_PAREN argument_list R_PAREN + { + $$ = $2; + printdebug("ablock is %d", $$); + } + ; + + argument_list: - expression COMMA argument_list { - CreateEntry(cur, look_up(cur, $1), "", NULL); - $$ = $3 + 1; - printdebug("[ARGUMENT_LIST] argument list is %d", $$);} - | expression { - CreateEntry(cur, look_up(cur, $1), "", NULL); - $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$);} - ; + expression COMMA argument_list + { + CreateEntry(cur, look_up(cur, $1), "", NULL); + $$ = $3 + 1; + printdebug("[ARGUMENT_LIST] argument list is %d", $$); + } + + | expression + { + CreateEntry(cur, look_up(cur, $1), "", NULL); + $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); + } + ; + + // will ALWAYS be a TYPE expression: - constant {printdebug("constant expression");} {$$ = $1;} + constant + { + printdebug("constant expression"); + $$ = $1; + } - | SUB_OR_NEG expression %prec UMINUS {printdebug("negative expression");if(strcmp($2,"integer") != 0) - {printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); - $$=strdup("undefined");}else{$$=$2;}} + | SUB_OR_NEG expression %prec UMINUS + { + printdebug("negative expression"); + if(strcmp($2,"integer") != 0) { + printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); + $$=strdup("undefined"); + } else { + $$=$2; + } + } - | NOT expression {printdebug("not expression"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined"); - printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", - @1.first_line,@1.first_column,$2);}} + | NOT expression + { + printdebug("not expression"); + if(strcmp($2,"Boolean")==0) { + $$=$2; + } else { + $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,$2); + } + } - | expression ADD expression - {printdebug("add expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression ADD expression + { + printdebug("add expression"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression SUB_OR_NEG expression - {printdebug("sub or neg expression");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression SUB_OR_NEG expression + { + printdebug("sub or neg expression"); + if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression MUL expression - {printdebug("multiply expression"); - if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression MUL expression + { + printdebug("multiply expression"); + if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else{ + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression DIV expression - {printdebug("divide expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression DIV expression + { + printdebug("divide expression"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression REM expression - {printdebug("remainder expression");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression REM expression + { + printdebug("remainder expression"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { + $$=strdup("integer"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression AND expression - {printdebug("AND expression");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression AND expression + { + printdebug("AND expression"); + if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) { + $$=strdup("Boolean"); + } else{ + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression OR expression - {printdebug("OR");if(strcmp($1,$3)==0 && - strcmp($1,"Boolean")==0){$$=strdup("Boolean");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression OR expression + { + printdebug("OR"); + if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) { + $$=strdup("Boolean"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression LESS_THAN expression - {printdebug("less than expression");if(strcmp($1,$3)==0 && - strcmp($1,"integer")==0){$$=strdup("Boolean");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", - @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined");}} + | expression LESS_THAN expression + { + printdebug("less than expression"); + if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { + $$=strdup("Boolean"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | expression EQUAL_TO expression {printdebug("equals check expression"); - if(strcmp($1,$3)==0){$$=strdup("Boolean");} - //else if((strcmp($1,"array")==0||strcmp($1,"record")==0|| - // strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");} - else{printdebug("mismatch at line %d and column %d. Invalid types %s and %s", - @2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}} + | expression EQUAL_TO expression + { + printdebug("equals check expression"); + if(strcmp($1,$3)==0) { + $$=strdup("Boolean"); + } else { + printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,$1,$3); + $$=strdup("undefined"); + } + } - | assignable {printdebug("assignable expression. current type is %s",$1);$$=$1;} + | assignable + { + printdebug("assignable expression. current type is %s",$1); + $$=$1; + } + + | L_PAREN expression R_PAREN + { + printdebug("paren expression. current type is %s",$2); + $$=$2; + } + + | memOp assignable + { + $$ = strdup("address"); + } + + ; - | L_PAREN expression R_PAREN {printdebug("paren expression. current type is %s",$2);$$=$2;} - | memOp assignable {$$ = strdup("address");} - ; // prolly right, check back with me later // add array case @@ -403,13 +576,16 @@ assignable: ID { $$ = getType(look_up(cur,$1)); - printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);} + printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1); + } + | assignable { printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); cur = CreateScope(cur, -1,-1); } - ablock { + ablock + { int type = getAdInfoType(look_up(getParent(cur), $1)); printdebug("%stype is %d", COLOR_PURPLE, type); @@ -434,8 +610,7 @@ assignable: tn = getNextEntry(tn); } lastCheckedRef = tn; - } - + } } else { char *expected = getName(getParameter(look_up(getParent(cur), $1))); char *actual = getType(getFirstEntry(cur)); @@ -443,6 +618,7 @@ assignable: printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); } } + $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); @@ -451,16 +627,12 @@ assignable: if (getNumArrDim(look_up(getParent(cur), $1)) != $2) { printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); } - // for (TableNode *tn = getFirstEntry(cur); tn != NULL; tn = getNextEntry(tn)) { - // if (strcmp(getName(tn), "integer") != 0) { - // printdebug("expected only integer expressions in array ablock at line %d column %d", @3.first_line, @3.first_column); - // } - // } $$ = getName(getArrType(look_up(getParent(cur), $1))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); } cur = getParent(cur); } + | assignable rec_op ID { if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)) { @@ -468,34 +640,97 @@ assignable: } printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1); } + ; + + memOp: - RESERVE {printdebug("reserve expression");} - | RELEASE {printdebug("release expression");} - ; + RESERVE + { + printdebug("reserve expression"); + } + + | RELEASE + { + printdebug("release expression"); + } + + ; constant: - C_STRING {$$ = $1; printdebug("string of C_STRING in constant is %s",$1);} - | C_INTEGER {$$ = "integer"; printdebug("string of C_INTEGER in constant is integer");} - | C_NULL {$$ = $1; printdebug("string of C_NULL in constant is %s",$1);} - | C_CHARACTER {$$ = $1; printdebug("string of C_CHARACTER in constant is %s",$1);} - | C_TRUE {$$ = $1; printdebug("string of C_TRUE in constant is %s",$1);} - | C_FALSE {$$ = $1; printdebug("string of C_FALSE in constant is %s",$1);} - ; + C_STRING + { + $$ = $1; + printdebug("string of C_STRING in constant is %s",$1); + } + + | C_INTEGER + { + $$ = "integer"; + printdebug("string of C_INTEGER in constant is integer"); + } + + | C_NULL + { + $$ = $1; + printdebug("string of C_NULL in constant is %s",$1); + } + + | C_CHARACTER + { + $$ = $1; + printdebug("string of C_CHARACTER in constant is %s",$1); + } + + | C_TRUE + { + $$ = $1; + printdebug("string of C_TRUE in constant is %s",$1); + } + + | C_FALSE + { + $$ = $1; + printdebug("string of C_FALSE in constant is %s",$1); + } + + ; + + types: - // Commented out T_String below - // T_STRING {printdebug("string of T_STRING in types is %s",$1);} {$$ = $1;} - T_INTEGER {printdebug("string of T_INTEGER in types is %s",$1);} {$$ = $1;} - | T_ADDRESS {printdebug("string of T_ADDRESS in types is %s",$1);} {$$ = $1;} - | T_CHARACTER {printdebug("string of T_CHARACTER in types is %s",$1);} {$$ = $1;} - | T_BOOLEAN {printdebug("string of T_BOOLEAN in types is %s",$1);} {$$ = $1;} - ; + T_INTEGER + { + $$ = $1; + printdebug("string of T_INTEGER in types is %s",$1); + } + + | T_ADDRESS + { + $$ = $1; + printdebug("string of T_ADDRESS in types is %s",$1); + } + + | T_CHARACTER + { + $$ = $1; + printdebug("string of T_CHARACTER in types is %s",$1); + } + + | T_BOOLEAN + { + $$ = $1; + printdebug("string of T_BOOLEAN in types is %s",$1); + } + + ; %% + + void yyerror(const char *err) { - fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column); + fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column); } diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index b43c979..920cdc4 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -5,25 +5,25 @@ %option header-file="flex.h" %option yylineno %{ - #include - #include "../tmp/grammar.tab.h" - #include "../src/symbol_table.h" - #ifndef DEBUG - #define DEBUG 0 - #endif - extern SymbolTable * cur; - extern FILE* tok_flag; - extern void incr(int lnum,int cnum, int tok); - extern void print_tok(int tok); - - int line_number = 1, column_number = 1; - int yycolumn = 1; - #define YY_USER_ACTION { \ - yylloc.first_line = yylineno; \ - yylloc.last_line = yylineno; \ - yylloc.first_column = yycolumn; \ - yylloc.last_column = yycolumn + yyleng - 1; \ - yycolumn += yyleng; } + #include + #include "../tmp/grammar.tab.h" + #include "../src/symbol_table.h" + #ifndef DEBUG + #define DEBUG 0 + #endif + extern SymbolTable * cur; + extern FILE* tok_flag; + extern void incr(int lnum,int cnum, int tok); + extern void print_tok(int tok); + + int line_number = 1, column_number = 1; + int yycolumn = 1; + #define YY_USER_ACTION { \ + yylloc.first_line = yylineno; \ + yylloc.last_line = yylineno; \ + yylloc.first_column = yycolumn; \ + yylloc.last_column = yycolumn + yyleng - 1; \ + yycolumn += yyleng; } %} STARCOM [^\*]|\*+[^\)\*]+ diff --git a/src/symbol_table.c b/src/symbol_table.c index 1a879cd..97b4eac 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -66,7 +66,8 @@ typedef enum { // TYPE_ADDRESS, // Type String is an array of char enclosed in double quotes per lexer TYPE_STRING = 1, - // Array can be multidimensional. Information should be stored here. This is the type of the array + // Array can be multidimensional. Information should be stored here. + // This is the type of the array TYPE_ARRAY_TYPE = 2, // Record is user defined types TYPE_RECORD_TYPE = 3, @@ -84,7 +85,7 @@ typedef enum { TYPE_ALL_ELSE = 7, TYPE_UNDEFINED = 8, TYPE_RECORD = 9, - TYPE_ARRAY = 10 + TYPE_ARRAY = 10 } types; @@ -513,8 +514,9 @@ SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) { // types SymbolTable *init(SymbolTable *start) { if (start->Parent_Scope != NULL) { - printdebug( - "%s[FATAL] Cannot initialize a scope that is not the parent scope", COLOR_RED); + printdebug("%s[FATAL] Cannot initialize a scope that is not " + "the parent scope", + COLOR_RED); return NULL; } integ = (TableNode *)calloc(1, sizeof(TableNode)); @@ -707,15 +709,15 @@ int getAdInfoType(TableNode *tn) { if (strcmp(getName(tn), getName(undefined)) == 0) { return TYPE_UNDEFINED; } else { - if(strcmp(getType(tn), getName(funtypeprime))==0){ + if (strcmp(getType(tn), getName(funtypeprime)) == 0) { printdebug("passed in a function to getAdInfoType"); return TYPE_FUNCTION_DECLARATION; } - if(strcmp(getType(tn), getName(arrayprim))==0){ + if (strcmp(getType(tn), getName(arrayprim)) == 0) { printdebug("passed in an array to getAdInfoType"); - return TYPE_ARRAY_TYPE; + return TYPE_ARRAY_TYPE; } - if(strcmp(getType(tn), getName(recprime))==0){ + if (strcmp(getType(tn), getName(recprime)) == 0) { printdebug("passed in a record to getAdInfoType"); return TYPE_RECORD; } @@ -1139,13 +1141,14 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getChildren(table) != NULL) { ListOfTable *node = getChildren(table); for (; node != NULL; node = node->next) { - if((node->table) == NULL){ - print_symbol_table(node->table, file_ptr); - }else{ - if ((node->table)->Line_Number == -1){ - continue; - }else{ - print_symbol_table(node->table, file_ptr); + if ((node->table) == NULL) { + print_symbol_table(node->table, file_ptr); + } else { + if ((node->table)->Line_Number == -1) { + continue; + } else { + print_symbol_table(node->table, + file_ptr); } } } diff --git a/test b/test deleted file mode 100644 index e69de29..0000000 From 1765878b85c9846e0b19134cdad9378fb6f1ace9 Mon Sep 17 00:00:00 2001 From: Annie Date: Thu, 3 Apr 2025 17:51:18 -0400 Subject: [PATCH 063/137] rebased made progress on type checking function definitions and calls --- src/grammar.y | 85 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index b3f2334..cbb9ec1 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -199,33 +199,45 @@ definition: } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { + setStartLine(node, @1.first_line); + setAsKeyword(node, false); + } + cur = CreateScope(cur, 0, 0); + } L_PAREN ID { + printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", + $1,$4); + CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + }R_PAREN ASSIGN sblock + | ID { + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == undefined) { + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ + printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + } + else { + printdebug("setting as keyword to true"); setStartLine(node, @1.first_line); setAsKeyword(node, true); } cur = CreateScope(cur, 0, 0); - } - AS L_PAREN - { + }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - printdebug("%s", getType(parameter)); + printdebug("parameter type: %s", getType(parameter)); if (parameter == undefined) { printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); - } else if(getAdInfoType(parameter) != TYPE_RECORD) { + }else if(getAdInfoType(parameter) != TYPE_RECORD){ printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); - } else { - for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)) { - CreateEntry(cur, entry, NULL, NULL); + }else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ + printdebug("creating entry of type %s for function", getType(entry)); + CreateEntry(cur, entry, "undefined", NULL); } } - } - idlist - { - printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$6); - } - R_PAREN ASSIGN sblock - ; - + } idlist {printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", + $1,$6);} R_PAREN ASSIGN sblock + ; function_declaration: @@ -403,22 +415,22 @@ ablock: argument_list: +<<<<<<< HEAD expression COMMA argument_list { - CreateEntry(cur, look_up(cur, $1), "", NULL); + CreateEntry(cur, look_up(cur, $1), $1, NULL); $$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } | expression { - CreateEntry(cur, look_up(cur, $1), "", NULL); + CreateEntry(cur, look_up(cur, $1), $1, NULL); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } ; - // will ALWAYS be a TYPE expression: constant @@ -575,6 +587,7 @@ expression: assignable: ID { + //$$ = $1; $$ = getType(look_up(cur,$1)); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1); } @@ -588,29 +601,40 @@ assignable: { int type = getAdInfoType(look_up(getParent(cur), $1)); printdebug("%stype is %d", COLOR_PURPLE, type); + printdebug("%s", $1); if (type == TYPE_FUNCTION_DECLARATION) { printdebug("%sEntering function call", COLOR_LIGHTGREEN); - if (getAsKeyword(look_up(getParent(cur), $1))) { - TableNode *param = getParameter(look_up(getParent(cur), $1)); + if (look_up(getParent(cur), $1)->additionalinfo->FunDecAdInfo->regularoras) { + printdebug("as function"); + //char *funtype = getType(look_up(cur, $1)); + printdebug("%s", getType(look_up(cur, $1))); + TableNode *param = getParameter(look_up(cur, getType(look_up(cur, $1)))); SymbolTable *recList = getRecList(param); TableNode *lastCheckedRef = getFirstEntry(recList); TableNode *lastCheckedAct = getFirstEntry(cur); while (getNextEntry(lastCheckedRef) != NULL) { - lastCheckedRef = getNextEntry(lastCheckedRef); + lastCheckedRef = getNextEntry(lastCheckedRef); } + + //this isn't very efficient, but will hopefully work while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + if (strcmp(getName(lastCheckedAct), getType(lastCheckedRef)) != 0) { + printdebug("expected %s. expression in function call got %s. at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + printdebug("%d", strcmp(getName(lastCheckedAct), getName(lastCheckedRef))); } lastCheckedAct = getNextEntry(lastCheckedAct); TableNode *tn = getFirstEntry(recList); - while (getNextEntry(tn) != lastCheckedRef) { - tn = getNextEntry(tn); - } - lastCheckedRef = tn; - } + + if (tn != lastCheckedRef) { + while (getNextEntry(tn) != lastCheckedRef) { + tn = getNextEntry(tn); + } + lastCheckedRef = tn; + } else {break;} + } + } else { char *expected = getName(getParameter(look_up(getParent(cur), $1))); char *actual = getType(getFirstEntry(cur)); @@ -618,8 +642,7 @@ assignable: printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); } } - - $$ = getName(getReturn(table_lookup(getAncestor(cur), $1))); + $$ = getName(getReturn((look_up(cur, getType(look_up(cur, $1)))))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); } else if (type == TYPE_ARRAY_TYPE) { From 4e862d54a4285d856dd53ba880b83b6d9e54674a Mon Sep 17 00:00:00 2001 From: Scarlett Date: Thu, 3 Apr 2025 18:29:43 -0400 Subject: [PATCH 064/137] Header files updated --- src/grammar.y | 29 +---- src/lexicalStructure.lex | 2 +- src/runner.c | 13 +-- src/runner.h | 46 ++++++-- src/symbol_table.c | 235 +-------------------------------------- src/symbol_table.h | 118 ++++++++++++++------ 6 files changed, 132 insertions(+), 311 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index b3f2334..63f2034 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -11,35 +11,16 @@ // 4️⃣ Rule end-markers (;, |) should always be 4 spaces in. // 5️⃣ C-blocks should always be clearly defined and follow clang formatting rules. // 6️⃣ 1-line if/for/while statements must be wrapped in curly braces. -// 7️⃣ DO NOT USE TABS. EVER. +// 7️⃣ Comments should always be above rules +// 8️⃣ DO NOT USE TABS. EVER. // Please ask Scarlett if you are unsure of how to format something. Thanks! 😀 %{ - #include #include "../src/symbol_table.c" - #include - extern int yylex(void); + void yyerror(const char *err); - extern char* yytext; - extern int yyleng; - extern int yychar; - extern SymbolTable * cur; - //char* cur_value; - //char* cur_type; int token_tracker; - extern int line_number; - extern int column_number; - extern FILE * yyin; - extern TableNode* funprime; - extern TableNode* arrayprim; - extern TableNode* recprime; - extern TableNode* funtypeprime; - extern TableNode* integ; - extern TableNode* addr; - extern TableNode* chara; - extern TableNode* stri; - extern TableNode* boo; TableNode * tn; %} @@ -144,7 +125,7 @@ definition: printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (table_lookup(getAncestor(cur), $2) == undefined) { - printdebug("rec not found "); + printdebug("rec not found"); } } dblock @@ -196,7 +177,7 @@ definition: } if (node == undefined) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { + } else if (getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 920cdc4..00b5a4d 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -4,8 +4,8 @@ %option noyywrap %option header-file="flex.h" %option yylineno + %{ - #include #include "../tmp/grammar.tab.h" #include "../src/symbol_table.h" #ifndef DEBUG diff --git a/src/runner.c b/src/runner.c index c6f94a3..5f903c3 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,17 +2,6 @@ /* The Translators - Spring 2025 */ #include "runner.h" -extern TableNode *funprime; -extern TableNode *arrayprim; -extern TableNode *integ; -extern TableNode *addr; -extern TableNode *chara; -extern TableNode *stri; -extern TableNode *boo; -extern bool DEBUG; -extern char *COLOR_YELLOW; -extern char *COLOR_BLUE; -extern char *COLOR_WHITE; int main(int argc, char *argv[]) { // if last argument is debug then set to true and ignore it for the rest @@ -91,10 +80,12 @@ void incr(int lnum, int cnum, int tok) { // column_number += yyleng; // } } + void print_tok(int tok) { fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, tok, yytext); } + int run(FILE *alpha) { int token; top = cur = init(CreateScope(NULL, 1, 1)); diff --git a/src/runner.h b/src/runner.h index 9678609..cc573c5 100644 --- a/src/runner.h +++ b/src/runner.h @@ -25,30 +25,56 @@ #include #include "../tmp/flex.h" -#include "symbol_table.h" -// #include "typedefs.h" #include "../tmp/grammar.tab.h" +#include "symbol_table.h" extern int line_number, column_number; extern char *yytext; extern FILE *yyin; -int arg; +extern bool DEBUG; SymbolTable *top; SymbolTable *cur; -// int main(int argc, char* argv[]); -char *is_tok(int argc, char *argv[]); -// int is_alpha_file(char *file, int file_len); - FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; +bool DEBUG = false; int no_flag = 0; +int arg; + +TableNode *funprime; +TableNode *arrayprim; +TableNode *integ; +TableNode *addr; +TableNode *chara; +TableNode *stri; +TableNode *boo; +TableNode *recprime; +TableNode *funtypeprime; +TableNode *undefined; int main(int argc, char *argv[]); +int check_flag(char *arg, char *alpha); +void incr(int lnum, int cnum, int tok); +void print_tok(int tok); +int run(FILE *alpha); +bool is_help(char *input); int new_file(char *arg, char *alpha); int is_alpha_file(char *alpha, int file_len); -bool is_help(char *input); -int run(FILE *alpha); -int check_flag(char *arg, char *alpha); + +char *COLOR_RED = "\033[0;31m"; +char *COLOR_GREEN = "\033[0;32m"; +char *COLOR_ORANGE = "\033[0;33m"; +char *COLOR_BLUE = "\033[0;34m"; +char *COLOR_PURPLE = "\033[0;35m"; +char *COLOR_CYAN = "\033[0;36m"; +char *COLOR_LIGHTGRAY = "\033[0;37m"; +char *COLOR_DARKGRAY = "\033[1;30m"; +char *COLOR_LIGHTRED = "\033[1;31m"; +char *COLOR_LIGHTGREEN = "\033[1;32m"; +char *COLOR_YELLOW = "\033[1;33m"; +char *COLOR_LIGHTBLUE = "\033[1;34m"; +char *COLOR_LIGHTPURPLE = "\033[1;35m"; +char *COLOR_LIGHTCYAN = "\033[1;36m"; +char *COLOR_WHITE = "\033[1;37m"; \ No newline at end of file diff --git a/src/symbol_table.c b/src/symbol_table.c index 97b4eac..f458769 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -3,44 +3,6 @@ #include "symbol_table.h" -#include -#include -#include -#include -char *typey = "type"; -char *funy = "function"; -TableNode *funprime; -TableNode *arrayprim; -extern SymbolTable *cur; -TableNode *integ; -TableNode *addr; -TableNode *chara; -TableNode *stri; -TableNode *boo; -TableNode *recprime; -TableNode *funtypeprime; -TableNode *undefined; - -char *COLOR_RED = "\033[0;31m"; -char *COLOR_GREEN = "\033[0;32m"; -char *COLOR_ORANGE = "\033[0;33m"; -char *COLOR_BLUE = "\033[0;34m"; -char *COLOR_PURPLE = "\033[0;35m"; -char *COLOR_CYAN = "\033[0;36m"; -char *COLOR_LIGHTGRAY = "\033[0;37m"; -char *COLOR_DARKGRAY = "\033[1;30m"; -char *COLOR_LIGHTRED = "\033[1;31m"; -char *COLOR_LIGHTGREEN = "\033[1;32m"; -char *COLOR_YELLOW = "\033[1;33m"; -char *COLOR_LIGHTBLUE = "\033[1;34m"; -char *COLOR_LIGHTPURPLE = "\033[1;35m"; -char *COLOR_LIGHTCYAN = "\033[1;36m"; -char *COLOR_WHITE = "\033[1;37m"; - -bool DEBUG = false; - -void printdebug_impl(char *file, int line, const char *format, ...); - void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { printf("%s<%s> [%d]%s ", COLOR_DARKGRAY, file, line, @@ -53,87 +15,6 @@ void printdebug_impl(char *file, int line, const char *format, ...) { } } -#define printdebug(format, ...) \ - printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) - -// AdInfo *Undefined_function_type_info; -typedef enum { - // First 4 below are primitive types that are all encapsulated in - // primitive type - // TYPE_INTEGER, - // TYPE_CHARACTER, - // TYPE_BOOLEAN, - // TYPE_ADDRESS, - // Type String is an array of char enclosed in double quotes per lexer - TYPE_STRING = 1, - // Array can be multidimensional. Information should be stored here. - // This is the type of the array - TYPE_ARRAY_TYPE = 2, - // Record is user defined types - TYPE_RECORD_TYPE = 3, - // Declaring what type a particular function is without as - TYPE_FUNCTION_DECLARATION = 4, - // Declaring what type a particular function is with as - // TYPE_AS_FUNCTION_DECLARATION, - // Declaring what type a function is (what the parameters and output - // are) - TYPE_FUNCTION_TYPE = 5, - // The Type being pointed to by the first 4 above that only stores the - // size - TYPE_PRIMITIVE = 6, - // likely NULL - TYPE_ALL_ELSE = 7, - TYPE_UNDEFINED = 8, - TYPE_RECORD = 9, - TYPE_ARRAY = 10 - -} types; - -/* put in symbol_table.h -typedef struct{ - int size; if(strcmp(getType(tn),getName(integ))==0){ - return - } -}primitive_info; - -typedef struct{ - int length; - char* location; -}string_info; - -typedef struct{ - int numofdimensions; - //the above value tells you how long the below array is. For example if num -of dimensions is 5, I can store 1,3,2,5,9 to define > int* sizesofdimensions; - TableNode* typeofarray; -}array_info; - -typedef struct{ - //similar to above we define a record to hold the number of elements and an -array of tablenodes (types) that it contains in the order specified by the user - int numofelements; - TableNode* listoftypes; -}record_info; - -typedef struct{ - int startlinenumber; - bool regularoras; -}function_declaration_info; - -typedef struct{ - TableNode* parameter; - TableNode* returntype; -}function_type_info; - -typedef union { - PrimAdInfo* primitive_info; - ArrayAdInfo* array_info; - RecAdInfo* record_info; - StringAdInfo* string_info; - FunDecAdInfo* func_dec_info; - FunTypeAdInfo* func_type_info; - }AdInfo; -*/ // primitive additional info only stores the size of that type AdInfo *CreatePrimitiveInfo(int size) { @@ -167,19 +48,10 @@ int getPrimSize(TableNode *definition) { return definition->additionalinfo->PrimAdInfo->size; } -// probably don't need the below structure since can create from an array -/*string_info* CreateStringInfo(int length, char* loc){ - string_info* stringy = (string_info*)malloc(sizeof(string_info)); - stringy.length=length; - char* location = loc; - return stringy; -} -*/ - // Only information stored in array info is the number of dimensions and the // type stored in the array per professor, the actual size of the array is // calculated at runtime so bounds checking only needs to be done then -AdInfo *CreateArrayInfo(int dim, /*int* sizes,*/ TableNode *type) { +AdInfo *CreateArrayInfo(int dim, TableNode *type) { if (type == NULL) { printdebug("passed a NULL reference to " "CreateArrayInfo. Invalid."); @@ -866,41 +738,7 @@ SymbolTable *setColumnNumber(SymbolTable *st, int column) { st->Line_Number = column; return st; } -/* -//we use false for type defs and true for functions for parameter of typeOf -TableNode* Define(SymbolTable* table, bool typeOf, char* id) { -if(table ==NULL || table->Parent_Scope != NULL){ - printdebug("No valid table given for header defs"); - return NULL; -} - - TableNode* newEntry = (TableNode*)malloc(sizeof(TableNode)); - -//possible issues with referencing text instead of heap -if(typeOf == 0){ - newEntry->theType = typey; -} -if (typeOf == 1){ - newEntry->theType = funy; -} -if(table_lookup(table,id) != NULL){ - printdebug("already defined at the top level, can't define duplicate -names"); return NULL; -} - newEntry->theName = id; - if (table->entries == NULL) { - table->entries = newEntry; - return newEntry; - } else { - TableNode* oldEntry = table->entries; - table->entries = newEntry; - newEntry->next = oldEntry; - return newEntry; - } - -} -*/ // only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { if (table == NULL) { @@ -915,6 +753,7 @@ TableNode *table_lookup(SymbolTable *table, char *x) { } return undefined; } + // check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { @@ -931,60 +770,7 @@ TableNode *look_up(SymbolTable *table, char *x) { x, getLine(table), getColumn(table)); return look_up(table->Parent_Scope, x); } -/* -void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", - "SCOPE", "PARENT", "TYPE", "Extra annotation"); - } - TableNode *entrie = table->entries; - fprintf(file_ptr, "-----------------:--------:--------:----------------" - "------:---------" - "--------------------\n"); - int parant_scope = 0; - int current_scope = 0; - if (table->Parent_Scope != NULL) { - parant_scope = table->Parent_Scope->Line_Number * 1000 + - table->Parent_Scope->Column_Number; - current_scope = - table->Line_Number * 1000 + table->Column_Number; - } else { - current_scope = 1001; - } - if (entrie == NULL) { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", - current_scope, parant_scope, "", "Empty Scope"); - } - for (; entrie != NULL; entrie = entrie->next) { - if (parant_scope == 0) { - /*have to update if (strcmp(entrie->theType->theName, - "function primitive") || - strcmp(entrie->theType->theName, - "array")) { - } - fprintf(file_ptr, - "%-17s: %06d : : %-21s: %-28s\n", - entrie->theName, current_scope, - entrie->theType->theName, "Extra annotation"); - } else { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", - entrie->theName, current_scope, parant_scope, - entrie->theType->theName, "Extra annotation"); - } - } - if (table->Children_Scope != NULL) { - ListOfTable *node = table->Children_Scope; - for (; node != NULL; node = node->next) { - print_symbol_table(node->table, file_ptr); - } - } - if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "-----------------:--------:--------:--------" - "--------------:-------" - "----------------------\n"); - } -}*/ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (table == NULL) { @@ -1286,20 +1072,3 @@ TableNode *getNextEntry(TableNode *tn) { } return tn->next; } - -// uncomment the below main function along with the headers above for a simple -// standalone test of table and entry creation - -/* - int main(){ - char* String = "STRING"; - char* X = "X"; - SymbolTable* Second = CreateScope(NULL, 2,2); - printdebug("Line number is %d, Column number of scope is - %d",Second->Line_Number,Second->Column_Number); TableNode* First_Entry = - CreateEntry(Second,String,X); - - printdebug("The type of the first entry is %s",First_Entry->theType); - return 0; - } - */ \ No newline at end of file diff --git a/src/symbol_table.h b/src/symbol_table.h index de37098..5f87b5b 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -1,3 +1,4 @@ +#include #include #include #include @@ -9,26 +10,12 @@ typedef struct { int size; } primitive_info; -/*This structure can be subsumed into the structure below (1-d array of chars) -typedef struct{ - //shouldn't need to store any values since would be compiled at runtime - //int length; - //char* location; -}string_info; -*/ - typedef struct { int numofdimensions; - // the above value tells you how long the below array is. For example if - // num of dimensions is 5, I can store 1,3,2,5,9 to define > int* - // arr; shouldn't need to store any values (like sizes of dimenions or - // the location int* sizesofdimensions; do have to store type of array struct TableNode *typeofarray; } array_info; typedef struct { - // similar to above we define a record to hold the number of elements - // and an array of tablenodes (types) that it contains in the > int numofelements; struct SymbolTable *recordScope; } record_info; @@ -47,19 +34,16 @@ typedef union { primitive_info *PrimAdInfo; array_info *ArrayAdInfo; record_info *RecAdInfo; - // string_info* StringAdInfo; function_declaration_info *FunDecAdInfo; function_type_info *FunTypeAdInfo; } AdInfo; typedef struct ListOfTable { struct SymbolTable *table; - // struct ListOfTable* prev; struct ListOfTable *next; } ListOfTable; typedef struct TableNode { - // reference to the type entry that this is struct TableNode *theType; char *theName; AdInfo *additionalinfo; @@ -74,30 +58,100 @@ typedef struct SymbolTable { int Column_Number; } SymbolTable; +typedef enum { + TYPE_STRING = 1, + TYPE_ARRAY_TYPE = 2, + TYPE_RECORD_TYPE = 3, + TYPE_FUNCTION_DECLARATION = 4, + TYPE_FUNCTION_TYPE = 5, + TYPE_PRIMITIVE = 6, + TYPE_ALL_ELSE = 7, + TYPE_UNDEFINED = 8, + TYPE_RECORD = 9, + TYPE_ARRAY = 10 +} types; + +AdInfo *CreatePrimitiveInfo(int size); +int getPrimSize(TableNode *definition); +AdInfo *CreateArrayInfo(int dim, TableNode *type); +int getNumArrDim(TableNode *definition); +TableNode *getArrType(TableNode *definition); +AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope); +int getRecLength(TableNode *definition); +SymbolTable *getRecList(TableNode *definition); +TableNode *setRecSize(TableNode *tn, int n); +int getRecSize(SymbolTable *tn); +AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular); +int getStartLine(TableNode *definition); +TableNode *setStartLine(TableNode *tn, int start); +bool getAsKeyword(TableNode *definition); +TableNode *setAsKeyword(TableNode *tn, bool as); +AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype); +TableNode *getParameter(TableNode *definition); +TableNode *getReturn(TableNode *definition); SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column); +SymbolTable *init(SymbolTable *start); +TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info); +int getAdInfoType(TableNode *tn); +TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, + AdInfo *ad); +char *getType(TableNode *tn); +char *getName(TableNode *tn); +int getLine(SymbolTable *st); +int getColumn(SymbolTable *st); +TableNode *addName(TableNode *tn, char *str); +SymbolTable *setLineNumber(SymbolTable *st, int line); +SymbolTable *setColumnNumber(SymbolTable *st, int column); TableNode *table_lookup(SymbolTable *table, char *x); TableNode *look_up(SymbolTable *table, char *x); void print_symbol_table(SymbolTable *table, FILE *file_ptr); - SymbolTable *getAncestor(SymbolTable *table); +SymbolTable *removeEntry(SymbolTable *scope, char *search); +bool typeCheck(char *firstID, char *secondID); SymbolTable *getParent(SymbolTable *st); ListOfTable *getChildren(SymbolTable *st); SymbolTable *getFirstChild(ListOfTable *lt); ListOfTable *getRestOfChildren(ListOfTable *lt); TableNode *getFirstEntry(SymbolTable *st); TableNode *getNextEntry(TableNode *tn); -SymbolTable *init(SymbolTable *scope); -int getPrimSize(TableNode *definition); -int getNumArrDim(TableNode *definition); -TableNode *getArrType(TableNode *definition); -int getRecLength(TableNode *definition); -SymbolTable *getRecList(TableNode *definition); -int getStartLine(TableNode *definition); -bool getAsKeyword(TableNode *definition); -TableNode *getParameter(TableNode *definition); -TableNode *getReturn(TableNode *definition); -char *getType(TableNode *tn); -char *getName(TableNode *tn); -int getLine(SymbolTable *st); -int getColumn(SymbolTable *st); +void printdebug_impl(char *file, int line, const char *format, ...); +#define printdebug(format, ...) \ + printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) + +extern int yylex(void); +extern char *yytext; +extern int yyleng; +extern int yychar; +extern SymbolTable *cur; +extern int line_number; +extern int column_number; +extern FILE *yyin; +extern bool DEBUG; + +extern TableNode *funprime; +extern TableNode *arrayprim; +extern TableNode *integ; +extern TableNode *addr; +extern TableNode *chara; +extern TableNode *stri; +extern TableNode *boo; +extern TableNode *recprime; +extern TableNode *funtypeprime; +extern TableNode *undefined; + +extern char *COLOR_RED; +extern char *COLOR_GREEN; +extern char *COLOR_ORANGE; +extern char *COLOR_BLUE; +extern char *COLOR_PURPLE; +extern char *COLOR_CYAN; +extern char *COLOR_LIGHTGRAY; +extern char *COLOR_DARKGRAY; +extern char *COLOR_LIGHTRED; +extern char *COLOR_LIGHTGREEN; +extern char *COLOR_YELLOW; +extern char *COLOR_LIGHTBLUE; +extern char *COLOR_LIGHTPURPLE; +extern char *COLOR_LIGHTCYAN; +extern char *COLOR_WHITE; \ No newline at end of file From 3bae28dfefb5c061c07f5229b186d1a8dbb4bfc4 Mon Sep 17 00:00:00 2001 From: Annie Date: Thu, 3 Apr 2025 19:04:43 -0400 Subject: [PATCH 065/137] started changing to pass up table nodes --- src/grammar.y | 56 +++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index cbb9ec1..33599a3 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -47,15 +47,16 @@ %union { int integ; - char * words; + TableNode *tn; + char *words; } %type idlist -%type assignable -%type expression -%type constant -%type id_or_types -%type types +%type assignable +%type expression +%type constant +%type id_or_types +%type types %token ID 101 %token T_INTEGER 201 %token T_ADDRESS 202 @@ -141,36 +142,36 @@ prototype: definition: TYPE ID COLON { - printdebug("Currently see a record definition for %s", $2); + printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); - if (table_lookup(getAncestor(cur), $2) == undefined) { + if (look_up(cur, $2) == undefined) { printdebug("rec not found "); } } dblock { - setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur)); + setRecSize(look_up(cur, $2), getRecSize(cur)); cur = getParent(cur); } | TYPE ID COLON C_INTEGER ARROW id_or_types { - printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, $6, $4); - CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6))); - printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6); + printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, getName($6), $4); + CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, $6)); + printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, getName($6)); } | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { - printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, $4, $6); - CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6))); + printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", getName($2), getName($4), getName($6)); + CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo($4 ,$6)); } | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); + TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { @@ -184,11 +185,11 @@ definition: L_PAREN ID { printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4); - CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); } R_PAREN ASSIGN sblock - | ID + | ID //EVERYTHING UP UNTIL THIS POINT HAS BEEN CHECKED FOR $TN TYPES { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { @@ -236,7 +237,7 @@ definition: } } } idlist {printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", - $1,$6);} R_PAREN ASSIGN sblock + $1,$6);} R_PAREN ASSIGN sblock //check sblock type ; @@ -343,7 +344,8 @@ declaration: id_or_types: ID { - printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1; + printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); + $$ = look_up(cur, $1); } | types @@ -415,7 +417,6 @@ ablock: argument_list: -<<<<<<< HEAD expression COMMA argument_list { CreateEntry(cur, look_up(cur, $1), $1, NULL); @@ -587,8 +588,7 @@ expression: assignable: ID { - //$$ = $1; - $$ = getType(look_up(cur,$1)); + $$ = look_up(cur,$1); printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1); } @@ -685,37 +685,37 @@ memOp: constant: C_STRING { - $$ = $1; + $$ = $1; printdebug("string of C_STRING in constant is %s",$1); } | C_INTEGER { - $$ = "integer"; + $$ = integ; printdebug("string of C_INTEGER in constant is integer"); } | C_NULL { - $$ = $1; + $$ = $1; printdebug("string of C_NULL in constant is %s",$1); } | C_CHARACTER { - $$ = $1; + $$ = $1; printdebug("string of C_CHARACTER in constant is %s",$1); } | C_TRUE { - $$ = $1; + $$ = $1; printdebug("string of C_TRUE in constant is %s",$1); } | C_FALSE { - $$ = $1; + $$ = $1; printdebug("string of C_FALSE in constant is %s",$1); } From 0eb0b8097ce935f45765aa9d05b06ca2bf6421f1 Mon Sep 17 00:00:00 2001 From: Partho Date: Thu, 3 Apr 2025 20:05:53 -0400 Subject: [PATCH 066/137] updated lex to return the right values to the tokens (mostly table entries) --- src/grammar.y | 28 ++++++++++++++-------------- src/lexicalStructure.lex | 28 +++++++++++++++++++--------- src/symbol_table.c | 20 ++++++++++++++++++++ 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 33599a3..8481152 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -47,28 +47,28 @@ %union { int integ; - TableNode *tn; - char *words; + char* words; + TableNode* tn; } %type idlist %type assignable %type expression -%type constant +%type constant %type id_or_types %type types -%token ID 101 -%token T_INTEGER 201 -%token T_ADDRESS 202 -%token T_BOOLEAN 203 -%token T_CHARACTER 204 -%token T_STRING 205 +%token ID 101 +%token T_INTEGER 201 +%token T_ADDRESS 202 +%token T_BOOLEAN 203 +%token T_CHARACTER 204 +%token T_STRING 205 %token C_INTEGER 301 -%token C_NULL 302 -%token C_CHARACTER 303 -%token C_STRING 304 -%token C_TRUE 305 -%token C_FALSE 306 +%token C_NULL 302 +%token C_CHARACTER 303 +%token C_STRING 304 +%token C_TRUE 305 +%token C_FALSE 306 %token WHILE 401 %token IF 402 %token THEN 403 diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 920cdc4..940681a 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -13,6 +13,16 @@ #endif extern SymbolTable * cur; extern FILE* tok_flag; + extern TableNode *funprime; + extern TableNode *funtypeprime; + extern TableNode *arrayprim; + extern TableNode *recprime; + extern TableNode *integ; + extern TableNode *addr; + extern TableNode *chara; + extern TableNode *stri; + extern TableNode *boo; + extern TableNode *undefined; extern void incr(int lnum,int cnum, int tok); extern void print_tok(int tok); @@ -36,10 +46,10 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] %% -"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup(yytext);return T_INTEGER;}} -"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {if(tok_flag != NULL){print_tok(T_ADDRESS);}incr(line_number,column_number,T_ADDRESS);yylval.words = strdup(yytext);return T_ADDRESS;}} -"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup(yytext);return T_BOOLEAN;}} -"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {if(tok_flag != NULL){print_tok(T_CHARACTER);}incr(line_number,column_number,T_CHARACTER);yylval.words = strdup(yytext);return T_CHARACTER;}} +"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.tn = integ;return T_INTEGER;}} +"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {if(tok_flag != NULL){print_tok(T_ADDRESS);}incr(line_number,column_number,T_ADDRESS);yylval.tn = addr;return T_ADDRESS;}} +"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.tn = boo;return T_BOOLEAN;}} +"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {if(tok_flag != NULL){print_tok(T_CHARACTER);}incr(line_number,column_number,T_CHARACTER);yylval.tn = chara;return T_CHARACTER;}} "while" {if(DEBUG) {printf( "WHILE: %s (%d)\n", yytext, WHILE);} else {if(tok_flag != NULL){print_tok(WHILE);}incr(line_number,column_number,WHILE);return WHILE;}} "if" {if(DEBUG) {printf( "IF: %s (%d)\n", yytext, IF);} else {if(tok_flag != NULL){print_tok(IF);}incr(line_number,column_number,IF);return IF;}} @@ -73,8 +83,8 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {if(tok_flag != NULL){print_tok(ARROW);}incr(line_number,column_number,ARROW);return ARROW;}} {DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytext)/*words = strdup("integer")*/;return C_INTEGER;}} -'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.words = strdup("character");return C_CHARACTER;}} -\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.words = strdup("string");return C_STRING;}} +'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.tn = chara;return C_CHARACTER;}} +\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.tn = stri;return C_STRING;}} {COMMENT} {if(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}} "(" {if(DEBUG) {printf( "L_PAREN: %s (%d)\n", yytext, L_PAREN);} else {if(tok_flag != NULL){print_tok(L_PAREN);}incr(line_number,column_number,L_PAREN);return L_PAREN;}} @@ -84,9 +94,9 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "{" {if(DEBUG) {printf( "L_BRACE: %s (%d)\n", yytext, L_BRACE);} else {if(tok_flag != NULL){print_tok(L_BRACE);}incr(line_number,column_number,L_BRACE);return L_BRACE;}} "}" {if(DEBUG) {printf( "R_BRACE: %s (%d)\n", yytext, R_BRACE);} else {if(tok_flag != NULL){print_tok(R_BRACE);}incr(line_number,column_number,R_BRACE);return R_BRACE;}} -"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.words = strdup("Boolean");return C_TRUE;}} -"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.words = strdup("Boolean");return C_FALSE;}} -"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.words = strdup("address");return C_NULL;}} +"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.tn = boo;return C_TRUE;}} +"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.tn = boo;return C_FALSE;}} +"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.tn = addr;return C_NULL;}} {ID} {if(DEBUG) {printf( "ID: %s (%d)\n", yytext, ID);} else {if(tok_flag != NULL){print_tok(ID);}incr(line_number,column_number,ID);yylval.words = strdup(yytext); return ID;}} diff --git a/src/symbol_table.c b/src/symbol_table.c index 97b4eac..ec960e1 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -769,6 +769,26 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } } +TableNode *getTypeEntry(TableNode *tn) { + if (tn == NULL) { + printdebug("passed a NULL table entry to getType"); + return undefined; + } + if (tn == undefined) { + printdebug("passed an undefined table entry to getType"); + return undefined; + } + if (tn->theType == NULL) { + printdebug("type of entry is currently NULL type"); + return undefined; + } + if (tn->theType == undefined) { + printdebug("type of entry is currently undefined type"); + return undefined; + } + return tn->theType; +} + char *getType(TableNode *tn) { if (tn == NULL) { printdebug("passed a NULL table entry to getType"); From 9b73c657467c973e703fc4664b732a6c7737aeb4 Mon Sep 17 00:00:00 2001 From: Annie Date: Thu, 3 Apr 2025 17:34:18 -0400 Subject: [PATCH 067/137] allow renaming of tablenodes --- src/symbol_table.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index ec960e1..70f28d5 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -390,8 +390,8 @@ bool getAsKeyword(TableNode *definition) { } if (strcmp(getType(definition), "primitive function") != 0) { printdebug( - "not checking if a function is called with as or not -- " - "invalid op"); + "not checking if a function is called with as or not (%s) -- " + "invalid op", getType(definition)); return 0; } return definition->additionalinfo->FunDecAdInfo->regularoras; @@ -856,6 +856,11 @@ TableNode *addName(TableNode *tn, char *str) { printdebug( "Name doesn't look like it is empty before you change. " "Are you sure you need to update name?"); + if (str != NULL) { + tn->theName = str; + return tn; + } + printdebug("passed a NULL string to the addName function"); return undefined; } if (str == NULL) { @@ -1322,4 +1327,4 @@ TableNode *getNextEntry(TableNode *tn) { printdebug("The type of the first entry is %s",First_Entry->theType); return 0; } - */ \ No newline at end of file + */ From 4f62851575eec84cb9c7c2ff1a336130eb8659c0 Mon Sep 17 00:00:00 2001 From: Annie Date: Thu, 3 Apr 2025 17:40:06 -0400 Subject: [PATCH 068/137] reseting carl's mistake to what it should be from my changes --- tests/sprint2/test/sp2_carls_mistake.alpha | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index 2f4c1ef..daca47e 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -25,4 +25,4 @@ entry(arg) := { result := bar1(w); (* pass w (a rec type value) to bar1 *) result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) return 0; -} +} \ No newline at end of file From f7d1d90856d2a40536e2969e0cbe8b077ce5f342 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Fri, 4 Apr 2025 04:43:36 -0400 Subject: [PATCH 069/137] Added body of some of the functions (not compiling) #t51 --- src/intermediate_code.c | 90 +++++++++++++++++++++++++++-------------- src/intermediate_code.h | 38 +++++++++++++---- 2 files changed, 90 insertions(+), 38 deletions(-) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 24f370c..38cbe10 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -1,85 +1,113 @@ +#include #include "intermediate_code.h" +#include "symbol_table.h" - -start = current = NULL; - +Instruction * begin; +Instruction * current; // TODO: this is here to bring your attention to the comment bellow. // check if start is NULL if it is assign it to the start globle variable // otherwise make it next of current and set cur to your instruction. - +void emit_helper(void){ + Instruction * inst = calloc(1, sizeof(*inst)); + if(begin == NULL){ + begin = current = inst; + current->index = 1; + } else { + current->next = inst; + inst->prev = current; + inst->index = current->index++; + current = inst; + } +} void emit_binary_op(char* result, Op op, char* arg1, char* arg2){ - Instruction * inst = calloc(1, sizeof(*inst)); - if(start == NULL){ - start = current = inst; - current->index = 1; - } else { - current->next = inst; - inst->prev = current; - inst->index = current->index++; - current = inst; - } + emit_helper(); current->opcode = op; - current->result = look_up(result); - current->operand1 = look_up(arg1); - current->operand2 = look_up(arg2); + current->result = look_up(cur, result); + current->operand1 = look_up(cur, arg1); + current->operand2 = look_up(cur, arg2); return; } - void emit_unary_op(char* result, Oo op, char* arg){ - Instruction * inst = calloc(1, sizeof(*inst)); - if(start == NULL){ - start = current = inst; - current->index = 1; - } else { - current->next = inst; - inst->prev = current; - inst->index = current->index++; - current = inst; - } + + void emit_unary_op(char* result, Op op, char* arg){ + emit_helper(); current->opcode = op; - current->result = look_up(result); - current->operand1 = look_up(arg); + current->result = look_up(cur, result); + current->operand1 = look_up(cur, arg); return; } + void emit_assignment(char* target, char* source){ - return; + emit_helper(); + current->opcode = ADD; // TODO: replace with move + current->result = look_up(cur, target); + current->operand1 = look_up(cur, source); + return; } + void emit_as_file(FILE * out_file, Instruction * instr_arr){ + if(instr_arr == NULL){ + return; + } + + //fprintf(out_file, return; } void emit_label(char* label){ + emit_helper(); + current->opcode = LABEL; + current->label = label; return; } void emit_jump(char* label){ + emit_helper(); + current->opcode = GOTO; + current->label = label; return; } void emit_conditional_jump(char* condition, char* label){ + emit_helper(); + current->opcode = CGOTO; // I am positive this needs to be 2 instructions + current->label = label; return; } void emit_function_start(char* name){ + emit_helper(); // actualy what is this? + current->opcode = LABLE; // I think this is right TODO: ask + current->label = name; return; } void emit_parameter(char* param){ + emit_helper(); + current->opcode = PARAM; + current->operand1 = look_up(cur, param); return; } void emit_function_call(char* result, char* name){ + emit_helper(); + current->opcode = CALL; + current->operand1 = look_up(cur, name); + current->result = look_up(cur, result); return; } void emit_return(char* value){ + emit_helper(); return; } void emit_reserve(char* result, char* type_name, int size){ + emit_helper(); return; } void emit_release(char* pointer){ + emit_helper(); return; } diff --git a/src/intermediate_code.h b/src/intermediate_code.h index fdd0aff..464d331 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -12,24 +12,48 @@ // - Subtraction, multiplication, division, modulo #include "symbol_table.h" -typedef enum {ADD, SUB, MUL, DIV} Op; // TODO: add all the instructions -typedef struct { +// these are from page 364 +typedef enum { + LABEL, // this is not in the book + ADD, // 1 from the list + SUB, // 1 + MUL, // 1 + DIV, // 1 + MOD, // 1 + OR, // 1 + AND, // 1 + NEG, // 2 + NOT, // 2 + ASSIGN, // 3 + GOTO, // 4 + CGOTO, // 5 + LESSTHEN, // 6 rule 1 + 5 + EQUALTO, // 6 rule 1 + 5 + PARAM, // 7 + CALL // 7 + +} Op; +typedef struct Instruction { Op opcode; TableNode * result; TableNode * operand1; TableNode * operand2; - int label; + char * label; + + int index; + + Instruction * prev; Instruction * next; } Instruction; -Instruction * start; -Instruction * current; +extern Instruction * begin; +extern Instruction * current; -void emit_binary_op(char* result, char* op, char* arg1, char* arg2); -void emit_unary_op(char* result, char* op, char* arg); +void emit_binary_op(char* result, Op op, char* arg1, char* arg2); +void emit_unary_op(char* result, Op op, char* arg); void emit_assignment(char* target, char* source); // TODO: Find out what these are suposed to do. Guess is create an entry in // the list of instructions. Guess is that its suposed to ret a struct ptr From 5e749eb1ac80c9338de329db044c2c49580554e6 Mon Sep 17 00:00:00 2001 From: Annie Date: Fri, 4 Apr 2025 10:16:45 -0400 Subject: [PATCH 070/137] updated 3756156 to use table nodes up until comment in grammar.y --- src/grammar.y | 144 +++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 8481152..7b39031 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -189,9 +189,9 @@ definition: } R_PAREN ASSIGN sblock - | ID //EVERYTHING UP UNTIL THIS POINT HAS BEEN CHECKED FOR $TN TYPES + | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); + TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { printdebug("null check"); } @@ -210,7 +210,7 @@ definition: CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); }R_PAREN ASSIGN sblock | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); + TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ @@ -223,7 +223,7 @@ definition: } cur = CreateScope(cur, 0, 0); }AS L_PAREN { - TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); printdebug("parameter type: %s", getType(parameter)); if (parameter == undefined) { printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); @@ -265,11 +265,11 @@ idlist: if (getNextEntry(entry) == NULL) { printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); } - addName(entry, $1); + addName(entry, 1); } COMMA idlist { - $$ = $4 + 1; + $$ = $4 + 1; } | ID @@ -334,8 +334,8 @@ declaration_list: declaration: id_or_types COLON ID { - printdebug("ID/TYPE: %s, ID: %s", $1, $3) ; - CreateEntry(cur,table_lookup(getAncestor(cur),$1),$3,NULL); + printdebug("ID/TYPE: %s, ID: %s", getName($1), $3) ; + CreateEntry(cur,$1,$3,NULL); } ; @@ -350,7 +350,7 @@ id_or_types: | types { - printdebug("string of type is %s in types pattern of id_or_type rule.",$1); + printdebug("string of type is %s in types pattern of id_or_type rule.",getName($1)); $$ = $1; } ; @@ -377,22 +377,22 @@ compound_statement: simple_statement: assignable ASSIGN expression { - if(strcmp($1, $3) == 0) { + if(strcmp(getType($1), getType($3)) == 0) { printdebug("Passed standard type check; assignable = expression"); - } else if((strcmp(getType(look_up(cur, $1)), "array") == 0) && (strcmp($3, "address") == 0)) { - printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, $1, $3); - } else if((strcmp(getType(look_up(cur, $1)), "record") == 0) && (strcmp($3, "address") == 0)) { - printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, $1, $3); - } else if((strcmp(getType(look_up(cur, $1)), "function type primitive") == 0) && (strcmp($3, "address") == 0)) { - printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, $1, $3); + } else if((strcmp(getType($1), "array") == 0) && (strcmp($3, "address") == 0)) { + printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, getType($1), getType($3)); + } else if((strcmp(getType($1), "record") == 0) && (strcmp($3, "address") == 0)) { + printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, getType($1), getType($3)); + } else if((strcmp(getType($1), "function type primitive") == 0) && (strcmp(getType($3), "address") == 0)) { + printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, getType($1), getType($3)); // } else if () { // } else if(strcmp(getType(table_lookup(cur, $1)), getType(table_lookup(cur, $3))) == 0) { // printdebug("%s[] Passed double lookup type check; %s = %s", COLOR_GREEN, $1, $3); } else { printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); - printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE); - printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(look_up(cur, $1))); + printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType($1), getType($3), COLOR_WHITE); + printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType($1)); } } @@ -409,8 +409,8 @@ rec_op: ablock: L_PAREN argument_list R_PAREN { - $$ = $2; - printdebug("ablock is %d", $$); + $$ = $2; + printdebug("ablock is %d", $$); } ; @@ -419,15 +419,15 @@ ablock: argument_list: expression COMMA argument_list { - CreateEntry(cur, look_up(cur, $1), $1, NULL); - $$ = $3 + 1; - printdebug("[ARGUMENT_LIST] argument list is %d", $$); + CreateEntry(cur, $1, getName($1), NULL); + $$ = $3 + 1; + printdebug("[ARGUMENT_LIST] argument list is %d", $$); } | expression { - CreateEntry(cur, look_up(cur, $1), $1, NULL); - $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); + CreateEntry(cur, $1, getName($1), NULL); + $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } ; @@ -437,15 +437,15 @@ expression: constant { printdebug("constant expression"); - $$ = $1; + $$ = $1; } | SUB_OR_NEG expression %prec UMINUS { printdebug("negative expression"); - if(strcmp($2,"integer") != 0) { + if($2 != integ) { printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); - $$=strdup("undefined"); + $$=undefined; } else { $$=$2; } @@ -454,133 +454,133 @@ expression: | NOT expression { printdebug("not expression"); - if(strcmp($2,"Boolean")==0) { + if($2 == boo) { $$=$2; } else { - $$=strdup("undefined"); - printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,$2); + $$=undefined; + printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,getName($2)); } } | expression ADD expression { printdebug("add expression"); - if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { - $$=strdup("integer"); + if($1 == $3 && $1 == integ) { + $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + $$=undefined; } } | expression SUB_OR_NEG expression { printdebug("sub or neg expression"); - if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) { - $$=strdup("integer"); + if($1 == $3 && $1 == integ) { + $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + $$=undefined; } } | expression MUL expression { printdebug("multiply expression"); - if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) { - $$=strdup("integer"); + if($1 == $3 && $1 == integ) { + $$=$1; } else{ - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + $$=undefined; } } | expression DIV expression { printdebug("divide expression"); - if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { - $$=strdup("integer"); + if(strcmp($1 == $3 && $1 == integ) { + $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + $$=undefined; } } | expression REM expression { printdebug("remainder expression"); - if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { - $$=strdup("integer"); + if($1 == $3 && $1 == integ) { + $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + $$=undefined; } } | expression AND expression { printdebug("AND expression"); - if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) { - $$=strdup("Boolean"); + if($1 == $3 && $1 == boo { + $$=$1; } else{ - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + $$=undefined; } } | expression OR expression { printdebug("OR"); - if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) { - $$=strdup("Boolean"); + if(strcmp($1 == $3 && $1 == boo) { + $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + $$=undefined; } } - + | expression LESS_THAN expression { printdebug("less than expression"); - if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) { - $$=strdup("Boolean"); + if($1 == $3 && $1==integ) { + $$=boo; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + $$=undefined; } } | expression EQUAL_TO expression { printdebug("equals check expression"); - if(strcmp($1,$3)==0) { - $$=strdup("Boolean"); + if($1 == $3 && $1 != undefined) { + $$=boo; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,$1,$3); - $$=strdup("undefined"); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,getName($1),getName($3)); + $$ = undefined; } } | assignable { printdebug("assignable expression. current type is %s",$1); - $$=$1; + $$= getTypeEntry($1);//idk if this is correct } | L_PAREN expression R_PAREN { - printdebug("paren expression. current type is %s",$2); + printdebug("paren expression. current type is %s",getName($2)); $$=$2; } | memOp assignable { - $$ = strdup("address"); + $$ = addr; } ; - +//UPDATED $$ for tablenodes to this point // prolly right, check back with me later // add array case From d1aa7f7e0f570d7ac63e687039f8f0cb88e93fe7 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 4 Apr 2025 15:42:50 -0400 Subject: [PATCH 071/137] =?UTF-8?q?Ready=20for=20Dev!=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/grammar.y | 18 ++++++++-- src/runner.c | 14 ++++++-- src/symbol_table.c | 55 ++++++++++++++--------------- tests/sprint2/test/sp2_llnode.alpha | 1 + 4 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 63f2034..7b925f6 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -196,7 +196,7 @@ definition: printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); } else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)) { - CreateEntry(cur, entry, NULL, NULL); + CreateEntry(cur, entry->theType, NULL, NULL); } } } @@ -258,8 +258,11 @@ idlist: sblock: L_BRACE { - if (getLine(cur) != 0 && getColumn(cur)) { + if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); + } else { + setLineNumber(cur, @1.first_line); + setColumnNumber(cur,@1.first_line); } } statement_list @@ -288,7 +291,16 @@ sblock: dblock: - L_BRACKET declaration_list R_BRACKET; + L_BRACKET + { + if(getLine(cur)==0) { + setLineNumber(cur, @1.first_line); + setColumnNumber(cur,@1.first_line); + } else { + cur = CreateScope(cur,@1.first_line,@1.first_column); + } + } + declaration_list R_BRACKET; diff --git a/src/runner.c b/src/runner.c index 5f903c3..578fa22 100644 --- a/src/runner.c +++ b/src/runner.c @@ -134,7 +134,16 @@ int run(FILE *alpha) { if (st_flag != NULL) { yyparse(); - print_symbol_table(getAncestor(cur), st_flag); + + if (cur == NULL) { + printdebug("%s[FATAL] cur is null", COLOR_LIGHTRED); + } + + if (top == NULL) { + printdebug("%s[FATAL] top is null", COLOR_LIGHTRED); + } + + print_symbol_table(top, st_flag); fclose(st_flag); if (yyin != NULL) { fclose(yyin); @@ -144,7 +153,8 @@ int run(FILE *alpha) { yyparse(); FILE *f = fdopen(1, "w"); - print_symbol_table(getAncestor(cur), f); + + print_symbol_table(top, f); fclose(f); if (yyin != NULL) { diff --git a/src/symbol_table.c b/src/symbol_table.c index f458769..f749b00 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -186,7 +186,7 @@ int getRecSize(SymbolTable *tn) { "passed in NULL SymbolTable for getRecSize. Invalid"); return -1; } - int s = 0; + int s = 1; TableNode *cur = getFirstEntry(tn); if (cur != NULL) { while (getNextEntry(cur) != NULL) { @@ -772,7 +772,6 @@ TableNode *look_up(SymbolTable *table, char *x) { } void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - if (table == NULL) { printdebug( "%s[FATAL] passed in NULL table to print_symbol_table", @@ -781,14 +780,14 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", + fprintf(file_ptr, "%-25s: %-6s : %-6s : %-25s: %-30s\n", "NAME", "SCOPE", "PARENT", "TYPE", "Extra annotation"); } TableNode *entrie = table->entries; - fprintf(file_ptr, "-----------------:--------:--------:----------------" - "------:---------" - "--------------------\n"); + fprintf(file_ptr, + "-------------------------:--------:--------:------------------" + "--------:------------------------------\n"); int parant_scope = 0; int current_scope = 0; if (table->Parent_Scope != NULL) { @@ -800,7 +799,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { current_scope = 1001; } if (entrie == NULL) { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", + fprintf(file_ptr, "%-25s: %06d : %06d : %-25s: %-30s\n", "", current_scope, parant_scope, "", "Empty Scope"); } for (; entrie != NULL; entrie = getNextEntry(entrie)) { @@ -808,8 +807,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : : %-21d -> " - "%-21s: %-28s\n", + "%-25s: %06d : : %d -> %-20s: " + "%-30s\n", entrie->theName, current_scope, entrie->additionalinfo->ArrayAdInfo ->numofdimensions, @@ -818,8 +817,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "Type of Array"); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21d -> %-21s: " - "%-28s\n", + "%-25s: %06d : : %d -> %-20s: " + "%-30s\n", entrie->theName, current_scope, parant_scope, entrie->additionalinfo->ArrayAdInfo @@ -833,16 +832,16 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : :%-21s: " - "elements-%-28d\n", + "%-25s: %06d : : %-25s: " + "elements-%-30d\n", entrie->theName, current_scope, "record", entrie->additionalinfo->RecAdInfo ->numofelements); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s: " - "elements-%-28d\n", + "%-25s: %06d : %06d : %-25s: " + "elements-%-30d\n", entrie->theName, current_scope, parant_scope, "record", entrie->additionalinfo->RecAdInfo @@ -854,14 +853,14 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { fprintf( file_ptr, - "%-17s: %06d : :%-21s: size-%-28d " + "%-25s: %06d : : %-25s: size-%d " "bytes\n", entrie->theName, current_scope, "Primitive", entrie->additionalinfo->PrimAdInfo->size); } else { fprintf( file_ptr, - "%-17s: %06d : %06d : %-21s: size-%-28d " + "%-25s: %06d : %06d : %-25s: size-%-30d " "bytes\n", entrie->theName, current_scope, parant_scope, "Primitive", @@ -872,8 +871,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : : %-21s -> " - "%-21s: %-28s\n", + "%-25s: %06d : : %-25s -> " + "%-25s: %-30s\n", entrie->theName, current_scope, entrie->additionalinfo->FunTypeAdInfo ->parameter->theName, @@ -882,8 +881,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { "Type of Function"); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s -> %-21s: " - "%-28s\n", + "%-25s: %06d : %06d : %-25s -> %-21s: " + "%-30s\n", entrie->theName, current_scope, parant_scope, entrie->additionalinfo->FunTypeAdInfo @@ -897,12 +896,12 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", + "%-25s: %06d : : %-25s: %-30s\n", entrie->theName, current_scope, getType(entrie), "User Defined"); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s: %-28s\n", + "%-25s: %06d : %06d : %-25s: %-30s\n", entrie->theName, current_scope, parant_scope, getType(entrie), "User Defined"); @@ -912,12 +911,12 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parant_scope == 0) { fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", + "%-25s: %06d : : %-25s: %-30s\n", entrie->theName, current_scope, "undefined", "undefined entry"); } else { fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s: %-28s\n", + "%-25s: %06d : %06d : %-25s: %-30s\n", entrie->theName, current_scope, parant_scope, "undefined", "undefined entry"); @@ -940,9 +939,9 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } } if (getParent(table) == NULL) { - fprintf(file_ptr, "-----------------:--------:--------:--------" - "--------------:-------" - "----------------------\n"); + fprintf(file_ptr, + "-------------------------:--------:--------:----------" + "----------------:------------------------------\n"); } } // get top most symbol table diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index 6b4912e..43007ef 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -9,6 +9,7 @@ function foo : T1 function bar1 : T2 function bar2 : T2 function make_list : list + make_list(a) := { [integer:orig_a; address: ret; address: curr; address: temp] if (a < 0 | a = 0) then { From 58b50ccb63856aed6a1c7ccf1c62478eedbd63ab Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Fri, 4 Apr 2025 18:06:01 -0400 Subject: [PATCH 072/137] Added some of the implementation but not complete #t51 --- src/intermediate_code.c | 2 ++ src/intermediate_code.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 38cbe10..c1e5980 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -100,6 +100,8 @@ void emit_function_call(char* result, char* name){ } void emit_return(char* value){ emit_helper(); + current->opcode = RETURN; + current->operand1 = look_up(cur, name); return; } void emit_reserve(char* result, char* type_name, int size){ diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 464d331..499d4c3 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -29,8 +29,10 @@ typedef enum { CGOTO, // 5 LESSTHEN, // 6 rule 1 + 5 EQUALTO, // 6 rule 1 + 5 + CALL, // 7 PARAM, // 7 - CALL // 7 + RETURN // 7 + } Op; typedef struct Instruction { From 376dfdf53de4f8fcfecc81f2b6cc0e757694495a Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 4 Apr 2025 18:08:59 -0400 Subject: [PATCH 073/137] ready for merge! --- .../expected/sp2_carls_mistake.expected | 31 +++++ .../expected/sp2_function_types.expected | 26 ++++ .../expected/sp2_integer_binary_op.expected | 17 +++ .../expected/sp2_invalid_recop.expected | 17 +++ .../expected/sp2_invalid_release.expected | 14 +++ tests/sprint2/expected/sp2_library.expected | 36 ++++++ tests/sprint2/expected/sp2_llnode.expected | 62 ++++++++++ tests/sprint2/expected/sp2_one_line.expected | 30 +++++ .../sprint2/expected/sp2_presidence.expected | 13 ++ tests/sprint2/expected/sp2_simple.expected | 12 ++ .../sp2_valid_assignable_and_mem.expected | 18 +++ tests/sprint2/test/sp2_carls_mistake.alpha | 42 ++++--- tests/sprint2/test/sp2_function_types.alpha | 18 +-- .../sprint2/test/sp2_integer_binary_op.alpha | 23 ++-- tests/sprint2/test/sp2_invalid_recop.alpha | 7 +- tests/sprint2/test/sp2_invalid_release.alpha | 10 +- tests/sprint2/test/sp2_library.alpha | 19 +-- tests/sprint2/test/sp2_llnode.alpha | 116 +++++++++--------- tests/sprint2/test/sp2_one_line.alpha | 2 +- tests/sprint2/test/sp2_presidence.alpha | 10 +- tests/sprint2/test/sp2_simple.alpha | 4 +- .../test/sp2_valid_assignable_and_mem.alpha | 12 +- .../sp3_boolean_binary_op_typecheck.expected | 17 +++ .../sp3_boolean_unary_op_typecheck.expected | 17 +++ .../sp3_carls_second_mistake.expected | 17 +++ .../sp3_integer_binary_op_typecheck.expected | 18 +++ .../sp3_integer_unary_op_typecheck.expected | 17 +++ .../sp3_boolean_binary_op_typecheck.alpha | 16 ++- .../test/sp3_boolean_unary_op_typecheck.alpha | 14 ++- .../test/sp3_carls_second_mistake.alpha | 9 +- .../sp3_integer_binary_op_typecheck.alpha | 22 ++-- .../test/sp3_integer_unary_op_typecheck.alpha | 12 +- 32 files changed, 564 insertions(+), 134 deletions(-) create mode 100644 tests/sprint2/expected/sp2_carls_mistake.expected create mode 100644 tests/sprint2/expected/sp2_function_types.expected create mode 100644 tests/sprint2/expected/sp2_integer_binary_op.expected create mode 100644 tests/sprint2/expected/sp2_invalid_recop.expected create mode 100644 tests/sprint2/expected/sp2_invalid_release.expected create mode 100644 tests/sprint2/expected/sp2_library.expected create mode 100644 tests/sprint2/expected/sp2_llnode.expected create mode 100644 tests/sprint2/expected/sp2_one_line.expected create mode 100644 tests/sprint2/expected/sp2_presidence.expected create mode 100644 tests/sprint2/expected/sp2_simple.expected create mode 100644 tests/sprint2/expected/sp2_valid_assignable_and_mem.expected create mode 100644 tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected create mode 100644 tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected create mode 100644 tests/sprint3/expected/sp3_carls_second_mistake.expected create mode 100644 tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected create mode 100644 tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected diff --git a/tests/sprint2/expected/sp2_carls_mistake.expected b/tests/sprint2/expected/sp2_carls_mistake.expected new file mode 100644 index 0000000..23a8694 --- /dev/null +++ b/tests/sprint2/expected/sp2_carls_mistake.expected @@ -0,0 +1,31 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +bar2 : 001001 : : T2 : User Defined +bar1 : 001001 : : T2 : User Defined +foo : 001001 : : T1 : User Defined +arr : 001001 : : 1 -> integer : Type of Array +T2 : 001001 : : primitive function type : User Defined +T1 : 001001 : : primitive function type : User Defined +rec : 001001 : : record : elements-2 +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +w : 026000 : 001001 : rec : User Defined +result : 026000 : 001001 : integer : User Defined +arg : 026000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +r : 021000 : 001001 : integer : User Defined +s : 021000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +a : 017000 : 001001 : rec : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +x : 013000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +y : 004000 : 001001 : integer : User Defined +x : 004000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_function_types.expected b/tests/sprint2/expected/sp2_function_types.expected new file mode 100644 index 0000000..bd1d2ce --- /dev/null +++ b/tests/sprint2/expected/sp2_function_types.expected @@ -0,0 +1,26 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +entry : 001001 : : string2integer : User Defined +integer2integer2integerFunc: 001001 : : integer2integer2integer : User Defined +released : 001001 : : address2integer : User Defined +reserved : 001001 : : integer2address : User Defined +printBoolean : 001001 : : Boolean2integer : User Defined +printCharacter : 001001 : : character2integer : User Defined +printInteger : 001001 : : integer2integer : User Defined +integer2integer2integer : 001001 : : primitive function type : User Defined +address2integer : 001001 : : primitive function type : User Defined +integer2address : 001001 : : primitive function type : User Defined +Boolean2Boolean2Boolean : 001001 : : primitive function type : User Defined +character2character2Boolean: 001001 : : primitive function type : User Defined +integer2integer2Boolean : 001001 : : primitive function type : User Defined +string2integer : 001001 : : primitive function type : User Defined +Boolean2integer : 001001 : : primitive function type : User Defined +character2integer : 001001 : : primitive function type : User Defined +integer2integer : 001001 : : primitive function type : User Defined +Boolean2Boolean : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_integer_binary_op.expected b/tests/sprint2/expected/sp2_integer_binary_op.expected new file mode 100644 index 0000000..299c09d --- /dev/null +++ b/tests/sprint2/expected/sp2_integer_binary_op.expected @@ -0,0 +1,17 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +b1 : 005000 : 001001 : Boolean : User Defined +b2 : 005000 : 001001 : Boolean : User Defined +arr2 : 005000 : 001001 : address : User Defined +arr : 005000 : 001001 : address : User Defined +x : 005000 : 001001 : integer : User Defined +arg : 005000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_invalid_recop.expected b/tests/sprint2/expected/sp2_invalid_recop.expected new file mode 100644 index 0000000..5274102 --- /dev/null +++ b/tests/sprint2/expected/sp2_invalid_recop.expected @@ -0,0 +1,17 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +rec : 001001 : : record : elements-2 +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +w : 007000 : 001001 : rec : User Defined +arg : 007000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +y : 004000 : 001001 : integer : User Defined +x : 004000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_invalid_release.expected b/tests/sprint2/expected/sp2_invalid_release.expected new file mode 100644 index 0000000..de26852 --- /dev/null +++ b/tests/sprint2/expected/sp2_invalid_release.expected @@ -0,0 +1,14 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +rec : 001001 : : record : elements-2 +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +w : 004000 : 001001 : rec : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +y : 001000 : 001001 : integer : User Defined +x : 001000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_library.expected b/tests/sprint2/expected/sp2_library.expected new file mode 100644 index 0000000..a1318bd --- /dev/null +++ b/tests/sprint2/expected/sp2_library.expected @@ -0,0 +1,36 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +entry : 001001 : : string2integer : User Defined +printBoolean : 001001 : : Boolean2integer : User Defined +printCharacter : 001001 : : character2integer : User Defined +printInteger : 001001 : : integer2integer : User Defined +address2integer : 001001 : : primitive function type : User Defined +integer2address : 001001 : : primitive function type : User Defined +BooleanXBoolean2Boolean : 001001 : : primitive function type : User Defined +characterXcharacter2Boolean: 001001 : : primitive function type : User Defined +integerXinteger2Boolean : 001001 : : primitive function type : User Defined +integerXinteger2integer : 001001 : : primitive function type : User Defined +string2integer : 001001 : : primitive function type : User Defined +Boolean2integer : 001001 : : primitive function type : User Defined +character2integer : 001001 : : primitive function type : User Defined +integer2integer : 001001 : : primitive function type : User Defined +Boolean2Boolean : 001001 : : primitive function type : User Defined +integerXinteger : 001001 : : record : elements-2 +characterXcharacter : 001001 : : record : elements-2 +BooleanXBoolean : 001001 : : record : elements-2 +string : 001001 : : 1 -> character : Type of Array +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +y : 015000 : 001001 : integer : User Defined +x : 015000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +y : 014000 : 001001 : character : User Defined +x : 014000 : 001001 : character : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +y : 013000 : 001001 : Boolean : User Defined +x : 013000 : 001001 : Boolean : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_llnode.expected b/tests/sprint2/expected/sp2_llnode.expected new file mode 100644 index 0000000..dfe8d53 --- /dev/null +++ b/tests/sprint2/expected/sp2_llnode.expected @@ -0,0 +1,62 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +make_list : 001001 : : list : User Defined +bar2 : 001001 : : T2 : User Defined +bar1 : 001001 : : T2 : User Defined +foo : 001001 : : T1 : User Defined +list : 001001 : : primitive function type : User Defined +llnode : 001001 : : record : elements-3 +T2 : 001001 : : primitive function type : User Defined +T1 : 001001 : : primitive function type : User Defined +rec : 001001 : : record : elements-2 +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +li : 070000 : 001001 : llnode : User Defined +w : 070000 : 001001 : rec : User Defined +result : 070000 : 001001 : integer : User Defined +arg : 070000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +r : 054000 : 001001 : integer : User Defined +s : 054000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +x : 060009 : 054000 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ + : 062028 : 060009 : : Empty Scope +-------------------------:--------:--------:--------------------------:------------------------------ + : 055021 : 054000 : : Empty Scope +-------------------------:--------:--------:--------------------------:------------------------------ + : 056026 : 055021 : : Empty Scope +-------------------------:--------:--------:--------------------------:------------------------------ +a : 050000 : 001001 : rec : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +x : 046000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +temp : 017000 : 001001 : address : User Defined +curr : 017000 : 001001 : address : User Defined +ret : 017000 : 001001 : address : User Defined +orig_a : 017000 : 001001 : integer : User Defined +a : 017000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ + : 021012 : 017000 : : Empty Scope +-------------------------:--------:--------:--------------------------:------------------------------ + : 026023 : 021012 : : Empty Scope +-------------------------:--------:--------:--------------------------:------------------------------ + : 035020 : 026023 : : Empty Scope +-------------------------:--------:--------:--------------------------:------------------------------ + : 031034 : 026023 : : Empty Scope +-------------------------:--------:--------:--------------------------:------------------------------ + : 019029 : 017000 : : Empty Scope +-------------------------:--------:--------:--------------------------:------------------------------ +next : 008000 : 001001 : llnode : User Defined +val : 008000 : 001001 : integer : User Defined +prev : 008000 : 001001 : llnode : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +y : 004000 : 001001 : integer : User Defined +x : 004000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_one_line.expected b/tests/sprint2/expected/sp2_one_line.expected new file mode 100644 index 0000000..8dde170 --- /dev/null +++ b/tests/sprint2/expected/sp2_one_line.expected @@ -0,0 +1,30 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +bar2 : 001001 : : T2 : User Defined +bar1 : 001001 : : T2 : User Defined +foo : 001001 : : T1 : User Defined +T2 : 001001 : : primitive function type : User Defined +T1 : 001001 : : primitive function type : User Defined +rec : 001001 : : record : elements-2 +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +w : 001000 : 001001 : rec : User Defined +result : 001000 : 001001 : integer : User Defined +arg : 001000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +r : 001000 : 001001 : integer : User Defined +s : 001000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +a : 001000 : 001001 : rec : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +x : 001000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +y : 001000 : 001001 : integer : User Defined +x : 001000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_presidence.expected b/tests/sprint2/expected/sp2_presidence.expected new file mode 100644 index 0000000..70d9f83 --- /dev/null +++ b/tests/sprint2/expected/sp2_presidence.expected @@ -0,0 +1,13 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +x : 005000 : 001001 : integer : User Defined +arg : 005000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_simple.expected b/tests/sprint2/expected/sp2_simple.expected new file mode 100644 index 0000000..8d55a97 --- /dev/null +++ b/tests/sprint2/expected/sp2_simple.expected @@ -0,0 +1,12 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +arg : 005000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected b/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected new file mode 100644 index 0000000..ab5cb2a --- /dev/null +++ b/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected @@ -0,0 +1,18 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +T2 : 001001 : : primitive function type : User Defined +rec : 001001 : : record : elements-2 +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +w : 008000 : 001001 : rec : User Defined +arg : 008000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ +y : 004000 : 001001 : integer : User Defined +x : 004000 : 001001 : integer : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index 2f4c1ef..eb9a6f0 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -1,28 +1,34 @@ +type main: string -> integer +function entry: main + type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer -type arr : 1 -> integer +type arr: 1 -> integer -function foo : T1 -function bar1 : T2 -function bar2 : T2 +function foo: T1 +function bar1: T2 +function bar2: T2 -foo(x) := { - return x * x; +foo (x) := { + return x * x; } -bar1(a) := { - return a.x * a.y; + +bar1 (a) := { + return a.x * a.y; } + bar2 as (r,s) := { - return r * s; + return r * s; } -entry(arg) := { - [ integer: result ; rec: w] - result := foo(5); - w := reserve w; (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*) - w.x := 5; - w.y := 7; - result := bar1(w); (* pass w (a rec type value) to bar1 *) - result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) - return 0; + +entry (arg) := { + [ integer: result ; rec: w] + result := foo(5); + w := reserve w; (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*) + w.x := 5; + w.y := 7; + result := bar1(w); (* pass w (a rec type value) to bar1 *) + result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) + return 0; } diff --git a/tests/sprint2/test/sp2_function_types.alpha b/tests/sprint2/test/sp2_function_types.alpha index 509de78..62711c3 100644 --- a/tests/sprint2/test/sp2_function_types.alpha +++ b/tests/sprint2/test/sp2_function_types.alpha @@ -3,15 +3,19 @@ type integer2integer: integer -> integer type character2integer: character -> integer type Boolean2integer: Boolean -> integer type string2integer: string -> integer -function integerXinteger2integer: integerXinteger (*-> integer -type integerXinteger2Boolean: integerXinteger -> Boolean -type characterXcharacter2Boolean: characterXcharacter -> Boolean -type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean + +type integer2integer2Boolean: integer2integer -> Boolean +type character2character2Boolean: character2character -> Boolean +type Boolean2Boolean2Boolean: Boolean2Boolean -> Boolean type integer2address: integer -> address type address2integer: address -> integer +type integer2integer2integer: integer2integer -> integer + external function printInteger: integer2integer external function printCharacter: character2integer external function printBoolean: Boolean2integer -external function reserve: integer2address -external function release: address2integer -function entry: string2integer*) \ No newline at end of file +external function reserved: integer2address +external function released: address2integer + +function integer2integer2integerFunc: integer2integer2integer +function entry: string2integer \ No newline at end of file diff --git a/tests/sprint2/test/sp2_integer_binary_op.alpha b/tests/sprint2/test/sp2_integer_binary_op.alpha index 39e00a6..856224f 100644 --- a/tests/sprint2/test/sp2_integer_binary_op.alpha +++ b/tests/sprint2/test/sp2_integer_binary_op.alpha @@ -1,12 +1,17 @@ -entry(arg) := { - [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] - x := 3 + 2 * 8; - x := 3 - 2 / 8; - x := 3 * 2 % 8; - x := 3 * 2 % 8; - x := 3 % 2 * 8; - x := 3 + 2 - 8; - arr2 := 1 * reserve x; +type main: string -> integer +function entry: main + +entry (arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + + x := 3 + 2 * 8; + x := 3 - 2 / 8; + x := 3 * 2 % 8; + x := 3 * 2 % 8; + x := 3 % 2 * 8; + x := 3 + 2 - 8; + + arr2 := 1 * reserve x; arr2 := release x; b2 := 3 < 2; b1 := 1 = 2; diff --git a/tests/sprint2/test/sp2_invalid_recop.alpha b/tests/sprint2/test/sp2_invalid_recop.alpha index 5ea874d..41b3a55 100644 --- a/tests/sprint2/test/sp2_invalid_recop.alpha +++ b/tests/sprint2/test/sp2_invalid_recop.alpha @@ -1,10 +1,13 @@ +type main: string -> integer +function entry: main + type rec: [integer: x; integer: y] -entry(arg) := { +entry (arg) := { [rec: w] w := reserve w; w.x := 1; w.y := 2; w.z := 3; - return 0; + return 0; } \ No newline at end of file diff --git a/tests/sprint2/test/sp2_invalid_release.alpha b/tests/sprint2/test/sp2_invalid_release.alpha index 41fbd8a..2bd645a 100644 --- a/tests/sprint2/test/sp2_invalid_release.alpha +++ b/tests/sprint2/test/sp2_invalid_release.alpha @@ -1,8 +1,8 @@ type rec: [integer: x; integer: y] -entry(arg) := { - [rec: w] - w := reserve w; - w := release (w); - return 0; +entry (arg) := { + [rec: w] + w := reserve w; + w := release (w); + return 0; } \ No newline at end of file diff --git a/tests/sprint2/test/sp2_library.alpha b/tests/sprint2/test/sp2_library.alpha index 866857c..82120be 100644 --- a/tests/sprint2/test/sp2_library.alpha +++ b/tests/sprint2/test/sp2_library.alpha @@ -1,11 +1,14 @@ -(* At compiler start-up your program should create symbol table entries for the four primitive types: - Boolean (1 byte) - character (1 byte) - integer (4 bytes) - address (8 bytes) -You should #include this file at the start of your alpha file. -Some useful types are defined below. +(* + At compiler start-up your program should create symbol table entries for the four primitive types: + Boolean (1 byte) + character (1 byte) + integer (4 bytes) + address (8 bytes) + + should #include this file at the start of your alpha file. + Some useful types are defined below. *) + type string: 1 -> character type BooleanXBoolean: [Boolean: x; Boolean: y] type characterXcharacter: [character: x; character: y] @@ -22,7 +25,9 @@ type characterXcharacter2Boolean: characterXcharacter -> Boolean type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean type integer2address: integer -> address type address2integer: address -> integer + external function printInteger: integer2integer external function printCharacter: character2integer external function printBoolean: Boolean2integer + function entry: string2integer diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index 43007ef..2011a83 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -1,3 +1,6 @@ +type main: string -> integer +function entry: main + type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer @@ -10,66 +13,69 @@ function bar1 : T2 function bar2 : T2 function make_list : list -make_list(a) := { - [integer:orig_a; address: ret; address: curr; address: temp] - if (a < 0 | a = 0) then { - return null; - } else { - ret := reserve llnode; - ret.prev := null; - ret.next := null; - ret.val := a; - while (0 < a) { - temp := reserve llnode; - temp.prev := null; - temp.next := null; - temp.val := val; - if (a = orig_a) then { - ret.next := temp; - temp.prev := ret; - curr := temp; - } else { - curr.next := temp; - temp.prev := curr; - curr := temp; - } - a := a - 1; - } - return ret; +make_list (a) := { + [integer:orig_a; address: ret; address: curr; address: temp] + + if (a < 0 | a = 0) then { + return null; + } else { + ret := reserve llnode; + ret.prev := null; + ret.next := null; + ret.val := a; + while (0 < a) { + temp := reserve llnode; + temp.prev := null; + temp.next := null; + temp.val := val; + if (a = orig_a) then { + ret.next := temp; + temp.prev := ret; + curr := temp; + } else { + curr.next := temp; + temp.prev := curr; + curr := temp; + } + a := a - 1; } + return ret; + } } +foo (x) := { + return x * x; +} -foo(x) := { - return x * x; - } -bar1(a) := { - return a.x * a.y; - } +bar1 (a) := { + return a.x * a.y; +} bar2 as (r,s) := { - if (r < s) then { - while (!(r < s)) { - r := r + 1; - } - } else { - [integer: x] - x := 0; - while (x < 10) { - r := r + s; - } + if (r < s) then { + while (!(r < s)) { + r := r + 1; } - return r * s; - } -entry(arg) := { - [ integer: result ; rec: w; llnode: li] - li := make_list(6); - result := foo(5); - w := reserve w; - w.x := 5; - w.y := 7; - result := bar1(w); - result := bar2(5,7); - - return 0; + } else { + [integer: x] + x := 0; + while (x < 10) { + r := r + s; + } + } + return r * s; +} + +entry (arg) := { + [ integer: result ; rec: w; llnode: li] + + li := make_list(6); + result := foo(5); + w := reserve w; + w.x := 5; + w.y := 7; + result := bar1(w); + result := bar2(5,7); + + return 0; } diff --git a/tests/sprint2/test/sp2_one_line.alpha b/tests/sprint2/test/sp2_one_line.alpha index 9031b5f..f1062e9 100644 --- a/tests/sprint2/test/sp2_one_line.alpha +++ b/tests/sprint2/test/sp2_one_line.alpha @@ -1 +1 @@ -type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer function foo : T1 function bar1 : T2 function bar2 : T2 foo(x) := { return x * x; } bar1(a) := { return a.x * a.y; } bar2 as (r,s) := { return r * s; } entry(arg) := { [ integer: result ; rec: w] result := foo(5); w := reserve w; w.x := 5; w.y := 7; result := bar1(w); result := bar2(5,7); return 0; } +type main: string -> integer function entry: main type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer function foo : T1 function bar1 : T2 function bar2 : T2 foo(x) := { return x * x; } bar1(a) := { return a.x * a.y; } bar2 as (r,s) := { return r * s; } entry(arg) := { [ integer: result ; rec: w] result := foo(5); w := reserve w; w.x := 5; w.y := 7; result := bar1(w); result := bar2(5,7); return 0; } diff --git a/tests/sprint2/test/sp2_presidence.alpha b/tests/sprint2/test/sp2_presidence.alpha index 9b2ef86..2d60209 100644 --- a/tests/sprint2/test/sp2_presidence.alpha +++ b/tests/sprint2/test/sp2_presidence.alpha @@ -1,4 +1,8 @@ -entry(arg) := { - [integer:x] - x := 3 + 2 * 8; +type main: string -> integer +function entry: main + +entry (arg) := { + [integer:x] + x := 3 + 2 * 8; + return 0; } diff --git a/tests/sprint2/test/sp2_simple.alpha b/tests/sprint2/test/sp2_simple.alpha index 0b214c3..5f60c1b 100644 --- a/tests/sprint2/test/sp2_simple.alpha +++ b/tests/sprint2/test/sp2_simple.alpha @@ -1,5 +1,7 @@ +type main: string -> integer +function entry: main entry(arg) := { [int : x] - return 0; + return 0; } diff --git a/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha index 43c5a5f..a49c5dd 100644 --- a/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha +++ b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha @@ -1,12 +1,16 @@ +type main: string -> integer +function entry: main + type rec: [integer: x; integer: y] type T2: rec -> integer entry(arg) := { - [rec: w] - w := reserve w; + [rec: w] + + w := reserve w; w.x := 1; w.y := 2; w := release w; - return 0; - + + return 0; } \ No newline at end of file diff --git a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected new file mode 100644 index 0000000..299c09d --- /dev/null +++ b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected @@ -0,0 +1,17 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +b1 : 005000 : 001001 : Boolean : User Defined +b2 : 005000 : 001001 : Boolean : User Defined +arr2 : 005000 : 001001 : address : User Defined +arr : 005000 : 001001 : address : User Defined +x : 005000 : 001001 : integer : User Defined +arg : 005000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected new file mode 100644 index 0000000..299c09d --- /dev/null +++ b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected @@ -0,0 +1,17 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +b1 : 005000 : 001001 : Boolean : User Defined +b2 : 005000 : 001001 : Boolean : User Defined +arr2 : 005000 : 001001 : address : User Defined +arr : 005000 : 001001 : address : User Defined +x : 005000 : 001001 : integer : User Defined +arg : 005000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint3/expected/sp3_carls_second_mistake.expected b/tests/sprint3/expected/sp3_carls_second_mistake.expected new file mode 100644 index 0000000..5d0682f --- /dev/null +++ b/tests/sprint3/expected/sp3_carls_second_mistake.expected @@ -0,0 +1,17 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +a_of_s : 001001 : : 1 -> string : Type of Array +string : 001001 : : 1 -> character : Type of Array +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +many_names : 010000 : 001001 : a_of_s : User Defined +another_name : 010000 : 001001 : string : User Defined +one_name : 010000 : 001001 : string : User Defined +arg : 010000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected new file mode 100644 index 0000000..a183cf5 --- /dev/null +++ b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected @@ -0,0 +1,18 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +a : 005000 : 001001 : character : User Defined +b1 : 005000 : 001001 : Boolean : User Defined +b2 : 005000 : 001001 : Boolean : User Defined +arr2 : 005000 : 001001 : address : User Defined +arr : 005000 : 001001 : address : User Defined +x : 005000 : 001001 : integer : User Defined +arg : 005000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected new file mode 100644 index 0000000..299c09d --- /dev/null +++ b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected @@ -0,0 +1,17 @@ +NAME : SCOPE : PARENT : TYPE : Extra annotation +-------------------------:--------:--------:--------------------------:------------------------------ +entry : 001001 : : main : User Defined +main : 001001 : : primitive function type : User Defined +integer : 001001 : : Primitive : size-4 bytes +address : 001001 : : Primitive : size-8 bytes +character : 001001 : : Primitive : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive : size-1 bytes +-------------------------:--------:--------:--------------------------:------------------------------ +b1 : 005000 : 001001 : Boolean : User Defined +b2 : 005000 : 001001 : Boolean : User Defined +arr2 : 005000 : 001001 : address : User Defined +arr : 005000 : 001001 : address : User Defined +x : 005000 : 001001 : integer : User Defined +arg : 005000 : 001001 : string : User Defined +-------------------------:--------:--------:--------------------------:------------------------------ diff --git a/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha index 5952129..538d982 100644 --- a/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha @@ -1,6 +1,12 @@ -entry(arg) := { - [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] - b2 := 3 < x; - b1 := arr = 2; - b1 := 6<7 & arr2=7; +type main: string -> integer +function entry: main + +entry (arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + + b2 := 3 < x; + b1 := arr = 2; + b1 := 6<7 & arr2=7; + + return 0; } diff --git a/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha index 12db768..6a23ff6 100644 --- a/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha @@ -1,5 +1,11 @@ -entry(arg) := { - [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] - b2 := !(3 < 2); - b1 := !5; +type main: string -> integer +function entry: main + +entry (arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + + b2 := !(3 < 2); + b1 := !5; + + return 0; } diff --git a/tests/sprint3/test/sp3_carls_second_mistake.alpha b/tests/sprint3/test/sp3_carls_second_mistake.alpha index 6d1d614..ddb58a4 100644 --- a/tests/sprint3/test/sp3_carls_second_mistake.alpha +++ b/tests/sprint3/test/sp3_carls_second_mistake.alpha @@ -1,10 +1,14 @@ +type main: string -> integer +function entry: main + type string: 1 -> character type a_of_s: 1 -> string (* maybe some other type definitions *) -entry(arg) := { +entry (arg) := { [ string: one_name; string: another_name; a_of_s: many_names ] + one_name := "a string literal"; another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) another_name(0) := 'C'; @@ -20,6 +24,7 @@ entry(arg) := { many_names(2)(2) := 'r'; many_names(2)(3) := 't'; many_names(2)(4) := 'h'; - 0(2)(5) := 'o'; + many_names(2)(5) := 'o'; + return 0; } \ No newline at end of file diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha index 5b13147..b042e5f 100644 --- a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -1,9 +1,15 @@ -entry(arg) := { - [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a] - x := 3 + 2 * 8; - x := 3 - 2 / 8; - x := a * 2 % 8; - b2 := 3 * 2 % 8; - x := 3 % 2 * 8; - x := 3 + arr - 8; +type main: string -> integer +function entry: main + +entry (arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a] + + x := 3 + 2 * 8; + x := 3 - 2 / 8; + x := a * 2 % 8; + b2 := 3 * 2 % 8; + x := 3 % 2 * 8; + x := 3 + arr - 8; + + return 0; } diff --git a/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha index 31e01a7..7ab6817 100644 --- a/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha @@ -1,6 +1,12 @@ -entry(arg) := { - [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] - x := -8; +type main: string -> integer +function entry: main + +entry (arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + + x := -8; x := -b1; b2 := -x; + + return 0; } From e56606941872188e91df0c2dcfaebff2f8a69849 Mon Sep 17 00:00:00 2001 From: Annie Date: Fri, 4 Apr 2025 18:43:53 -0400 Subject: [PATCH 074/137] updated to allow -tc and -debug --- Makefile | 4 ++-- src/runner.c | 29 +++++++++++++++++++++++------ test.sh | 20 ++++++++++---------- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 4b92e65..0f7f411 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ debug: clean compiler test: chmod +x ./check.sh chmod +x ./test.sh - $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) -debug || true);) + $(foreach test, $(TESTS-S1), (./$(EXE) -tok -debug $(test) || true);) ./test.sh sp2 ./test.sh sp3 ./test.sh sp4 @@ -46,7 +46,7 @@ test: test-s1: chmod +x ./check.sh chmod +x ./test.sh - $(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) -debug || true);) + $(foreach test, $(TESTS-S1), (./$(EXE) -tok -debug $(test) || true);) ./check.sh sp1 test-s2: diff --git a/src/runner.c b/src/runner.c index 578fa22..3fdb399 100644 --- a/src/runner.c +++ b/src/runner.c @@ -6,10 +6,10 @@ int main(int argc, char *argv[]) { // if last argument is debug then set to true and ignore it for the rest // of this file - if (argc > 1 && strcmp(argv[argc - 1], "-debug") == 0) { - DEBUG = true; - argc--; - } + //if (argc > 1 && strcmp(argv[argc - 1], "-debug") == 0) { + // DEBUG = true; + // argc--; + // } if (argc == 1) { fprintf(stderr, INVALID); @@ -61,6 +61,14 @@ int check_flag(char *arg, char *alpha) { } fprintf(stderr, "FLAGS REPEAT\n"); return -1; + + } else if (strcmp("-tc", arg) == 0) { + if (tc_flag == NULL) { + return new_file(arg, alpha); + } + } else if (strcmp("-debug", arg) == 0) { + DEBUG = true; + return 0; } else { fprintf(stderr, "INVALID FLAG: Use -help for valid inputs\n"); return -1; @@ -151,6 +159,10 @@ int run(FILE *alpha) { return 0; } + if (tc_flag != NULL) { + //SCARLETT NEEDS TO ADD THIS FUNCTIONALITY + } + yyparse(); FILE *f = fdopen(1, "w"); @@ -194,7 +206,9 @@ int new_file(char *arg, char *alpha) { type_len = TOK_LEN; } else if (strcmp(arg, "-st") == 0) { type_len = ST_LEN; - } else { + } else if (strcmp(arg, "-tc") == 0){ + type_len = TC_LEN; + }else { fprintf(stderr, "INVALID FLAG: Use -help to view valid inputs\n"); return -1; @@ -214,6 +228,9 @@ int new_file(char *arg, char *alpha) { tok_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-st") == 0) { st_flag = fopen(file_name, "w"); + + } else if (strcmp(arg, "-tc") == 0) { + tc_flag = fopen(file_name, "w"); } return 0; } @@ -224,4 +241,4 @@ int is_alpha_file(char *alpha, int file_len) { return -1; // not alpha file } return 0; // is alpha file -} \ No newline at end of file +} diff --git a/test.sh b/test.sh index 9c32bed..8443215 100755 --- a/test.sh +++ b/test.sh @@ -48,7 +48,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" -debug + ./alpha -st -debug "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -60,7 +60,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" -debug + ./alpha -st -debug "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -72,7 +72,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" -debug + ./alpha -st -debug "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -84,7 +84,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" -debug + ./alpha -st -debug "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n${WHITE}" switchfunc fi @@ -106,7 +106,7 @@ else if [ -f "$1" ]; then filename=$(basename -- "$1") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$1" -debug + ./alpha -st -debug "$1" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}" exit 1 else @@ -121,7 +121,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" -debug + ./alpha -st -debug "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -132,7 +132,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" -debug + ./alpha -st -debug "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -143,7 +143,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" -debug + ./alpha -st -debug "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -154,7 +154,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st "$file" -debug + ./alpha -st -debug "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi @@ -163,4 +163,4 @@ else echo -e "${RED}[ERROR] ${YELLOW}Invalid prefix $1!${WHITE}" exit 1 fi -fi \ No newline at end of file +fi From 0b33ea4dea5108e6cf431614e9d90da0eb8d7be3 Mon Sep 17 00:00:00 2001 From: Annie Date: Fri, 4 Apr 2025 18:49:04 -0400 Subject: [PATCH 075/137] added -debug option to -help output --- src/runner.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/runner.h b/src/runner.h index cc573c5..0483e12 100644 --- a/src/runner.h +++ b/src/runner.h @@ -4,16 +4,18 @@ #define ALPHA_OFFSET 6 #define TOK_LEN 3 #define ST_LEN 2 +#define TC_LEN 2 #define HELP \ "HELP:\nHow to run the alpha compiler:\n./alpha [options] " \ "program\nValid " \ - "options:\n-tok output the token number, token, line number, and " \ + "options:\n-tok output the token number, token, line number, and " \ "column " \ - "number for each of the tokens to the .tok file\n-st output the " \ + "number for each of the tokens to the .tok file\n-st output the " \ "symbol " \ - "table for the program to the .st file\n-help print this message " \ + "table for the program to the .st file\n-help print this message " \ "and exit " \ - "the alpha compiler\n" + "the alpha compiler\n-debug print debugging messages in grammar rules \n" + #define SET_FLAG 1 // Used to set flags for arg types #define INVALID \ "INVALID INPUT: Include a .alpha file or use -help for more inputs \n" @@ -39,6 +41,7 @@ SymbolTable *cur; FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; +FILE *tc_flag = NULL; bool DEBUG = false; int no_flag = 0; int arg; @@ -77,4 +80,4 @@ char *COLOR_YELLOW = "\033[1;33m"; char *COLOR_LIGHTBLUE = "\033[1;34m"; char *COLOR_LIGHTPURPLE = "\033[1;35m"; char *COLOR_LIGHTCYAN = "\033[1;36m"; -char *COLOR_WHITE = "\033[1;37m"; \ No newline at end of file +char *COLOR_WHITE = "\033[1;37m"; From f6abbbd67ffad3ddc8200be31dedc4f301bdea71 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 4 Apr 2025 20:24:05 -0400 Subject: [PATCH 076/137] updated to change strings to nodes in most locations --- src/grammar.y | 151 +++++++++++------ src/symbol_table.c | 397 +++++++++++++++++++++++++-------------------- src/symbol_table.h | 8 + 3 files changed, 327 insertions(+), 229 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 7b39031..119960a 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -43,21 +43,23 @@ TableNode * tn; %} -%locations - %union { int integ; char* words; - TableNode* tn; + void* tn; } +%locations + %type idlist %type assignable %type expression %type constant %type id_or_types %type types -%token ID 101 +%type argument_list +%type ablock +%token ID 101 %token T_INTEGER 201 %token T_ADDRESS 202 %token T_BOOLEAN 203 @@ -143,13 +145,15 @@ definition: TYPE ID COLON { printdebug("Currently see a record definition for %s", $2); - tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); + tn = CreateEntry(getAncestor(cur),TYPE_RECORD_TYPE, recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); if (look_up(cur, $2) == undefined) { - printdebug("rec not found "); + printdebug("rec not found"); } } dblock { + //We are scanning through the dblock scope to get the length of the dblock (num of elements) from getRecSize + //and then putting it in the entry that we created above. setRecSize(look_up(cur, $2), getRecSize(cur)); cur = getParent(cur); } @@ -157,7 +161,7 @@ definition: | TYPE ID COLON C_INTEGER ARROW id_or_types { printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, getName($6), $4); - CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, $6)); + CreateEntry(cur,TYPE_ARRAY_TYPE, arrayprim, $2, CreateArrayInfo($4, $6)); printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, getName($6)); } @@ -165,8 +169,8 @@ definition: | TYPE ID COLON id_or_types ARROW id_or_types { - printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", getName($2), getName($4), getName($6)); - CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo($4 ,$6)); + printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, getName($4), getName($6)); + CreateEntry(cur,TYPE_FUNCTION_TYPE,funtypeprime,$2,CreateFunctionTypeInfo($4 ,$6)); } | ID @@ -185,11 +189,25 @@ definition: L_PAREN ID { printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4); - CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); + TableNode* type_of_param = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + int type_of_param_type = getAdInfoType(type_of_param); + if( type_of_param_type == TYPE_UNDEFINED + || type_of_param_type == TYPE_FUNCTION_DECLARATION + || type_of_param_type == TYPE_ARRAY + || type_of_param_type == TYPE_ALL_ELSE + || type_of_param_type == TYPE_SYSTEM_DEFINED + || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused + printdebug("type of parameter is undefined or invalid at line %d, column %d", @4.first_line, @4.first_column); + type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases + }else{ + printdebug("type of parameter is %s at line %d, column %d", getName(type_of_param), @4.first_line, @4.first_column); + } + + CreateEntry(cur,type_of_param_type, type_of_param, $4, getAdInfo(type_of_param)); } - R_PAREN ASSIGN sblock + R_PAREN ASSIGN sblock //leaving scope is being taken care of in sblock - | ID + /* | ID { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { @@ -208,13 +226,13 @@ definition: printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4); CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); - }R_PAREN ASSIGN sblock + }R_PAREN ASSIGN sblock */ | ID { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + printdebug(" undefined nodedeclared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + printdebug("not a valid function declaration at line %d, column %d", @1.first_line, @1.first_column); } else { printdebug("setting as keyword to true"); @@ -232,9 +250,26 @@ definition: printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); }else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ - printdebug("creating entry of type %s for function", getType(entry)); - CreateEntry(cur, entry, "undefined", NULL); + int type_of_param_type = getAdInfoType(entry); + if( type_of_param_type == TYPE_UNDEFINED + || type_of_param_type == TYPE_FUNCTION_DECLARATION + || type_of_param_type == TYPE_ARRAY + || type_of_param_type == TYPE_ALL_ELSE + || type_of_param_type == TYPE_SYSTEM_DEFINED + || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused + printdebug("type of parameter being passed in to AS function definition is %s which is invalid", getName(entry)); + type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases + }else{ + printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); + } + if(type_of_param_type == TYPE_UNDEFINED){ + CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); + } else { + CreateEntry(cur,type_of_param_type, entry, NULL, getAdInfo(entry)); + /*printdebug("creating entry of type %s for function", getType(entry)); + CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ } + } } } idlist {printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$6);} R_PAREN ASSIGN sblock //check sblock type @@ -244,12 +279,12 @@ definition: function_declaration: FUNCTION ID COLON ID { - CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); } | EXTERNAL FUNCTION ID COLON ID { - CreateEntry(cur, look_up(cur, $5), $3, NULL); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, NULL); } ; @@ -265,7 +300,7 @@ idlist: if (getNextEntry(entry) == NULL) { printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); } - addName(entry, 1); + addName(entry, $1); } COMMA idlist { @@ -290,8 +325,11 @@ idlist: sblock: L_BRACE { - if (getLine(cur) != 0 && getColumn(cur)) { + if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); + } else { + setLineNumber(cur, @1.first_line); + setColumnNumber(cur,@1.first_line); } } statement_list @@ -302,8 +340,11 @@ sblock: | L_BRACE { - if (getLine(cur) != 0 && getColumn(cur)) { + if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); + } else { + setLineNumber(cur, @1.first_line); + setColumnNumber(cur,@1.first_line); } } dblock @@ -320,7 +361,15 @@ sblock: dblock: - L_BRACKET declaration_list R_BRACKET; + L_BRACKET + {if(getLine(cur)==0){ + setLineNumber(cur, @1.first_line); + setColumnNumber(cur,@1.first_line);} + else{ + cur = CreateScope(cur,@1.first_line,@1.first_column); + } + } + declaration_list R_BRACKET; @@ -335,7 +384,7 @@ declaration: id_or_types COLON ID { printdebug("ID/TYPE: %s, ID: %s", getName($1), $3) ; - CreateEntry(cur,$1,$3,NULL); + CreateEntry(cur,getAdInfoType($1),$1,$3,getAdInfo($1)); } ; @@ -369,7 +418,7 @@ statement_list: compound_statement: WHILE L_PAREN expression R_PAREN sblock | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock - | sblock + | sblock ; @@ -377,14 +426,14 @@ compound_statement: simple_statement: assignable ASSIGN expression { - if(strcmp(getType($1), getType($3)) == 0) { + if(strcmp(getName($1), getName($3)) == 0) { printdebug("Passed standard type check; assignable = expression"); - } else if((strcmp(getType($1), "array") == 0) && (strcmp($3, "address") == 0)) { - printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, getType($1), getType($3)); - } else if((strcmp(getType($1), "record") == 0) && (strcmp($3, "address") == 0)) { - printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, getType($1), getType($3)); - } else if((strcmp(getType($1), "function type primitive") == 0) && (strcmp(getType($3), "address") == 0)) { - printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, getType($1), getType($3)); + } else if((strcmp(getName($1), "array") == 0) && (strcmp(getName($3), "address") == 0)) { + printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, getName($1), getName($3)); + } else if((strcmp(getName($1), "record") == 0) && (strcmp(getName($3), "address") == 0)) { + printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, getName($1), getName($3)); + } else if((strcmp(getName($1), "function type primitive") == 0) && (strcmp(getName($3), "address") == 0)) { + printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, getName($1), getName($3)); // } else if () { // } else if(strcmp(getType(table_lookup(cur, $1)), getType(table_lookup(cur, $3))) == 0) { @@ -419,14 +468,14 @@ ablock: argument_list: expression COMMA argument_list { - CreateEntry(cur, $1, getName($1), NULL); + CreateEntry(cur,getAdInfoType($1), $1, getName($1), NULL); $$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } | expression { - CreateEntry(cur, $1, getName($1), NULL); + CreateEntry(cur,getAdInfoType($1),$1, getName($1), NULL); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } ; @@ -498,7 +547,7 @@ expression: | expression DIV expression { printdebug("divide expression"); - if(strcmp($1 == $3 && $1 == integ) { + if((strcmp(getName($1),getName($3))==0) && ($1 == integ)) { $$=$1; } else { printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); @@ -520,7 +569,7 @@ expression: | expression AND expression { printdebug("AND expression"); - if($1 == $3 && $1 == boo { + if($1 == $3 && $1 == boo){ $$=$1; } else{ printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); @@ -531,7 +580,7 @@ expression: | expression OR expression { printdebug("OR"); - if(strcmp($1 == $3 && $1 == boo) { + if((strcmp(getName($1),getName($3))==0) && $1 == boo) { $$=$1; } else { printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); @@ -599,17 +648,17 @@ assignable: } ablock { - int type = getAdInfoType(look_up(getParent(cur), $1)); + int type = getAdInfoType(look_up(cur, getName($1))); printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", $1); if (type == TYPE_FUNCTION_DECLARATION) { printdebug("%sEntering function call", COLOR_LIGHTGREEN); - if (look_up(getParent(cur), $1)->additionalinfo->FunDecAdInfo->regularoras) { + if (look_up(getParent(cur), getName($1))->additionalinfo->FunDecAdInfo->regularoras) { printdebug("as function"); //char *funtype = getType(look_up(cur, $1)); - printdebug("%s", getType(look_up(cur, $1))); - TableNode *param = getParameter(look_up(cur, getType(look_up(cur, $1)))); + printdebug("%s", getType(look_up(cur, getName($1)))); + TableNode *param = getParameter(look_up(cur, getType(look_up(cur, getName($1))))); SymbolTable *recList = getRecList(param); TableNode *lastCheckedRef = getFirstEntry(recList); TableNode *lastCheckedAct = getFirstEntry(cur); @@ -636,32 +685,32 @@ assignable: } } else { - char *expected = getName(getParameter(look_up(getParent(cur), $1))); + char *expected = getName(getParameter(look_up(getParent(cur), getName($1)))); char *actual = getType(getFirstEntry(cur)); if (strcmp(expected, actual) != 0) { printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); } } - $$ = getName(getReturn((look_up(cur, getType(look_up(cur, $1)))))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + $$ = getReturn((look_up(cur, getType(look_up(cur, getName($1)))))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName($1)); } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); - if (getNumArrDim(look_up(getParent(cur), $1)) != $2) { - printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $2, @2.first_line, @2.first_column); + if (getNumArrDim(look_up(getParent(cur), getName($1))) != $2) { + printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName($1))), $2, @2.first_line, @2.first_column); } - $$ = getName(getArrType(look_up(getParent(cur), $1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1); + $$ = getArrType(look_up(getParent(cur), getName($1))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName($1)); } cur = getParent(cur); } | assignable rec_op ID { - if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)) { - $$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)); + if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName($1))), $3)) { + $$ = table_lookup(getRecList(table_lookup(getAncestor(cur), getName($1))), $3); } - printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1); + printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName($$), $1); } ; diff --git a/src/symbol_table.c b/src/symbol_table.c index 70f28d5..2e1af13 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -85,7 +85,8 @@ typedef enum { TYPE_ALL_ELSE = 7, TYPE_UNDEFINED = 8, TYPE_RECORD = 9, - TYPE_ARRAY = 10 + TYPE_ARRAY = 10, + TYPE_SYSTEM_DEFINED = 11 // for system defined entries like funprimetype etc. } types; @@ -314,7 +315,7 @@ int getRecSize(SymbolTable *tn) { "passed in NULL SymbolTable for getRecSize. Invalid"); return -1; } - int s = 0; + int s = 1; TableNode *cur = getFirstEntry(tn); if (cur != NULL) { while (getNextEntry(cur) != NULL) { @@ -551,6 +552,7 @@ SymbolTable *init(SymbolTable *start) { prime->theType = NULL; prime->additionalinfo = NULL; prime->next = NULL; + prime->tag = TYPE_SYSTEM_DEFINED; // not sure exatly how to get array types to look right so using a dummy // Table Node below and updating the print symbol table function to @@ -560,7 +562,8 @@ SymbolTable *init(SymbolTable *start) { arrayprim->theName = "array"; arrayprim->theType = NULL; arrayprim->additionalinfo = NULL; - prime->next = NULL; + arrayprim->next = NULL; + prime->tag = TYPE_SYSTEM_DEFINED; // funprime = CreateEntry(NULL,NULL,strdup("function primitive"),NULL); @@ -570,6 +573,7 @@ SymbolTable *init(SymbolTable *start) { funprime->theType = NULL; funprime->additionalinfo = NULL; funprime->next = NULL; + funprime->tag = TYPE_SYSTEM_DEFINED; // record recprime = (TableNode *)malloc(sizeof(TableNode)); @@ -577,18 +581,21 @@ SymbolTable *init(SymbolTable *start) { recprime->theType = NULL; recprime->additionalinfo = NULL; recprime->next = NULL; + recprime->tag = TYPE_SYSTEM_DEFINED; funtypeprime = (TableNode *)malloc(sizeof(TableNode)); funtypeprime->theName = "primitive function type"; funtypeprime->theType = NULL; funtypeprime->additionalinfo = NULL; funtypeprime->next = NULL; + funtypeprime->tag = TYPE_SYSTEM_DEFINED; undefined = (TableNode *)malloc(sizeof(TableNode)); undefined->theName = "undefined"; undefined->theType = NULL; undefined->additionalinfo = NULL; undefined->next = NULL; + undefined->tag = TYPE_SYSTEM_DEFINED; // Undefined_function_type_info = CreateFunctionTypeInfo(undefined, // undefined); @@ -605,11 +612,17 @@ SymbolTable *init(SymbolTable *start) { // be the size of these primitive types. We can change these if needed // to not be hard coded numbers as a reminder, stri below is defined as // a one dimensional array of characters - integ->additionalinfo = CreatePrimitiveInfo(4); - addr->additionalinfo = CreatePrimitiveInfo(8); - chara->additionalinfo = CreatePrimitiveInfo(1); + integ->additionalinfo = CreatePrimitiveInfo(SIZE_INT); + addr->additionalinfo = CreatePrimitiveInfo(SIZE_ADDR); + chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR); stri->additionalinfo = CreateArrayInfo(1, chara); - boo->additionalinfo = CreatePrimitiveInfo(1); + boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); + + integ->tag = TYPE_PRIMITIVE; // explicitly set the type for integ + addr->tag = TYPE_PRIMITIVE; // explicitly set the type for addr + chara->tag = TYPE_PRIMITIVE; // explicitly set the type for chara + stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri + boo->tag = TYPE_PRIMITIVE; // explicitly set the type for boo // addr->additionalinfo = CreatePrimitiveInfo(8); start->Line_Number = 1; @@ -661,12 +674,33 @@ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { return tn; } +AdInfo *getAdInfo(TableNode *tn) { + if (tn == NULL) { + printdebug("passed a NULL table entry to getAdInfo. Invalid."); + return NULL; + } + if (tn == undefined) { + printdebug( + "passed an undefined table entry to getAdInfo. Invalid."); + return NULL; + } + if (tn->additionalinfo == NULL) { + printdebug( + "no additional info found in the table node. Invalid."); + return NULL; + } + return tn->additionalinfo; +} + +//simplified getAdInfoType int getAdInfoType(TableNode *tn) { if (tn == NULL) { printdebug( "passing in NULL table entry to getAdInfoType. Invalid"); return -1; } + return tn->tag; + /* if (tn == undefined) { printdebug("passing in undefined table entry to getAdInfoType. " "Invalid"); @@ -725,11 +759,10 @@ int getAdInfoType(TableNode *tn) { "passed in an entry that is not a primitive type, array, " "or record. Invalid."); return TYPE_FUNCTION_DECLARATION; - } + }*/ } -TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, - AdInfo *ad) { +TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, AdInfo *ad) { if (table == NULL) { printdebug("Null reference to table"); @@ -752,7 +785,14 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, return undefined; } + TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); + if(tag<1 && tag>11){ + printdebug("Note- not passing in valid 'tag' identifier to create entry function. Setting tag to undefined"); + newEntry->tag = TYPE_UNDEFINED; + } else{ + newEntry->tag = tag; + } newEntry->theType = typeOf /*topDef*/; newEntry->theName = id; newEntry->additionalinfo = ad; @@ -769,6 +809,8 @@ TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, } } + + TableNode *getTypeEntry(TableNode *tn) { if (tn == NULL) { printdebug("passed a NULL table entry to getType"); @@ -853,9 +895,9 @@ TableNode *addName(TableNode *tn, char *str) { return undefined; } if (tn->theName != NULL) { - printdebug( - "Name doesn't look like it is empty before you change. " - "Are you sure you need to update name?"); + //printdebug( + //"Name doesn't look like it is empty before you change. " + //"Are you sure you need to update name?"); if (str != NULL) { tn->theName = str; return tn; @@ -1011,178 +1053,177 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } }*/ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + if (table == NULL) { + printdebug( + "%s[FATAL] passed in NULL table to print_symbol_table", + COLOR_RED); + return; + } - if (table == NULL) { - printdebug( - "%s[FATAL] passed in NULL table to print_symbol_table", - COLOR_RED); - return; - } + if (table->Parent_Scope == NULL) { + fprintf(file_ptr, "%-25s: %-6s : %-6s : %-25s: %-30s\n", "NAME", + "SCOPE", "PARENT", "TYPE", "Extra annotation"); + } - if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "%-17s: %-6s : %-6s : %-21s: %-28s\n", "NAME", - "SCOPE", "PARENT", "TYPE", "Extra annotation"); - } + TableNode *entrie = table->entries; + fprintf(file_ptr, + "-------------------------:--------:--------:------------------" + "--------:------------------------------\n"); + int parant_scope = 0; + int current_scope = 0; + if (table->Parent_Scope != NULL) { + parant_scope = getParent(table)->Line_Number * 1000 + + getParent(table)->Column_Number; + current_scope = + table->Line_Number * 1000 + table->Column_Number; + } else { + current_scope = 1001; + } + if (entrie == NULL) { + fprintf(file_ptr, "%-25s: %06d : %06d : %-25s: %-30s\n", "", + current_scope, parant_scope, "", "Empty Scope"); + } + for (; entrie != NULL; entrie = getNextEntry(entrie)) { + if (getAdInfoType(entrie) == TYPE_ARRAY_TYPE) { + if (parant_scope == 0) { - TableNode *entrie = table->entries; - fprintf(file_ptr, "-----------------:--------:--------:----------------" - "------:---------" - "--------------------\n"); - int parant_scope = 0; - int current_scope = 0; - if (table->Parent_Scope != NULL) { - parant_scope = getParent(table)->Line_Number * 1000 + - getParent(table)->Column_Number; - current_scope = - table->Line_Number * 1000 + table->Column_Number; - } else { - current_scope = 1001; - } - if (entrie == NULL) { - fprintf(file_ptr, "%-17s: %06d : %06d : %-21s: %-28s\n", "", - current_scope, parant_scope, "", "Empty Scope"); - } - for (; entrie != NULL; entrie = getNextEntry(entrie)) { - if (getAdInfoType(entrie) == TYPE_ARRAY_TYPE) { - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : : %-21d -> " - "%-21s: %-28s\n", - entrie->theName, current_scope, - entrie->additionalinfo->ArrayAdInfo - ->numofdimensions, - entrie->additionalinfo->ArrayAdInfo - ->typeofarray->theName, - "Type of Array"); - } else { - fprintf(file_ptr, - "%-17s: %06d : %06d : %-21d -> %-21s: " - "%-28s\n", - entrie->theName, current_scope, - parant_scope, - entrie->additionalinfo->ArrayAdInfo - ->numofdimensions, - entrie->additionalinfo->ArrayAdInfo - ->typeofarray->theName, - "Type of Array"); - } - } - if (getAdInfoType(entrie) == TYPE_RECORD) { - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-17s: %06d : :%-21s: " - "elements-%-28d\n", - entrie->theName, current_scope, - "record", - entrie->additionalinfo->RecAdInfo - ->numofelements); - } else { - fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s: " - "elements-%-28d\n", - entrie->theName, current_scope, - parant_scope, "record", - entrie->additionalinfo->RecAdInfo - ->numofelements); - } - } - if (getAdInfoType(entrie) == TYPE_PRIMITIVE) { - if (parant_scope == 0) { - - fprintf( - file_ptr, - "%-17s: %06d : :%-21s: size-%-28d " - "bytes\n", - entrie->theName, current_scope, "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } else { - fprintf( - file_ptr, - "%-17s: %06d : %06d : %-21s: size-%-28d " - "bytes\n", + fprintf(file_ptr, + "%-25s: %06d : : %d -> %-20s: " + "%-30s\n", entrie->theName, current_scope, - parant_scope, "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE) { - if (parant_scope == 0) { + entrie->additionalinfo->ArrayAdInfo + ->numofdimensions, + entrie->additionalinfo->ArrayAdInfo + ->typeofarray->theName, + "Type of Array"); + } else { + fprintf(file_ptr, + "%-25s: %06d : : %d -> %-20s: " + "%-30s\n", + entrie->theName, current_scope, + parant_scope, + entrie->additionalinfo->ArrayAdInfo + ->numofdimensions, + entrie->additionalinfo->ArrayAdInfo + ->typeofarray->theName, + "Type of Array"); + } + } + if (getAdInfoType(entrie) == TYPE_RECORD) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : : %-21s -> " - "%-21s: %-28s\n", - entrie->theName, current_scope, - entrie->additionalinfo->FunTypeAdInfo - ->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo - ->returntype->theName, - "Type of Function"); - } else { - fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s -> %-21s: " - "%-28s\n", - entrie->theName, current_scope, - parant_scope, - entrie->additionalinfo->FunTypeAdInfo - ->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo - ->returntype->theName, - "Type of Function"); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION) { - if (parant_scope == 0) { + fprintf(file_ptr, + "%-25s: %06d : : %-25s: " + "elements-%-30d\n", + entrie->theName, current_scope, + "record", + entrie->additionalinfo->RecAdInfo + ->numofelements); + } else { + fprintf(file_ptr, + "%-25s: %06d : %06d : %-25s: " + "elements-%-30d\n", + entrie->theName, current_scope, + parant_scope, "record", + entrie->additionalinfo->RecAdInfo + ->numofelements); + } + } + if (getAdInfoType(entrie) == TYPE_PRIMITIVE) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", - entrie->theName, current_scope, - getType(entrie), "User Defined"); - } else { - fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s: %-28s\n", - entrie->theName, current_scope, - parant_scope, getType(entrie), - "User Defined"); - } - } - if (getAdInfoType(entrie) == TYPE_UNDEFINED) { - if (parant_scope == 0) { + fprintf( + file_ptr, + "%-25s: %06d : : %-25s: size-%d " + "bytes\n", + entrie->theName, current_scope, "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } else { + fprintf( + file_ptr, + "%-25s: %06d : %06d : %-25s: size-%-30d " + "bytes\n", + entrie->theName, current_scope, + parant_scope, "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-17s: %06d : :%-21s: %-28s\n", - entrie->theName, current_scope, - "undefined", "undefined entry"); - } else { - fprintf(file_ptr, - "%-17s: %06d : %06d : %-21s: %-28s\n", - entrie->theName, current_scope, - parant_scope, "undefined", - "undefined entry"); - } - } - } - if (getChildren(table) != NULL) { - ListOfTable *node = getChildren(table); - for (; node != NULL; node = node->next) { - if ((node->table) == NULL) { - print_symbol_table(node->table, file_ptr); - } else { - if ((node->table)->Line_Number == -1) { - continue; - } else { - print_symbol_table(node->table, - file_ptr); - } - } - } - } - if (getParent(table) == NULL) { - fprintf(file_ptr, "-----------------:--------:--------:--------" - "--------------:-------" - "----------------------\n"); - } + fprintf(file_ptr, + "%-25s: %06d : : %-25s -> " + "%-25s: %-30s\n", + entrie->theName, current_scope, + entrie->additionalinfo->FunTypeAdInfo + ->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo + ->returntype->theName, + "Type of Function"); + } else { + fprintf(file_ptr, + "%-25s: %06d : %06d : %-25s -> %-21s: " + "%-30s\n", + entrie->theName, current_scope, + parant_scope, + entrie->additionalinfo->FunTypeAdInfo + ->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo + ->returntype->theName, + "Type of Function"); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION) { + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-25s: %06d : : %-25s: %-30s\n", + entrie->theName, current_scope, + getType(entrie), "User Defined"); + } else { + fprintf(file_ptr, + "%-25s: %06d : %06d : %-25s: %-30s\n", + entrie->theName, current_scope, + parant_scope, getType(entrie), + "User Defined"); + } + } + if (getAdInfoType(entrie) == TYPE_UNDEFINED) { + if (parant_scope == 0) { + + fprintf(file_ptr, + "%-25s: %06d : : %-25s: %-30s\n", + entrie->theName, current_scope, + "undefined", "undefined entry"); + } else { + fprintf(file_ptr, + "%-25s: %06d : %06d : %-25s: %-30s\n", + entrie->theName, current_scope, + parant_scope, "undefined", + "undefined entry"); + } + } + } + if (getChildren(table) != NULL) { + ListOfTable *node = getChildren(table); + for (; node != NULL; node = node->next) { + if ((node->table) == NULL) { + print_symbol_table(node->table, file_ptr); + } else { + if ((node->table)->Line_Number == -1) { + continue; + } else { + print_symbol_table(node->table, + file_ptr); + } + } + } + } + if (getParent(table) == NULL) { + fprintf(file_ptr, + "-------------------------:--------:--------:----------" + "----------------:------------------------------\n"); + } } // get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { diff --git a/src/symbol_table.h b/src/symbol_table.h index de37098..f223b8a 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -3,6 +3,12 @@ #include #include +#define SIZE_INT 4 +#define SIZE_ADDR 8 +#define SIZE_CHAR 1 +#define SIZE_BOOL 4 //TODO: Ask Carl what this size should be + + struct TableNode; typedef struct { @@ -58,9 +64,11 @@ typedef struct ListOfTable { struct ListOfTable *next; } ListOfTable; +//Table node to store typedef struct TableNode { // reference to the type entry that this is struct TableNode *theType; + int tag; char *theName; AdInfo *additionalinfo; struct TableNode *next; From a53a22530dc5e346afdc020ad9e7dbd95d085a3b Mon Sep 17 00:00:00 2001 From: Annie Date: Fri, 4 Apr 2025 20:29:41 -0400 Subject: [PATCH 077/137] added tests for sprint 2 and 3 --- .../sp2_invalid_multiple_params_no_as.alpha | 7 ++++ .../sprint3/test/sp3_and_or_type_check.alpha | 37 +++++++++++++++++++ .../sp3_integer_binary_op_typecheck.alpha | 25 +++++++++---- 3 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha create mode 100644 tests/sprint3/test/sp3_and_or_type_check.alpha diff --git a/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha b/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha new file mode 100644 index 0000000..805fb6e --- /dev/null +++ b/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha @@ -0,0 +1,7 @@ +type rec: [integer: x; integer: y] +type main: rec -> integer +function test: main + +test (arg, arg2) := { + return 0; +} \ No newline at end of file diff --git a/tests/sprint3/test/sp3_and_or_type_check.alpha b/tests/sprint3/test/sp3_and_or_type_check.alpha new file mode 100644 index 0000000..a6cf442 --- /dev/null +++ b/tests/sprint3/test/sp3_and_or_type_check.alpha @@ -0,0 +1,37 @@ +type rec: [integer: x; integer: y] +type main: rec -> integer +function test: main + +test (arg, arg2) := { + [integer:x; Boolean: b] + while (true) { + x := 0; + } + + while (7) { + x := 1; + } + + if (true) { + x := 1; + } else { + x := 0; + } + + if (x) { + x := 0; + } else { + x := 1; + } + + b := b | b; + b := b & b; + b := 1 | b; + b := b | 1; + b := b & 1; + b := 1 & b; + b := 1 = 1; + b := 1 = b; + + return 0; +} diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha index 5b13147..d8670ff 100644 --- a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -1,9 +1,18 @@ -entry(arg) := { - [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a] - x := 3 + 2 * 8; - x := 3 - 2 / 8; - x := a * 2 % 8; - b2 := 3 * 2 % 8; - x := 3 % 2 * 8; - x := 3 + arr - 8; +type main: string -> integer +type rec: [integer: x; integer: y] +function entry: main + +entry (arg) := { + [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a; rec : r] + + x := 3 + 2 * 8; + x := 3 - 2 / 8; + x := a * 2 % 8; + b2 := 3 * 2 % 8; + x := 3 % 2 * 8; + x := 3 + arr - 8; + r.x; + a.x; + + return 0; } From a5e1acefde50d43f00c5170a936658a3aba69eb5 Mon Sep 17 00:00:00 2001 From: Annie Date: Fri, 4 Apr 2025 20:39:01 -0400 Subject: [PATCH 078/137] fixed sytnax errors in tests --- tests/sprint3/test/sp3_and_or_type_check.alpha | 6 +++--- tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/sprint3/test/sp3_and_or_type_check.alpha b/tests/sprint3/test/sp3_and_or_type_check.alpha index a6cf442..450aee0 100644 --- a/tests/sprint3/test/sp3_and_or_type_check.alpha +++ b/tests/sprint3/test/sp3_and_or_type_check.alpha @@ -2,7 +2,7 @@ type rec: [integer: x; integer: y] type main: rec -> integer function test: main -test (arg, arg2) := { +test (arg) := { [integer:x; Boolean: b] while (true) { x := 0; @@ -12,13 +12,13 @@ test (arg, arg2) := { x := 1; } - if (true) { + if (true) then { x := 1; } else { x := 0; } - if (x) { + if (x) then { x := 0; } else { x := 1; diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha index d8670ff..8d8ad70 100644 --- a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -11,8 +11,8 @@ entry (arg) := { b2 := 3 * 2 % 8; x := 3 % 2 * 8; x := 3 + arr - 8; - r.x; - a.x; + x := r.x; + x := a.x; return 0; } From 6a6677ccb523cb391788ecb1dfc9aed8ea9b4012 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 4 Apr 2025 21:12:11 -0400 Subject: [PATCH 079/137] checking diff --- src/grammar.y | 42 +++++++++++------------------------------- src/runner.c | 2 +- src/symbol_table.c | 2 +- 3 files changed, 13 insertions(+), 33 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 119960a..1725d62 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -154,7 +154,7 @@ definition: { //We are scanning through the dblock scope to get the length of the dblock (num of elements) from getRecSize //and then putting it in the entry that we created above. - setRecSize(look_up(cur, $2), getRecSize(cur)); + setRecSize(look_up(getParent(cur), $2), getRecSize(cur)); cur = getParent(cur); } @@ -206,27 +206,7 @@ definition: CreateEntry(cur,type_of_param_type, type_of_param, $4, getAdInfo(type_of_param)); } R_PAREN ASSIGN sblock //leaving scope is being taken care of in sblock - - /* | ID - { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == undefined) { - printdebug("null check"); - } - if (node == undefined) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); - } else { - setStartLine(node, @1.first_line); - setAsKeyword(node, false); - } - cur = CreateScope(cur, 0, 0); - } L_PAREN ID { - printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", - $1,$4); - CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))), $4, NULL); - }R_PAREN ASSIGN sblock */ + | ID { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { @@ -394,7 +374,7 @@ id_or_types: ID { printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); - $$ = look_up(cur, $1); + $$ = table_lookup(getAncestor(cur), $1); } | types @@ -428,11 +408,11 @@ simple_statement: { if(strcmp(getName($1), getName($3)) == 0) { printdebug("Passed standard type check; assignable = expression"); - } else if((strcmp(getName($1), "array") == 0) && (strcmp(getName($3), "address") == 0)) { + } else if((strcmp(getType($1), "array") == 0) && (strcmp(getName($3), "address") == 0)) { printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, getName($1), getName($3)); - } else if((strcmp(getName($1), "record") == 0) && (strcmp(getName($3), "address") == 0)) { + } else if((strcmp(getType($1), "record") == 0) && (strcmp(getName($3), "address") == 0)) { printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, getName($1), getName($3)); - } else if((strcmp(getName($1), "function type primitive") == 0) && (strcmp(getName($3), "address") == 0)) { + } else if((strcmp(getType($1), "function type primitive") == 0) && (strcmp(getName($3), "address") == 0)) { printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, getName($1), getName($3)); // } else if () { @@ -613,7 +593,7 @@ expression: | assignable { printdebug("assignable expression. current type is %s",$1); - $$= getTypeEntry($1);//idk if this is correct + $$= getTypeEntry($1); } | L_PAREN expression R_PAREN @@ -648,7 +628,7 @@ assignable: } ablock { - int type = getAdInfoType(look_up(cur, getName($1))); + int type = getAdInfoType(look_up(getParent(cur), getName($1))); printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", $1); @@ -658,7 +638,7 @@ assignable: printdebug("as function"); //char *funtype = getType(look_up(cur, $1)); printdebug("%s", getType(look_up(cur, getName($1)))); - TableNode *param = getParameter(look_up(cur, getType(look_up(cur, getName($1))))); + TableNode *param = getParameter(look_up(getParent(cur), getName($1))); SymbolTable *recList = getRecList(param); TableNode *lastCheckedRef = getFirstEntry(recList); TableNode *lastCheckedAct = getFirstEntry(cur); @@ -669,7 +649,7 @@ assignable: //this isn't very efficient, but will hopefully work while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (strcmp(getName(lastCheckedAct), getType(lastCheckedRef)) != 0) { + if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { printdebug("expected %s. expression in function call got %s. at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); printdebug("%d", strcmp(getName(lastCheckedAct), getName(lastCheckedRef))); } @@ -691,7 +671,7 @@ assignable: printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); } } - $$ = getReturn((look_up(cur, getType(look_up(cur, getName($1)))))); + $$ = getReturn((table_lookup(getAncestor(cur), getType($1)))); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName($1)); } else if (type == TYPE_ARRAY_TYPE) { diff --git a/src/runner.c b/src/runner.c index c6f94a3..b20f594 100644 --- a/src/runner.c +++ b/src/runner.c @@ -143,7 +143,7 @@ int run(FILE *alpha) { if (st_flag != NULL) { yyparse(); - print_symbol_table(getAncestor(cur), st_flag); + print_symbol_table(top, st_flag); fclose(st_flag); if (yyin != NULL) { fclose(yyin); diff --git a/src/symbol_table.c b/src/symbol_table.c index 2e1af13..08a0932 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1330,7 +1330,7 @@ SymbolTable *getParent(SymbolTable *st) { if (st->Parent_Scope == NULL) { printdebug("passed a top level scope to getParent function. " "Invalid."); - return NULL; + return st; } return st->Parent_Scope; } From e2aa9e7c12bb4702cd5b4e6b592269ccec040d99 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 4 Apr 2025 21:40:13 -0400 Subject: [PATCH 080/137] fixed header for this branch --- src/symbol_table.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/symbol_table.h b/src/symbol_table.h index 53c2fa2..cf1273a 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -76,7 +76,8 @@ typedef enum { TYPE_ALL_ELSE = 7, TYPE_UNDEFINED = 8, TYPE_RECORD = 9, - TYPE_ARRAY = 10 + TYPE_ARRAY = 10, + TYPE_SYSTEM_DEFINED = 11 } types; AdInfo *CreatePrimitiveInfo(int size); @@ -101,7 +102,7 @@ SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column); SymbolTable *init(SymbolTable *start); TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info); int getAdInfoType(TableNode *tn); -TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id, +TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, AdInfo *ad); char *getType(TableNode *tn); char *getName(TableNode *tn); From e42e53733916891633537a76372bb0cd2e988a5a Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 7 Apr 2025 12:32:20 -0400 Subject: [PATCH 081/137] ran through derefenced most if not all of the pointers --- src/grammar.y | 123 +++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 62 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 7dd6499..4a09304 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -18,7 +18,6 @@ %{ #include "../src/symbol_table.c" - void yyerror(const char *err); int token_tracker; TableNode * tn; @@ -142,17 +141,17 @@ definition: | TYPE ID COLON C_INTEGER ARROW id_or_types { - printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, getName($6), $4); - CreateEntry(cur,TYPE_ARRAY_TYPE, arrayprim, $2, CreateArrayInfo($4, $6)); - printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, getName($6)); + printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, getName((TableNode*)$6), $4); + CreateEntry(cur,TYPE_ARRAY_TYPE, arrayprim, $2, CreateArrayInfo($4, (TableNode*)$6)); + printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, getName((TableNode*)$6)); } | function_declaration | TYPE ID COLON id_or_types ARROW id_or_types { - printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, getName($4), getName($6)); - CreateEntry(cur,TYPE_FUNCTION_TYPE,funtypeprime,$2,CreateFunctionTypeInfo($4 ,$6)); + printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, getName((TableNode*)$4), getName((TableNode*)$6)); + CreateEntry(cur,TYPE_FUNCTION_TYPE,funtypeprime,$2,CreateFunctionTypeInfo((TableNode*)$4 ,(TableNode*)$6)); } | ID @@ -349,8 +348,8 @@ declaration_list: declaration: id_or_types COLON ID { - printdebug("ID/TYPE: %s, ID: %s", getName($1), $3) ; - CreateEntry(cur,getAdInfoType($1),$1,$3,getAdInfo($1)); + printdebug("ID/TYPE: %s, ID: %s", getName((TableNode*)$1), $3) ; + CreateEntry(cur,getAdInfoType((TableNode*)$1),(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } ; @@ -365,8 +364,8 @@ id_or_types: | types { - printdebug("string of type is %s in types pattern of id_or_type rule.",getName($1)); - $$ = $1; + printdebug("string of type is %s in types pattern of id_or_type rule.",getName((TableNode*)$1)); + $$ = (TableNode*)$1; } ; @@ -392,22 +391,22 @@ compound_statement: simple_statement: assignable ASSIGN expression { - if(strcmp(getName($1), getName($3)) == 0) { + if(strcmp(getName((TableNode*)$1), getName((TableNode*)$3)) == 0) { printdebug("Passed standard type check; assignable = expression"); - } else if((strcmp(getType($1), "array") == 0) && (strcmp(getName($3), "address") == 0)) { - printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, getName($1), getName($3)); - } else if((strcmp(getType($1), "record") == 0) && (strcmp(getName($3), "address") == 0)) { - printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, getName($1), getName($3)); - } else if((strcmp(getType($1), "function type primitive") == 0) && (strcmp(getName($3), "address") == 0)) { - printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, getName($1), getName($3)); + } else if((strcmp(getType((TableNode*)$1), "array") == 0) && (strcmp(getName((TableNode*)$3), "address") == 0)) { + printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, getName((TableNode*)$1), getName((TableNode*)$3)); + } else if((strcmp(getType((TableNode*)$1), "record") == 0) && (strcmp(getName((TableNode*)$3), "address") == 0)) { + printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, getName((TableNode*)$1), getName((TableNode*)$3)); + } else if((strcmp(getType((TableNode*)$1), "function type primitive") == 0) && (strcmp(getName((TableNode*)$3), "address") == 0)) { + printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, getName((TableNode*)$1), getName((TableNode*)$3)); // } else if () { // } else if(strcmp(getType(table_lookup(cur, $1)), getType(table_lookup(cur, $3))) == 0) { // printdebug("%s[] Passed double lookup type check; %s = %s", COLOR_GREEN, $1, $3); } else { printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); - printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType($1), getType($3), COLOR_WHITE); - printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType($1)); + printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType((TableNode*)$1), getType((TableNode*)$3), COLOR_WHITE); + printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType((TableNode*)$1)); } } @@ -434,14 +433,14 @@ ablock: argument_list: expression COMMA argument_list { - CreateEntry(cur,getAdInfoType($1), $1, getName($1), NULL); + CreateEntry(cur,getAdInfoType((TableNode*)$1), (TableNode*)$1, getName((TableNode*)$1), NULL); $$ = $3 + 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } | expression { - CreateEntry(cur,getAdInfoType($1),$1, getName($1), NULL); + CreateEntry(cur,getAdInfoType((TableNode*)$1),(TableNode*)$1, getName((TableNode*)$1), NULL); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } ; @@ -452,38 +451,38 @@ expression: constant { printdebug("constant expression"); - $$ = $1; + $$ = (TableNode*)$1; } | SUB_OR_NEG expression %prec UMINUS { printdebug("negative expression"); - if($2 != integ) { + if((TableNode*)$2 != integ) { printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); $$=undefined; } else { - $$=$2; + $$=(TableNode*)$2; } } | NOT expression { printdebug("not expression"); - if($2 == boo) { - $$=$2; + if((TableNode*)$2 == boo) { + $$=(TableNode*)$2; } else { $$=undefined; - printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,getName($2)); + printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,getName((TableNode*)$2)); } } | expression ADD expression { printdebug("add expression"); - if($1 == $3 && $1 == integ) { - $$=$1; + if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { + $$=(TableNode*)$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -491,10 +490,10 @@ expression: | expression SUB_OR_NEG expression { printdebug("sub or neg expression"); - if($1 == $3 && $1 == integ) { - $$=$1; + if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { + $$=(TableNode*)$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -502,8 +501,8 @@ expression: | expression MUL expression { printdebug("multiply expression"); - if($1 == $3 && $1 == integ) { - $$=$1; + if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { + $$=(TableNode*)$1; } else{ printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); $$=undefined; @@ -513,10 +512,10 @@ expression: | expression DIV expression { printdebug("divide expression"); - if((strcmp(getName($1),getName($3))==0) && ($1 == integ)) { - $$=$1; + if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && ((TableNode*)$1 == integ)) { + $$=(TableNode*)$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -527,7 +526,7 @@ expression: if($1 == $3 && $1 == integ) { $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -538,7 +537,7 @@ expression: if($1 == $3 && $1 == boo){ $$=$1; } else{ - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -546,10 +545,10 @@ expression: | expression OR expression { printdebug("OR"); - if((strcmp(getName($1),getName($3))==0) && $1 == boo) { + if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && $1 == boo) { $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -560,7 +559,7 @@ expression: if($1 == $3 && $1==integ) { $$=boo; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -571,20 +570,20 @@ expression: if($1 == $3 && $1 != undefined) { $$=boo; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$ = undefined; } } | assignable { - printdebug("assignable expression. current type is %s",$1); - $$= getTypeEntry($1); + printdebug("assignable expression. current type is %s",getName((TableNode*)$1)); + $$= getTypeEntry((TableNode*)$1); } | L_PAREN expression R_PAREN { - printdebug("paren expression. current type is %s",getName($2)); + printdebug("paren expression. current type is %s",getName((TableNode*)$2)); $$=$2; } @@ -614,17 +613,17 @@ assignable: } ablock { - int type = getAdInfoType(look_up(getParent(cur), getName($1))); + int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); printdebug("%stype is %d", COLOR_PURPLE, type); - printdebug("%s", $1); + printdebug("%s", getName((TableNode*)$1)); if (type == TYPE_FUNCTION_DECLARATION) { printdebug("%sEntering function call", COLOR_LIGHTGREEN); - if (look_up(getParent(cur), getName($1))->additionalinfo->FunDecAdInfo->regularoras) { + if (look_up(getParent(cur), getName((TableNode*)$1))->additionalinfo->FunDecAdInfo->regularoras) { printdebug("as function"); //char *funtype = getType(look_up(cur, $1)); - printdebug("%s", getType(look_up(cur, getName($1)))); - TableNode *param = getParameter(look_up(getParent(cur), getName($1))); + printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); + TableNode *param = getParameter(look_up(getParent(cur), getName((TableNode*)$1))); SymbolTable *recList = getRecList(param); TableNode *lastCheckedRef = getFirstEntry(recList); TableNode *lastCheckedAct = getFirstEntry(cur); @@ -651,32 +650,32 @@ assignable: } } else { - char *expected = getName(getParameter(look_up(getParent(cur), getName($1)))); + char *expected = getName(getParameter(look_up(getParent(cur), getName((TableNode*)$1)))); char *actual = getType(getFirstEntry(cur)); if (strcmp(expected, actual) != 0) { printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); } } - $$ = getReturn((table_lookup(getAncestor(cur), getType($1)))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName($1)); + $$ = getReturn((table_lookup(getAncestor(cur), getType((TableNode*)$1)))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName((TableNode*)$1)); } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); - if (getNumArrDim(look_up(getParent(cur), getName($1))) != $2) { - printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName($1))), $2, @2.first_line, @2.first_column); + if (getNumArrDim(look_up(getParent(cur), getName((TableNode*)$1))) != $2) { + printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $2, @2.first_line, @2.first_column); } - $$ = getArrType(look_up(getParent(cur), getName($1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName($1)); + $$ = getArrType(look_up(getParent(cur), getName((TableNode*)$1))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName((TableNode*)$1)); } cur = getParent(cur); } | assignable rec_op ID { - if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName($1))), $3)) { - $$ = table_lookup(getRecList(table_lookup(getAncestor(cur), getName($1))), $3); + if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3)) { + $$ = table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3); } - printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName($$), $1); + printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName((TableNode*)($$)), $1); } ; From 4058b090a00023708d08c2f9452b00ed99dc7b55 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 7 Apr 2025 15:51:45 -0400 Subject: [PATCH 082/137] found one segfault. (not fixed yet) --- check.sh | 2 + src/grammar.y | 5 + src/symbol_table.c | 460 +++++++++++++++++++++++++++------------------ src/symbol_table.h | 1 + 4 files changed, 287 insertions(+), 181 deletions(-) diff --git a/check.sh b/check.sh index bac18ec..cf7c946 100755 --- a/check.sh +++ b/check.sh @@ -33,6 +33,8 @@ compare_files() { diff -q "$file" "$exp" > /dev/null if [[ $? -eq 0 ]]; then echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed.${NOCOLOR}" + elif [[ ! -s "$file" ]]; then + echo -e "${RED}[✘] ${PURPLE}$filename ${WHITE}failed with an empty file. (did it segfault?)${NOCOLOR}" else echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value...${NOCOLOR}" diff --color=always "$file" "$exp" diff --git a/src/grammar.y b/src/grammar.y index 4a09304..b20c09e 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -623,7 +623,12 @@ assignable: printdebug("as function"); //char *funtype = getType(look_up(cur, $1)); printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); + + // Something fishy is going on here....... TableNode *param = getParameter(look_up(getParent(cur), getName((TableNode*)$1))); + printTableNode(table_lookup(getAncestor(cur), getName((TableNode*)$1))); + + SymbolTable *recList = getRecList(param); TableNode *lastCheckedRef = getFirstEntry(recList); TableNode *lastCheckedAct = getFirstEntry(cur); diff --git a/src/symbol_table.c b/src/symbol_table.c index 1cb6cc8..3e67b95 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -261,9 +261,10 @@ bool getAsKeyword(TableNode *definition) { return false; } if (strcmp(getType(definition), "primitive function") != 0) { - printdebug( - "not checking if a function is called with as or not (%s) -- " - "invalid op", getType(definition)); + printdebug("not checking if a function is called with as or " + "not (%s) -- " + "invalid op", + getType(definition)); return 0; } return definition->additionalinfo->FunDecAdInfo->regularoras; @@ -490,10 +491,10 @@ SymbolTable *init(SymbolTable *start) { boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); integ->tag = TYPE_PRIMITIVE; // explicitly set the type for integ - addr->tag = TYPE_PRIMITIVE; // explicitly set the type for addr + addr->tag = TYPE_PRIMITIVE; // explicitly set the type for addr chara->tag = TYPE_PRIMITIVE; // explicitly set the type for chara stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri - boo->tag = TYPE_PRIMITIVE; // explicitly set the type for boo + boo->tag = TYPE_PRIMITIVE; // explicitly set the type for boo // addr->additionalinfo = CreatePrimitiveInfo(8); start->Line_Number = 1; @@ -563,7 +564,7 @@ AdInfo *getAdInfo(TableNode *tn) { return tn->additionalinfo; } -//simplified getAdInfoType +// simplified getAdInfoType int getAdInfoType(TableNode *tn) { if (tn == NULL) { printdebug( @@ -633,7 +634,8 @@ int getAdInfoType(TableNode *tn) { }*/ } -TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, AdInfo *ad) { +TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, + AdInfo *ad) { if (table == NULL) { printdebug("Null reference to table"); @@ -656,12 +658,12 @@ TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, return undefined; } - TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); - if(tag<1 && tag>11){ - printdebug("Note- not passing in valid 'tag' identifier to create entry function. Setting tag to undefined"); + if (tag < 1 && tag > 11) { + printdebug("Note- not passing in valid 'tag' identifier to " + "create entry function. Setting tag to undefined"); newEntry->tag = TYPE_UNDEFINED; - } else{ + } else { newEntry->tag = tag; } newEntry->theType = typeOf /*topDef*/; @@ -680,8 +682,6 @@ TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, } } - - TableNode *getTypeEntry(TableNode *tn) { if (tn == NULL) { printdebug("passed a NULL table entry to getType"); @@ -766,12 +766,12 @@ TableNode *addName(TableNode *tn, char *str) { return undefined; } if (tn->theName != NULL) { - //printdebug( - //"Name doesn't look like it is empty before you change. " - //"Are you sure you need to update name?"); + // printdebug( + //"Name doesn't look like it is empty before you change. " + //"Are you sure you need to update name?"); if (str != NULL) { - tn->theName = str; - return tn; + tn->theName = str; + return tn; } printdebug("passed a NULL string to the addName function"); return undefined; @@ -839,177 +839,177 @@ TableNode *look_up(SymbolTable *table, char *x) { void print_symbol_table(SymbolTable *table, FILE *file_ptr) { - if (table == NULL) { - printdebug( - "%s[FATAL] passed in NULL table to print_symbol_table", - COLOR_RED); - return; - } + if (table == NULL) { + printdebug( + "%s[FATAL] passed in NULL table to print_symbol_table", + COLOR_RED); + return; + } - if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "%-25s: %-6s : %-6s : %-25s: %-30s\n", "NAME", - "SCOPE", "PARENT", "TYPE", "Extra annotation"); - } + if (table->Parent_Scope == NULL) { + fprintf(file_ptr, "%-25s: %-6s : %-6s : %-25s: %-30s\n", "NAME", + "SCOPE", "PARENT", "TYPE", "Extra annotation"); + } - TableNode *entrie = table->entries; - fprintf(file_ptr, - "-------------------------:--------:--------:------------------" - "--------:------------------------------\n"); - int parant_scope = 0; - int current_scope = 0; - if (table->Parent_Scope != NULL) { - parant_scope = getParent(table)->Line_Number * 1000 + - getParent(table)->Column_Number; - current_scope = - table->Line_Number * 1000 + table->Column_Number; - } else { - current_scope = 1001; - } - if (entrie == NULL) { - fprintf(file_ptr, "%-25s: %06d : %06d : %-25s: %-30s\n", "", - current_scope, parant_scope, "", "Empty Scope"); - } - for (; entrie != NULL; entrie = getNextEntry(entrie)) { - if (getAdInfoType(entrie) == TYPE_ARRAY_TYPE) { - if (parant_scope == 0) { + TableNode *entrie = table->entries; + fprintf(file_ptr, + "-------------------------:--------:--------:------------------" + "--------:------------------------------\n"); + int parant_scope = 0; + int current_scope = 0; + if (table->Parent_Scope != NULL) { + parant_scope = getParent(table)->Line_Number * 1000 + + getParent(table)->Column_Number; + current_scope = + table->Line_Number * 1000 + table->Column_Number; + } else { + current_scope = 1001; + } + if (entrie == NULL) { + fprintf(file_ptr, "%-25s: %06d : %06d : %-25s: %-30s\n", "", + current_scope, parant_scope, "", "Empty Scope"); + } + for (; entrie != NULL; entrie = getNextEntry(entrie)) { + if (getAdInfoType(entrie) == TYPE_ARRAY_TYPE) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-25s: %06d : : %d -> %-20s: " - "%-30s\n", - entrie->theName, current_scope, - entrie->additionalinfo->ArrayAdInfo - ->numofdimensions, - entrie->additionalinfo->ArrayAdInfo - ->typeofarray->theName, - "Type of Array"); - } else { - fprintf(file_ptr, - "%-25s: %06d : : %d -> %-20s: " - "%-30s\n", - entrie->theName, current_scope, - parant_scope, - entrie->additionalinfo->ArrayAdInfo - ->numofdimensions, - entrie->additionalinfo->ArrayAdInfo - ->typeofarray->theName, - "Type of Array"); - } - } - if (getAdInfoType(entrie) == TYPE_RECORD) { - if (parant_scope == 0) { + fprintf(file_ptr, + "%-25s: %06d : : %d -> %-20s: " + "%-30s\n", + entrie->theName, current_scope, + entrie->additionalinfo->ArrayAdInfo + ->numofdimensions, + entrie->additionalinfo->ArrayAdInfo + ->typeofarray->theName, + "Type of Array"); + } else { + fprintf(file_ptr, + "%-25s: %06d : : %d -> %-20s: " + "%-30s\n", + entrie->theName, current_scope, + parant_scope, + entrie->additionalinfo->ArrayAdInfo + ->numofdimensions, + entrie->additionalinfo->ArrayAdInfo + ->typeofarray->theName, + "Type of Array"); + } + } + if (getAdInfoType(entrie) == TYPE_RECORD) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-25s: %06d : : %-25s: " - "elements-%-30d\n", - entrie->theName, current_scope, - "record", - entrie->additionalinfo->RecAdInfo - ->numofelements); - } else { - fprintf(file_ptr, - "%-25s: %06d : %06d : %-25s: " - "elements-%-30d\n", - entrie->theName, current_scope, - parant_scope, "record", - entrie->additionalinfo->RecAdInfo - ->numofelements); - } - } - if (getAdInfoType(entrie) == TYPE_PRIMITIVE) { - if (parant_scope == 0) { + fprintf(file_ptr, + "%-25s: %06d : : %-25s: " + "elements-%-30d\n", + entrie->theName, current_scope, + "record", + entrie->additionalinfo->RecAdInfo + ->numofelements); + } else { + fprintf(file_ptr, + "%-25s: %06d : %06d : %-25s: " + "elements-%-30d\n", + entrie->theName, current_scope, + parant_scope, "record", + entrie->additionalinfo->RecAdInfo + ->numofelements); + } + } + if (getAdInfoType(entrie) == TYPE_PRIMITIVE) { + if (parant_scope == 0) { - fprintf( - file_ptr, - "%-25s: %06d : : %-25s: size-%d " - "bytes\n", - entrie->theName, current_scope, "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } else { - fprintf( - file_ptr, - "%-25s: %06d : %06d : %-25s: size-%-30d " - "bytes\n", - entrie->theName, current_scope, - parant_scope, "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE) { - if (parant_scope == 0) { + fprintf( + file_ptr, + "%-25s: %06d : : %-25s: size-%d " + "bytes\n", + entrie->theName, current_scope, "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } else { + fprintf( + file_ptr, + "%-25s: %06d : %06d : %-25s: size-%-30d " + "bytes\n", + entrie->theName, current_scope, + parant_scope, "Primitive", + entrie->additionalinfo->PrimAdInfo->size); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-25s: %06d : : %-25s -> " - "%-25s: %-30s\n", - entrie->theName, current_scope, - entrie->additionalinfo->FunTypeAdInfo - ->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo - ->returntype->theName, - "Type of Function"); - } else { - fprintf(file_ptr, - "%-25s: %06d : %06d : %-25s -> %-21s: " - "%-30s\n", - entrie->theName, current_scope, - parant_scope, - entrie->additionalinfo->FunTypeAdInfo - ->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo - ->returntype->theName, - "Type of Function"); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION) { - if (parant_scope == 0) { + fprintf(file_ptr, + "%-25s: %06d : : %-25s -> " + "%-25s: %-30s\n", + entrie->theName, current_scope, + entrie->additionalinfo->FunTypeAdInfo + ->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo + ->returntype->theName, + "Type of Function"); + } else { + fprintf(file_ptr, + "%-25s: %06d : %06d : %-25s -> %-21s: " + "%-30s\n", + entrie->theName, current_scope, + parant_scope, + entrie->additionalinfo->FunTypeAdInfo + ->parameter->theName, + entrie->additionalinfo->FunTypeAdInfo + ->returntype->theName, + "Type of Function"); + } + } + if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-25s: %06d : : %-25s: %-30s\n", - entrie->theName, current_scope, - getType(entrie), "User Defined"); - } else { - fprintf(file_ptr, - "%-25s: %06d : %06d : %-25s: %-30s\n", - entrie->theName, current_scope, - parant_scope, getType(entrie), - "User Defined"); - } - } - if (getAdInfoType(entrie) == TYPE_UNDEFINED) { - if (parant_scope == 0) { + fprintf(file_ptr, + "%-25s: %06d : : %-25s: %-30s\n", + entrie->theName, current_scope, + getType(entrie), "User Defined"); + } else { + fprintf(file_ptr, + "%-25s: %06d : %06d : %-25s: %-30s\n", + entrie->theName, current_scope, + parant_scope, getType(entrie), + "User Defined"); + } + } + if (getAdInfoType(entrie) == TYPE_UNDEFINED) { + if (parant_scope == 0) { - fprintf(file_ptr, - "%-25s: %06d : : %-25s: %-30s\n", - entrie->theName, current_scope, - "undefined", "undefined entry"); - } else { - fprintf(file_ptr, - "%-25s: %06d : %06d : %-25s: %-30s\n", - entrie->theName, current_scope, - parant_scope, "undefined", - "undefined entry"); - } - } - } - if (getChildren(table) != NULL) { - ListOfTable *node = getChildren(table); - for (; node != NULL; node = node->next) { - if ((node->table) == NULL) { - print_symbol_table(node->table, file_ptr); - } else { - if ((node->table)->Line_Number == -1) { - continue; - } else { - print_symbol_table(node->table, - file_ptr); - } - } - } - } - if (getParent(table) == NULL) { - fprintf(file_ptr, - "-------------------------:--------:--------:----------" - "----------------:------------------------------\n"); - } + fprintf(file_ptr, + "%-25s: %06d : : %-25s: %-30s\n", + entrie->theName, current_scope, + "undefined", "undefined entry"); + } else { + fprintf(file_ptr, + "%-25s: %06d : %06d : %-25s: %-30s\n", + entrie->theName, current_scope, + parant_scope, "undefined", + "undefined entry"); + } + } + } + if (getChildren(table) != NULL) { + ListOfTable *node = getChildren(table); + for (; node != NULL; node = node->next) { + if ((node->table) == NULL) { + print_symbol_table(node->table, file_ptr); + } else { + if ((node->table)->Line_Number == -1) { + continue; + } else { + print_symbol_table(node->table, + file_ptr); + } + } + } + } + if (getParent(table) == NULL) { + fprintf(file_ptr, + "-------------------------:--------:--------:----------" + "----------------:------------------------------\n"); + } } // get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { @@ -1138,3 +1138,101 @@ TableNode *getNextEntry(TableNode *tn) { } return tn->next; } + +// Prints all info about a table node +// Uses pointers to the table node to print the info +TableNode *printTableNode(TableNode *tn) { + if (DEBUG == 0) { + return tn; + } + + if (tn == NULL) { + printdebug("%s[PrintTN] Passed a NULL tablenode!", COLOR_RED); + return undefined; + } + if (tn->theName == NULL) { + printdebug("%s[PrintTN] Passed a tablenode with NULL name!", + COLOR_RED); + return undefined; + } + if (tn->theType == NULL) { + printdebug("%s[PrintTN] Passed a tablenode with NULL type!", + COLOR_RED); + return undefined; + } + if (tn == undefined) { + printdebug("%s[PrintTN] Passed an undefined tablenode!", + COLOR_RED); + return undefined; + } + if (tn->additionalinfo == NULL) { + printdebug( + "%s[PrintTN] Passed a tablenode with NULL additional info!", + COLOR_RED); + return undefined; + } + + printdebug("%s[PrintTN] Printing tablenode...", COLOR_ORANGE); + printdebug(" %sName: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->theName); + printdebug(" %sType: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->theType->theName); + printdebug(" %sTag: %s%d", COLOR_YELLOW, COLOR_LIGHTBLUE, tn->tag); + + if (tn->tag == TYPE_RECORD_TYPE || tn->tag == TYPE_RECORD) { + printdebug(" %sAdditional Info: %sRecAdInfo", COLOR_YELLOW, + COLOR_LIGHTBLUE); + printdebug(" %snumberOfElements: %s%d", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->RecAdInfo->numofelements); + if (tn->additionalinfo->RecAdInfo->recordScope == NULL) { + printdebug(" %srecordScope (line): %s(NULL)", + COLOR_YELLOW, COLOR_LIGHTBLUE); + } else { + printdebug(" %srecordScope (line): %s%d", + COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->additionalinfo->RecAdInfo->recordScope + ->Line_Number); + } + } else if (tn->tag == TYPE_ARRAY_TYPE || tn->tag == TYPE_ARRAY) { + printdebug(" %sAdditional Info: %sArrayAdInfo", COLOR_YELLOW, + COLOR_LIGHTBLUE); + printdebug(" %snumberOfDimensions: %s%d", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->ArrayAdInfo->numofdimensions); + printdebug( + " %stypeOfArray: %s%s", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->ArrayAdInfo->typeofarray->theName); + } else if (tn->tag == TYPE_FUNCTION_TYPE) { + printdebug(" %sAdditional Info: %sFunTypeAdInfo", + COLOR_YELLOW, COLOR_LIGHTBLUE); + printdebug( + " %sparameter: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->additionalinfo->FunTypeAdInfo->parameter->theName); + printdebug( + " %sreturntype: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->additionalinfo->FunTypeAdInfo->returntype->theName); + } else if (tn->tag == TYPE_FUNCTION_DECLARATION) { + printdebug(" %sAdditional Info: %sFunDecAdInfo", + COLOR_YELLOW, COLOR_LIGHTBLUE); + printdebug(" %sstartLineNumber: %s%d", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->FunDecAdInfo->startlinenumber); + printdebug(" %sregularOrAs: %s%s", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->FunDecAdInfo->regularoras + ? "true" + : "false"); + } else if (tn->tag == TYPE_PRIMITIVE) { + printdebug(" %sAdditional Info: %sPrimAdInfo", COLOR_YELLOW, + COLOR_LIGHTBLUE); + printdebug(" %ssize: %s%d", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->PrimAdInfo->size); + } else { + printdebug(" AdInfo not handled."); + } + + return tn; +} \ No newline at end of file diff --git a/src/symbol_table.h b/src/symbol_table.h index cf1273a..7c5322d 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -124,6 +124,7 @@ ListOfTable *getRestOfChildren(ListOfTable *lt); TableNode *getFirstEntry(SymbolTable *st); TableNode *getNextEntry(TableNode *tn); +TableNode * printTableNode(TableNode * tn); void printdebug_impl(char *file, int line, const char *format, ...); #define printdebug(format, ...) \ printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) From e7ee370dcfc53ff4756c12502b47f5cedcee126c Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 7 Apr 2025 17:00:24 -0400 Subject: [PATCH 083/137] fixed segfault, but am now having a new unknown one :( --- src/grammar.y | 7 +++---- src/symbol_table.c | 10 +++++----- tests/sprint2/test/sp2_llnode.alpha | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index b20c09e..946c9ad 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -624,10 +624,9 @@ assignable: //char *funtype = getType(look_up(cur, $1)); printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); - // Something fishy is going on here....... - TableNode *param = getParameter(look_up(getParent(cur), getName((TableNode*)$1))); - printTableNode(table_lookup(getAncestor(cur), getName((TableNode*)$1))); - + TableNode * typeNode = table_lookup(getAncestor(cur), getType((TableNode*)$1)); + TableNode *param = getParameter(typeNode); + printTableNode(param); SymbolTable *recList = getRecList(param); TableNode *lastCheckedRef = getFirstEntry(recList); diff --git a/src/symbol_table.c b/src/symbol_table.c index 3e67b95..cec150c 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1150,6 +1150,11 @@ TableNode *printTableNode(TableNode *tn) { printdebug("%s[PrintTN] Passed a NULL tablenode!", COLOR_RED); return undefined; } + if (tn == undefined) { + printdebug("%s[PrintTN] Passed an undefined tablenode!", + COLOR_RED); + return undefined; + } if (tn->theName == NULL) { printdebug("%s[PrintTN] Passed a tablenode with NULL name!", COLOR_RED); @@ -1160,11 +1165,6 @@ TableNode *printTableNode(TableNode *tn) { COLOR_RED); return undefined; } - if (tn == undefined) { - printdebug("%s[PrintTN] Passed an undefined tablenode!", - COLOR_RED); - return undefined; - } if (tn->additionalinfo == NULL) { printdebug( "%s[PrintTN] Passed a tablenode with NULL additional info!", diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index 2011a83..08048a7 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -78,4 +78,4 @@ entry (arg) := { result := bar2(5,7); return 0; -} +} \ No newline at end of file From 87659ebf46e07468c13dbb1904b6e45664c7b6ba Mon Sep 17 00:00:00 2001 From: Scarlett Date: Mon, 7 Apr 2025 23:53:08 -0400 Subject: [PATCH 084/137] segfaults fixed. print_symbol_table format updated for dynamic column width. --- .clang-format | 6 + src/symbol_table.c | 1933 ++++++++++++++++++++++---------------------- 2 files changed, 978 insertions(+), 961 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..504b122 --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +BasedOnStyle: Google +IndentWidth: 4 +ColumnLimit: 0 +AllowShortStringsOnSingleLine: true +BreakStringLiterals: false +ReflowComments: false diff --git a/src/symbol_table.c b/src/symbol_table.c index cec150c..86fca5b 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -4,113 +4,120 @@ #include "symbol_table.h" void printdebug_impl(char *file, int line, const char *format, ...) { - if (DEBUG) { - printf("%s<%s> [%d]%s ", COLOR_DARKGRAY, file, line, - COLOR_WHITE); - va_list args; - va_start(args, format); - vprintf(format, args); - va_end(args); - printf("\n"); - } + if (DEBUG) { + printf("%s<%s> [%d]%s ", COLOR_DARKGRAY, file, line, + COLOR_WHITE); + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); + } } // primitive additional info only stores the size of that type AdInfo *CreatePrimitiveInfo(int size) { - - AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); - info->PrimAdInfo = (primitive_info *)malloc(sizeof(primitive_info)); - info->PrimAdInfo->size = size; - return info; + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->PrimAdInfo = (primitive_info *)malloc(sizeof(primitive_info)); + info->PrimAdInfo->size = size; + return info; } // only gets the size of a primitive type int getPrimSize(TableNode *definition) { - if (definition == NULL) { - printdebug( - "passed an NULL entry to getPrimSize function. Invalid."); - return -1; - } - if (definition == undefined) { - printdebug("passed an undefined entry to getPrimSize function. " - "Invalid."); - return -1; - } - if (definition->additionalinfo == NULL) { - printdebug("node has NULL additionalinfo. Invalid."); - return -1; - } - if (strcmp(getType(definition), "primitive") != 0) { - printdebug( - "not checking the size of a primitive -- invalid op"); - return 0; - } - return definition->additionalinfo->PrimAdInfo->size; + if (definition == NULL) { + printdebug( + "passed an NULL entry to getPrimSize function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getPrimSize function. " + "Invalid."); + return -1; + } + if (definition->additionalinfo == NULL) { + printdebug("node has NULL additionalinfo. Invalid."); + return -1; + } + if (strcmp(getType(definition), "primitive") != 0) { + printdebug( + "not checking the size of a primitive -- invalid op"); + return 0; + } + return definition->additionalinfo->PrimAdInfo->size; } // Only information stored in array info is the number of dimensions and the // type stored in the array per professor, the actual size of the array is // calculated at runtime so bounds checking only needs to be done then AdInfo *CreateArrayInfo(int dim, TableNode *type) { - if (type == NULL) { - printdebug("passed a NULL reference to " - "CreateArrayInfo. Invalid."); - return NULL; - } - if (type == undefined) { - printdebug("passed an undefined reference to " - "CreateArrayInfo. Invalid."); - return NULL; - } - if (type == undefined) { - printdebug("passed a undefined type reference to " - "CreateArrayInfo. Invalid."); - return NULL; - } - AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); - info->ArrayAdInfo = (array_info *)malloc(sizeof(array_info)); - info->ArrayAdInfo->numofdimensions = dim; - info->ArrayAdInfo->typeofarray = type; - // avoiding storing any types like below - // int* dimensionsizes = loc; - return info; + if (type == NULL) { + printdebug( + "passed a NULL reference to " + "CreateArrayInfo. Invalid."); + return NULL; + } + if (type == undefined) { + printdebug( + "passed an undefined reference to " + "CreateArrayInfo. Invalid."); + return NULL; + } + if (type == undefined) { + printdebug( + "passed a undefined type reference to " + "CreateArrayInfo. Invalid."); + return NULL; + } + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->ArrayAdInfo = (array_info *)malloc(sizeof(array_info)); + info->ArrayAdInfo->numofdimensions = dim; + info->ArrayAdInfo->typeofarray = type; + // avoiding storing any types like below + // int* dimensionsizes = loc; + return info; } // This gets the number of dimensions from array info int getNumArrDim(TableNode *definition) { - if (definition == NULL) { - printdebug("passed an NULL entry to getNumArrDim " - "function. Invalid."); - return -1; - } - if (definition == undefined) { - printdebug("passed an undefined entry to getNumArrDim " - "function. Invalid."); - return -1; - } - if (strcmp(getType(definition), "array") != 0) { - printdebug("not checking the dim of an array -- invalid op"); - return 0; - } - return definition->additionalinfo->ArrayAdInfo->numofdimensions; + if (definition == NULL) { + printdebug( + "passed an NULL entry to getNumArrDim " + "function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getNumArrDim " + "function. Invalid."); + return -1; + } + if (strcmp(getType(definition), "array") != 0) { + printdebug("not checking the dim of an array -- invalid op"); + return 0; + } + return definition->additionalinfo->ArrayAdInfo->numofdimensions; } // This gets the type stored in an array from arrtype. It returns a reference to // the entry of that type TableNode *getArrType(TableNode *definition) { - if (definition == NULL) { - printdebug("passed an NULL entry to getArrType " - "function. Invalid."); - return NULL; - } - if (definition == undefined) { - printdebug("passed an undefined entry to getArrType " - "function. Invalid."); - return NULL; - } - if (strcmp(getType(definition), "array") != 0) { - printdebug("not checking the type of an array -- invalid op"); - return undefined; - } - return definition->additionalinfo->ArrayAdInfo->typeofarray; + if (definition == NULL) { + printdebug( + "passed an NULL entry to getArrType " + "function. Invalid."); + return NULL; + } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getArrType " + "function. Invalid."); + return NULL; + } + if (strcmp(getType(definition), "array") != 0) { + printdebug("not checking the type of an array -- invalid op"); + return undefined; + } + return definition->additionalinfo->ArrayAdInfo->typeofarray; } // Record type currently stores the number of elements as well as the types, in @@ -118,391 +125,413 @@ TableNode *getArrType(TableNode *definition) { // should probably instead be replaced by a reference to a scope in which those // elements are found. AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { - AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); - info->RecAdInfo = (record_info *)malloc(sizeof(record_info)); - info->RecAdInfo->numofelements = length; - // replace below with reference to a scope, not an array - info->RecAdInfo->recordScope = recordScope; - return info; + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->RecAdInfo = (record_info *)malloc(sizeof(record_info)); + info->RecAdInfo->numofelements = length; + // replace below with reference to a scope, not an array + info->RecAdInfo->recordScope = recordScope; + return info; } // This gets the number of elements that make up a record. // Perhaps this may not be needed since we need to iterate over all elements // anyways. int getRecLength(TableNode *definition) { - if (definition == NULL) { - printdebug("passed an NULL entry to getRecLength " - "function. Invalid."); - return -1; - } - if (definition == undefined) { - printdebug("passed an undefined entry to getRecLength " - "function. Invalid."); - return -1; - } - if (strcmp(getType(definition), "record") != 0) { - printdebug( - "not checking the length of an record -- invalid op"); - return 0; - } - return definition->additionalinfo->RecAdInfo->numofelements; + if (definition == NULL) { + printdebug( + "passed an NULL entry to getRecLength " + "function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getRecLength " + "function. Invalid."); + return -1; + } + if (strcmp(getType(definition), "record") != 0) { + printdebug( + "not checking the length of an record -- invalid op"); + return 0; + } + return definition->additionalinfo->RecAdInfo->numofelements; } // This gets the array. Needs to up be updated to get the scope instead SymbolTable *getRecList(TableNode *definition) { - if (definition == NULL) { - printdebug("passed a NULL entry to getRecList " - "function. Invalid."); - return NULL; - } - if (definition == undefined) { - printdebug("passed an undefined entry to getRecList " - "function. Invalid."); - return NULL; - } - if (strcmp(getType(definition), "record") != 0) { - printdebug( - "not checking the list of types of a record -- invalid " - "op"); - return NULL; - } - return definition->additionalinfo->RecAdInfo->recordScope; + if (definition == NULL) { + printdebug( + "passed a NULL entry to getRecList " + "function. Invalid."); + return NULL; + } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getRecList " + "function. Invalid."); + return NULL; + } + if (strcmp(getType(definition), "record") != 0) { + printdebug( + "not checking the list of types of a record -- invalid " + "op"); + return NULL; + } + return definition->additionalinfo->RecAdInfo->recordScope; } TableNode *setRecSize(TableNode *tn, int n) { - if (tn == NULL) { - printdebug("passed in NULL entry for setRecSize. Invalid"); - return undefined; - } - if (tn == undefined) { - printdebug("passed in undefined entry for setRecSize. Invalid"); - return undefined; - } - tn->additionalinfo->RecAdInfo->numofelements = n; - return tn; + if (tn == NULL) { + printdebug("passed in NULL entry for setRecSize. Invalid"); + return undefined; + } + if (tn == undefined) { + printdebug("passed in undefined entry for setRecSize. Invalid"); + return undefined; + } + tn->additionalinfo->RecAdInfo->numofelements = n; + return tn; } int getRecSize(SymbolTable *tn) { - if (tn == NULL) { - printdebug( - "passed in NULL SymbolTable for getRecSize. Invalid"); - return -1; - } - int s = 1; - TableNode *cur = getFirstEntry(tn); - if (cur != NULL) { - while (getNextEntry(cur) != NULL) { - s++; - cur = getNextEntry(cur); - } - return s; - } + if (tn == NULL) { + printdebug( + "passed in NULL SymbolTable for getRecSize. Invalid"); return -1; + } + int s = 1; + TableNode *cur = getFirstEntry(tn); + if (cur != NULL) { + while (getNextEntry(cur) != NULL) { + s++; + cur = getNextEntry(cur); + } + return s; + } + return -1; } // below function takes a bool to see if parameter should be decomposed or not -; // note that functions only take one input and have one output +; // note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of // multiple inputs Below function also has the line number where the function is // first defined AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { - AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); - info->FunDecAdInfo = (function_declaration_info *)malloc( - sizeof(function_declaration_info)); - info->FunDecAdInfo->startlinenumber = line; - info->FunDecAdInfo->regularoras = asorregular; - return info; + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->FunDecAdInfo = (function_declaration_info *)malloc( + sizeof(function_declaration_info)); + info->FunDecAdInfo->startlinenumber = line; + info->FunDecAdInfo->regularoras = asorregular; + return info; } // gets the line at which the function was first defined. (Can be used to print // out in table if needed) int getStartLine(TableNode *definition) { - if (definition == NULL) { - printdebug("passed a NULL entry to getStartLine " - "function. Invalid."); - return -1; - } - if (definition == undefined) { - printdebug("passed an undefined entry to getStartLine " - "function. Invalid."); - return -1; - } - if (strcmp(getType(definition), "primitive function") != 0) { - printdebug( - "not checking the start line of a function -- invalid " - "op"); - return 0; - } - return definition->additionalinfo->FunDecAdInfo->startlinenumber; + if (definition == NULL) { + printdebug( + "passed a NULL entry to getStartLine " + "function. Invalid."); + return -1; + } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getStartLine " + "function. Invalid."); + return -1; + } + if (strcmp(getType(definition), "primitive function") != 0) { + printdebug( + "not checking the start line of a function -- invalid " + "op"); + return 0; + } + return definition->additionalinfo->FunDecAdInfo->startlinenumber; } TableNode *setStartLine(TableNode *tn, int start) { - if (tn == NULL) { - printdebug("passing in a NULL entry to setStartLine. " - "invalid"); - return undefined; - } - if (tn == undefined) { - printdebug("passing in an undefined entry to setStartLine. " - "invalid"); - return undefined; - } - tn->additionalinfo->FunDecAdInfo->startlinenumber = start; - return tn; + if (tn == NULL) { + printdebug( + "passing in a NULL entry to setStartLine. " + "invalid"); + return undefined; + } + if (tn == undefined) { + printdebug( + "passing in an undefined entry to setStartLine. " + "invalid"); + return undefined; + } + tn->additionalinfo->FunDecAdInfo->startlinenumber = start; + return tn; } // checks if "as" keyword was used for function definition. Either 0 or 1 for // not used or used. bool getAsKeyword(TableNode *definition) { - if (definition == NULL) { - printdebug("passed a NULL entry to getAsKeyword " - "function. Invalid."); - return false; - } - if (definition == undefined) { - printdebug("passed an undefined entry to getAsKeyword " - "function. Invalid."); - return false; - } - if (strcmp(getType(definition), "primitive function") != 0) { - printdebug("not checking if a function is called with as or " - "not (%s) -- " - "invalid op", - getType(definition)); - return 0; - } - return definition->additionalinfo->FunDecAdInfo->regularoras; + if (definition == NULL) { + printdebug( + "passed a NULL entry to getAsKeyword " + "function. Invalid."); + return false; + } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getAsKeyword " + "function. Invalid."); + return false; + } + if (strcmp(getType(definition), "primitive function") != 0) { + printdebug( + "not checking if a function is called with as or " + "not (%s) -- " + "invalid op", + getType(definition)); + return 0; + } + return definition->additionalinfo->FunDecAdInfo->regularoras; } TableNode *setAsKeyword(TableNode *tn, bool as) { - if (tn == NULL) { - printdebug("passing in a NULL entry to setAsKeyword. " - "invalid"); - return undefined; - } - if (tn == undefined) { - printdebug("passing in an undefined entry to setAsKeyword. " - "invalid"); - return undefined; - } - tn->additionalinfo->FunDecAdInfo->regularoras = as; - return tn; + if (tn == NULL) { + printdebug( + "passing in a NULL entry to setAsKeyword. " + "invalid"); + return undefined; + } + if (tn == undefined) { + printdebug( + "passing in an undefined entry to setAsKeyword. " + "invalid"); + return undefined; + } + tn->additionalinfo->FunDecAdInfo->regularoras = as; + return tn; } // stores the type of a function (parameter type and return type) AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype) { - if (parameter == NULL) { - printdebug("passed a NULL parameter to " - "CreateFunctionTypeInfo. Invalid."); - return NULL; - } - if (parameter == undefined) { - printdebug("passed an undefined parameter to " - "CreateFunctionTypeInfo. Invalid."); - return NULL; - } - if (returntype == NULL) { - printdebug("passed a NULL return type to " - "CreateFunctionTypeInfo. Invalid."); - return NULL; - } - if (returntype == undefined) { - printdebug("passed an undefined return type to " - "CreateFunctionTypeInfo. Invalid."); - return NULL; - } - AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); - info->FunTypeAdInfo = - (function_type_info *)malloc(sizeof(function_type_info)); - info->FunTypeAdInfo->parameter = parameter; - info->FunTypeAdInfo->returntype = returntype; - return info; + if (parameter == NULL) { + printdebug( + "passed a NULL parameter to " + "CreateFunctionTypeInfo. Invalid."); + return NULL; + } + if (parameter == undefined) { + printdebug( + "passed an undefined parameter to " + "CreateFunctionTypeInfo. Invalid."); + return NULL; + } + if (returntype == NULL) { + printdebug( + "passed a NULL return type to " + "CreateFunctionTypeInfo. Invalid."); + return NULL; + } + if (returntype == undefined) { + printdebug( + "passed an undefined return type to " + "CreateFunctionTypeInfo. Invalid."); + return NULL; + } + AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); + info->FunTypeAdInfo = + (function_type_info *)malloc(sizeof(function_type_info)); + info->FunTypeAdInfo->parameter = parameter; + info->FunTypeAdInfo->returntype = returntype; + return info; } // returns parameter type of a function TableNode *getParameter(TableNode *definition) { - if (definition == NULL) { - printdebug("passed a NULL entry to getParameter " - "function. Invalid."); - return undefined; - } - if (definition == undefined) { - printdebug("passed an undefined entry to getParameter " - "function. Invalid."); - return undefined; - } - if (strcmp(getType(definition), "primitive function type") != 0) { - printdebug( - "not checking the parameter of a function -- invalid op"); - return undefined; - } - return definition->additionalinfo->FunTypeAdInfo->parameter; + if (definition == NULL) { + printdebug( + "passed a NULL entry to getParameter " + "function. Invalid."); + return undefined; + } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getParameter " + "function. Invalid."); + return undefined; + } + if (strcmp(getType(definition), "primitive function type") != 0) { + printdebug( + "not checking the parameter of a function -- invalid op"); + return undefined; + } + return definition->additionalinfo->FunTypeAdInfo->parameter; } // returns return type of a function TableNode *getReturn(TableNode *definition) { - if (definition == NULL) { - printdebug("passed a NULL entry to getReturn " - "function. Invalid."); - return NULL; - } - if (definition == undefined) { - printdebug("passed an undefined entry to getReturn " - "function. Invalid."); - return NULL; - } - if (strcmp(getType(definition), "primitive function type") != 0) { - printdebug( - "not checking the return of a function -- invalid op"); - return undefined; - } - return definition->additionalinfo->FunTypeAdInfo->returntype; + if (definition == NULL) { + printdebug( + "passed a NULL entry to getReturn " + "function. Invalid."); + return NULL; + } + if (definition == undefined) { + printdebug( + "passed an undefined entry to getReturn " + "function. Invalid."); + return NULL; + } + if (strcmp(getType(definition), "primitive function type") != 0) { + printdebug( + "not checking the return of a function -- invalid op"); + return undefined; + } + return definition->additionalinfo->FunTypeAdInfo->returntype; } // creates a new scope (not the top scope though) SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column) { - SymbolTable *table = (SymbolTable *)malloc(sizeof(SymbolTable)); - table->Line_Number = Line; - table->Column_Number = Column; - table->Parent_Scope = ParentScope; - table->Children_Scope = NULL; - table->entries = NULL; - if (ParentScope != NULL) { - if (ParentScope->Children_Scope == NULL) { - ListOfTable *newEntry = - (ListOfTable *)malloc(sizeof(ListOfTable)); - newEntry->next = NULL; - // newEntry->prev = NULL; - newEntry->table = table; - ParentScope->Children_Scope = newEntry; - } else { - ListOfTable *newEntry = - (ListOfTable *)malloc(sizeof(ListOfTable)); - // newEntry->prev = NULL; - newEntry->table = table; - ListOfTable *oldEntry = ParentScope->Children_Scope; - ParentScope->Children_Scope = newEntry; - newEntry->next = oldEntry; - } + SymbolTable *table = (SymbolTable *)malloc(sizeof(SymbolTable)); + table->Line_Number = Line; + table->Column_Number = Column; + table->Parent_Scope = ParentScope; + table->Children_Scope = NULL; + table->entries = NULL; + if (ParentScope != NULL) { + if (ParentScope->Children_Scope == NULL) { + ListOfTable *newEntry = + (ListOfTable *)malloc(sizeof(ListOfTable)); + newEntry->next = NULL; + // newEntry->prev = NULL; + newEntry->table = table; + ParentScope->Children_Scope = newEntry; + } else { + ListOfTable *newEntry = + (ListOfTable *)malloc(sizeof(ListOfTable)); + // newEntry->prev = NULL; + newEntry->table = table; + ListOfTable *oldEntry = ParentScope->Children_Scope; + ParentScope->Children_Scope = newEntry; + newEntry->next = oldEntry; } - return table; + } + return table; } // create entry just for things below top level scope // This function defines the integer, address, character, and bool primitive // types SymbolTable *init(SymbolTable *start) { - if (start->Parent_Scope != NULL) { - printdebug("%s[FATAL] Cannot initialize a scope that is not " - "the parent scope", - COLOR_RED); - return NULL; - } - integ = (TableNode *)calloc(1, sizeof(TableNode)); - addr = (TableNode *)calloc(1, sizeof(TableNode)); - chara = (TableNode *)calloc(1, sizeof(TableNode)); - stri = (TableNode *)calloc(1, sizeof(TableNode)); - boo = (TableNode *)calloc(1, sizeof(TableNode)); - // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); - start->entries = integ; - integ->next = addr; - addr->next = chara; - chara->next = stri; - stri->next = boo; - // boo->next = arr; - boo->next = NULL; + if (start->Parent_Scope != NULL) { + printdebug( + "%s[FATAL] Cannot initialize a scope that is not " + "the parent scope", + COLOR_RED); + return NULL; + } + integ = (TableNode *)calloc(1, sizeof(TableNode)); + addr = (TableNode *)calloc(1, sizeof(TableNode)); + chara = (TableNode *)calloc(1, sizeof(TableNode)); + stri = (TableNode *)calloc(1, sizeof(TableNode)); + boo = (TableNode *)calloc(1, sizeof(TableNode)); + // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); + start->entries = integ; + integ->next = addr; + addr->next = chara; + chara->next = stri; + stri->next = boo; + // boo->next = arr; + boo->next = NULL; - integ->theName = "integer"; - addr->theName = "address"; - chara->theName = "character"; - boo->theName = "Boolean"; - stri->theName = "string"; - // arr->theName= "array" + integ->theName = "integer"; + addr->theName = "address"; + chara->theName = "character"; + boo->theName = "Boolean"; + stri->theName = "string"; + // arr->theName= "array" - // root TableNode that all are pointing to but not in table - // This is only to solve the issue that all entries must have a name and - // a type and the type must point to an actual table entry Again, this - // primitive table entry isn't in the top scope. It is outside the top - // scope and is only there to facilitate the fact that these are - // primitive - TableNode *prime = (TableNode *)malloc(sizeof(TableNode)); - prime->theName = "primitive"; - prime->theType = NULL; - prime->additionalinfo = NULL; - prime->next = NULL; - prime->tag = TYPE_SYSTEM_DEFINED; + // root TableNode that all are pointing to but not in table + // This is only to solve the issue that all entries must have a name and + // a type and the type must point to an actual table entry Again, this + // primitive table entry isn't in the top scope. It is outside the top + // scope and is only there to facilitate the fact that these are + // primitive + TableNode *prime = (TableNode *)malloc(sizeof(TableNode)); + prime->theName = "primitive"; + prime->theType = NULL; + prime->additionalinfo = NULL; + prime->next = NULL; + prime->tag = TYPE_SYSTEM_DEFINED; - // not sure exatly how to get array types to look right so using a dummy - // Table Node below and updating the print symbol table function to - // access the additional information to print for array types, similar - // to function types when printing symbol table, if array is seen - arrayprim = (TableNode *)malloc(sizeof(TableNode)); - arrayprim->theName = "array"; - arrayprim->theType = NULL; - arrayprim->additionalinfo = NULL; - arrayprim->next = NULL; - prime->tag = TYPE_SYSTEM_DEFINED; + // not sure exatly how to get array types to look right so using a dummy + // Table Node below and updating the print symbol table function to + // access the additional information to print for array types, similar + // to function types when printing symbol table, if array is seen + arrayprim = (TableNode *)malloc(sizeof(TableNode)); + arrayprim->theName = "array"; + arrayprim->theType = NULL; + arrayprim->additionalinfo = NULL; + arrayprim->next = NULL; + prime->tag = TYPE_SYSTEM_DEFINED; - // funprime = CreateEntry(NULL,NULL,strdup("function primitive"),NULL); + // funprime = CreateEntry(NULL,NULL,strdup("function primitive"),NULL); - // similar workaround to arrays above - funprime = (TableNode *)malloc(sizeof(TableNode)); - funprime->theName = "primitive function"; - funprime->theType = NULL; - funprime->additionalinfo = NULL; - funprime->next = NULL; - funprime->tag = TYPE_SYSTEM_DEFINED; + // similar workaround to arrays above + funprime = (TableNode *)malloc(sizeof(TableNode)); + funprime->theName = "primitive function"; + funprime->theType = NULL; + funprime->additionalinfo = NULL; + funprime->next = NULL; + funprime->tag = TYPE_SYSTEM_DEFINED; - // record - recprime = (TableNode *)malloc(sizeof(TableNode)); - recprime->theName = "record"; - recprime->theType = NULL; - recprime->additionalinfo = NULL; - recprime->next = NULL; - recprime->tag = TYPE_SYSTEM_DEFINED; + // record + recprime = (TableNode *)malloc(sizeof(TableNode)); + recprime->theName = "record"; + recprime->theType = NULL; + recprime->additionalinfo = NULL; + recprime->next = NULL; + recprime->tag = TYPE_SYSTEM_DEFINED; - funtypeprime = (TableNode *)malloc(sizeof(TableNode)); - funtypeprime->theName = "primitive function type"; - funtypeprime->theType = NULL; - funtypeprime->additionalinfo = NULL; - funtypeprime->next = NULL; - funtypeprime->tag = TYPE_SYSTEM_DEFINED; + funtypeprime = (TableNode *)malloc(sizeof(TableNode)); + funtypeprime->theName = "primitive function type"; + funtypeprime->theType = NULL; + funtypeprime->additionalinfo = NULL; + funtypeprime->next = NULL; + funtypeprime->tag = TYPE_SYSTEM_DEFINED; - undefined = (TableNode *)malloc(sizeof(TableNode)); - undefined->theName = "undefined"; - undefined->theType = NULL; - undefined->additionalinfo = NULL; - undefined->next = NULL; - undefined->tag = TYPE_SYSTEM_DEFINED; + undefined = (TableNode *)malloc(sizeof(TableNode)); + undefined->theName = "undefined"; + undefined->theType = NULL; + undefined->additionalinfo = NULL; + undefined->next = NULL; + undefined->tag = TYPE_SYSTEM_DEFINED; - // Undefined_function_type_info = CreateFunctionTypeInfo(undefined, - // undefined); + // Undefined_function_type_info = CreateFunctionTypeInfo(undefined, + // undefined); - integ->theType = prime; - addr->theType = prime; - chara->theType = prime; - stri->theType = arrayprim; - boo->theType = prime; - // arr->theType=arrayprim; + integ->theType = prime; + addr->theType = prime; + chara->theType = prime; + stri->theType = arrayprim; + boo->theType = prime; + // arr->theType=arrayprim; - // filling in all the values for the additional info for initial types - // These numbers below for create primitive specifically are supposed to - // be the size of these primitive types. We can change these if needed - // to not be hard coded numbers as a reminder, stri below is defined as - // a one dimensional array of characters - integ->additionalinfo = CreatePrimitiveInfo(SIZE_INT); - addr->additionalinfo = CreatePrimitiveInfo(SIZE_ADDR); - chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR); - stri->additionalinfo = CreateArrayInfo(1, chara); - boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); + // filling in all the values for the additional info for initial types + // These numbers below for create primitive specifically are supposed to + // be the size of these primitive types. We can change these if needed + // to not be hard coded numbers as a reminder, stri below is defined as + // a one dimensional array of characters + integ->additionalinfo = CreatePrimitiveInfo(SIZE_INT); + addr->additionalinfo = CreatePrimitiveInfo(SIZE_ADDR); + chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR); + stri->additionalinfo = CreateArrayInfo(1, chara); + boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); - integ->tag = TYPE_PRIMITIVE; // explicitly set the type for integ - addr->tag = TYPE_PRIMITIVE; // explicitly set the type for addr - chara->tag = TYPE_PRIMITIVE; // explicitly set the type for chara - stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri - boo->tag = TYPE_PRIMITIVE; // explicitly set the type for boo - // addr->additionalinfo = CreatePrimitiveInfo(8); + integ->tag = TYPE_PRIMITIVE; // explicitly set the type for integ + addr->tag = TYPE_PRIMITIVE; // explicitly set the type for addr + chara->tag = TYPE_PRIMITIVE; // explicitly set the type for chara + stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri + boo->tag = TYPE_PRIMITIVE; // explicitly set the type for boo + // addr->additionalinfo = CreatePrimitiveInfo(8); - start->Line_Number = 1; - start->Column_Number = 1; - start->Parent_Scope = NULL; - start->Children_Scope = NULL; + start->Line_Number = 1; + start->Column_Number = 1; + start->Parent_Scope = NULL; + start->Children_Scope = NULL; - return start; + return start; } /* TableNode* integ; @@ -514,65 +543,67 @@ TableNode* recprime; TableNode* funtypeprime; */ TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info) { - if (tn == NULL) { - printdebug( - "passed in an NULL table node to populateTypeAndInfo."); - return undefined; - } - if (tn == undefined) { - printdebug( - "passed in an undefined table node to populateTypeAndInfo"); - return undefined; - } - if (type == NULL) { - printdebug("passed in a NULL type reference to " - "populate a table node. Invalid."); - return undefined; - } - if (type == undefined) { - printdebug("passed in an undefined type reference to " - "populate a table node. Invalid."); - return undefined; - } - if (info == NULL) { - printdebug( - "passed in a NULL info reference to populate a table " - "node. Invalid."); - return undefined; - } - tn->theType = type; - tn->additionalinfo = info; - // returning reference to modified table node - return tn; + if (tn == NULL) { + printdebug( + "passed in an NULL table node to populateTypeAndInfo."); + return undefined; + } + if (tn == undefined) { + printdebug( + "passed in an undefined table node to populateTypeAndInfo"); + return undefined; + } + if (type == NULL) { + printdebug( + "passed in a NULL type reference to " + "populate a table node. Invalid."); + return undefined; + } + if (type == undefined) { + printdebug( + "passed in an undefined type reference to " + "populate a table node. Invalid."); + return undefined; + } + if (info == NULL) { + printdebug( + "passed in a NULL info reference to populate a table " + "node. Invalid."); + return undefined; + } + tn->theType = type; + tn->additionalinfo = info; + // returning reference to modified table node + return tn; } AdInfo *getAdInfo(TableNode *tn) { - if (tn == NULL) { - printdebug("passed a NULL table entry to getAdInfo. Invalid."); - return NULL; - } - if (tn == undefined) { - printdebug( - "passed an undefined table entry to getAdInfo. Invalid."); - return NULL; - } - if (tn->additionalinfo == NULL) { - printdebug( - "no additional info found in the table node. Invalid."); - return NULL; - } - return tn->additionalinfo; + if (tn == NULL) { + printdebug("passed a NULL table entry to getAdInfo. Invalid."); + return NULL; + } + if (tn == undefined) { + printdebug( + "passed an undefined table entry to getAdInfo. Invalid."); + return NULL; + } + if (tn->additionalinfo == NULL) { + printdebug( + "no additional info found in the table node. Invalid."); + return NULL; + } + return tn->additionalinfo; } // simplified getAdInfoType int getAdInfoType(TableNode *tn) { - if (tn == NULL) { - printdebug( - "passing in NULL table entry to getAdInfoType. Invalid"); - return -1; - } - return tn->tag; - /* + if (tn == NULL) { + printdebug( + "passing in NULL table entry to getAdInfoType. Invalid"); + return -1; + } + return tn->tag; + /* if (tn == undefined) { printdebug("passing in undefined table entry to getAdInfoType. " "Invalid"); @@ -636,489 +667,463 @@ int getAdInfoType(TableNode *tn) { TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, AdInfo *ad) { + if (table == NULL) { + printdebug("Null reference to table"); + return undefined; + } - if (table == NULL) { - printdebug("Null reference to table"); - return undefined; - } - - /* + /* TableNode* topDef = (table_lookup(getAncestor(table),typeOf)); if(topDef == NULL){ printdebug("This type is not defined at the top level"); return NULL; } */ - if (typeOf == NULL) { - printdebug("Passing an NULL Type Node to Create Entry"); - return undefined; - } - if (typeOf == undefined) { - printdebug("Passing an undefined Type Node to Create Entry"); - return undefined; - } + if (typeOf == NULL) { + printdebug("Passing an NULL Type Node to Create Entry"); + return undefined; + } + if (typeOf == undefined) { + printdebug("Passing an undefined Type Node to Create Entry"); + return undefined; + } - TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); - if (tag < 1 && tag > 11) { - printdebug("Note- not passing in valid 'tag' identifier to " - "create entry function. Setting tag to undefined"); - newEntry->tag = TYPE_UNDEFINED; - } else { - newEntry->tag = tag; - } - newEntry->theType = typeOf /*topDef*/; - newEntry->theName = id; - newEntry->additionalinfo = ad; - if (table->entries == NULL) { - table->entries = newEntry; - printdebug("[CreateEntry] Adding %s to the symbol table", id); - return newEntry; - } else { - TableNode *oldEntry = table->entries; - table->entries = newEntry; - newEntry->next = oldEntry; - printdebug("[CreateEntry] Adding %s to the symbol table", id); - return newEntry; - } + TableNode *newEntry = (TableNode *)calloc(1, sizeof(TableNode)); + if (tag < 1 && tag > 11) { + printdebug( + "Note- not passing in valid 'tag' identifier to " + "create entry function. Setting tag to undefined"); + newEntry->tag = TYPE_UNDEFINED; + } else { + newEntry->tag = tag; + } + newEntry->theType = typeOf /*topDef*/; + newEntry->theName = id; + newEntry->additionalinfo = ad; + if (table->entries == NULL) { + table->entries = newEntry; + printdebug("[CreateEntry] Adding %s to the symbol table", id); + return newEntry; + } else { + TableNode *oldEntry = table->entries; + table->entries = newEntry; + newEntry->next = oldEntry; + printdebug("[CreateEntry] Adding %s to the symbol table", id); + return newEntry; + } } TableNode *getTypeEntry(TableNode *tn) { - if (tn == NULL) { - printdebug("passed a NULL table entry to getType"); - return undefined; - } - if (tn == undefined) { - printdebug("passed an undefined table entry to getType"); - return undefined; - } - if (tn->theType == NULL) { - printdebug("type of entry is currently NULL type"); - return undefined; - } - if (tn->theType == undefined) { - printdebug("type of entry is currently undefined type"); - return undefined; - } - return tn->theType; + if (tn == NULL) { + printdebug("passed a NULL table entry to getType"); + return undefined; + } + if (tn == undefined) { + printdebug("passed an undefined table entry to getType"); + return undefined; + } + if (tn->theType == NULL) { + printdebug("type of entry is currently NULL type"); + return undefined; + } + if (tn->theType == undefined) { + printdebug("type of entry is currently undefined type"); + return undefined; + } + return tn->theType; } char *getType(TableNode *tn) { - if (tn == NULL) { - printdebug("passed a NULL table entry to getType"); - return getName(undefined); - } - if (tn == undefined) { - printdebug("passed an undefined table entry to getType"); - return getName(undefined); - } - if (tn->theType == NULL) { - printdebug("type of entry is currently NULL type"); - return getName(undefined); - } - if (tn->theType == undefined) { - printdebug("type of entry is currently undefined type"); - return getName(undefined); - } - return tn->theType->theName; + if (tn == NULL) { + printdebug("passed a NULL table entry to getType"); + return getName(undefined); + } + if (tn == undefined) { + printdebug("passed an undefined table entry to getType"); + return getName(undefined); + } + if (tn->theType == NULL) { + printdebug("type of entry is currently NULL type"); + return getName(undefined); + } + if (tn->theType == undefined) { + printdebug("type of entry is currently undefined type"); + return getName(undefined); + } + return tn->theType->theName; } char *getName(TableNode *tn) { - if (tn == NULL) { - printdebug("passed a NULL table entry to getName"); - return undefined->theName; - } - if (tn == undefined) { - printdebug("passed an undefined table entry to getName"); - return undefined->theName; - } - if (tn->theName == NULL) { - printdebug("name of entry is currently NULL, undefined"); - return undefined->theName; - } - return tn->theName; + if (tn == NULL) { + printdebug("passed a NULL table entry to getName"); + return undefined->theName; + } + if (tn == undefined) { + printdebug("passed an undefined table entry to getName"); + return undefined->theName; + } + if (tn->theName == NULL) { + printdebug("name of entry is currently NULL, undefined"); + return undefined->theName; + } + return tn->theName; } int getLine(SymbolTable *st) { - if (st == NULL) { - printdebug("passed a NULL symbol table to getLine function. " - "Invalid."); - return -1; - } - return st->Line_Number; + if (st == NULL) { + printdebug( + "passed a NULL symbol table to getLine function. " + "Invalid."); + return -1; + } + return st->Line_Number; } int getColumn(SymbolTable *st) { - if (st == NULL) { - printdebug("passed a NULL symbol table to getColumn function. " - "Invalid."); - return -1; - } - return st->Column_Number; + if (st == NULL) { + printdebug( + "passed a NULL symbol table to getColumn function. " + "Invalid."); + return -1; + } + return st->Column_Number; } TableNode *addName(TableNode *tn, char *str) { - if (tn == NULL) { - printdebug("passed a Null table node to the addName " - "function. Invalid."); - return undefined; + if (tn == NULL) { + printdebug( + "passed a Null table node to the addName " + "function. Invalid."); + return undefined; + } + if (tn == undefined) { + printdebug( + "passed an undefined table node to the addName " + "function. Invalid."); + return undefined; + } + if (tn->theName != NULL) { + // printdebug( + //"Name doesn't look like it is empty before you change. " + //"Are you sure you need to update name?"); + if (str != NULL) { + tn->theName = str; + return tn; } - if (tn == undefined) { - printdebug("passed an undefined table node to the addName " - "function. Invalid."); - return undefined; - } - if (tn->theName != NULL) { - // printdebug( - //"Name doesn't look like it is empty before you change. " - //"Are you sure you need to update name?"); - if (str != NULL) { - tn->theName = str; - return tn; - } - printdebug("passed a NULL string to the addName function"); - return undefined; - } - if (str == NULL) { - printdebug( - "passed a NULL string to the addName function. Invalid."); - return undefined; - } - tn->theName = str; - return tn; + printdebug("passed a NULL string to the addName function"); + return undefined; + } + if (str == NULL) { + printdebug( + "passed a NULL string to the addName function. Invalid."); + return undefined; + } + tn->theName = str; + return tn; } SymbolTable *setLineNumber(SymbolTable *st, int line) { - if (st == NULL) { - printdebug("passed a Null Symbol Table to the setLineNumber " - "function. Invalid."); - return st; - } - st->Line_Number = line; + if (st == NULL) { + printdebug( + "passed a Null Symbol Table to the setLineNumber " + "function. Invalid."); return st; + } + st->Line_Number = line; + return st; } SymbolTable *setColumnNumber(SymbolTable *st, int column) { - if (st == NULL) { - printdebug("passed a Null Symbol Table to the setColumnNumber " - "function. Invalid."); - return st; - } - st->Line_Number = column; + if (st == NULL) { + printdebug( + "passed a Null Symbol Table to the setColumnNumber " + "function. Invalid."); return st; + } + st->Line_Number = column; + return st; } // only check table that is given TableNode *table_lookup(SymbolTable *table, char *x) { - if (table == NULL) { - printdebug("passed in empty scope. error."); - return undefined; - } - TableNode *entrie = table->entries; - for (; entrie != NULL; entrie = entrie->next) { - if (!strcmp(entrie->theName, x)) { - return entrie; - } - } + if (table == NULL) { + printdebug("passed in empty scope. error."); return undefined; + } + TableNode *entrie = table->entries; + for (; entrie != NULL; entrie = entrie->next) { + if (!strcmp(entrie->theName, x)) { + return entrie; + } + } + return undefined; } // check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { - if (table == NULL) { - printdebug("passed in empty scope. error."); - return undefined; + if (table == NULL) { + printdebug("passed in empty scope. error."); + return undefined; + } + TableNode *ret = table_lookup(table, x); + if (ret != NULL && ret != undefined) { + return ret; + } + printdebug( + "could not find %s in scope that started at line %d and column " + "%d so moving up a scope", + x, getLine(table), getColumn(table)); + return look_up(table->Parent_Scope, x); +} + +int col_widths[5] = {30, 8, 8, 35, 35}; +void printline(FILE *file_ptr); +void printline(FILE *file_ptr) { + for (int i = 0; i < 5; i++) { + for (int ii = 0; ii < col_widths[i]; ii++) { + fprintf(file_ptr, "-"); } - TableNode *ret = table_lookup(table, x); - if (ret != NULL && ret != undefined) { - return ret; - } - printdebug( - "could not find %s in scope that started at line %d and column " - "%d so moving up a scope", - x, getLine(table), getColumn(table)); - return look_up(table->Parent_Scope, x); + fprintf(file_ptr, ":"); + } + fprintf(file_ptr, "\n"); +} + +void st_fprint(FILE *file_ptr, char *label1, int label2, int label3, char *label4, char *label5); +void st_fprint(FILE *file_ptr, char *label1, int label2, int label3, char *label4, char *label5) { + if (label3 == -100) { + fprintf(file_ptr, "%-*s: %0*d : %*s :%-*s:%-*s\n", + col_widths[0], (label1 ? label1 : ""), + col_widths[1] - 2, label2, + col_widths[2] - 2, "", + col_widths[3], (label4 ? label4 : ""), + col_widths[4], (label5 ? label5 : "")); + } else { + fprintf(file_ptr, "%-*s: %0*d : %0*d :%-*s:%-*s\n", + col_widths[0], (label1 ? label1 : ""), + col_widths[1] - 2, label2, + col_widths[2] - 2, label3, + col_widths[3], (label4 ? label4 : ""), + col_widths[4], (label5 ? label5 : "")); + } } void print_symbol_table(SymbolTable *table, FILE *file_ptr) { + if (table == NULL) { + printdebug("%s[FATAL] passed in NULL table to print_symbol_table", COLOR_RED); + return; + } - if (table == NULL) { - printdebug( - "%s[FATAL] passed in NULL table to print_symbol_table", - COLOR_RED); - return; + if (table->Parent_Scope == NULL) { + fprintf(file_ptr, "%-*s:%-*s:%-*s:%-*s:%-*s:\n", + col_widths[0], " NAME", + col_widths[1], " SCOPE", + col_widths[2], " PARENT", + col_widths[3], " TYPE", + col_widths[4], " EXTRA ANNOTATION"); + } + + TableNode *entry = table->entries; + printline(file_ptr); + int parentScopeNum = 0; + int currentScopeNum = 0; + + if (table->Parent_Scope != NULL) { + parentScopeNum = getParent(table)->Line_Number * 1000 + getParent(table)->Column_Number; + currentScopeNum = table->Line_Number * 1000 + table->Column_Number; + } else { + currentScopeNum = 1001; + } + + if (entry == NULL) { + st_fprint(file_ptr, "", currentScopeNum, parentScopeNum, "", " Empty Scope"); + } + + for (; entry != NULL; entry = getNextEntry(entry)) { + if (getAdInfoType(entry) == TYPE_ARRAY_TYPE) { + char *arrayType = (char *)malloc(100); + sprintf(arrayType, " %d -> %s", entry->additionalinfo->ArrayAdInfo->numofdimensions, + entry->additionalinfo->ArrayAdInfo->typeofarray->theName); + + if (parentScopeNum == 0) { + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, arrayType, " Type of Array"); + } else { + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, arrayType, " Type of Array"); + } } - if (table->Parent_Scope == NULL) { - fprintf(file_ptr, "%-25s: %-6s : %-6s : %-25s: %-30s\n", "NAME", - "SCOPE", "PARENT", "TYPE", "Extra annotation"); + if (getAdInfoType(entry) == TYPE_RECORD) { + char *recordAdInfo = (char *)malloc(100); + sprintf(recordAdInfo, " elements-%d", entry->additionalinfo->RecAdInfo->numofelements); + if (parentScopeNum == 0) { + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, "record", recordAdInfo); + } else { + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, "record", recordAdInfo); + } } - TableNode *entrie = table->entries; - fprintf(file_ptr, - "-------------------------:--------:--------:------------------" - "--------:------------------------------\n"); - int parant_scope = 0; - int current_scope = 0; - if (table->Parent_Scope != NULL) { - parant_scope = getParent(table)->Line_Number * 1000 + - getParent(table)->Column_Number; - current_scope = - table->Line_Number * 1000 + table->Column_Number; - } else { - current_scope = 1001; + if (getAdInfoType(entry) == TYPE_PRIMITIVE) { + char *primAdInfo = (char *)malloc(100); + sprintf(primAdInfo, " size-%d bytes", entry->additionalinfo->PrimAdInfo->size); + if (parentScopeNum == 0) { + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, " Primitive", primAdInfo); + } else { + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, " Primitive", primAdInfo); + } } - if (entrie == NULL) { - fprintf(file_ptr, "%-25s: %06d : %06d : %-25s: %-30s\n", "", - current_scope, parant_scope, "", "Empty Scope"); + + if (getAdInfoType(entry) == TYPE_FUNCTION_TYPE) { + char *functiontype = (char *)malloc(100); + sprintf(functiontype, " %s -> %s", entry->additionalinfo->FunTypeAdInfo->parameter->theName, + entry->additionalinfo->FunTypeAdInfo->returntype->theName); + if (parentScopeNum == 0) { + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, functiontype, " Type of Function"); + } else { + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, functiontype, " Type of Function"); + } } - for (; entrie != NULL; entrie = getNextEntry(entrie)) { - if (getAdInfoType(entrie) == TYPE_ARRAY_TYPE) { - if (parant_scope == 0) { - fprintf(file_ptr, - "%-25s: %06d : : %d -> %-20s: " - "%-30s\n", - entrie->theName, current_scope, - entrie->additionalinfo->ArrayAdInfo - ->numofdimensions, - entrie->additionalinfo->ArrayAdInfo - ->typeofarray->theName, - "Type of Array"); - } else { - fprintf(file_ptr, - "%-25s: %06d : : %d -> %-20s: " - "%-30s\n", - entrie->theName, current_scope, - parant_scope, - entrie->additionalinfo->ArrayAdInfo - ->numofdimensions, - entrie->additionalinfo->ArrayAdInfo - ->typeofarray->theName, - "Type of Array"); - } - } - if (getAdInfoType(entrie) == TYPE_RECORD) { - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-25s: %06d : : %-25s: " - "elements-%-30d\n", - entrie->theName, current_scope, - "record", - entrie->additionalinfo->RecAdInfo - ->numofelements); - } else { - fprintf(file_ptr, - "%-25s: %06d : %06d : %-25s: " - "elements-%-30d\n", - entrie->theName, current_scope, - parant_scope, "record", - entrie->additionalinfo->RecAdInfo - ->numofelements); - } - } - if (getAdInfoType(entrie) == TYPE_PRIMITIVE) { - if (parant_scope == 0) { - - fprintf( - file_ptr, - "%-25s: %06d : : %-25s: size-%d " - "bytes\n", - entrie->theName, current_scope, "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } else { - fprintf( - file_ptr, - "%-25s: %06d : %06d : %-25s: size-%-30d " - "bytes\n", - entrie->theName, current_scope, - parant_scope, "Primitive", - entrie->additionalinfo->PrimAdInfo->size); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_TYPE) { - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-25s: %06d : : %-25s -> " - "%-25s: %-30s\n", - entrie->theName, current_scope, - entrie->additionalinfo->FunTypeAdInfo - ->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo - ->returntype->theName, - "Type of Function"); - } else { - fprintf(file_ptr, - "%-25s: %06d : %06d : %-25s -> %-21s: " - "%-30s\n", - entrie->theName, current_scope, - parant_scope, - entrie->additionalinfo->FunTypeAdInfo - ->parameter->theName, - entrie->additionalinfo->FunTypeAdInfo - ->returntype->theName, - "Type of Function"); - } - } - if (getAdInfoType(entrie) == TYPE_FUNCTION_DECLARATION) { - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-25s: %06d : : %-25s: %-30s\n", - entrie->theName, current_scope, - getType(entrie), "User Defined"); - } else { - fprintf(file_ptr, - "%-25s: %06d : %06d : %-25s: %-30s\n", - entrie->theName, current_scope, - parant_scope, getType(entrie), - "User Defined"); - } - } - if (getAdInfoType(entrie) == TYPE_UNDEFINED) { - if (parant_scope == 0) { - - fprintf(file_ptr, - "%-25s: %06d : : %-25s: %-30s\n", - entrie->theName, current_scope, - "undefined", "undefined entry"); - } else { - fprintf(file_ptr, - "%-25s: %06d : %06d : %-25s: %-30s\n", - entrie->theName, current_scope, - parant_scope, "undefined", - "undefined entry"); - } - } + if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) { + if (parentScopeNum == 0) { + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, " Function", " Function Declaration"); + } else { + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, " Function", " Function Declaration"); + } } - if (getChildren(table) != NULL) { - ListOfTable *node = getChildren(table); - for (; node != NULL; node = node->next) { - if ((node->table) == NULL) { - print_symbol_table(node->table, file_ptr); - } else { - if ((node->table)->Line_Number == -1) { - continue; - } else { - print_symbol_table(node->table, - file_ptr); - } - } + + if (getAdInfoType(entry) == TYPE_UNDEFINED) { + if (parentScopeNum == 0) { + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, " undefined", "undefined entry"); + } else { + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, " undefined", "undefined entry"); + } + } + } + + if (getChildren(table) != NULL) { + ListOfTable *node = getChildren(table); + for (; node != NULL; node = node->next) { + if ((node->table) == NULL) { + print_symbol_table(node->table, file_ptr); + } else { + if ((node->table)->Line_Number == -1) { + continue; + } else { + print_symbol_table(node->table, file_ptr); } + } } - if (getParent(table) == NULL) { - fprintf(file_ptr, - "-------------------------:--------:--------:----------" - "----------------:------------------------------\n"); - } + } + + if (table->Parent_Scope == NULL) { + printline(file_ptr); + } } // get top most symbol table SymbolTable *getAncestor(SymbolTable *table) { - if (table == NULL) { - printdebug("passing a NULL reference to getAncestor. Invalid."); - return NULL; - } - if (table->Parent_Scope == NULL) { - // if table has no parent, return itself - printdebug("already at top scope!"); - if (table == cur) { - printdebug("passed in the current scope"); - } else { - printdebug("passed in a different scope"); - } - return table; + if (table == NULL) { + printdebug("passing a NULL reference to getAncestor. Invalid."); + return NULL; + } + if (table->Parent_Scope == NULL) { + // if table has no parent, return itself + printdebug("already at top scope!"); + if (table == cur) { + printdebug("passed in the current scope"); } else { - // call function recursively to grab ancestor - return getAncestor(table->Parent_Scope); + printdebug("passed in a different scope"); } + return table; + } else { + // call function recursively to grab ancestor + return getAncestor(table->Parent_Scope); + } } SymbolTable *removeEntry(SymbolTable *scope, char *search) { - - if (scope == NULL) { - return NULL; - } - if (scope->entries == NULL) { - return scope; - } - - TableNode *prev = NULL; - TableNode *now = scope->entries; - - while (now != NULL) { - if (strcmp(getName(now), search) == 0) { - if (prev == NULL) { - scope->entries = getNextEntry(now); - return scope; - } else { - prev->next = now->next; - return scope; - } - } - prev = now; - now = now->next; - } + if (scope == NULL) { + return NULL; + } + if (scope->entries == NULL) { return scope; + } + + TableNode *prev = NULL; + TableNode *now = scope->entries; + + while (now != NULL) { + if (strcmp(getName(now), search) == 0) { + if (prev == NULL) { + scope->entries = getNextEntry(now); + return scope; + } else { + prev->next = now->next; + return scope; + } + } + prev = now; + now = now->next; + } + return scope; } // almost certainly don't need to use the below function since type checking // happens by passing types up the grammar bool typeCheck(char *firstID, char *secondID) { - - TableNode *entry1 = look_up(cur, firstID); - TableNode *entry2 = look_up(cur, secondID); - if (entry1 == NULL) { - printdebug("first type is NULL in type check. Invalid."); - return false; - } - if (entry1 == undefined) { - printdebug("first type is undefined in type check. Invalid."); - return false; - } - if (entry2 == NULL) { - printdebug("second type is NULL in type check. Invalid."); - return false; - } - if (entry2 == undefined) { - printdebug("second type is undefined in type check. Invalid."); - return false; - } - if (table_lookup(getAncestor(cur), getType(look_up(cur, firstID))) == - table_lookup(getAncestor(cur), getType(look_up(cur, secondID)))) { - if (strcmp(getType(look_up(cur, firstID)), "array") == 0) { - if (look_up(cur, firstID) - ->additionalinfo->ArrayAdInfo - ->numofdimensions == - look_up(cur, secondID) - ->additionalinfo->ArrayAdInfo - ->numofdimensions && - look_up(cur, firstID) - ->additionalinfo->ArrayAdInfo - ->typeofarray == - look_up(cur, secondID) - ->additionalinfo->ArrayAdInfo - ->typeofarray) { - return true; - } else { - return false; - } - } - return true; - } + TableNode *entry1 = look_up(cur, firstID); + TableNode *entry2 = look_up(cur, secondID); + if (entry1 == NULL) { + printdebug("first type is NULL in type check. Invalid."); return false; + } + if (entry1 == undefined) { + printdebug("first type is undefined in type check. Invalid."); + return false; + } + if (entry2 == NULL) { + printdebug("second type is NULL in type check. Invalid."); + return false; + } + if (entry2 == undefined) { + printdebug("second type is undefined in type check. Invalid."); + return false; + } + if (table_lookup(getAncestor(cur), getType(look_up(cur, firstID))) == + table_lookup(getAncestor(cur), getType(look_up(cur, secondID)))) { + if (strcmp(getType(look_up(cur, firstID)), "array") == 0) { + if (look_up(cur, firstID) + ->additionalinfo->ArrayAdInfo + ->numofdimensions == + look_up(cur, secondID) + ->additionalinfo->ArrayAdInfo + ->numofdimensions && + look_up(cur, firstID) + ->additionalinfo->ArrayAdInfo + ->typeofarray == + look_up(cur, secondID) + ->additionalinfo->ArrayAdInfo + ->typeofarray) { + return true; + } else { + return false; + } + } + return true; + } + return false; } SymbolTable *getParent(SymbolTable *st) { - if (st == NULL) { - printdebug("passed a NULL symbol table to getParent function. " - "Invalid."); - return NULL; - } - if (st->Parent_Scope == NULL) { - printdebug("passed a top level scope to getParent function. " - "Invalid."); - return st; - } - return st->Parent_Scope; + if (st == NULL) { + printdebug( + "passed a NULL symbol table to getParent function. " + "Invalid."); + return NULL; + } + if (st->Parent_Scope == NULL) { + printdebug( + "passed a top level scope to getParent function. " + "Invalid."); + return st; + } + return st->Parent_Scope; } ListOfTable *getChildren(SymbolTable *st) { return st->Children_Scope; } @@ -1128,111 +1133,117 @@ TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } // Segfaults when passed an invalid table node! TableNode *getNextEntry(TableNode *tn) { - if (tn == NULL) { - printdebug("passed a NULL table node to getNextEntry"); - return undefined; - } - if (tn == undefined) { - printdebug("passed an undefined table node to getNextEntry"); - return undefined; - } - return tn->next; + if (tn == NULL) { + printdebug("passed a NULL table node to getNextEntry"); + return undefined; + } + if (tn == undefined) { + printdebug("passed an undefined table node to getNextEntry"); + return undefined; + } + return tn->next; } // Prints all info about a table node // Uses pointers to the table node to print the info TableNode *printTableNode(TableNode *tn) { - if (DEBUG == 0) { - return tn; - } - - if (tn == NULL) { - printdebug("%s[PrintTN] Passed a NULL tablenode!", COLOR_RED); - return undefined; - } - if (tn == undefined) { - printdebug("%s[PrintTN] Passed an undefined tablenode!", - COLOR_RED); - return undefined; - } - if (tn->theName == NULL) { - printdebug("%s[PrintTN] Passed a tablenode with NULL name!", - COLOR_RED); - return undefined; - } - if (tn->theType == NULL) { - printdebug("%s[PrintTN] Passed a tablenode with NULL type!", - COLOR_RED); - return undefined; - } - if (tn->additionalinfo == NULL) { - printdebug( - "%s[PrintTN] Passed a tablenode with NULL additional info!", - COLOR_RED); - return undefined; - } - - printdebug("%s[PrintTN] Printing tablenode...", COLOR_ORANGE); - printdebug(" %sName: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, - tn->theName); - printdebug(" %sType: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, - tn->theType->theName); - printdebug(" %sTag: %s%d", COLOR_YELLOW, COLOR_LIGHTBLUE, tn->tag); - - if (tn->tag == TYPE_RECORD_TYPE || tn->tag == TYPE_RECORD) { - printdebug(" %sAdditional Info: %sRecAdInfo", COLOR_YELLOW, - COLOR_LIGHTBLUE); - printdebug(" %snumberOfElements: %s%d", COLOR_YELLOW, - COLOR_LIGHTBLUE, - tn->additionalinfo->RecAdInfo->numofelements); - if (tn->additionalinfo->RecAdInfo->recordScope == NULL) { - printdebug(" %srecordScope (line): %s(NULL)", - COLOR_YELLOW, COLOR_LIGHTBLUE); - } else { - printdebug(" %srecordScope (line): %s%d", - COLOR_YELLOW, COLOR_LIGHTBLUE, - tn->additionalinfo->RecAdInfo->recordScope - ->Line_Number); - } - } else if (tn->tag == TYPE_ARRAY_TYPE || tn->tag == TYPE_ARRAY) { - printdebug(" %sAdditional Info: %sArrayAdInfo", COLOR_YELLOW, - COLOR_LIGHTBLUE); - printdebug(" %snumberOfDimensions: %s%d", COLOR_YELLOW, - COLOR_LIGHTBLUE, - tn->additionalinfo->ArrayAdInfo->numofdimensions); - printdebug( - " %stypeOfArray: %s%s", COLOR_YELLOW, - COLOR_LIGHTBLUE, - tn->additionalinfo->ArrayAdInfo->typeofarray->theName); - } else if (tn->tag == TYPE_FUNCTION_TYPE) { - printdebug(" %sAdditional Info: %sFunTypeAdInfo", - COLOR_YELLOW, COLOR_LIGHTBLUE); - printdebug( - " %sparameter: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, - tn->additionalinfo->FunTypeAdInfo->parameter->theName); - printdebug( - " %sreturntype: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, - tn->additionalinfo->FunTypeAdInfo->returntype->theName); - } else if (tn->tag == TYPE_FUNCTION_DECLARATION) { - printdebug(" %sAdditional Info: %sFunDecAdInfo", - COLOR_YELLOW, COLOR_LIGHTBLUE); - printdebug(" %sstartLineNumber: %s%d", COLOR_YELLOW, - COLOR_LIGHTBLUE, - tn->additionalinfo->FunDecAdInfo->startlinenumber); - printdebug(" %sregularOrAs: %s%s", COLOR_YELLOW, - COLOR_LIGHTBLUE, - tn->additionalinfo->FunDecAdInfo->regularoras - ? "true" - : "false"); - } else if (tn->tag == TYPE_PRIMITIVE) { - printdebug(" %sAdditional Info: %sPrimAdInfo", COLOR_YELLOW, - COLOR_LIGHTBLUE); - printdebug(" %ssize: %s%d", COLOR_YELLOW, - COLOR_LIGHTBLUE, - tn->additionalinfo->PrimAdInfo->size); - } else { - printdebug(" AdInfo not handled."); - } - + if (DEBUG == 0) { return tn; + } + + if (tn == NULL) { + printdebug("%s[PrintTN] Passed a NULL tablenode!", COLOR_RED); + return undefined; + } + if (tn == undefined) { + printdebug("%s[PrintTN] Passed an undefined tablenode!", + COLOR_RED); + return undefined; + } + if (tn->theName == NULL) { + printdebug("%s[PrintTN] Passed a tablenode with NULL name!", + COLOR_RED); + return undefined; + } + if (tn->theType == NULL) { + printdebug("%s[PrintTN] Passed a tablenode with NULL type!", + COLOR_RED); + return undefined; + } + if (tn->additionalinfo == NULL) { + printdebug( + "%s[PrintTN] Passed a tablenode with NULL additional info!", + COLOR_RED); + return undefined; + } + + printdebug("%s[PrintTN] Printing tablenode...", COLOR_ORANGE); + printdebug(" %sName: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->theName); + printdebug(" %sType: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->theType->theName); + printdebug(" %sTag: %s%d", COLOR_YELLOW, COLOR_LIGHTBLUE, tn->tag); + + if (tn->next == NULL) { + printdebug(" %sNext: %sNULL", COLOR_YELLOW, COLOR_LIGHTBLUE); + } else { + printdebug(" %sNext: %s%s (tn)", COLOR_YELLOW, COLOR_LIGHTBLUE, tn->next->theName); + } + + if (tn->tag == TYPE_RECORD_TYPE || tn->tag == TYPE_RECORD) { + printdebug(" %sAdditional Info: %sRecAdInfo", COLOR_YELLOW, + COLOR_LIGHTBLUE); + printdebug(" %snumberOfElements: %s%d", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->RecAdInfo->numofelements); + if (tn->additionalinfo->RecAdInfo->recordScope == NULL) { + printdebug(" %srecordScope (line): %s(NULL)", + COLOR_YELLOW, COLOR_LIGHTBLUE); + } else { + printdebug(" %srecordScope (line): %s%d", + COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->additionalinfo->RecAdInfo->recordScope + ->Line_Number); + } + } else if (tn->tag == TYPE_ARRAY_TYPE || tn->tag == TYPE_ARRAY) { + printdebug(" %sAdditional Info: %sArrayAdInfo", COLOR_YELLOW, + COLOR_LIGHTBLUE); + printdebug(" %snumberOfDimensions: %s%d", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->ArrayAdInfo->numofdimensions); + printdebug( + " %stypeOfArray: %s%s", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->ArrayAdInfo->typeofarray->theName); + } else if (tn->tag == TYPE_FUNCTION_TYPE) { + printdebug(" %sAdditional Info: %sFunTypeAdInfo", + COLOR_YELLOW, COLOR_LIGHTBLUE); + printdebug( + " %sparameter: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->additionalinfo->FunTypeAdInfo->parameter->theName); + printdebug( + " %sreturntype: %s%s", COLOR_YELLOW, COLOR_LIGHTBLUE, + tn->additionalinfo->FunTypeAdInfo->returntype->theName); + } else if (tn->tag == TYPE_FUNCTION_DECLARATION) { + printdebug(" %sAdditional Info: %sFunDecAdInfo", + COLOR_YELLOW, COLOR_LIGHTBLUE); + printdebug(" %sstartLineNumber: %s%d", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->FunDecAdInfo->startlinenumber); + printdebug(" %sregularOrAs: %s%s", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->FunDecAdInfo->regularoras + ? "true" + : "false"); + } else if (tn->tag == TYPE_PRIMITIVE) { + printdebug(" %sAdditional Info: %sPrimAdInfo", COLOR_YELLOW, + COLOR_LIGHTBLUE); + printdebug(" %ssize: %s%d", COLOR_YELLOW, + COLOR_LIGHTBLUE, + tn->additionalinfo->PrimAdInfo->size); + } else { + printdebug(" AdInfo not handled."); + } + + return tn; } \ No newline at end of file From a4dc3d90be97b38e78677ee3ae9394c1e38e10ab Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 8 Apr 2025 16:01:36 -0400 Subject: [PATCH 085/137] update --- src/grammar.y | 67 +++++++++++++------ src/symbol_table.c | 8 ++- tests/sprint2/test/sp2_presidence.alpha | 6 +- .../sprint3/test/sp3_and_or_type_check.alpha | 3 + .../test/sp3_primitive_type_check.alpha | 23 +++++++ 5 files changed, 82 insertions(+), 25 deletions(-) create mode 100644 tests/sprint3/test/sp3_primitive_type_check.alpha diff --git a/src/grammar.y b/src/grammar.y index 946c9ad..e70363d 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -326,14 +326,14 @@ sblock: dblock: L_BRACKET - {if(getLine(cur)==0){ - setLineNumber(cur, @1.first_line); - setColumnNumber(cur,@1.first_line);} - else{ - cur = CreateScope(cur,@1.first_line,@1.first_column); + { + if (getLine(cur) == 0) { + setLineNumber(cur, @1.first_line); + setColumnNumber(cur,@1.first_line); + } else{ + cur = CreateScope(cur,@1.first_line,@1.first_column); // <----- What is this? } - } - + } declaration_list R_BRACKET; @@ -391,22 +391,45 @@ compound_statement: simple_statement: assignable ASSIGN expression { - if(strcmp(getName((TableNode*)$1), getName((TableNode*)$3)) == 0) { - printdebug("Passed standard type check; assignable = expression"); - } else if((strcmp(getType((TableNode*)$1), "array") == 0) && (strcmp(getName((TableNode*)$3), "address") == 0)) { - printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, getName((TableNode*)$1), getName((TableNode*)$3)); - } else if((strcmp(getType((TableNode*)$1), "record") == 0) && (strcmp(getName((TableNode*)$3), "address") == 0)) { - printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, getName((TableNode*)$1), getName((TableNode*)$3)); - } else if((strcmp(getType((TableNode*)$1), "function type primitive") == 0) && (strcmp(getName((TableNode*)$3), "address") == 0)) { - printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, getName((TableNode*)$1), getName((TableNode*)$3)); - // } else if () { + bool passCheck = false; + TableNode * left = (TableNode*)$1; + TableNode * right = (TableNode*)$3; + + printTableNode((TableNode*)$1); + printTableNode((TableNode*)$3); - // } else if(strcmp(getType(table_lookup(cur, $1)), getType(table_lookup(cur, $3))) == 0) { - // printdebug("%s[] Passed double lookup type check; %s = %s", COLOR_GREEN, $1, $3); - } else { + if (strcmp(getType(right), "primitive") == 0) { + if (strcmp((getType(left)),(getName(right))) == 0) { + printdebug("%s[☺] Passed primitive type check; %s = %s", COLOR_GREEN, getName(left), getName(right)); + passCheck = true; + } + } + + if(strcmp(getName(left), getName(right)) == 0) { + printdebug("Passed standard type check; assignable = expression"); + passCheck = true; + } + + if((strcmp(getType(left), "array") == 0) && (strcmp(getName(right), "address") == 0)) { + printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, getName(left), getName(right)); + passCheck = true; + } + + if((strcmp(getType(left), "record") == 0) && (strcmp(getName(right), "address") == 0)) { + printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, getName(left), getName(right)); + passCheck = true; + } + + if((strcmp(getType(left), "function type primitive") == 0) && (strcmp(getName(right), "address") == 0)) { + printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, getName(left), getName(right)); + passCheck = true; + } + + // Type check fails: + if (!passCheck) { printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); - printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType((TableNode*)$1), getType((TableNode*)$3), COLOR_WHITE); - printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType((TableNode*)$1)); + printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType(left), getType(right), COLOR_WHITE); + printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(left)); } } @@ -624,6 +647,8 @@ assignable: //char *funtype = getType(look_up(cur, $1)); printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); + + TableNode * typeNode = table_lookup(getAncestor(cur), getType((TableNode*)$1)); TableNode *param = getParameter(typeNode); printTableNode(param); diff --git a/src/symbol_table.c b/src/symbol_table.c index 86fca5b..debc4d5 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -913,7 +913,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (table->Parent_Scope == NULL) { fprintf(file_ptr, "%-*s:%-*s:%-*s:%-*s:%-*s:\n", - col_widths[0], " NAME", + col_widths[0], "NAME", col_widths[1], " SCOPE", col_widths[2], " PARENT", col_widths[3], " TYPE", @@ -965,7 +965,11 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parentScopeNum == 0) { st_fprint(file_ptr, entry->theName, currentScopeNum, -100, " Primitive", primAdInfo); } else { - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, " Primitive", primAdInfo); + printdebug("%sTHIS ONE", COLOR_RED); + printTableNode(entry); + char *primType = (char *)malloc(sizeof(getType(entry) + 1)); + sprintf(primType, " %s", getType(entry)); + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, primType, primAdInfo); } } diff --git a/tests/sprint2/test/sp2_presidence.alpha b/tests/sprint2/test/sp2_presidence.alpha index 2d60209..d60611d 100644 --- a/tests/sprint2/test/sp2_presidence.alpha +++ b/tests/sprint2/test/sp2_presidence.alpha @@ -1,8 +1,10 @@ type main: string -> integer +type rec: [integer: rec_x; integer: rec_y] + function entry: main entry (arg) := { - [integer:x] - x := 3 + 2 * 8; + [integer: arg_x; integer: arg_y; rec: arg_record; Boolean: arg_bool] + arg_x := 3 + 2 * 8; return 0; } diff --git a/tests/sprint3/test/sp3_and_or_type_check.alpha b/tests/sprint3/test/sp3_and_or_type_check.alpha index 450aee0..c01fc10 100644 --- a/tests/sprint3/test/sp3_and_or_type_check.alpha +++ b/tests/sprint3/test/sp3_and_or_type_check.alpha @@ -31,6 +31,9 @@ test (arg) := { b := b & 1; b := 1 & b; b := 1 = 1; + + + b := 1 = b; return 0; diff --git a/tests/sprint3/test/sp3_primitive_type_check.alpha b/tests/sprint3/test/sp3_primitive_type_check.alpha new file mode 100644 index 0000000..6980aba --- /dev/null +++ b/tests/sprint3/test/sp3_primitive_type_check.alpha @@ -0,0 +1,23 @@ +(* + Testing the following type checks: + - integer : primitive + - character : primitive + - boolean : primitive + + - address (not included, special case) +*) + + + +type main: string -> integer +function entry: main + +entry (arg) := { + [integer: i; address: add; character: char; Boolean: bool] + + i := 3 + 2 * 8; + char := 'a'; + bool := true; + + return 0; +} From faf592a725d8881730f9d3fdb41862f646373913 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 8 Apr 2025 18:12:11 -0400 Subject: [PATCH 086/137] Added most type checking. Entries seem printing mostly OK in table. --- src/grammar.y | 155 +++++++++++++++++++++++++++++++++------------ src/symbol_table.c | 13 +++- 2 files changed, 127 insertions(+), 41 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index e70363d..fa52d73 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -127,15 +127,17 @@ definition: printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur),TYPE_RECORD_TYPE, recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); - if (look_up(cur, $2) == undefined) { - printdebug("rec not found"); - } + printdebug("Created a new scope"); + //if (look_up(cur, $2) == undefined) { + // printdebug("rec not found"); + //} } dblock { //We are scanning through the dblock scope to get the length of the dblock (num of elements) from getRecSize //and then putting it in the entry that we created above. setRecSize(look_up(getParent(cur), $2), getRecSize(cur)); + printdebug("Moving up a scope after seeing a record definition"); cur = getParent(cur); } @@ -158,14 +160,15 @@ definition: { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + printdebug("[TYPE CHECK] function not declared at line %d, column %d", @1.first_line, @1.first_column); } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { - printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column); + printdebug("[TYPE CHECK] function not declared at line %d, column %d", @1.first_line, @1.first_column); } else { setStartLine(node, @1.first_line); setAsKeyword(node, false); } cur = CreateScope(cur, 0, 0); + printdebug("Created a new scope"); } L_PAREN ID { @@ -178,7 +181,7 @@ definition: || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("type of parameter is undefined or invalid at line %d, column %d", @4.first_line, @4.first_column); + printdebug("[TYPE CHECK] type of parameter is undefined or invalid at line %d, column %d", @4.first_line, @4.first_column); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ printdebug("type of parameter is %s at line %d, column %d", getName(type_of_param), @4.first_line, @4.first_column); @@ -192,9 +195,9 @@ definition: TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { - printdebug(" undefined nodedeclared at line %d, column %d", @1.first_line, @1.first_column); + printdebug(" [TYPE CHECK] undefined nodedeclared at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printdebug("not a valid function declaration at line %d, column %d", @1.first_line, @1.first_column); + printdebug("[TYPE CHECK] not a valid function declaration at line %d, column %d", @1.first_line, @1.first_column); } else { printdebug("setting as keyword to true"); @@ -202,11 +205,12 @@ definition: setAsKeyword(node, true); } cur = CreateScope(cur, 0, 0); + printdebug("Created a new scope"); }AS L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); printdebug("parameter type: %s", getType(parameter)); if (parameter == undefined) { - printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); + printdebug("[TYPE CHECK] function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(parameter) != TYPE_RECORD){ printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); @@ -220,7 +224,7 @@ definition: || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("type of parameter being passed in to AS function definition is %s which is invalid", getName(entry)); + printdebug("[TYPE CHECK] type of parameter being passed in to AS function definition is %s which is invalid", getName(entry)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); @@ -241,13 +245,27 @@ definition: function_declaration: FUNCTION ID COLON ID - { + { + if(getAdInfoType(look_up(cur, $4))==TYPE_FUNCTION_TYPE){ CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); } + else{ + printdebug("[TYPE CHECK] function declaration of %s is not a valid function type at line %d, column %d", $2, @1.first_line, @1.first_column); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + + } + } | EXTERNAL FUNCTION ID COLON ID - { - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, NULL); + { + if(getAdInfoType(look_up(cur, $5))==TYPE_FUNCTION_TYPE){ + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); + } + else{ + printdebug("[TYPE CHECK] function declaration of %s is not a valid function type at line %d, column %d", $3, @1.first_line, @1.first_column); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); + + } } ; @@ -290,6 +308,7 @@ sblock: { if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); + printdebug("Created a new scope"); } else { setLineNumber(cur, @1.first_line); setColumnNumber(cur,@1.first_line); @@ -297,6 +316,7 @@ sblock: } statement_list { + printdebug("Moving up a scope after seeing sblock"); cur = getParent(cur); } R_BRACE @@ -305,9 +325,11 @@ sblock: { if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); + printdebug("Created a new scope when seeing an L brace"); } else { setLineNumber(cur, @1.first_line); setColumnNumber(cur,@1.first_line); + printdebug("Did not create a new scope when saw L Brace, set line number to %d", @1.first_line); } } dblock @@ -316,6 +338,7 @@ sblock: } statement_list { + printdebug("Moving up a scope after seeing sblock with dblock"); cur = getParent(cur); } R_BRACE @@ -330,8 +353,10 @@ dblock: if (getLine(cur) == 0) { setLineNumber(cur, @1.first_line); setColumnNumber(cur,@1.first_line); + printdebug("Did not create a new scope when saw dblock, set line number to %d instead", @1.first_line); } else{ cur = CreateScope(cur,@1.first_line,@1.first_column); // <----- What is this? + printdebug("Created a new scope when seeing a dblock"); } } declaration_list R_BRACKET; @@ -349,7 +374,33 @@ declaration: id_or_types COLON ID { printdebug("ID/TYPE: %s, ID: %s", getName((TableNode*)$1), $3) ; - CreateEntry(cur,getAdInfoType((TableNode*)$1),(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + int d = getAdInfoType((TableNode*)$1); + if(d == TYPE_UNDEFINED) { + printdebug("undefined type at line %d and column %d", @2.first_line, @2.first_column); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } + else if(d == TYPE_FUNCTION_TYPE) { + printdebug("invalid (function) type passed in declaration list in dblock", @2.first_line, @2.first_column); + d = TYPE_FUNCTION_TYPE; + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } + else if(d == TYPE_ARRAY_TYPE){ + printdebug("array variable at line %d and column %d", @2.first_line, @2.first_column); + d = TYPE_ARRAY; + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } + else if(d == TYPE_RECORD_TYPE){ + printdebug("record variable at line %d and column %d", @2.first_line, @2.first_column); + d = TYPE_RECORD; + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } + else if(d == TYPE_PRIMITIVE){ + printdebug("primitive variable at line %d and column %d", @2.first_line, @2.first_column); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + }else { + printdebug("other invalid type passed at %d and column %d", @2.first_line, @2.first_column); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + } } ; @@ -427,7 +478,7 @@ simple_statement: // Type check fails: if (!passCheck) { - printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); + printdebug("%s[TYPE CHECK] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType(left), getType(right), COLOR_WHITE); printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(left)); } @@ -495,7 +546,7 @@ expression: $$=(TableNode*)$2; } else { $$=undefined; - printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,getName((TableNode*)$2)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,getName((TableNode*)$2)); } } @@ -505,7 +556,7 @@ expression: if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { $$=(TableNode*)$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -516,7 +567,7 @@ expression: if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { $$=(TableNode*)$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -527,7 +578,7 @@ expression: if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { $$=(TableNode*)$1; } else{ - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); $$=undefined; } } @@ -538,7 +589,7 @@ expression: if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && ((TableNode*)$1 == integ)) { $$=(TableNode*)$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -549,7 +600,7 @@ expression: if($1 == $3 && $1 == integ) { $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -560,7 +611,7 @@ expression: if($1 == $3 && $1 == boo){ $$=$1; } else{ - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -571,7 +622,7 @@ expression: if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && $1 == boo) { $$=$1; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -582,7 +633,7 @@ expression: if($1 == $3 && $1==integ) { $$=boo; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; } } @@ -593,7 +644,7 @@ expression: if($1 == $3 && $1 != undefined) { $$=boo; } else { - printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); + printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$ = undefined; } } @@ -601,7 +652,25 @@ expression: | assignable { printdebug("assignable expression. current type is %s",getName((TableNode*)$1)); - $$= getTypeEntry((TableNode*)$1); + if(getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE|| + getAdInfoType((TableNode*)$1) == TYPE_ARRAY || + getAdInfoType((TableNode*)$1) == TYPE_RECORD){ + printdebug("assignable passing up to expression is primitive, array instance, or record instance. Passing up its type"); + $$= getTypeEntry((TableNode*)$1); + } + + else if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + printdebug("assignable passing up to expression is array type, record type, function type, or function declaration"); + $$= ((TableNode*)$1); + } + else { + printdebug("[TYPE CHECK] assignable passing up an invalid type to expression"); + $$= ((TableNode*)$1); + } + } | L_PAREN expression R_PAREN @@ -612,7 +681,14 @@ expression: | memOp assignable { - $$ = addr; + int d = getAdInfoType((TableNode*)$2); + if(d == TYPE_ARRAY_TYPE || d == TYPE_ARRAY || d == TYPE_RECORD_TYPE || d == TYPE_RECORD) { + //printdebug("[TYPE CHECK] valid memOp expression"); + $$ = addr; + } else { + printdebug("[TYPE CHECK] invalid memOp expression at line %d and column %d.", @2.first_line,@2.first_column,getName((TableNode*)$2)); + $$=undefined; + } } ; @@ -626,7 +702,7 @@ assignable: ID { $$ = look_up(cur,$1); - printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1); + printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getName((TableNode*)$$), $1); } | assignable @@ -686,7 +762,7 @@ assignable: } } $$ = getReturn((table_lookup(getAncestor(cur), getType((TableNode*)$1)))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName((TableNode*)$1)); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); @@ -694,7 +770,7 @@ assignable: printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $2, @2.first_line, @2.first_column); } $$ = getArrType(look_up(getParent(cur), getName((TableNode*)$1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName($$), getName((TableNode*)$1)); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); } cur = getParent(cur); } @@ -702,6 +778,7 @@ assignable: | assignable rec_op ID { if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3)) { + $$ = table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3); } printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName((TableNode*)($$)), $1); @@ -729,7 +806,7 @@ constant: C_STRING { $$ = $1; - printdebug("string of C_STRING in constant is %s",$1); + printdebug("string of C_STRING in constant is %s",getName((TableNode*)$1)); } | C_INTEGER @@ -741,25 +818,25 @@ constant: | C_NULL { $$ = $1; - printdebug("string of C_NULL in constant is %s",$1); + printdebug("string of C_NULL in constant is %s",getName((TableNode*)$1)); } | C_CHARACTER { $$ = $1; - printdebug("string of C_CHARACTER in constant is %s",$1); + printdebug("string of C_CHARACTER in constant is %s",getName((TableNode*)$1)); } | C_TRUE { $$ = $1; - printdebug("string of C_TRUE in constant is %s",$1); + printdebug("string of C_TRUE in constant is %s",getName((TableNode*)$1)); } | C_FALSE { $$ = $1; - printdebug("string of C_FALSE in constant is %s",$1); + printdebug("string of C_FALSE in constant is %s",getName((TableNode*)$1)); } ; @@ -770,25 +847,25 @@ types: T_INTEGER { $$ = $1; - printdebug("string of T_INTEGER in types is %s",$1); + printdebug("string of T_INTEGER in types is %s",getName((TableNode*)$1)); } | T_ADDRESS { $$ = $1; - printdebug("string of T_ADDRESS in types is %s",$1); + printdebug("string of T_ADDRESS in types is %s",getName((TableNode*)$1)); } | T_CHARACTER { $$ = $1; - printdebug("string of T_CHARACTER in types is %s",$1); + printdebug("string of T_CHARACTER in types is %s",getName((TableNode*)$1)); } | T_BOOLEAN { $$ = $1; - printdebug("string of T_BOOLEAN in types is %s",$1); + printdebug("string of T_BOOLEAN in types is %s",getName((TableNode*)$1)); } ; diff --git a/src/symbol_table.c b/src/symbol_table.c index debc4d5..a4c909b 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -948,14 +948,23 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, arrayType, " Type of Array"); } } + if (getAdInfoType(entry) == TYPE_RECORD_TYPE) { + char *recordAdInfo = (char *)malloc(100); + sprintf(recordAdInfo, " elements-%d", entry->additionalinfo->RecAdInfo->numofelements); + if (parentScopeNum == 0) { + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, "record type", recordAdInfo); + } else { + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, "record type", recordAdInfo); + } + } if (getAdInfoType(entry) == TYPE_RECORD) { char *recordAdInfo = (char *)malloc(100); sprintf(recordAdInfo, " elements-%d", entry->additionalinfo->RecAdInfo->numofelements); if (parentScopeNum == 0) { - st_fprint(file_ptr, entry->theName, currentScopeNum, -100, "record", recordAdInfo); + st_fprint(file_ptr, entry->theName, currentScopeNum, -100, "record instance", recordAdInfo); } else { - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, "record", recordAdInfo); + st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, "record instance", recordAdInfo); } } From 3010ad651730e0a99d78df69c8f4f44631e823ca Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 8 Apr 2025 18:16:56 -0400 Subject: [PATCH 087/137] Added more debug statements --- src/symbol_table.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index a4c909b..c76043f 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -854,13 +854,14 @@ TableNode *table_lookup(SymbolTable *table, char *x) { return entrie; } } + printdebug("Could not find %s in scope using table_lookup", x); return undefined; } // check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { - printdebug("passed in empty scope. error."); + printdebug("Could not find %s in any scope using lookup",x); return undefined; } TableNode *ret = table_lookup(table, x); From d262bd9c3916dc47325a6ba044ad54890a2a7e18 Mon Sep 17 00:00:00 2001 From: Annie Date: Wed, 9 Apr 2025 13:13:20 -0400 Subject: [PATCH 088/137] removed as from function definitions --- src/grammar.y | 94 ++++++++++++++++++++------------------------------- 1 file changed, 36 insertions(+), 58 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index fa52d73..e12580d 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -156,41 +156,6 @@ definition: CreateEntry(cur,TYPE_FUNCTION_TYPE,funtypeprime,$2,CreateFunctionTypeInfo((TableNode*)$4 ,(TableNode*)$6)); } - | ID - { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == undefined) { - printdebug("[TYPE CHECK] function not declared at line %d, column %d", @1.first_line, @1.first_column); - } else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) { - printdebug("[TYPE CHECK] function not declared at line %d, column %d", @1.first_line, @1.first_column); - } else { - setStartLine(node, @1.first_line); - setAsKeyword(node, false); - } - cur = CreateScope(cur, 0, 0); - printdebug("Created a new scope"); - } - L_PAREN ID - { - printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4); - TableNode* type_of_param = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - int type_of_param_type = getAdInfoType(type_of_param); - if( type_of_param_type == TYPE_UNDEFINED - || type_of_param_type == TYPE_FUNCTION_DECLARATION - || type_of_param_type == TYPE_ARRAY - || type_of_param_type == TYPE_ALL_ELSE - || type_of_param_type == TYPE_SYSTEM_DEFINED - || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("[TYPE CHECK] type of parameter is undefined or invalid at line %d, column %d", @4.first_line, @4.first_column); - type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases - }else{ - printdebug("type of parameter is %s at line %d, column %d", getName(type_of_param), @4.first_line, @4.first_column); - } - - CreateEntry(cur,type_of_param_type, type_of_param, $4, getAdInfo(type_of_param)); - } - R_PAREN ASSIGN sblock //leaving scope is being taken care of in sblock - | ID { TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { @@ -206,42 +171,55 @@ definition: } cur = CreateScope(cur, 0, 0); printdebug("Created a new scope"); - }AS L_PAREN { + } L_PAREN { TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); printdebug("parameter type: %s", getType(parameter)); if (parameter == undefined) { printdebug("[TYPE CHECK] function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); }else if(getAdInfoType(parameter) != TYPE_RECORD){ - printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime)); - printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column); - - }else { - for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ - int type_of_param_type = getAdInfoType(entry); - if( type_of_param_type == TYPE_UNDEFINED + int type_of_param_type = getAdInfoType(parameter); + if( type_of_param_type == TYPE_UNDEFINED || type_of_param_type == TYPE_FUNCTION_DECLARATION || type_of_param_type == TYPE_ARRAY || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("[TYPE CHECK] type of parameter being passed in to AS function definition is %s which is invalid", getName(entry)); - type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases - }else{ - printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); - } - if(type_of_param_type == TYPE_UNDEFINED){ - CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); - } else { - CreateEntry(cur,type_of_param_type, entry, NULL, getAdInfo(entry)); - /*printdebug("creating entry of type %s for function", getType(entry)); - CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ + printdebug("[TYPE CHECK] type of parameter being passed in to function definition is %s which is invalid", getAdInfo(parameter)); + type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases + } + if(type_of_param_type == TYPE_UNDEFINED){ + CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); + } else { + CreateEntry(cur, getAdInfoType(parameter), parameter,NULL, getAdInfo(parameter)); + } + } else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ + int type_of_param_type = getAdInfoType(entry); + if( type_of_param_type == TYPE_UNDEFINED + || type_of_param_type == TYPE_FUNCTION_DECLARATION + || type_of_param_type == TYPE_ARRAY + || type_of_param_type == TYPE_ALL_ELSE + || type_of_param_type == TYPE_SYSTEM_DEFINED + || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused + printdebug("[TYPE CHECK] type of parameter being passed in to AS function definition is %s which is invalid", getName(entry)); + type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases + }else{ + printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); + } + if(type_of_param_type == TYPE_UNDEFINED){ + CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); + } else { + CreateEntry(cur,type_of_param_type, entry, NULL, getAdInfo(entry)); + /*printdebug("creating entry of type %s for function", getType(entry)); + CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ + } } - } } - } idlist {printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", - $1,$6);} R_PAREN ASSIGN sblock //check sblock type - ; + } idlist { + printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$5); + } R_PAREN ASSIGN sblock //check sblock type + ; function_declaration: FUNCTION ID COLON ID From d17e99758f5e36774408824dc3c2ab2225f0b027 Mon Sep 17 00:00:00 2001 From: Annie Date: Wed, 9 Apr 2025 13:29:50 -0400 Subject: [PATCH 089/137] added offsets to record type structure --- src/symbol_table.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/symbol_table.h b/src/symbol_table.h index 7c5322d..e2fac84 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -24,6 +24,8 @@ typedef struct { typedef struct { int numofelements; struct SymbolTable *recordScope; + int totalsize; + int offsets[]; } record_info; typedef struct { @@ -164,4 +166,4 @@ extern char *COLOR_YELLOW; extern char *COLOR_LIGHTBLUE; extern char *COLOR_LIGHTPURPLE; extern char *COLOR_LIGHTCYAN; -extern char *COLOR_WHITE; \ No newline at end of file +extern char *COLOR_WHITE; From 859ff3fd032db8774c5d4a1e26d9c080f8ac3113 Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 9 Apr 2025 15:15:17 -0400 Subject: [PATCH 090/137] added offset code in symbol table for records --- src/grammar.y | 2 +- src/symbol_table.c | 163 +++++++++++++++++++++++++++++++++++++++++++++ src/symbol_table.h | 4 +- 3 files changed, 166 insertions(+), 3 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index e12580d..4b4d14c 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -680,7 +680,7 @@ assignable: ID { $$ = look_up(cur,$1); - printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getName((TableNode*)$$), $1); + printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getTypeEntry((TableNode*)$$), $1); } | assignable diff --git a/src/symbol_table.c b/src/symbol_table.c index c76043f..cd04f8a 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -135,6 +135,169 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // This gets the number of elements that make up a record. // Perhaps this may not be needed since we need to iterate over all elements // anyways. + +int getRecTotal(TableNode* node){ + if(node == NULL){ + printdebug( + "passed a NULL node to getRecTotal. Invalid."); + return -1; + } + if(getAdInfoType(node) != TYPE_RECORD_TYPE){ + printdebug( + "passed an invalid node to getRecTotal. Invalid."); + return -1; + } + if(node->additionalinfo == NULL){ + printdebug( + "node has NULL additionalinfo. Invalid."); + return -1; + } + return node->additionalinfo->RecAdInfo->total_size; +} +TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { + if (node == NULL) { + printdebug( + "passed a NULL node to setRecOffsetInfo. Invalid."); + return undefined; + } + if (scope == NULL) { + printdebug( + "passed an NULL scope to setRecOffsetInfo. Invalid."); + return undefined; + } + if(getFirstEntry(scope) == NULL){ + printdebug( + "passed an empty scope to setRecOffsetInfo. Invalid."); + return undefined; + } + TableNode* this = getFirstEntry(scope); + int largest = 0; + int k = getRecLength(node); + int total_size = 0; + int counter = 0; + int *offsets = (int *)calloc(2 * k, sizeof(int)); + if(getAdInfoType(this) == TYPE_FUNCTION_TYPE){ + offsets[counter] = 8; + total_size = total_size + offsets[counter]; + largest = 8; + counter++; + } + else if(getAdInfoType(this) == TYPE_RECORD_TYPE){ + offsets[counter] = getRecTotal(this); + total_size = total_size + offsets[counter]; + largest = offsets[counter]; + counter++; + } + else if(getAdInfoType(this)==TYPE_PRIMITIVE){ + offsets[counter] = getPrimSize(this); + total_size = total_size + offsets[counter]; + largest = offsets[counter]; + counter++; + } + else if(getAdInfoType(this)==TYPE_ARRAY_TYPE){ + offsets[counter] = 8; + total_size = total_size + offsets[counter]; + largest = offsets[counter]; + counter++; + } + else { + printdebug( + "[TYPE CHECK] passed an invalid (first) parameter to a function definition."); + return undefined; + } + this = getNextEntry(this); + while(this != NULL){ + if(getAdInfoType(this) == TYPE_FUNCTION_TYPE){ + int s = 8; + if (s > largest) { + largest = s; + } + //make sure current location is aligned properly + offsets[counter] = (total_size % s); + total_size = total_size + offsets[counter]; + counter++; + //add in the size of the entry and increment + offsets[counter] = s; + total_size = total_size + offsets[counter]; + counter++; + this = getNextEntry(this); + } + else if(getAdInfoType(this) == TYPE_ARRAY_TYPE){ + int s = 8; + if (s > largest) { + largest = s; + } + //make sure current location is aligned properly + offsets[counter] = (total_size % s); + total_size = total_size + offsets[counter]; + counter++; + //add in the size of the entry and increment + offsets[counter] = s; + total_size = total_size + offsets[counter]; + counter++; + this = getNextEntry(this); + } + else if(getAdInfoType(this) == TYPE_RECORD_TYPE){ + int s = getRecTotal(this); + if (s > largest) { + largest = s; + } + //make sure current location is aligned properly + offsets[counter] = (total_size % s); + total_size = total_size + offsets[counter]; + counter++; + //add in the size of the entry and increment + offsets[counter] = s; + total_size = total_size + offsets[counter]; + counter++; + this = getNextEntry(this); + } + else if(getAdInfoType(this) == TYPE_PRIMITIVE){ + int s = getPrimSize(this); + if (s > largest) { + largest = s; + } + //make sure current location is aligned properly + offsets[counter] = (total_size % s); + total_size = total_size + offsets[counter]; + counter++; + //add in the size of the entry and increment + offsets[counter] = s; + total_size = total_size + offsets[counter]; + counter++; + this = getNextEntry(this); + }else{ + printdebug( + "[TYPE CHECK] passed an invalid parameter at position %d in record.",((counter+1)/2)); + return undefined; + } + } + //make sure that size of whole structure is aligned with largest element in struct: + offsets[counter] = (total_size % largest); + total_size = total_size + offsets[counter]; + node->additionalinfo->RecAdInfo->offsets = offsets; + node->additionalinfo->RecAdInfo->total_size = total_size; + return node; +} + +int* getRecOffsets(TableNode* node){ + if(node == NULL){ + printdebug( + "passed a NULL node to getRecTotal. Invalid."); + return NULL; + } + if(getAdInfoType(node) != TYPE_RECORD_TYPE){ + printdebug( + "passed an invalid node to getRecTotal. Invalid."); + return NULL; + } + if(node->additionalinfo == NULL){ + printdebug( + "node has NULL additionalinfo. Invalid."); + return NULL; + } + return node->additionalinfo->RecAdInfo->offsets; +} int getRecLength(TableNode *definition) { if (definition == NULL) { printdebug( diff --git a/src/symbol_table.h b/src/symbol_table.h index e2fac84..af2d827 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -24,8 +24,8 @@ typedef struct { typedef struct { int numofelements; struct SymbolTable *recordScope; - int totalsize; - int offsets[]; + int total_size; + int* offsets; } record_info; typedef struct { From d7d7d22c72719512544dd737027fbe26e0b72165 Mon Sep 17 00:00:00 2001 From: Annie Date: Fri, 11 Apr 2025 10:08:23 -0400 Subject: [PATCH 091/137] fixed seg fault for non record function calls --- src/grammar.y | 51 +++++++++++++--------- src/symbol_table.c | 4 +- tests/sprint2/test/sp2_carls_mistake.alpha | 6 +-- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 4b4d14c..029d545 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -707,31 +707,40 @@ assignable: TableNode *param = getParameter(typeNode); printTableNode(param); - SymbolTable *recList = getRecList(param); - TableNode *lastCheckedRef = getFirstEntry(recList); - TableNode *lastCheckedAct = getFirstEntry(cur); - while (getNextEntry(lastCheckedRef) != NULL) { - lastCheckedRef = getNextEntry(lastCheckedRef); - } + if (getAdInfoType(param) == TYPE_RECORD) { + SymbolTable *recList = getRecList(param); + TableNode *lastCheckedRef = getFirstEntry(recList); + TableNode *lastCheckedAct = getFirstEntry(cur); + while (getNextEntry(lastCheckedRef) != NULL) { + lastCheckedRef = getNextEntry(lastCheckedRef); + } - //this isn't very efficient, but will hopefully work - while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { - printdebug("expected %s. expression in function call got %s. at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); - printdebug("%d", strcmp(getName(lastCheckedAct), getName(lastCheckedRef))); - } - lastCheckedAct = getNextEntry(lastCheckedAct); - TableNode *tn = getFirstEntry(recList); - - if (tn != lastCheckedRef) { - while (getNextEntry(tn) != lastCheckedRef) { - tn = getNextEntry(tn); + //this isn't very efficient, but will hopefully work + while (lastCheckedAct != NULL && lastCheckedRef != NULL) { + if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { + printdebug("expected %s. expression in function call got %s. at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); + printdebug("%d", strcmp(getName(lastCheckedAct), getName(lastCheckedRef))); } - lastCheckedRef = tn; - } else {break;} + lastCheckedAct = getNextEntry(lastCheckedAct); + TableNode *tn = getFirstEntry(recList); + + if (tn != lastCheckedRef) { + while (getNextEntry(tn) != lastCheckedRef) { + tn = getNextEntry(tn); + } + lastCheckedRef = tn; + } else {break;} + } + } else { + if (strcmp(getName(param), getName(getFirstEntry(cur))) != 0) { + printdebug("expected %s expression in function call but got %s", getName(param), getName(getFirstEntry(cur))); + } + + if (getNextEntry(getFirstEntry(cur)) != NULL) { + printdebug("expected 1 parameter, but got multiple in function call"); + } } - } else { char *expected = getName(getParameter(look_up(getParent(cur), getName((TableNode*)$1)))); char *actual = getType(getFirstEntry(cur)); diff --git a/src/symbol_table.c b/src/symbol_table.c index cd04f8a..a187fdf 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -335,7 +335,7 @@ SymbolTable *getRecList(TableNode *definition) { if (strcmp(getType(definition), "record") != 0) { printdebug( "not checking the list of types of a record -- invalid " - "op"); + "op of type %s", getType(definition)); return NULL; } return definition->additionalinfo->RecAdInfo->recordScope; @@ -1423,4 +1423,4 @@ TableNode *printTableNode(TableNode *tn) { } return tn; -} \ No newline at end of file +} diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index 8d705a7..c85c310 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -14,11 +14,11 @@ foo (x) := { return x * x; } -bar1 (a) := { - return a.x * a.y; +bar1 (x, y) := { + return x * y; } -bar2 as (r,s) := { +bar2 (r,s) := { return r * s; } From df8c9fb6618b919e90c5f0fbd48b9e3f9a30830b Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 11 Apr 2025 12:50:24 -0400 Subject: [PATCH 092/137] updated print symbol table to use getters --- src/symbol_table.c | 58 +++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index a187fdf..ce69570 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -105,13 +105,13 @@ TableNode *getArrType(TableNode *definition) { printdebug( "passed an NULL entry to getArrType " "function. Invalid."); - return NULL; + return undefined; } if (definition == undefined) { printdebug( "passed an undefined entry to getArrType " "function. Invalid."); - return NULL; + return undefined; } if (strcmp(getType(definition), "array") != 0) { printdebug("not checking the type of an array -- invalid op"); @@ -1103,93 +1103,93 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { for (; entry != NULL; entry = getNextEntry(entry)) { if (getAdInfoType(entry) == TYPE_ARRAY_TYPE) { char *arrayType = (char *)malloc(100); - sprintf(arrayType, " %d -> %s", entry->additionalinfo->ArrayAdInfo->numofdimensions, - entry->additionalinfo->ArrayAdInfo->typeofarray->theName); + sprintf(arrayType, " %d -> %s", getNumArrDim(entry), + getName(getArrType(entry))); if (parentScopeNum == 0) { - st_fprint(file_ptr, entry->theName, currentScopeNum, -100, arrayType, " Type of Array"); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, arrayType, " Type of Array"); } else { - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, arrayType, " Type of Array"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, arrayType, " Type of Array"); } } if (getAdInfoType(entry) == TYPE_RECORD_TYPE) { char *recordAdInfo = (char *)malloc(100); - sprintf(recordAdInfo, " elements-%d", entry->additionalinfo->RecAdInfo->numofelements); + sprintf(recordAdInfo, " elements-%d", getRecLength(entry)); if (parentScopeNum == 0) { - st_fprint(file_ptr, entry->theName, currentScopeNum, -100, "record type", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, "record type", recordAdInfo); } else { - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, "record type", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, "record type", recordAdInfo); } } if (getAdInfoType(entry) == TYPE_RECORD) { char *recordAdInfo = (char *)malloc(100); - sprintf(recordAdInfo, " elements-%d", entry->additionalinfo->RecAdInfo->numofelements); + sprintf(recordAdInfo, " elements-%d", getRecLength(entry)); if (parentScopeNum == 0) { - st_fprint(file_ptr, entry->theName, currentScopeNum, -100, "record instance", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, "record instance", recordAdInfo); } else { - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, "record instance", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, "record instance", recordAdInfo); } } if (getAdInfoType(entry) == TYPE_PRIMITIVE) { char *primAdInfo = (char *)malloc(100); - sprintf(primAdInfo, " size-%d bytes", entry->additionalinfo->PrimAdInfo->size); + sprintf(primAdInfo, " size-%d bytes", getPrimSize(entry)); if (parentScopeNum == 0) { - st_fprint(file_ptr, entry->theName, currentScopeNum, -100, " Primitive", primAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " Primitive", primAdInfo); } else { printdebug("%sTHIS ONE", COLOR_RED); printTableNode(entry); char *primType = (char *)malloc(sizeof(getType(entry) + 1)); sprintf(primType, " %s", getType(entry)); - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, primType, primAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, primType, primAdInfo); } } if (getAdInfoType(entry) == TYPE_FUNCTION_TYPE) { char *functiontype = (char *)malloc(100); - sprintf(functiontype, " %s -> %s", entry->additionalinfo->FunTypeAdInfo->parameter->theName, - entry->additionalinfo->FunTypeAdInfo->returntype->theName); + sprintf(functiontype, " %s -> %s", getName(getParameter(entry)), + getName(getReturn(entry))); if (parentScopeNum == 0) { - st_fprint(file_ptr, entry->theName, currentScopeNum, -100, functiontype, " Type of Function"); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, " Type of Function"); } else { - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, functiontype, " Type of Function"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, functiontype, " Type of Function"); } } if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) { if (parentScopeNum == 0) { - st_fprint(file_ptr, entry->theName, currentScopeNum, -100, " Function", " Function Declaration"); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " Function", " Function Declaration"); } else { - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, " Function", " Function Declaration"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, " Function", " Function Declaration"); } } if (getAdInfoType(entry) == TYPE_UNDEFINED) { if (parentScopeNum == 0) { - st_fprint(file_ptr, entry->theName, currentScopeNum, -100, " undefined", "undefined entry"); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " undefined", "undefined entry"); } else { - st_fprint(file_ptr, entry->theName, currentScopeNum, parentScopeNum, " undefined", "undefined entry"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, " undefined", "undefined entry"); } } } if (getChildren(table) != NULL) { ListOfTable *node = getChildren(table); - for (; node != NULL; node = node->next) { - if ((node->table) == NULL) { - print_symbol_table(node->table, file_ptr); + for (; node != NULL; node = getRestOfChildren(node)) { + if ((getFirstChild(node)) == NULL) { + print_symbol_table(getFirstChild(node), file_ptr); } else { - if ((node->table)->Line_Number == -1) { + if (getLine(getFirstChild(node)) == -1) { continue; } else { - print_symbol_table(node->table, file_ptr); + print_symbol_table(getFirstChild(node), file_ptr); } } } } - if (table->Parent_Scope == NULL) { + if (getParent(table) == NULL) { printline(file_ptr); } } From 7296a24c7445d0ee1366af7801fde47a8903b698 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Fri, 11 Apr 2025 12:51:14 -0400 Subject: [PATCH 093/137] I added some code to help with constants but it's not working. --- src/intermediate_code.c | 14 +++++++------- src/intermediate_code.h | 24 ++++++++++++++++++++++++ test.alpha | 29 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 test.alpha diff --git a/src/intermediate_code.c b/src/intermediate_code.c index c1e5980..c7938ec 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -23,20 +23,20 @@ void emit_helper(void){ } } - void emit_binary_op(char* result, Op op, char* arg1, char* arg2){ + void emit_binary_op(TableNode * result, Op op, TableNode * arg1, TableNode * arg2){ emit_helper(); current->opcode = op; - current->result = look_up(cur, result); - current->operand1 = look_up(cur, arg1); - current->operand2 = look_up(cur, arg2); + current->result = result; + current->operand1 = arg1; + current->operand2 = arg2; return; } - void emit_unary_op(char* result, Op op, char* arg){ + void emit_unary_op(TableNode * result, Op op, TableNode * arg){ emit_helper(); current->opcode = op; - current->result = look_up(cur, result); - current->operand1 = look_up(cur, arg); + current->result = result; + current->operand1 = arg; return; } diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 499d4c3..6266b79 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -35,6 +35,30 @@ typedef enum { } Op; + +typedef enum { + NODE, + INTEGER, + STRING, + CHARACTER, + ADDRESS, + BOOLEAN +} Discriminant; + +typedef union { + TableNode * node; + int integer; + char * string; + char character; + void * address; + bool Boolean; +} Register_union; + +typedef struct { + Discriminant d; + Register_union r_union; +} TNodeOrConst; + typedef struct Instruction { Op opcode; TableNode * result; diff --git a/test.alpha b/test.alpha new file mode 100644 index 0000000..7b06a5e --- /dev/null +++ b/test.alpha @@ -0,0 +1,29 @@ + + + +type a : 1 -> integers +type t : integer -> a +type r : integer -> integer + + + +function foo : t +function bar : r +function entry : + +bar(a) := { + 5 + bar(a - 1); + return a * bar(a-1); +} + +foo(c) := { + [a: arg] + arg := reserve arg(c); + return arg; +} + +entry(args) := { + [a: b] + b := foo(8); +} + From 8bc5997996719772f02c6fe08894b491b9c43e1d Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 11 Apr 2025 12:55:14 -0400 Subject: [PATCH 094/137] fixed getReturn to not return NULL --- src/symbol_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index ce69570..2204ba3 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -528,13 +528,13 @@ TableNode *getReturn(TableNode *definition) { printdebug( "passed a NULL entry to getReturn " "function. Invalid."); - return NULL; + return undefined; } if (definition == undefined) { printdebug( "passed an undefined entry to getReturn " "function. Invalid."); - return NULL; + return undefined; } if (strcmp(getType(definition), "primitive function type") != 0) { printdebug( From 541a2ba44a22678b7fd7942ec8945533a406249d Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 11 Apr 2025 13:08:43 -0400 Subject: [PATCH 095/137] tweaked get return --- src/symbol_table.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/symbol_table.c b/src/symbol_table.c index 2204ba3..913a32b 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -541,6 +541,11 @@ TableNode *getReturn(TableNode *definition) { "not checking the return of a function -- invalid op"); return undefined; } + if(definition->additionalinfo == NULL){ + printdebug( + "node has NULL additionalinfo. Invalid."); + return undefined; + } return definition->additionalinfo->FunTypeAdInfo->returntype; } From 1f0a2c189d0c98685d3ffb649cfff25e9ca08e52 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Fri, 11 Apr 2025 13:09:49 -0400 Subject: [PATCH 096/137] Added the debug flags to make --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0f7f411..c9797be 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ tmp/symbol_table.o: src/symbol_table.c src/symbol_table.h $(CC) $(CFLAGS) -o tmp/symbol_table.o -c src/symbol_table.c runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o - $(CC) $(CFLAGS) -o $(EXE) tmp/runner.o tmp/grammar.tab.c tmp/lex.yy.c + $(CC) $(CFLAGS) -o $(EXE) -g -ggdb tmp/runner.o tmp/grammar.tab.c tmp/lex.yy.c debug: CFLAGS += -DDEBUG=1 debug: clean compiler From 413a4854b4185461096318c5ba3ea1ff69fe2f32 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 11 Apr 2025 13:11:48 -0400 Subject: [PATCH 097/137] tweaked get parameter --- src/symbol_table.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/symbol_table.c b/src/symbol_table.c index 913a32b..89d133a 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -515,6 +515,11 @@ TableNode *getParameter(TableNode *definition) { "function. Invalid."); return undefined; } + if(definition->additionalinfo == NULL){ + printdebug( + "node has NULL additionalinfo. Invalid."); + return undefined; + } if (strcmp(getType(definition), "primitive function type") != 0) { printdebug( "not checking the parameter of a function -- invalid op"); From f6dabd8d0342f0ef30161e7aba7412bfe6d88c3e Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 11 Apr 2025 14:02:34 -0400 Subject: [PATCH 098/137] working on make sure types pass properly in grammar --- src/grammar.y | 5 +++-- src/symbol_table.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 029d545..651c5ae 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -172,7 +172,8 @@ definition: cur = CreateScope(cur, 0, 0); printdebug("Created a new scope"); } L_PAREN { - TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); + TableNode * parameter = getParameter(getTypeEntry(table_lookup(getAncestor(cur), $1))); + //TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); printdebug("parameter type: %s", getType(parameter)); if (parameter == undefined) { printdebug("[TYPE CHECK] function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); @@ -359,7 +360,7 @@ declaration: } else if(d == TYPE_FUNCTION_TYPE) { printdebug("invalid (function) type passed in declaration list in dblock", @2.first_line, @2.first_column); - d = TYPE_FUNCTION_TYPE; + d = TYPE_FUNCTION_DECLARATION; CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } else if(d == TYPE_ARRAY_TYPE){ diff --git a/src/symbol_table.c b/src/symbol_table.c index 89d133a..1283d6a 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1124,11 +1124,11 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } if (getAdInfoType(entry) == TYPE_RECORD_TYPE) { char *recordAdInfo = (char *)malloc(100); - sprintf(recordAdInfo, " elements-%d", getRecLength(entry)); + sprintf(recordAdInfo, " elements-%d size-%d bytes", getRecLength(entry), getRecTotal(entry)); if (parentScopeNum == 0) { - st_fprint(file_ptr, getName(entry), currentScopeNum, -100, "record type", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " record type", recordAdInfo); } else { - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, "record type", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, " record type", recordAdInfo); } } @@ -1136,15 +1136,15 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { char *recordAdInfo = (char *)malloc(100); sprintf(recordAdInfo, " elements-%d", getRecLength(entry)); if (parentScopeNum == 0) { - st_fprint(file_ptr, getName(entry), currentScopeNum, -100, "record instance", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, getType(entry), "record instance"); } else { - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, "record instance", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, getType(entry), "record instance"); } } if (getAdInfoType(entry) == TYPE_PRIMITIVE) { char *primAdInfo = (char *)malloc(100); - sprintf(primAdInfo, " size-%d bytes", getPrimSize(entry)); + sprintf(primAdInfo, " size-%d bytes", getPrimSize(getTypeEntry(entry))); if (parentScopeNum == 0) { st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " Primitive", primAdInfo); } else { @@ -1169,9 +1169,9 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) { if (parentScopeNum == 0) { - st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " Function", " Function Declaration"); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, getType(entry), " Function Definition"); } else { - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, " Function", " Function Declaration"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, getType(entry), " Function Definition"); } } From 3e1e159561443ac2bfb275ec0b3e28cd6f9947df Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 11 Apr 2025 15:45:33 -0400 Subject: [PATCH 099/137] starting to work on grammar fixes --- src/grammar.y | 14 ++++++++------ src/symbol_table.c | 15 ++++++++++++++- src/symbol_table.h | 3 ++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 651c5ae..24b7d15 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -174,14 +174,15 @@ definition: } L_PAREN { TableNode * parameter = getParameter(getTypeEntry(table_lookup(getAncestor(cur), $1))); //TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); - printdebug("parameter type: %s", getType(parameter)); + printdebug("type of parameter: %s", getName(parameter)); if (parameter == undefined) { printdebug("[TYPE CHECK] function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); - }else if(getAdInfoType(parameter) != TYPE_RECORD){ - int type_of_param_type = getAdInfoType(parameter); + }else if(getAdInfoType(parameter) != TYPE_RECORD_TYPE){ + int type_of_param_type = getAdInfoType(parameter);//this is an enum value defined in symbol_table.h if( type_of_param_type == TYPE_UNDEFINED || type_of_param_type == TYPE_FUNCTION_DECLARATION || type_of_param_type == TYPE_ARRAY + || type_of_param_type == TYPE_PRIMITIVE || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused @@ -355,7 +356,7 @@ declaration: printdebug("ID/TYPE: %s, ID: %s", getName((TableNode*)$1), $3) ; int d = getAdInfoType((TableNode*)$1); if(d == TYPE_UNDEFINED) { - printdebug("undefined type at line %d and column %d", @2.first_line, @2.first_column); + printdebug("[TYPE CHECK] undefined type at line %d and column %d", @2.first_line, @2.first_column); CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } else if(d == TYPE_FUNCTION_TYPE) { @@ -373,11 +374,12 @@ declaration: d = TYPE_RECORD; CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } - else if(d == TYPE_PRIMITIVE){ + else if(d == TYPE_PRIMITIVE_TYPE){ printdebug("primitive variable at line %d and column %d", @2.first_line, @2.first_column); + d = TYPE_PRIMITIVE; CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); }else { - printdebug("other invalid type passed at %d and column %d", @2.first_line, @2.first_column); + printdebug("[TYPE CHECK] other invalid type passed at %d and column %d", @2.first_line, @2.first_column); CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } } diff --git a/src/symbol_table.c b/src/symbol_table.c index 1283d6a..60752bd 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1142,6 +1142,19 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } } + if (getAdInfoType(entry) == TYPE_PRIMITIVE_TYPE) { + char *primAdInfo = (char *)malloc(100); + sprintf(primAdInfo, " size-%d bytes", getPrimSize(getTypeEntry(entry))); + if (parentScopeNum == 0) { + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " Primitive Type", primAdInfo); + } else { + //printdebug("%sTHIS ONE", COLOR_RED); + printTableNode(entry); + char *primType = (char *)malloc(sizeof(getType(entry) + 1)); + sprintf(primType, " %s", getType(entry)); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, primType, primAdInfo); + } + } if (getAdInfoType(entry) == TYPE_PRIMITIVE) { char *primAdInfo = (char *)malloc(100); sprintf(primAdInfo, " size-%d bytes", getPrimSize(getTypeEntry(entry))); @@ -1152,7 +1165,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { printTableNode(entry); char *primType = (char *)malloc(sizeof(getType(entry) + 1)); sprintf(primType, " %s", getType(entry)); - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, primType, primAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, getType(entry), "Primitive Instance"); } } diff --git a/src/symbol_table.h b/src/symbol_table.h index af2d827..5f04f7c 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -79,7 +79,8 @@ typedef enum { TYPE_UNDEFINED = 8, TYPE_RECORD = 9, TYPE_ARRAY = 10, - TYPE_SYSTEM_DEFINED = 11 + TYPE_SYSTEM_DEFINED = 11, + TYPE_PRIMITIVE_TYPE = 12 } types; AdInfo *CreatePrimitiveInfo(int size); From 55bc098de5cf080845e06dc03cafd5c6af12116c Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 11 Apr 2025 16:28:16 -0400 Subject: [PATCH 100/137] edited function definitions --- src/grammar.y | 41 ++++++++++++++++------ tests/sprint2/test/sp2_carls_mistake.alpha | 2 +- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 24b7d15..579ebd5 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -185,6 +185,7 @@ definition: || type_of_param_type == TYPE_PRIMITIVE || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED + || type_of_param_type == TYPE_RECORD || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused printdebug("[TYPE CHECK] type of parameter being passed in to function definition is %s which is invalid", getAdInfo(parameter)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases @@ -192,7 +193,15 @@ definition: if(type_of_param_type == TYPE_UNDEFINED){ CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); } else { - CreateEntry(cur, getAdInfoType(parameter), parameter,NULL, getAdInfo(parameter)); + if(type_of_param_type == TYPE_FUNCTION_TYPE){ + CreateEntry(cur, TYPE_FUNCTION_DECLARATION, parameter,NULL, getAdInfo(parameter)); + } + if(type_of_param_type == TYPE_ARRAY_TYPE){ + CreateEntry(cur, TYPE_ARRAY, parameter,NULL, getAdInfo(parameter)); + } + if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ + CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter)); + } } } else { for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ @@ -200,22 +209,32 @@ definition: if( type_of_param_type == TYPE_UNDEFINED || type_of_param_type == TYPE_FUNCTION_DECLARATION || type_of_param_type == TYPE_ARRAY + || type_of_param_type == TYPE_PRIMITIVE || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED + || type_of_param_type == TYPE_RECORD || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("[TYPE CHECK] type of parameter being passed in to AS function definition is %s which is invalid", getName(entry)); + printdebug("[TYPE CHECK] type of parameter (if record) inside record being passed in to function definition is %s which is invalid", getAdInfo(parameter)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ - printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); + printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); + } + if(type_of_param_type == TYPE_UNDEFINED){ + CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); + } else { + if(type_of_param_type == TYPE_FUNCTION_TYPE){ + CreateEntry(cur, TYPE_FUNCTION_DECLARATION, entry,NULL, getAdInfo(entry)); + } + if(type_of_param_type == TYPE_ARRAY_TYPE){ + CreateEntry(cur, TYPE_ARRAY, entry,NULL, getAdInfo(entry)); + } + if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ + CreateEntry(cur, TYPE_PRIMITIVE, entry,NULL, getAdInfo(entry)); + } + /*printdebug("creating entry of type %s for function", getType(entry)); + CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ + } } - if(type_of_param_type == TYPE_UNDEFINED){ - CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); - } else { - CreateEntry(cur,type_of_param_type, entry, NULL, getAdInfo(entry)); - /*printdebug("creating entry of type %s for function", getType(entry)); - CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ - } - } } } idlist { printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$5); diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index c85c310..45d53c3 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -5,7 +5,7 @@ type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer type arr: 1 -> integer - +type w : rec function foo: T1 function bar1: T2 function bar2: T2 From e8bad449493a8ff8f0dbc667a79420a840ee3e8a Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 11 Apr 2025 16:37:57 -0400 Subject: [PATCH 101/137] fixed print symbol table and added primitive types --- src/symbol_table.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 60752bd..ae81eb8 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -692,11 +692,11 @@ SymbolTable *init(SymbolTable *start) { stri->additionalinfo = CreateArrayInfo(1, chara); boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); - integ->tag = TYPE_PRIMITIVE; // explicitly set the type for integ - addr->tag = TYPE_PRIMITIVE; // explicitly set the type for addr - chara->tag = TYPE_PRIMITIVE; // explicitly set the type for chara + integ->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for integ + addr->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for addr + chara->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for chara stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri - boo->tag = TYPE_PRIMITIVE; // explicitly set the type for boo + boo->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for boo // addr->additionalinfo = CreatePrimitiveInfo(8); start->Line_Number = 1; @@ -1144,7 +1144,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getAdInfoType(entry) == TYPE_PRIMITIVE_TYPE) { char *primAdInfo = (char *)malloc(100); - sprintf(primAdInfo, " size-%d bytes", getPrimSize(getTypeEntry(entry))); + sprintf(primAdInfo, " size-%d bytes", getPrimSize(entry)); if (parentScopeNum == 0) { st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " Primitive Type", primAdInfo); } else { From 3fc7a6371a9abe377fea41f1f8a473f7b24d3aab Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 11 Apr 2025 19:00:24 -0400 Subject: [PATCH 102/137] have to finish idlist rules --- src/grammar.y | 25 +++++++++++-- src/symbol_table.c | 36 +++++++++++-------- src/symbol_table.h | 1 + .../sprint3/test/sp3_record_size_check.alpha | 2 ++ 4 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 tests/sprint3/test/sp3_record_size_check.alpha diff --git a/src/grammar.y b/src/grammar.y index 579ebd5..dfc8db3 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -21,6 +21,7 @@ void yyerror(const char *err); int token_tracker; TableNode * tn; + int counter; %} %union { @@ -137,6 +138,8 @@ definition: //We are scanning through the dblock scope to get the length of the dblock (num of elements) from getRecSize //and then putting it in the entry that we created above. setRecSize(look_up(getParent(cur), $2), getRecSize(cur)); + //putting in all the offsets + setRecOffsetInfo(cur, look_up(getParent(cur),$2)); printdebug("Moving up a scope after seeing a record definition"); cur = getParent(cur); } @@ -236,6 +239,8 @@ definition: } } } + counter = 0; + printdebug("Created a new scope after seeing a function definition"); } idlist { printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$5); } R_PAREN ASSIGN sblock //check sblock type @@ -273,7 +278,15 @@ function_declaration: idlist: ID { + counter ++; TableNode *entry = getFirstEntry(cur); + int count = 1; + while(count largest) { largest = s; @@ -222,7 +222,7 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { counter++; this = getNextEntry(this); } - else if(getAdInfoType(this) == TYPE_ARRAY_TYPE){ + else if(getAdInfoType(this) == TYPE_ARRAY){ int s = 8; if (s > largest) { largest = s; @@ -237,12 +237,14 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { counter++; this = getNextEntry(this); } - else if(getAdInfoType(this) == TYPE_RECORD_TYPE){ - int s = getRecTotal(this); + else if((getAdInfoType(this) == TYPE_RECORD) && (node != getTypeEntry(this))){ + int s = getRecTotal(getTypeEntry(this)); if (s > largest) { largest = s; } //make sure current location is aligned properly + printTableNode(this); + printTableNode(node); offsets[counter] = (total_size % s); total_size = total_size + offsets[counter]; counter++; @@ -253,7 +255,7 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { this = getNextEntry(this); } else if(getAdInfoType(this) == TYPE_PRIMITIVE){ - int s = getPrimSize(this); + int s = getPrimSize(getTypeEntry(this)); if (s > largest) { largest = s; } @@ -1049,8 +1051,12 @@ TableNode *look_up(SymbolTable *table, char *x) { } int col_widths[5] = {30, 8, 8, 35, 35}; -void printline(FILE *file_ptr); -void printline(FILE *file_ptr) { +void printline(FILE *file_ptr, bool b); +void printline(FILE *file_ptr, bool b) { + if (b) { + fprintf(file_ptr, "oop\n"); + } + for (int i = 0; i < 5; i++) { for (int ii = 0; ii < col_widths[i]; ii++) { fprintf(file_ptr, "-"); @@ -1095,7 +1101,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } TableNode *entry = table->entries; - printline(file_ptr); + printline(file_ptr, false); int parentScopeNum = 0; int currentScopeNum = 0; @@ -1213,7 +1219,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } if (getParent(table) == NULL) { - printline(file_ptr); + printline(file_ptr, true); } } // get top most symbol table diff --git a/src/symbol_table.h b/src/symbol_table.h index 5f04f7c..6a33974 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -111,6 +111,7 @@ char *getType(TableNode *tn); char *getName(TableNode *tn); int getLine(SymbolTable *st); int getColumn(SymbolTable *st); +TableNode *getTypeEntry(TableNode *tn); TableNode *addName(TableNode *tn, char *str); SymbolTable *setLineNumber(SymbolTable *st, int line); SymbolTable *setColumnNumber(SymbolTable *st, int column); diff --git a/tests/sprint3/test/sp3_record_size_check.alpha b/tests/sprint3/test/sp3_record_size_check.alpha new file mode 100644 index 0000000..a6217fe --- /dev/null +++ b/tests/sprint3/test/sp3_record_size_check.alpha @@ -0,0 +1,2 @@ +type tom : [integer : x; integer: y] +type rec : [integer : x; tom : prev; character : c; character : d; Boolean: b; integer : y] \ No newline at end of file From 3baa95288a5c1e4cec342471940440c4dea28da8 Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 14 Apr 2025 02:01:51 -0400 Subject: [PATCH 103/137] fixed issue with not printing array instances in symbol table --- src/grammar.y | 179 +++++++++++++++------------- src/symbol_table.c | 11 ++ tests/sprint2/test/sp2_llnode.alpha | 6 +- 3 files changed, 108 insertions(+), 88 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index dfc8db3..79ff3db 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -21,7 +21,7 @@ void yyerror(const char *err); int token_tracker; TableNode * tn; - int counter; +// int counter; %} %union { @@ -159,29 +159,57 @@ definition: CreateEntry(cur,TYPE_FUNCTION_TYPE,funtypeprime,$2,CreateFunctionTypeInfo((TableNode*)$4 ,(TableNode*)$6)); } - | ID { - TableNode *node = table_lookup(getAncestor(cur), $1); - if (node == undefined) { + | ID { + printdebug("see function def rule 1\n"); + TableNode *node = table_lookup(getAncestor(cur), $1); + if (node == undefined) { - printdebug(" [TYPE CHECK] undefined nodedeclared at line %d, column %d", @1.first_line, @1.first_column); - }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printdebug("[TYPE CHECK] not a valid function declaration at line %d, column %d", @1.first_line, @1.first_column); - } - else { - printdebug("setting as keyword to true"); - setStartLine(node, @1.first_line); - setAsKeyword(node, true); - } - cur = CreateScope(cur, 0, 0); - printdebug("Created a new scope"); + printdebug(" [TYPE CHECK] undefined nodedeclared at line %d, column %d", @1.first_line, @1.first_column); + }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ + printdebug("[TYPE CHECK] not a valid function declaration at line %d, column %d", @1.first_line, @1.first_column); + } + else { + printdebug("setting as keyword to true"); + setStartLine(node, @1.first_line); + setAsKeyword(node, true); + } + cur = CreateScope(cur, 0, 0); + printdebug("Created a new scope"); } L_PAREN { TableNode * parameter = getParameter(getTypeEntry(table_lookup(getAncestor(cur), $1))); //TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); printdebug("type of parameter: %s", getName(parameter)); - if (parameter == undefined) { - printdebug("[TYPE CHECK] function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); - }else if(getAdInfoType(parameter) != TYPE_RECORD_TYPE){ - int type_of_param_type = getAdInfoType(parameter);//this is an enum value defined in symbol_table.h + if (parameter == undefined) { + printdebug("[TYPE CHECK] function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); + }else if(getAdInfoType(parameter) != TYPE_RECORD_TYPE){ + int type_of_param_type = getAdInfoType(parameter);//this is an enum value defined in symbol_table.h + if( type_of_param_type == TYPE_UNDEFINED + || type_of_param_type == TYPE_FUNCTION_DECLARATION + || type_of_param_type == TYPE_ARRAY + || type_of_param_type == TYPE_PRIMITIVE + || type_of_param_type == TYPE_ALL_ELSE + || type_of_param_type == TYPE_SYSTEM_DEFINED + || type_of_param_type == TYPE_RECORD + || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused + printdebug("[TYPE CHECK] type of parameter being passed in to function definition is %s which is invalid", getAdInfo(parameter)); + type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases + } + if(type_of_param_type == TYPE_UNDEFINED){ + CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); + } else { + if(type_of_param_type == TYPE_FUNCTION_TYPE){ + CreateEntry(cur, TYPE_FUNCTION_DECLARATION, parameter,NULL, getAdInfo(parameter)); + } + if(type_of_param_type == TYPE_ARRAY_TYPE){ + CreateEntry(cur, TYPE_ARRAY, parameter,NULL, getAdInfo(parameter)); + } + if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ + CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter)); + } + } + } else { + for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ + int type_of_param_type = getAdInfoType(entry); if( type_of_param_type == TYPE_UNDEFINED || type_of_param_type == TYPE_FUNCTION_DECLARATION || type_of_param_type == TYPE_ARRAY @@ -190,60 +218,31 @@ definition: || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_RECORD || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("[TYPE CHECK] type of parameter being passed in to function definition is %s which is invalid", getAdInfo(parameter)); + printdebug("[TYPE CHECK] type of parameter (if record) inside record being passed in to function definition is %s which is invalid", getAdInfo(parameter)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases + }else{ + printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); } if(type_of_param_type == TYPE_UNDEFINED){ CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); } else { if(type_of_param_type == TYPE_FUNCTION_TYPE){ - CreateEntry(cur, TYPE_FUNCTION_DECLARATION, parameter,NULL, getAdInfo(parameter)); + CreateEntry(cur, TYPE_FUNCTION_DECLARATION, entry,NULL, getAdInfo(entry)); } if(type_of_param_type == TYPE_ARRAY_TYPE){ - CreateEntry(cur, TYPE_ARRAY, parameter,NULL, getAdInfo(parameter)); + CreateEntry(cur, TYPE_ARRAY, entry,NULL, getAdInfo(entry)); } if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ - CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter)); - } - } - } else { - for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ - int type_of_param_type = getAdInfoType(entry); - if( type_of_param_type == TYPE_UNDEFINED - || type_of_param_type == TYPE_FUNCTION_DECLARATION - || type_of_param_type == TYPE_ARRAY - || type_of_param_type == TYPE_PRIMITIVE - || type_of_param_type == TYPE_ALL_ELSE - || type_of_param_type == TYPE_SYSTEM_DEFINED - || type_of_param_type == TYPE_RECORD - || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("[TYPE CHECK] type of parameter (if record) inside record being passed in to function definition is %s which is invalid", getAdInfo(parameter)); - type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases - }else{ - printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); - } - if(type_of_param_type == TYPE_UNDEFINED){ - CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); - } else { - if(type_of_param_type == TYPE_FUNCTION_TYPE){ - CreateEntry(cur, TYPE_FUNCTION_DECLARATION, entry,NULL, getAdInfo(entry)); - } - if(type_of_param_type == TYPE_ARRAY_TYPE){ - CreateEntry(cur, TYPE_ARRAY, entry,NULL, getAdInfo(entry)); - } - if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ - CreateEntry(cur, TYPE_PRIMITIVE, entry,NULL, getAdInfo(entry)); - } + CreateEntry(cur, TYPE_PRIMITIVE, entry,NULL, getAdInfo(entry)); + } /*printdebug("creating entry of type %s for function", getType(entry)); CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ - } - } + } } - counter = 0; + } + //counter = 0; printdebug("Created a new scope after seeing a function definition"); - } idlist { - printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$5); - } R_PAREN ASSIGN sblock //check sblock type + } idlist R_PAREN ASSIGN sblock //check sblock type ; @@ -278,24 +277,31 @@ function_declaration: idlist: ID { - counter ++; + printdebug("idlist rule 1 ID: %s", $1); TableNode *entry = getFirstEntry(cur); - int count = 1; - while(counttheName == NULL){ + addName(entry, $1); + printdebug("name added to entry of type %s is %s in function parameter scope",getType(entry), $1); + } else { + printdebug("undefined types passed in to function scope. Improper."); + addName(entry, $1); } - addName(entry, $1); - printdebug("name added to entry is %s", $1); printTableNode(entry); + //while (strcmp(getName(entry),"undefined") != 0) { + // entry = getNextEntry(entry); + //} + //if (getNextEntry(entry) == NULL) { + // printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column); + //} + //addName(entry, $1); + //printdebug("name added to entry is %s", $1); + //printTableNode(entry); } COMMA idlist { @@ -303,22 +309,25 @@ idlist: } | ID - { - counter ++; + { printdebug("idlist rule 2 ID: %s", $1); TableNode *entry = getFirstEntry(cur); - int count = 1; - while(count1); - $$ = 1; + else if(entry->theName == NULL){ + addName(entry, $1); + printdebug("name added to entry of type %s is %s in function parameter scope",getType(entry), $1); + } else { + printdebug("undefined types passed in to function scope. Improper."); + addName(entry, $1); + } + printTableNode(entry); + printdebug("Name of entry is now %s", getName(entry)); + printdebug("Type of entry is %s", getType(entry)); + printdebug("tag is %d", getAdInfoType(entry)); } ; @@ -375,7 +384,7 @@ dblock: setColumnNumber(cur,@1.first_line); printdebug("Did not create a new scope when saw dblock, set line number to %d instead", @1.first_line); } else{ - cur = CreateScope(cur,@1.first_line,@1.first_column); // <----- What is this? + //cur = CreateScope(cur,@1.first_line,@1.first_column); // <----- What is this? printdebug("Created a new scope when seeing a dblock"); } } diff --git a/src/symbol_table.c b/src/symbol_table.c index 7cd8b01..5370912 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1128,6 +1128,17 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, arrayType, " Type of Array"); } } + if (getAdInfoType(entry) == TYPE_ARRAY) { + char *arrayType = (char *)malloc(100); + sprintf(arrayType, " %d -> %s", getNumArrDim(entry), + getName(getArrType(entry))); + + if (parentScopeNum == 0) { + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, getType(entry), " Array Instance"); + } else { + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, getType(entry), " Array Instance"); + } + } if (getAdInfoType(entry) == TYPE_RECORD_TYPE) { char *recordAdInfo = (char *)malloc(100); sprintf(recordAdInfo, " elements-%d size-%d bytes", getRecLength(entry), getRecTotal(entry)); diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index 08048a7..b102ba8 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -47,11 +47,11 @@ foo (x) := { return x * x; } -bar1 (a) := { - return a.x * a.y; +bar1(a,b) := { + return a * b; } -bar2 as (r,s) := { +bar2(r,s) := { if (r < s) then { while (!(r < s)) { r := r + 1; From 5c6ab345183ff646b8ba3fe28eab2ca1106aa10f Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 14 Apr 2025 11:43:49 -0400 Subject: [PATCH 104/137] fixed issue with records being size of their reference (8 bytes) not their actual total --- src/symbol_table.c | 14 ++++++++------ tests/sprint2/test/sp2_llnode.alpha | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/symbol_table.c b/src/symbol_table.c index 5370912..897d787 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -182,8 +182,9 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { largest = 8; counter++; } - else if((getAdInfoType(this) == TYPE_RECORD) && (node != getTypeEntry(this))){ - offsets[counter] = getRecTotal(getTypeEntry(this)); + else if((getAdInfoType(this) == TYPE_RECORD)){ + offsets[counter] = 8; + printf("hitting record and adding to largest"); total_size = total_size + offsets[counter]; largest = offsets[counter]; counter++; @@ -202,7 +203,8 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { } else { printdebug( - "[TYPE CHECK] passed an invalid (first) parameter to a function definition. seeing %d",getAdInfoType(this)); + "[TYPE CHECK] passed an invalid (first) parameter to a function definition. seeing %d. Type of entry is %s. Name attempted to pass is %s.",getAdInfoType(this),getType(this),getName(this)); + return undefined; } this = getNextEntry(this); @@ -237,8 +239,8 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { counter++; this = getNextEntry(this); } - else if((getAdInfoType(this) == TYPE_RECORD) && (node != getTypeEntry(this))){ - int s = getRecTotal(getTypeEntry(this)); + else if((getAdInfoType(this) == TYPE_RECORD)){ + int s = 8; if (s > largest) { largest = s; } @@ -1365,7 +1367,7 @@ TableNode *getNextEntry(TableNode *tn) { // Uses pointers to the table node to print the info TableNode *printTableNode(TableNode *tn) { if (DEBUG == 0) { - return tn; + return tn; } if (tn == NULL) { diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index b102ba8..31f0c2b 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -48,6 +48,7 @@ foo (x) := { } bar1(a,b) := { + [integer : t] return a * b; } From f2db338257b93f91f9853397419e6dbcc471cb7d Mon Sep 17 00:00:00 2001 From: Partho Date: Mon, 14 Apr 2025 12:33:52 -0400 Subject: [PATCH 105/137] fixed type check issues with records as params --- src/grammar.y | 29 +++++++++++++++++------------ tests/sprint2/test/sp2_llnode.alpha | 1 - 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 79ff3db..b10933b 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -208,32 +208,37 @@ definition: } } } else { + printdebug("record found"); for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ int type_of_param_type = getAdInfoType(entry); if( type_of_param_type == TYPE_UNDEFINED - || type_of_param_type == TYPE_FUNCTION_DECLARATION - || type_of_param_type == TYPE_ARRAY - || type_of_param_type == TYPE_PRIMITIVE + || type_of_param_type == TYPE_FUNCTION_TYPE + || type_of_param_type == TYPE_ARRAY_TYPE + || type_of_param_type == TYPE_PRIMITIVE_TYPE || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED - || type_of_param_type == TYPE_RECORD + || type_of_param_type == TYPE_RECORD_TYPE || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("[TYPE CHECK] type of parameter (if record) inside record being passed in to function definition is %s which is invalid", getAdInfo(parameter)); + printdebug("[TYPE CHECK] type of parameter (if record) inside record being passed in to function definition is %s which is invalid", getType(entry)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ - printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getName(entry)); + printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getType(entry)); } if(type_of_param_type == TYPE_UNDEFINED){ + printdebug("undefined type of parameter inside record"); CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); } else { - if(type_of_param_type == TYPE_FUNCTION_TYPE){ - CreateEntry(cur, TYPE_FUNCTION_DECLARATION, entry,NULL, getAdInfo(entry)); + if(type_of_param_type == TYPE_FUNCTION_DECLARATION){ + printdebug("function declaration of parameter inside record"); + CreateEntry(cur, TYPE_FUNCTION_DECLARATION, getTypeEntry(entry),NULL, getAdInfo(entry)); } - if(type_of_param_type == TYPE_ARRAY_TYPE){ - CreateEntry(cur, TYPE_ARRAY, entry,NULL, getAdInfo(entry)); + if(type_of_param_type == TYPE_ARRAY){ + printdebug("array type of parameter inside record"); + CreateEntry(cur, TYPE_ARRAY, getTypeEntry(entry),NULL, getAdInfo(entry)); } - if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ - CreateEntry(cur, TYPE_PRIMITIVE, entry,NULL, getAdInfo(entry)); + if(type_of_param_type == TYPE_PRIMITIVE){ + printdebug("primitive type of parameter inside record"); + CreateEntry(cur, TYPE_PRIMITIVE, getTypeEntry(entry),NULL, getAdInfo(entry)); } /*printdebug("creating entry of type %s for function", getType(entry)); CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index 31f0c2b..b102ba8 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -48,7 +48,6 @@ foo (x) := { } bar1(a,b) := { - [integer : t] return a * b; } From ccc3c57f1cbc2d8e061d44626b85eb708ff56820 Mon Sep 17 00:00:00 2001 From: Annie Date: Mon, 14 Apr 2025 21:36:52 -0400 Subject: [PATCH 106/137] got rid of invalid typ declaration --- tests/sprint2/test/sp2_carls_mistake.alpha | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index 45d53c3..26b8725 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -1,11 +1,11 @@ -type main: string -> integer -function entry: main - type rec: [integer: x; integer: y] + type T1: integer -> integer type T2: rec -> integer type arr: 1 -> integer -type w : rec + +type main: string -> integer +function entry: main function foo: T1 function bar1: T2 function bar2: T2 From 06db19042839c12de6a011f576ba41df94046d88 Mon Sep 17 00:00:00 2001 From: Annie Date: Mon, 14 Apr 2025 21:37:37 -0400 Subject: [PATCH 107/137] added array so test uses array instead of address --- tests/sprint2/test/sp2_integer_binary_op.alpha | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/sprint2/test/sp2_integer_binary_op.alpha b/tests/sprint2/test/sp2_integer_binary_op.alpha index 856224f..2dfeb73 100644 --- a/tests/sprint2/test/sp2_integer_binary_op.alpha +++ b/tests/sprint2/test/sp2_integer_binary_op.alpha @@ -1,8 +1,9 @@ type main: string -> integer function entry: main +type testarr : 1 -> integer entry (arg) := { - [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] + [integer:x; testarr: arr; testarr: arr2; Boolean : b2; Boolean : b1] x := 3 + 2 * 8; x := 3 - 2 / 8; From 2b1557b52c1b543a5734c6dfa70559b2f3c11ac2 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 15 Apr 2025 00:53:03 -0400 Subject: [PATCH 108/137] worked on function call return type check and started checking return type --- src/grammar.y | 101 ++++++++++++++++---- tests/sprint2/test/sp2_sp2_arrayargs.alpha | 16 ++++ tests/sprint2/test/sp2_sp2_arrayargs.alpha~ | 16 ++++ tests/sprint3/test/sp3_multiple_args.alpha | 17 ++++ tests/sprint3/test/sp3_multiple_args.alpha~ | 17 ++++ 5 files changed, 150 insertions(+), 17 deletions(-) create mode 100644 tests/sprint2/test/sp2_sp2_arrayargs.alpha create mode 100644 tests/sprint2/test/sp2_sp2_arrayargs.alpha~ create mode 100644 tests/sprint3/test/sp3_multiple_args.alpha create mode 100644 tests/sprint3/test/sp3_multiple_args.alpha~ diff --git a/src/grammar.y b/src/grammar.y index b10933b..ab9e3a2 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -32,12 +32,17 @@ %locations + %type idlist %type assignable %type expression %type constant %type id_or_types %type types +%type sblock +%type compound_statement +%type simple_statement +%type statement_list %type argument_list %type ablock %token ID 101 @@ -100,6 +105,7 @@ %precedence DOT %precedence RESERVE RELEASE + %% program: @@ -247,7 +253,16 @@ definition: } //counter = 0; printdebug("Created a new scope after seeing a function definition"); - } idlist R_PAREN ASSIGN sblock //check sblock type + } idlist R_PAREN ASSIGN sblock { + TableNode *expected = getReturn(getTypeEntry(look_up(cur, $1))); + if ($8 == undefined) { + printdebug("sblock return type is undefined"); + } else if ($8 != expected) { + printdebug("expected %s as return type but got %s", getName(expected), getName($8)); + } else { + printdebug("CORRECT RETURN TYPE!!!"); + } + } ; @@ -350,6 +365,7 @@ sblock: } statement_list { + $$ = $3; printdebug("Moving up a scope after seeing sblock"); cur = getParent(cur); } @@ -374,6 +390,7 @@ sblock: { printdebug("Moving up a scope after seeing sblock with dblock"); cur = getParent(cur); + $$ = $5; } R_BRACE ; @@ -458,18 +475,59 @@ id_or_types: statement_list: - compound_statement statement_list - | compound_statement - | simple_statement SEMI_COLON statement_list - | simple_statement SEMI_COLON +compound_statement statement_list { + if ($1 == undefined && $2 != undefined) { + $$ = $2; + } else if ($1 != undefined && $2 == undefined) { + $$ = $1; + } else if ($1 == $2) { + $$ = $1; + } else { + printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + $$ = undefined; + } +} + | compound_statement { + $$ = $1; + } + | simple_statement SEMI_COLON statement_list{ + if ($1 == undefined && $3 != undefined) { + $$ = $3; + } else if ($1 != undefined && $3 == undefined) { + $$ = $1; + } else if ($1 == $3) { + $$ = $1; + } else { + printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + $$ = undefined; + } + } + | simple_statement SEMI_COLON { + $$ = $1; + } ; compound_statement: - WHILE L_PAREN expression R_PAREN sblock - | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock - | sblock +WHILE L_PAREN expression R_PAREN sblock { + $$ = $5; +} + | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock { + if ($6 == undefined && $8 != undefined) { + $$ = $8; + } else if ($6 != undefined && $8 == undefined) { + $$ = $6; + } else if ($6 == $8) { + $$ = $6; + } else { + printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + $$ = undefined; + } + } + | sblock { + $$ = $1; + } ; @@ -517,9 +575,11 @@ simple_statement: printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType(left), getType(right), COLOR_WHITE); printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(left)); } + + $$ = undefined; } - | RETURN expression +| RETURN expression {$$ = $2;} ; @@ -697,6 +757,7 @@ expression: else if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE|| getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE|| getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE_TYPE || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ printdebug("assignable passing up to expression is array type, record type, function type, or function declaration"); $$= ((TableNode*)$1); @@ -751,20 +812,20 @@ assignable: printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", getName((TableNode*)$1)); - if (type == TYPE_FUNCTION_DECLARATION) { + if (type == TYPE_FUNCTION_TYPE) { printdebug("%sEntering function call", COLOR_LIGHTGREEN); if (look_up(getParent(cur), getName((TableNode*)$1))->additionalinfo->FunDecAdInfo->regularoras) { printdebug("as function"); //char *funtype = getType(look_up(cur, $1)); - printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); +// printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); - TableNode * typeNode = table_lookup(getAncestor(cur), getType((TableNode*)$1)); + TableNode * typeNode = $1; TableNode *param = getParameter(typeNode); printTableNode(param); - if (getAdInfoType(param) == TYPE_RECORD) { + if (getAdInfoType(param) == TYPE_RECORD_TYPE) { SymbolTable *recList = getRecList(param); TableNode *lastCheckedRef = getFirstEntry(recList); TableNode *lastCheckedAct = getFirstEntry(cur); @@ -772,12 +833,14 @@ assignable: lastCheckedRef = getNextEntry(lastCheckedRef); } - + if ($3 != getRecLength(param)) { + printdebug("expected %d arguments but got %d", getRecLength(param), $3); + } //this isn't very efficient, but will hopefully work while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) { + if (getTypeEntry(lastCheckedRef) != getTypeEntry(lastCheckedAct)) { printdebug("expected %s. expression in function call got %s. at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); - printdebug("%d", strcmp(getName(lastCheckedAct), getName(lastCheckedRef))); + } lastCheckedAct = getNextEntry(lastCheckedAct); TableNode *tn = getFirstEntry(recList); @@ -804,8 +867,12 @@ assignable: if (strcmp(expected, actual) != 0) { printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); } + if ($3 != 1) { + printdebug("expected 1 argument but got %d", $3); + } } - $$ = getReturn((table_lookup(getAncestor(cur), getType((TableNode*)$1)))); + printTableNode(getReturn($1)); + $$ = getReturn($1); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); } else if (type == TYPE_ARRAY_TYPE) { diff --git a/tests/sprint2/test/sp2_sp2_arrayargs.alpha b/tests/sprint2/test/sp2_sp2_arrayargs.alpha new file mode 100644 index 0000000..dfb0332 --- /dev/null +++ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha @@ -0,0 +1,16 @@ +type string: 1 -> character +type a_of_s: 1 -> string + +(* maybe some other type definitions *) + +entry(arg) := { + [ string: one_name; string: another_name; a_of_s: many_names ] + another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) + many_names := reserve a_of_s(many_names); + many_names(0) := one_name; + many_names(1) := another_name; + many_names(2) := reserve a_of_s(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) + many_names(2)(0) := "P"; + + return 0; +} \ No newline at end of file diff --git a/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ new file mode 100644 index 0000000..ce1673d --- /dev/null +++ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ @@ -0,0 +1,16 @@ +type string: 1 -> character +type a_of_s: 1 -> string + +(* maybe some other type definitions *) + +entry(arg) := { + [ string: one_name; string: another_name; a_of_s: many_names ] + another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) + many_names := reserve a_of_s(3); + many_names(0) := one_name; + many_names(1) := another_name; + many_names(2) := reserve a_of_s(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) + many_names(2)(0) := "P"; + + return 0; +} \ No newline at end of file diff --git a/tests/sprint3/test/sp3_multiple_args.alpha b/tests/sprint3/test/sp3_multiple_args.alpha new file mode 100644 index 0000000..e59c4b6 --- /dev/null +++ b/tests/sprint3/test/sp3_multiple_args.alpha @@ -0,0 +1,17 @@ +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar2 (r,s) := { + return r; +} + +entry (arg) := { + [ integer: result ; rec: w] + result := bar('c', 7); + return 0; +} \ No newline at end of file diff --git a/tests/sprint3/test/sp3_multiple_args.alpha~ b/tests/sprint3/test/sp3_multiple_args.alpha~ new file mode 100644 index 0000000..641c654 --- /dev/null +++ b/tests/sprint3/test/sp3_multiple_args.alpha~ @@ -0,0 +1,17 @@ +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar2 (r,s) := { + return s; +} + +entry (arg) := { + [ integer: result ; rec: w] + result := bar('c', 7); + return 0; +} \ No newline at end of file From 8057060f2683801948a3e6bdb5f5fb3b8bf94c75 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 15 Apr 2025 01:40:18 -0400 Subject: [PATCH 109/137] fixed several small issues --- src/grammar.y | 9 ++++++--- src/symbol_table.c | 16 +++++++++------- tests/sprint2/test/sp2_simple.alpha | 2 +- tests/sprint3/test/sp3_record_size_check.alpha | 3 ++- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index ab9e3a2..4e2aa1d 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -365,11 +365,12 @@ sblock: } statement_list { - $$ = $3; + //$$ = $3; printdebug("Moving up a scope after seeing sblock"); cur = getParent(cur); } R_BRACE + {$$ = $3;} | L_BRACE { @@ -390,9 +391,10 @@ sblock: { printdebug("Moving up a scope after seeing sblock with dblock"); cur = getParent(cur); - $$ = $5; + //$$ = $5; } R_BRACE + {$$ = $5;} ; @@ -880,7 +882,8 @@ assignable: if (getNumArrDim(look_up(getParent(cur), getName((TableNode*)$1))) != $2) { printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $2, @2.first_line, @2.first_column); } - $$ = getArrType(look_up(getParent(cur), getName((TableNode*)$1))); + $$ = getArrType(look_up(cur, getName((TableNode*)$1))); + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); } cur = getParent(cur); diff --git a/src/symbol_table.c b/src/symbol_table.c index 897d787..4232c16 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -92,9 +92,10 @@ int getNumArrDim(TableNode *definition) { "function. Invalid."); return -1; } - if (strcmp(getType(definition), "array") != 0) { - printdebug("not checking the dim of an array -- invalid op"); - return 0; + if(getAdInfoType(definition) != TYPE_ARRAY_TYPE){ + printdebug( + "passed an invalid node to getNumArrDim. Seeing tag %d in getNumArrDim. Invalid.",getAdInfoType(definition)); + return -1; } return definition->additionalinfo->ArrayAdInfo->numofdimensions; } @@ -113,8 +114,9 @@ TableNode *getArrType(TableNode *definition) { "function. Invalid."); return undefined; } - if (strcmp(getType(definition), "array") != 0) { - printdebug("not checking the type of an array -- invalid op"); + if(getAdInfoType(definition) != TYPE_ARRAY_TYPE){ + printdebug( + "passed an invalid node to getArrType. Seeing tag %d. Invalid.",getAdInfoType(definition)); return undefined; } return definition->additionalinfo->ArrayAdInfo->typeofarray; @@ -1132,8 +1134,8 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } if (getAdInfoType(entry) == TYPE_ARRAY) { char *arrayType = (char *)malloc(100); - sprintf(arrayType, " %d -> %s", getNumArrDim(entry), - getName(getArrType(entry))); + //sprintf(arrayType, " %d -> %s", getNumArrDim(entry), + // getName(getArrType(entry))); if (parentScopeNum == 0) { st_fprint(file_ptr, getName(entry), currentScopeNum, -100, getType(entry), " Array Instance"); diff --git a/tests/sprint2/test/sp2_simple.alpha b/tests/sprint2/test/sp2_simple.alpha index 5f60c1b..825fdcd 100644 --- a/tests/sprint2/test/sp2_simple.alpha +++ b/tests/sprint2/test/sp2_simple.alpha @@ -2,6 +2,6 @@ type main: string -> integer function entry: main entry(arg) := { - [int : x] + [integer : x] return 0; } diff --git a/tests/sprint3/test/sp3_record_size_check.alpha b/tests/sprint3/test/sp3_record_size_check.alpha index a6217fe..8e123d0 100644 --- a/tests/sprint3/test/sp3_record_size_check.alpha +++ b/tests/sprint3/test/sp3_record_size_check.alpha @@ -1,2 +1,3 @@ type tom : [integer : x; integer: y] -type rec : [integer : x; tom : prev; character : c; character : d; Boolean: b; integer : y] \ No newline at end of file +type rec : [integer : x; tom : prev; character : c; character : d; Boolean: b; integer : y] +type tricky : [Boolean : b1; integer : k1; Boolean : b2; integer : k2] \ No newline at end of file From f8010f463b2e2af2b4c7b2b3c48d3b75b5d807c3 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Tue, 15 Apr 2025 10:59:38 -0400 Subject: [PATCH 110/137] latest version still not working #t51 --- src/intermediate_code.c | 103 ++++++++++++++++++++++++++++++---------- src/intermediate_code.h | 95 ++++++++++++++++++------------------ 2 files changed, 124 insertions(+), 74 deletions(-) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index c7938ec..cd967cc 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -4,13 +4,16 @@ Instruction * begin; Instruction * current; +char * temp = NULL; // TODO: this is here to bring your attention to the comment bellow. // check if start is NULL if it is assign it to the start globle variable // otherwise make it next of current and set cur to your instruction. -void emit_helper(void){ +TNodeOrConst * tn_or_const(Op op, RegConstUnion r); + +static void emit_helper(void){ Instruction * inst = calloc(1, sizeof(*inst)); if(begin == NULL){ begin = current = inst; @@ -23,7 +26,7 @@ void emit_helper(void){ } } - void emit_binary_op(TableNode * result, Op op, TableNode * arg1, TableNode * arg2){ +void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TableNode * arg2){ emit_helper(); current->opcode = op; current->result = result; @@ -32,7 +35,7 @@ void emit_helper(void){ return; } - void emit_unary_op(TableNode * result, Op op, TableNode * arg){ +void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ emit_helper(); current->opcode = op; current->result = result; @@ -40,11 +43,11 @@ void emit_helper(void){ return; } - void emit_assignment(char* target, char* source){ +void emit_assignment(TableNode * target, TNodeOrConst * source){ emit_helper(); - current->opcode = ADD; // TODO: replace with move - current->result = look_up(cur, target); - current->operand1 = look_up(cur, source); + current->opcode = E_ASSIGN; // TODO: replace with move + current->result = target; + current->operand1 = source; return; } @@ -60,48 +63,77 @@ void emit_as_file(FILE * out_file, Instruction * instr_arr){ void emit_label(char* label){ emit_helper(); - current->opcode = LABEL; + current->opcode = E_LABEL; current->label = label; return; } void emit_jump(char* label){ emit_helper(); - current->opcode = GOTO; + current->opcode = E_GOTO; current->label = label; return; } -void emit_conditional_jump(char* condition, char* label){ +void emit_conditional_jump(int count, ...){ + // it apears that I cant do what I want So we will have to deal with + // the limitations presented. + // arg_count is the number of args passed to the function + // from there the sequence is Op, char * , TableNode * , and an optional + // extra TableNode *. + // when this instruction is a conditional jump then ... is 1 + // when the inst is a cond with a Relational op then ... is 2 emit_helper(); - current->opcode = CGOTO; // I am positive this needs to be 2 instructions + va_list argptr; + va_start(argptr, count); + Op condition = va_arg(argptr, Op); + char * label = va_arg(argptr, char *); + current->opcode = condition; current->label = label; + TNodeOrConst * n1; + TableNode * n2; + switch (condition) { + case E_IF_X_TRUE: case E_IF_X_FALSE: + n1 = va_arg(argptr, TNodeOrConst *); + current->operand1 = n1; + break; + case E_LESSTHEN: case E_EQUALTO: + n1 = va_arg(argptr, TNodeOrConst *); + n2 = va_arg(argptr, TableNode *); + current->operand1 = n1; + current->operand2 = n2; + break; + } return; } - - -void emit_function_start(char* name){ +void emit_function_start(char * name){ emit_helper(); // actualy what is this? - current->opcode = LABLE; // I think this is right TODO: ask - current->label = name; + current->opcode = E_LABEL; // I think this is right TODO: ask + current->label = name; // wait what is a function start + // this is probabaly a func decleration return; } -void emit_parameter(char* param){ +void emit_parameter(TNodeOrConst * param){ emit_helper(); - current->opcode = PARAM; - current->operand1 = look_up(cur, param); + current->opcode = E_PARAM; + current->operand1 = param; return; } -void emit_function_call(char* result, char* name){ + +void emit_function_call(TableNode * result, int param_count, TableNode * name){ emit_helper(); - current->opcode = CALL; - current->operand1 = look_up(cur, name); - current->result = look_up(cur, result); + current->opcode = E_CALL; + TNodeOrConst * count = calloc(1, sizeof(*count)); + count->d = INTEGER; + count->rc_union->integer = param_count; + current->operand1 = count; + current->operand2 = name; + current->result = result; return; } -void emit_return(char* value){ +void emit_return(TNodeOrConst * value){ emit_helper(); - current->opcode = RETURN; - current->operand1 = look_up(cur, name); + current->opcode = E_RETURN; + current->operand1 = value; return; } void emit_reserve(char* result, char* type_name, int size){ @@ -115,11 +147,30 @@ void emit_release(char* pointer){ void emit_field_access(char* result, char* record, char* field){ + emit_helper(); return; } void emit_array_access(char* result, char* array, char* index, char* dimension){ + emit_helper(); return; } void emit_bounds_check(char* index, char* size, char* error_label){ + emit_helper(); return; } + + +// * Implement temp variable generator function that produces unique names (t1, t2, etc.) +char * temp_var_gen(){ + char * ret = calloc(9, sizeof(*ret)); + sprintf(ret, "$t%d", temp_count); + temp_count++; + return ret; +} + +char * lable_gen(){ + char * ret = calloc( 9, sizeof(*ret)); + sprintf(ret, "L_%d", label_count); + label_count++; + return ret; +} diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 6266b79..8b8edb5 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -1,48 +1,46 @@ // Track 1: Core Infrastructure & Basic Expressions -// * Create intermediate_code.h/.c defining the instruction structure: -// - Struct with fields for: opcode, result, operand1, operand2, label -// - Enum for all operation types (ADD, SUB, MUL, DIV, etc.) -// * Implement temp variable generator function that produces unique names (t1, t2, etc.) -// * Create specific code emission functions: -// - emit_binary_op(char* result, char* op, char* arg1, char* arg2) -// - emit_unary_op(char* result, char* op, char* arg) -// - emit_assignment(char* target, char* source) // * Add Bison actions for arithmetic expressions: // - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); // - Subtraction, multiplication, division, modulo #include "symbol_table.h" +#include // these are from page 364 typedef enum { - LABEL, // this is not in the book - ADD, // 1 from the list - SUB, // 1 - MUL, // 1 - DIV, // 1 - MOD, // 1 - OR, // 1 - AND, // 1 - NEG, // 2 - NOT, // 2 - ASSIGN, // 3 - GOTO, // 4 - CGOTO, // 5 - LESSTHEN, // 6 rule 1 + 5 - EQUALTO, // 6 rule 1 + 5 - CALL, // 7 - PARAM, // 7 - RETURN // 7 - - + E_LABEL = 10000, // this is not in the book + E_ADD, // 1 from the list + E_SUB, // 1 + E_MUL, // 1 + E_DIV, // 1 + E_MOD, // 1 + E_OR, // 1 + E_AND, // 1 + E_NEG, // 2 + E_NOT, // 2 + E_ASSIGN, // 3 + E_GOTO, // 4 + E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got + E_IF_X_TRUE, // 5 + E_IF_X_FALSE, // 5 + E_LESSTHEN, // 6 rule 1 + 5 + E_EQUALTO, // 6 rule 1 + 5 + E_CALL, // 7 + E_PARAM, // 7 + E_RETURN, // 7 + E_INDEX_COPY_RIGHT, // 8 + E_INDEX_COPY_LEFT, // 8 + E_ADDRESS_OF // 9 + /* for x = *y and *y = x we can just use index copy right and left with + index 0*/ } Op; typedef enum { - NODE, - INTEGER, - STRING, - CHARACTER, - ADDRESS, - BOOLEAN + NODE = 11000, // TableNode + INTEGER, // int + STRING, // char * + CHARACTER, // char + ADDRESS, // void * + BOOLEAN // bool } Discriminant; typedef union { @@ -52,39 +50,41 @@ typedef union { char character; void * address; bool Boolean; -} Register_union; +} RegConstUnion; typedef struct { Discriminant d; - Register_union r_union; + RegConstUnion * rc_union; } TNodeOrConst; +typedef struct Instruction Instruction; typedef struct Instruction { Op opcode; TableNode * result; - TableNode * operand1; + TNodeOrConst * operand1; TableNode * operand2; char * label; - int index; - Instruction * prev; Instruction * next; } Instruction; extern Instruction * begin; extern Instruction * current; +int temp_count = 0; +int label_count = 0; +bool code_gen = true; -void emit_binary_op(char* result, Op op, char* arg1, char* arg2); -void emit_unary_op(char* result, Op op, char* arg); -void emit_assignment(char* target, char* source); + +void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TableNode * arg2); +void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); +void emit_assignment(TableNode * target, TNodeOrConst * source); // TODO: Find out what these are suposed to do. Guess is create an entry in // the list of instructions. Guess is that its suposed to ret a struct ptr - // * Implement integer/boolean/character specific operation handling // TODO: Find out what this means. @@ -95,16 +95,15 @@ void emit_as_file(FILE * out_file, Instruction * instr_arr); void emit_label(char* label); void emit_jump(char* label); -void emit_conditional_jump(char* condition, char* label); +void emit_conditional_jump(int count, ...); void emit_function_start(char* name); -void emit_parameter(char* param); -void emit_function_call(char* result, char* name); -void emit_return(char* value); +void emit_parameter(TNodeOrConst * param); +void emit_function_call(TNodeOrConst * result, TNodeOrConst * name); +void emit_return(TNodeOrConst * value); void emit_reserve(char* result, char* type_name, int size); void emit_release(char* pointer); - void emit_field_access(char* result, char* record, char* field); void emit_array_access(char* result, char* array, char* index, char* dimension); void emit_bounds_check(char* index, char* size, char* error_label); From c091927fe7e9aa778e5a4dc6276af1f45a34d79f Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 15 Apr 2025 14:46:00 -0400 Subject: [PATCH 111/137] carl --- tests/carl/Errors/entry.undeclaredType.alpha | 10 +++ .../Errors/entry.undeclaredType.alpha.asc | 16 ++++ tests/carl/Errors/entry.undeclaredVar.alpha | 7 ++ .../carl/Errors/entry.undeclaredVar.alpha.asc | 12 +++ tests/carl/Errors/error.operator.alpha | 14 ++++ tests/carl/Errors/error.operator.alpha.asc | 19 +++++ tests/carl/NoErrors/entry.definition.alpha | 8 ++ .../carl/NoErrors/entry.definition.alpha.asc | 10 +++ .../NoErrors/entry.duplicateDifferent.alpha | 11 +++ .../entry.duplicateDifferent.alpha.asc | 13 ++++ tests/carl/NoErrors/entry.duplicateSame.alpha | 9 +++ .../NoErrors/entry.duplicateSame.alpha.asc | 11 +++ tests/carl/NoErrors/entry.local.alpha | 11 +++ tests/carl/NoErrors/entry.local.alpha.asc | 13 ++++ tests/carl/NoErrors/error.none.alpha | 14 ++++ tests/carl/NoErrors/error.none.alpha.asc | 16 ++++ .../carl/NoErrors/function.declaration.alpha | 3 + .../NoErrors/function.declaration.alpha.asc | 5 ++ tests/carl/NoErrors/function.definition.alpha | 7 ++ .../NoErrors/function.definition.alpha.asc | 9 +++ tests/carl/NoErrors/functionValue.alpha | 73 ++++++++++++++++++ tests/carl/NoErrors/functionValue.alpha.asc | 75 ++++++++++++++++++ tests/carl/NoErrors/sample.good.alpha | 29 +++++++ tests/carl/NoErrors/sample.good.alpha.asc | 31 ++++++++ tests/carl/NoErrors/selectionSort.alpha | 68 ++++++++++++++++ tests/carl/NoErrors/selectionSort.alpha.asc | 70 +++++++++++++++++ tests/carl/NoErrors/type.array.alpha | 1 + tests/carl/NoErrors/type.array.alpha.asc | 3 + tests/carl/NoErrors/type.mapping.alpha | 2 + tests/carl/NoErrors/type.mapping.alpha.asc | 4 + tests/carl/NoErrors/type.record.alpha | 1 + tests/carl/NoErrors/type.record.alpha.asc | 3 + tests/carl/NoErrors/types.alpha | 75 ++++++++++++++++++ tests/carl/NoErrors/types.alpha.asc | 77 +++++++++++++++++++ 34 files changed, 730 insertions(+) create mode 100644 tests/carl/Errors/entry.undeclaredType.alpha create mode 100644 tests/carl/Errors/entry.undeclaredType.alpha.asc create mode 100644 tests/carl/Errors/entry.undeclaredVar.alpha create mode 100644 tests/carl/Errors/entry.undeclaredVar.alpha.asc create mode 100644 tests/carl/Errors/error.operator.alpha create mode 100644 tests/carl/Errors/error.operator.alpha.asc create mode 100644 tests/carl/NoErrors/entry.definition.alpha create mode 100644 tests/carl/NoErrors/entry.definition.alpha.asc create mode 100644 tests/carl/NoErrors/entry.duplicateDifferent.alpha create mode 100644 tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc create mode 100644 tests/carl/NoErrors/entry.duplicateSame.alpha create mode 100644 tests/carl/NoErrors/entry.duplicateSame.alpha.asc create mode 100644 tests/carl/NoErrors/entry.local.alpha create mode 100644 tests/carl/NoErrors/entry.local.alpha.asc create mode 100644 tests/carl/NoErrors/error.none.alpha create mode 100644 tests/carl/NoErrors/error.none.alpha.asc create mode 100644 tests/carl/NoErrors/function.declaration.alpha create mode 100644 tests/carl/NoErrors/function.declaration.alpha.asc create mode 100644 tests/carl/NoErrors/function.definition.alpha create mode 100644 tests/carl/NoErrors/function.definition.alpha.asc create mode 100644 tests/carl/NoErrors/functionValue.alpha create mode 100644 tests/carl/NoErrors/functionValue.alpha.asc create mode 100644 tests/carl/NoErrors/sample.good.alpha create mode 100644 tests/carl/NoErrors/sample.good.alpha.asc create mode 100644 tests/carl/NoErrors/selectionSort.alpha create mode 100644 tests/carl/NoErrors/selectionSort.alpha.asc create mode 100644 tests/carl/NoErrors/type.array.alpha create mode 100644 tests/carl/NoErrors/type.array.alpha.asc create mode 100644 tests/carl/NoErrors/type.mapping.alpha create mode 100644 tests/carl/NoErrors/type.mapping.alpha.asc create mode 100644 tests/carl/NoErrors/type.record.alpha create mode 100644 tests/carl/NoErrors/type.record.alpha.asc create mode 100644 tests/carl/NoErrors/types.alpha create mode 100644 tests/carl/NoErrors/types.alpha.asc diff --git a/tests/carl/Errors/entry.undeclaredType.alpha b/tests/carl/Errors/entry.undeclaredType.alpha new file mode 100644 index 0000000..6b9531f --- /dev/null +++ b/tests/carl/Errors/entry.undeclaredType.alpha @@ -0,0 +1,10 @@ +type M : string -> integer + +function foo : M + +foo (s) := { + [ + int: x + ] + return 0; +} diff --git a/tests/carl/Errors/entry.undeclaredType.alpha.asc b/tests/carl/Errors/entry.undeclaredType.alpha.asc new file mode 100644 index 0000000..cd1d37c --- /dev/null +++ b/tests/carl/Errors/entry.undeclaredType.alpha.asc @@ -0,0 +1,16 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.undeclaredType.alpha +001: type M : string -> integer +002: +003: function foo : M +004: +005: foo (s) := { +006: [ +007: int: x + ^0 ^1 + LINE 7:9 ** ERROR #0: the name 'int', used here as a type, has not been declared at this point in the program. + LINE 7:14 ** ERROR #1: the name 'x' is being declared with an unknown type. + +008: ] +009: return 0; +010: } +011: diff --git a/tests/carl/Errors/entry.undeclaredVar.alpha b/tests/carl/Errors/entry.undeclaredVar.alpha new file mode 100644 index 0000000..6cd5fa7 --- /dev/null +++ b/tests/carl/Errors/entry.undeclaredVar.alpha @@ -0,0 +1,7 @@ +type M : string -> integer + +function entry : M + +entry(s) := { + return x; +} diff --git a/tests/carl/Errors/entry.undeclaredVar.alpha.asc b/tests/carl/Errors/entry.undeclaredVar.alpha.asc new file mode 100644 index 0000000..7c4e6c2 --- /dev/null +++ b/tests/carl/Errors/entry.undeclaredVar.alpha.asc @@ -0,0 +1,12 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.undeclaredVar.alpha +001: type M : string -> integer +002: +003: function entry : M +004: +005: entry(s) := { +006: return x; + ^0 + LINE 6:12 ** ERROR #0: the name 'x', used here as a variable name, has not been declared at this point in the program. + +007: } +008: diff --git a/tests/carl/Errors/error.operator.alpha b/tests/carl/Errors/error.operator.alpha new file mode 100644 index 0000000..a7b0691 --- /dev/null +++ b/tests/carl/Errors/error.operator.alpha @@ -0,0 +1,14 @@ +type string2int: string -> integer + +function entry : string2int + +entry(arg) := { + [ integer: i; integer: sum ] + sum := 0; + i := 0; + while (i < 10) { + sum = sum + i; + i := i + 1; + } + return 0; +} diff --git a/tests/carl/Errors/error.operator.alpha.asc b/tests/carl/Errors/error.operator.alpha.asc new file mode 100644 index 0000000..82f5614 --- /dev/null +++ b/tests/carl/Errors/error.operator.alpha.asc @@ -0,0 +1,19 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file error.operator.alpha +001: type string2int: string -> integer +002: +003: function entry : string2int +004: +005: entry(arg) := { +006: [ integer: i; integer: sum ] +007: sum := 0; +008: i := 0; +009: while (i < 10) { +010: sum = sum + i; + ^0 + LINE 10:13 ** ERROR #0: assignment operator (:=) expected but equality operator (=) found. + +011: i := i + 1; +012: } +013: return 0; +014: } +015: diff --git a/tests/carl/NoErrors/entry.definition.alpha b/tests/carl/NoErrors/entry.definition.alpha new file mode 100644 index 0000000..0003cd5 --- /dev/null +++ b/tests/carl/NoErrors/entry.definition.alpha @@ -0,0 +1,8 @@ +(* type string : 1 -> character *) +type M : string -> integer + +function entry : M + +entry(s) := { + return 0; +} diff --git a/tests/carl/NoErrors/entry.definition.alpha.asc b/tests/carl/NoErrors/entry.definition.alpha.asc new file mode 100644 index 0000000..07dbd42 --- /dev/null +++ b/tests/carl/NoErrors/entry.definition.alpha.asc @@ -0,0 +1,10 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.definition.alpha +001: (* type string : 1 -> character *) +002: type M : string -> integer +003: +004: function entry : M +005: +006: entry(s) := { +007: return 0; +008: } +009: diff --git a/tests/carl/NoErrors/entry.duplicateDifferent.alpha b/tests/carl/NoErrors/entry.duplicateDifferent.alpha new file mode 100644 index 0000000..5cbd668 --- /dev/null +++ b/tests/carl/NoErrors/entry.duplicateDifferent.alpha @@ -0,0 +1,11 @@ +type M : string -> integer + +function entry : M + +entry(s) := { + [ + integer: x; + character: x + ] + return x; +} diff --git a/tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc b/tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc new file mode 100644 index 0000000..65ae8d8 --- /dev/null +++ b/tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc @@ -0,0 +1,13 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.duplicateDifferent.alpha +001: type M : string -> integer +002: +003: function entry : M +004: +005: entry(s) := { +006: [ +007: integer: x; +008: character: x +009: ] +010: return x; +011: } +012: diff --git a/tests/carl/NoErrors/entry.duplicateSame.alpha b/tests/carl/NoErrors/entry.duplicateSame.alpha new file mode 100644 index 0000000..554b9d8 --- /dev/null +++ b/tests/carl/NoErrors/entry.duplicateSame.alpha @@ -0,0 +1,9 @@ +type M : string -> integer +function entry : M + +entry(s) := { + [ + integer: x; integer: x + ] + return x; +} diff --git a/tests/carl/NoErrors/entry.duplicateSame.alpha.asc b/tests/carl/NoErrors/entry.duplicateSame.alpha.asc new file mode 100644 index 0000000..7861cc6 --- /dev/null +++ b/tests/carl/NoErrors/entry.duplicateSame.alpha.asc @@ -0,0 +1,11 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.duplicateSame.alpha +001: type M : string -> integer +002: function entry : M +003: +004: entry(s) := { +005: [ +006: integer: x; integer: x +007: ] +008: return x; +009: } +010: diff --git a/tests/carl/NoErrors/entry.local.alpha b/tests/carl/NoErrors/entry.local.alpha new file mode 100644 index 0000000..cff2062 --- /dev/null +++ b/tests/carl/NoErrors/entry.local.alpha @@ -0,0 +1,11 @@ +type M : string -> integer + +function entry : M + +entry(s) := { + [ + integer: x + ] + x := 0; + return x; +} diff --git a/tests/carl/NoErrors/entry.local.alpha.asc b/tests/carl/NoErrors/entry.local.alpha.asc new file mode 100644 index 0000000..e9882d4 --- /dev/null +++ b/tests/carl/NoErrors/entry.local.alpha.asc @@ -0,0 +1,13 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.local.alpha +001: type M : string -> integer +002: +003: function entry : M +004: +005: entry(s) := { +006: [ +007: integer: x +008: ] +009: x := 0; +010: return x; +011: } +012: diff --git a/tests/carl/NoErrors/error.none.alpha b/tests/carl/NoErrors/error.none.alpha new file mode 100644 index 0000000..85aa4f2 --- /dev/null +++ b/tests/carl/NoErrors/error.none.alpha @@ -0,0 +1,14 @@ +type string2int: string -> integer + +function entry : string2int + +entry(arg) := { + [ integer: i ; integer: sum ] + sum := 0; + i := 0 ; + while (i < 10) { + sum := sum + i; + i := i + 1; + } + return 0; +} diff --git a/tests/carl/NoErrors/error.none.alpha.asc b/tests/carl/NoErrors/error.none.alpha.asc new file mode 100644 index 0000000..9fdcadb --- /dev/null +++ b/tests/carl/NoErrors/error.none.alpha.asc @@ -0,0 +1,16 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file error.none.alpha +001: type string2int: string -> integer +002: +003: function entry : string2int +004: +005: entry(arg) := { +006: [ integer: i ; integer: sum ] +007: sum := 0; +008: i := 0 ; +009: while (i < 10) { +010: sum := sum + i; +011: i := i + 1; +012: } +013: return 0; +014: } +015: diff --git a/tests/carl/NoErrors/function.declaration.alpha b/tests/carl/NoErrors/function.declaration.alpha new file mode 100644 index 0000000..69f210f --- /dev/null +++ b/tests/carl/NoErrors/function.declaration.alpha @@ -0,0 +1,3 @@ +type M : integer -> integer + +function f : M diff --git a/tests/carl/NoErrors/function.declaration.alpha.asc b/tests/carl/NoErrors/function.declaration.alpha.asc new file mode 100644 index 0000000..fca046a --- /dev/null +++ b/tests/carl/NoErrors/function.declaration.alpha.asc @@ -0,0 +1,5 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file function.declaration.alpha +001: type M : integer -> integer +002: +003: function f : M +004: diff --git a/tests/carl/NoErrors/function.definition.alpha b/tests/carl/NoErrors/function.definition.alpha new file mode 100644 index 0000000..b729610 --- /dev/null +++ b/tests/carl/NoErrors/function.definition.alpha @@ -0,0 +1,7 @@ +type M : integer -> integer + +function f : M + +f(x) := { + return x; +} diff --git a/tests/carl/NoErrors/function.definition.alpha.asc b/tests/carl/NoErrors/function.definition.alpha.asc new file mode 100644 index 0000000..e476758 --- /dev/null +++ b/tests/carl/NoErrors/function.definition.alpha.asc @@ -0,0 +1,9 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file function.definition.alpha +001: type M : integer -> integer +002: +003: function f : M +004: +005: f(x) := { +006: return x; +007: } +008: diff --git a/tests/carl/NoErrors/functionValue.alpha b/tests/carl/NoErrors/functionValue.alpha new file mode 100644 index 0000000..f521a42 --- /dev/null +++ b/tests/carl/NoErrors/functionValue.alpha @@ -0,0 +1,73 @@ +(* Type definitions *) + +(* mapping type *) +type string2int: string -> integer + +(* array of functions *) +type funArray: 1 -> string2int + +(* record of functions *) +type funRec: [ string2int: f; string2int: g ] + +(* function returning function *) +type integer_2_string2int: integer -> string2int + +(* function returning function *) +type string2int_2_integer: string2int -> integer + + +type iXiXc: [integer: a; integer: b; character: c] + +type iic2b: iXiXc -> Boolean + +(* Function declarations using the above type definitions *) +function a: string2int +function b: integer_2_string2int +function c: string2int_2_integer + +function d: iic2b + +d(x,y,z) := { + return (x < y & z < 'm'); +} + +function entry: string2int + +a(x) := { + [string : s] + s := x; + return 0; +} + +b(x) := { + [integer: i] + i := x; + return a; +} + +c(x) := { + [string: s] + s := "Hi!"; + return x(s); +} + + +(* Function definition + entry is the first function called + *) +entry(arg) := { + [integer: result; string2int: f; integer: temp] + temp := a("Hello"); + f := b(temp); + result := c(f); + if (d(1,2,'c')) + then { + result := 0; + } + else { + [ Boolean : b] + result := entry("hello"); + } + result := c(f); + return result; +} diff --git a/tests/carl/NoErrors/functionValue.alpha.asc b/tests/carl/NoErrors/functionValue.alpha.asc new file mode 100644 index 0000000..882d558 --- /dev/null +++ b/tests/carl/NoErrors/functionValue.alpha.asc @@ -0,0 +1,75 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file functionValue.alpha +001: (* Type definitions *) +002: +003: (* mapping type *) +004: type string2int: string -> integer +005: +006: (* array of functions *) +007: type funArray: 1 -> string2int +008: +009: (* record of functions *) +010: type funRec: [ string2int: f; string2int: g ] +011: +012: (* function returning function *) +013: type integer_2_string2int: integer -> string2int +014: +015: (* function returning function *) +016: type string2int_2_integer: string2int -> integer +017: +018: +019: type iXiXc: [integer: a; integer: b; character: c] +020: +021: type iic2b: iXiXc -> Boolean +022: +023: (* Function declarations using the above type definitions *) +024: function a: string2int +025: function b: integer_2_string2int +026: function c: string2int_2_integer +027: +028: function d: iic2b +029: +030: d(x,y,z) := { +031: return (x < y & z < 'm'); +032: } +033: +034: function entry: string2int +035: +036: a(x) := { +037: [string : s] +038: s := x; +039: return 0; +040: } +041: +042: b(x) := { +043: [integer: i] +044: i := x; +045: return a; +046: } +047: +048: c(x) := { +049: [string: s] +050: s := "Hi!"; +051: return x(s); +052: } +053: +054: +055: (* Function definition +056: entry is the first function called +057: *) +058: entry(arg) := { +059: [integer: result; string2int: f; integer: temp] +060: temp := a("Hello"); +061: f := b(temp); +062: result := c(f); +063: if (d(1,2,'c')) +064: then { +065: result := 0; +066: } +067: else { +068: [ Boolean : b] +069: result := entry("hello"); +070: } +071: result := c(f); +072: return result; +073: } +074: diff --git a/tests/carl/NoErrors/sample.good.alpha b/tests/carl/NoErrors/sample.good.alpha new file mode 100644 index 0000000..8a8b727 --- /dev/null +++ b/tests/carl/NoErrors/sample.good.alpha @@ -0,0 +1,29 @@ + +(* Type definitions *) +type int2int: integer -> integer +type string2int: string -> integer + +(* Function declarations + They use the above type definitions +*) +function square : int2int +function entry : string2int + +(* Function definition + Functions must be declared before they are defined + *) +square(x) := { + return x * x; +} + +(* Function definition + entry is the first function called + *) +entry(arg) := { + [ integer: input ; integer: expected ; integer: actual ; Boolean: result ] + input := 7; + expected := 49; + actual := square(input); + result := expected = actual; + return 0; +} diff --git a/tests/carl/NoErrors/sample.good.alpha.asc b/tests/carl/NoErrors/sample.good.alpha.asc new file mode 100644 index 0000000..a4bfa3a --- /dev/null +++ b/tests/carl/NoErrors/sample.good.alpha.asc @@ -0,0 +1,31 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file sample.good.alpha +001: +001: (* Type definitions *) +003: type int2int: integer -> integer +004: type string2int: string -> integer +005: +006: (* Function declarations +007: They use the above type definitions +008: *) +009: function square : int2int +010: function entry : string2int +011: +012: (* Function definition +013: Functions must be declared before they are defined +014: *) +015: square(x) := { +016: return x * x; +017: } +018: +019: (* Function definition +020: entry is the first function called +021: *) +022: entry(arg) := { +023: [ integer: input ; integer: expected ; integer: actual ; Boolean: result ] +024: input := 7; +025: expected := 49; +026: actual := square(input); +027: result := expected = actual; +028: return 0; +029: } +030: diff --git a/tests/carl/NoErrors/selectionSort.alpha b/tests/carl/NoErrors/selectionSort.alpha new file mode 100644 index 0000000..edd2076 --- /dev/null +++ b/tests/carl/NoErrors/selectionSort.alpha @@ -0,0 +1,68 @@ +(* Type definitions *) + +type string2int: string -> integer +type intArray: 1 -> integer +type intArrayXinteger: [ intArray: data; integer: index ] +type intArrayXinteger2integer: intArrayXinteger -> integer +type intArray2Boolean: intArray -> Boolean + + +(* Function declarations + They use the above type definitions +*) +function indexOfSmallest: intArrayXinteger2integer +function selectionSort: intArray2Boolean +function entry : string2int + +(* indexOfSmallest *) +indexOfSmallest (* as *) (data, startingIndex) := { + [ integer: indexOfSmallestSoFar; integer: i ] + indexOfSmallestSoFar := startingIndex; + i := 0 ; + while (i < data._1 ) { + if ( data(i) < data(indexOfSmallestSoFar) ) + then { + indexOfSmallestSoFar := i; + } + else { + i := i; + } + i := i + 1; + } + return indexOfSmallestSoFar; +} + + +(* selectionSort *) +selectionSort(data) := { + [ integer: i ] + i := 0 ; + while (i < data._1 ) { + [ integer: index; integer: temp ] + index := indexOfSmallest(data,i); + temp := data(index); + data(index) := data(i); + data(i) := temp; + i := i + 1; + } + return true; +} + + +(* Function definition + entry is the first function called + *) +entry(arg) := { + [ intArray: data; Boolean: _ ] + data := reserve data(8); + data(0) := 60; + data(1) := 80; + data(2) := 10; + data(3) := 50; + data(4) := 30; + data(5) := 40; + data(6) := 20; + data(7) := 70; + _ := selectionSort(data); + return 0; +} diff --git a/tests/carl/NoErrors/selectionSort.alpha.asc b/tests/carl/NoErrors/selectionSort.alpha.asc new file mode 100644 index 0000000..2a12877 --- /dev/null +++ b/tests/carl/NoErrors/selectionSort.alpha.asc @@ -0,0 +1,70 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file selectionSort.alpha +001: (* Type definitions *) +002: +003: type string2int: string -> integer +004: type intArray: 1 -> integer +005: type intArrayXinteger: [ intArray: data; integer: index ] +006: type intArrayXinteger2integer: intArrayXinteger -> integer +007: type intArray2Boolean: intArray -> Boolean +008: +009: +010: (* Function declarations +011: They use the above type definitions +012: *) +013: function indexOfSmallest: intArrayXinteger2integer +014: function selectionSort: intArray2Boolean +015: function entry : string2int +016: +017: (* indexOfSmallest *) +018: indexOfSmallest (* as *) (data, startingIndex) := { +019: [ integer: indexOfSmallestSoFar; integer: i ] +020: indexOfSmallestSoFar := startingIndex; +021: i := 0 ; +022: while (i < data._1 ) { +023: if ( data(i) < data(indexOfSmallestSoFar) ) +024: then { +025: indexOfSmallestSoFar := i; +026: } +027: else { +028: i := i; +029: } +030: i := i + 1; +031: } +032: return indexOfSmallestSoFar; +033: } +034: +035: +036: (* selectionSort *) +037: selectionSort(data) := { +038: [ integer: i ] +039: i := 0 ; +040: while (i < data._1 ) { +041: [ integer: index; integer: temp ] +042: index := indexOfSmallest(data,i); +043: temp := data(index); +044: data(index) := data(i); +045: data(i) := temp; +046: i := i + 1; +047: } +048: return true; +049: } +050: +051: +052: (* Function definition +053: entry is the first function called +054: *) +055: entry(arg) := { +056: [ intArray: data; Boolean: _ ] +057: data := reserve data(8); +058: data(0) := 60; +059: data(1) := 80; +060: data(2) := 10; +061: data(3) := 50; +062: data(4) := 30; +063: data(5) := 40; +064: data(6) := 20; +065: data(7) := 70; +066: _ := selectionSort(data); +067: return 0; +068: } +069: diff --git a/tests/carl/NoErrors/type.array.alpha b/tests/carl/NoErrors/type.array.alpha new file mode 100644 index 0000000..2b04ba0 --- /dev/null +++ b/tests/carl/NoErrors/type.array.alpha @@ -0,0 +1 @@ +type A : 1 -> integer diff --git a/tests/carl/NoErrors/type.array.alpha.asc b/tests/carl/NoErrors/type.array.alpha.asc new file mode 100644 index 0000000..8e6154d --- /dev/null +++ b/tests/carl/NoErrors/type.array.alpha.asc @@ -0,0 +1,3 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.array.alpha +001: type A : 1 -> integer +002: diff --git a/tests/carl/NoErrors/type.mapping.alpha b/tests/carl/NoErrors/type.mapping.alpha new file mode 100644 index 0000000..8b6bc50 --- /dev/null +++ b/tests/carl/NoErrors/type.mapping.alpha @@ -0,0 +1,2 @@ +type M : integer -> character + diff --git a/tests/carl/NoErrors/type.mapping.alpha.asc b/tests/carl/NoErrors/type.mapping.alpha.asc new file mode 100644 index 0000000..2ce8f0c --- /dev/null +++ b/tests/carl/NoErrors/type.mapping.alpha.asc @@ -0,0 +1,4 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.mapping.alpha +001: type M : integer -> character +002: +003: diff --git a/tests/carl/NoErrors/type.record.alpha b/tests/carl/NoErrors/type.record.alpha new file mode 100644 index 0000000..2c5e9c9 --- /dev/null +++ b/tests/carl/NoErrors/type.record.alpha @@ -0,0 +1 @@ +type R : [ integer : i ; character : c ] diff --git a/tests/carl/NoErrors/type.record.alpha.asc b/tests/carl/NoErrors/type.record.alpha.asc new file mode 100644 index 0000000..848948b --- /dev/null +++ b/tests/carl/NoErrors/type.record.alpha.asc @@ -0,0 +1,3 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.record.alpha +001: type R : [ integer : i ; character : c ] +002: diff --git a/tests/carl/NoErrors/types.alpha b/tests/carl/NoErrors/types.alpha new file mode 100644 index 0000000..0402f95 --- /dev/null +++ b/tests/carl/NoErrors/types.alpha @@ -0,0 +1,75 @@ +(* + + At compiler start-up your program should + create symbol table entries for the following + built-in types: + + Boolean (1 byte) + character (1 byte) + integer (4 bytes) + address (8 bytes) + + and the following privileged type (it has literals): + + type string: 1 -> character + + Your compiler can define other types during + its start-up routine as well, if it is helpful + to do so. + +*) + + + +type BooleanXBoolean: [Boolean: x; Boolean: y] +type characterXcharacter: [character: x; character: y] +type integerXinteger: [integer: x; integer: y] + +type Boolean2Boolean: Boolean -> Boolean +type integer2integer: integer -> integer + +type character2integer: character -> integer +type Boolean2integer: Boolean -> integer +type string2integer: string -> integer + +type integerXinteger2integer: integerXinteger -> integer + +type integerXinteger2Boolean: integerXinteger -> Boolean +type characterXcharacter2Boolean: characterXcharacter -> Boolean +type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean + + +type integer2address: integer -> address +type address2integer: address -> integer + + +(* The alpha library functions + You will be provided with x86-64 assembly + code implementations of these. +*) + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +(* + A declaration of the entry point function for your program + + You may assume that when starting this function will behave as if + it had been called from the C language main function like this: + + int main(int argc, char * argv[]) { + if (argc == 1) { + return entry(NULL); + } + else { + return entry(makeAlphaString(argv[1])); + } + } + + for some suitable definition of makeAlphaString which creates + an alpha string representation of its argument C string in memory + and returns a pointer to that alpha string. +*) + +function entry: string2integer diff --git a/tests/carl/NoErrors/types.alpha.asc b/tests/carl/NoErrors/types.alpha.asc new file mode 100644 index 0000000..8844865 --- /dev/null +++ b/tests/carl/NoErrors/types.alpha.asc @@ -0,0 +1,77 @@ +alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file types.alpha +001: (* +001: +002: At compiler start-up your program should +003: create symbol table entries for the following +004: built-in types: +005: +006: Boolean (1 byte) +007: character (1 byte) +008: integer (4 bytes) +009: address (8 bytes) +010: +011: and the following privileged type (it has literals): +012: +013: type string: 1 -> character +014: +015: Your compiler can define other types during +016: its start-up routine as well, if it is helpful +017: to do so. +018: +019: *) +021: +022: +023: +024: type BooleanXBoolean: [Boolean: x; Boolean: y] +025: type characterXcharacter: [character: x; character: y] +026: type integerXinteger: [integer: x; integer: y] +027: +028: type Boolean2Boolean: Boolean -> Boolean +029: type integer2integer: integer -> integer +030: +031: type character2integer: character -> integer +032: type Boolean2integer: Boolean -> integer +033: type string2integer: string -> integer +034: +035: type integerXinteger2integer: integerXinteger -> integer +036: +037: type integerXinteger2Boolean: integerXinteger -> Boolean +038: type characterXcharacter2Boolean: characterXcharacter -> Boolean +039: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +040: +041: +042: type integer2address: integer -> address +043: type address2integer: address -> integer +044: +045: +046: (* The alpha library functions +047: You will be provided with x86-64 assembly +048: code implementations of these. +049: *) +050: +051: external function printInteger: integer2integer +052: external function printCharacter: character2integer +053: external function printBoolean: Boolean2integer +054: +055: (* +056: A declaration of the entry point function for your program +057: +058: You may assume that when starting this function will behave as if +059: it had been called from the C language main function like this: +060: +061: int main(int argc, char * argv[]) { +062: if (argc == 1) { +063: return entry(NULL); +064: } +065: else { +066: return entry(makeAlphaString(argv[1])); +067: } +068: } +069: +070: for some suitable definition of makeAlphaString which creates +071: an alpha string representation of its argument C string in memory +072: and returns a pointer to that alpha string. +073: *) +074: +075: function entry: string2integer +076: From b7c6ebb3f2f75ca9fbcc17d77262297817390ed2 Mon Sep 17 00:00:00 2001 From: Annie Date: Tue, 15 Apr 2025 15:41:46 -0400 Subject: [PATCH 112/137] fixed -tok handling --- src/runner.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/runner.c b/src/runner.c index 5aedc59..4962b98 100644 --- a/src/runner.c +++ b/src/runner.c @@ -106,8 +106,8 @@ int run(FILE *alpha) { yyin = alpha; // TOK FLAG - if (tok_flag != NULL) { - while (0 != (token = yylex())) { +// if (tok_flag != NULL) { + // while (0 != (token = yylex())) { // if (tok_flag != NULL) { // fprintf(tok_flag, "%d %d %3d \"%s\"\n", // line_number, column_number, @@ -131,7 +131,7 @@ int run(FILE *alpha) { yytext); } column_number += yyleng; */ - } + /* } fclose(tok_flag); if (yyin != NULL) { @@ -139,7 +139,7 @@ int run(FILE *alpha) { } return 0; } - +*/ if (st_flag != NULL) { yyparse(); From b325548b970b449f481cb274ceace09b8d2565ff Mon Sep 17 00:00:00 2001 From: Scarlett Date: Tue, 15 Apr 2025 16:25:51 -0400 Subject: [PATCH 113/137] flag updates --- src/runner.c | 358 ++++++++++++++++++++++++--------------------------- src/runner.h | 32 +++-- 2 files changed, 184 insertions(+), 206 deletions(-) diff --git a/src/runner.c b/src/runner.c index 4962b98..ba7f64e 100644 --- a/src/runner.c +++ b/src/runner.c @@ -4,242 +4,214 @@ #include "runner.h" int main(int argc, char *argv[]) { - // if last argument is debug then set to true and ignore it for the rest - // of this file - //if (argc > 1 && strcmp(argv[argc - 1], "-debug") == 0) { - // DEBUG = true; - // argc--; - // } + if (argc == 1) { + fprintf(stderr, INVALID); + return -1; + } - if (argc == 1) { - fprintf(stderr, INVALID); - return -1; + else if (argc == 2) { + if (is_help(argv[1])) { + return 0; + } else if (is_alpha_file(argv[1], strlen(argv[1])) == 0) { + no_flag = SET_FLAG; + alpha_file = fopen(argv[1], "r"); + } else { + fprintf(stderr, INVALID); + return -1; } + } - else if (argc == 2) { - if (is_help(argv[1])) { - return 0; - } else if (is_alpha_file(argv[1], strlen(argv[1])) == 0) { - no_flag = SET_FLAG; - alpha_file = fopen(argv[1], "r"); - } else { - fprintf(stderr, INVALID); - return -1; + else { + if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != + 0) { + fprintf(stderr, INVALID); + return -1; + } else { + for (int i = 1; i < argc - 1; i++) { + if (check_flag(argv[i], argv[argc - 1]) != 0) { + fprintf(stderr, INVALID); + return -1; } + } + alpha_file = fopen(argv[argc - 1], "r"); } - - else { - if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != - 0) { - fprintf(stderr, INVALID); - return -1; - } else { - for (int i = 1; i < argc - 1; i++) { - if (check_flag(argv[i], argv[argc - 1]) != 0) { - fprintf(stderr, - "INVALID FLAG(S): Use -help to " - "view valid inputs \n"); - return -1; - } - } - alpha_file = fopen(argv[argc - 1], "r"); - } - } - return run(alpha_file); + } + return run(alpha_file); } int check_flag(char *arg, char *alpha) { - if (strcmp("-tok", arg) == 0) { - if (tok_flag == NULL) { - return new_file(arg, alpha); - } - fprintf(stderr, "FLAGS REPEAT\n"); - return -1; - } else if (strcmp("-st", arg) == 0) { - if (st_flag == NULL) { - return new_file(arg, alpha); - } - fprintf(stderr, "FLAGS REPEAT\n"); - return -1; - - } else if (strcmp("-tc", arg) == 0) { - if (tc_flag == NULL) { - return new_file(arg, alpha); - } - } else if (strcmp("-debug", arg) == 0) { - DEBUG = true; - return 0; - } else { - fprintf(stderr, "INVALID FLAG: Use -help for valid inputs\n"); - return -1; + if (strcmp("-tok", arg) == 0) { + if (tok_flag == NULL) { + return new_file(arg, alpha); } + fprintf(stderr, "FLAGS REPEAT\n"); + return -1; + } else if (strcmp("-st", arg) == 0) { + if (st_flag == NULL) { + return new_file(arg, alpha); + } + fprintf(stderr, "FLAGS REPEAT\n"); + return -1; + } else if (strcmp("-asc", arg) == 0) { + if (asc_flag == NULL) { + return new_file(arg, alpha); + } + fprintf(stderr, "FLAGS REPEAT\n"); + return -1; + } else if (strcmp("-tc", arg) == 0) { + if (tc_flag == NULL) { + return new_file(arg, alpha); + } + fprintf(stderr, "FLAGS REPEAT\n"); + return -1; + } else if (strcmp("-ir", arg) == 0) { + if (ir_flag == NULL) { + return new_file(arg, alpha); + } + fprintf(stderr, "FLAGS REPEAT\n"); + return -1; + } else if (strcmp("-cg", arg) == 0) { + if (cg_flag == NULL) { + return new_file(arg, alpha); + } + fprintf(stderr, "FLAGS REPEAT\n"); + return -1; + } else if (strcmp("-debug", arg) == 0) { + DEBUG = true; + return 0; + } else { + fprintf(stderr, "INVALID FLAG: Use -help for valid inputs\n"); + return -1; + } } void incr(int lnum, int cnum, int tok) { - // if (tok == COMMENT) { - for (int i = 0; i < yyleng; i++) { - if (yytext[i] == '\n') { - line_number++; - column_number = 0; - } - column_number++; + for (int i = 0; i < yyleng; i++) { + if (yytext[i] == '\n') { + line_number++; + column_number = 0; } - // }else{ - // column_number += yyleng; - // } + column_number++; + } } void print_tok(int tok) { - fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, tok, - yytext); + fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, tok, yytext); } int run(FILE *alpha) { - int token; - top = cur = init(CreateScope(NULL, 1, 1)); + int token; + top = cur = init(CreateScope(NULL, 1, 1)); - // If file is not found - if (alpha == NULL) { - fprintf(stderr, "INPUT FILE NOT FOUND\n"); - return -1; - } - yyin = alpha; + // If file is not found + if (alpha == NULL) { + fprintf(stderr, "INPUT FILE NOT FOUND\n"); + return -1; + } + yyin = alpha; + yyparse(); - // TOK FLAG -// if (tok_flag != NULL) { - // while (0 != (token = yylex())) { - // if (tok_flag != NULL) { - // fprintf(tok_flag, "%d %d %3d \"%s\"\n", - // line_number, column_number, - // token, yytext); - // } - /*if (token == COMMENT) { - for (int i = 0; i < yyleng; i++) { - if (yytext[i] == '\n') { - line_number++; - column_number = 0; - } - column_number++; - } - continue; - } - if (token == 1999) { - printf( - "On line number %d and column - number %d we have an invalid " "character:%s\n", - line_number, column_number, - yytext); - } - column_number += yyleng; */ - /* } - fclose(tok_flag); + if (st_flag != NULL) { + print_symbol_table(top, st_flag); + fclose(st_flag); + } - if (yyin != NULL) { - fclose(yyin); - } - return 0; - } -*/ - if (st_flag != NULL) { - yyparse(); + if (asc_flag != NULL) { + printf("Flag -asc is not implemented yet\n"); + fclose(asc_flag); + } - if (cur == NULL) { - printdebug("%s[FATAL] cur is null", COLOR_LIGHTRED); - } + if (tc_flag != NULL) { + printf("Flag -tc is not implemented yet\n"); + fclose(tc_flag); + } - if (top == NULL) { - printdebug("%s[FATAL] top is null", COLOR_LIGHTRED); - } + if (ir_flag != NULL) { + printf("Flag -ir is not implemented yet\n"); + fclose(ir_flag); + } + if (cg_flag != NULL) { + printf("Flag -cg is not implemented yet\n"); + fclose(cg_flag); + } - print_symbol_table(top, st_flag); - fclose(st_flag); - if (yyin != NULL) { - fclose(yyin); - } - return 0; - } + yyparse(); - if (tc_flag != NULL) { - //SCARLETT NEEDS TO ADD THIS FUNCTIONALITY - } + if (yyin != NULL) { + fclose(yyin); + } - yyparse(); - FILE *f = fdopen(1, "w"); - - print_symbol_table(top, f); - fclose(f); - - if (yyin != NULL) { - fclose(yyin); - } - - return 0; + return 0; } bool is_help(char *input) { - if (strcmp(input, "-help") == 0) { - printf("%s", HELP); - return true; - } + if (strcmp(input, "-help") == 0) { + printf("%s", HELP); + return true; + } - return false; + return false; } int new_file(char *arg, char *alpha) { - int type_len; - const char *basename = alpha; - const char *slash = strchr(alpha, '/'); + int type_len; + const char *basename = alpha; + const char *slash = strchr(alpha, '/'); - while (slash != NULL) { - basename = slash + 1; - slash = strchr(basename, '/'); - } + while (slash != NULL) { + basename = slash + 1; + slash = strchr(basename, '/'); + } - mkdir("./out", 0777); + mkdir("./out", 0777); - char *new_basename = calloc(strlen(basename) + 5, sizeof(char)); - strcpy(new_basename, "./out/"); - strcat(new_basename, basename); - basename = new_basename; + char *new_basename = calloc(strlen(basename) + 5, sizeof(char)); + strcpy(new_basename, "./out/"); + strcat(new_basename, basename); + basename = new_basename; - if (strcmp(arg, "-tok") == 0) { - type_len = TOK_LEN; - } else if (strcmp(arg, "-st") == 0) { - type_len = ST_LEN; - } else if (strcmp(arg, "-tc") == 0){ - type_len = TC_LEN; - }else { - fprintf(stderr, - "INVALID FLAG: Use -help to view valid inputs\n"); - return -1; - } + if (strcmp(arg, "-tok") == 0) { + type_len = TOK_LEN; + } else if (strcmp(arg, "-st") == 0) { + type_len = ST_LEN; + } else if (strcmp(arg, "-tc") == 0) { + type_len = TC_LEN; + } else { + fprintf(stderr, INVALID); + return -1; + } - // calculate lengths - int basename_len = strlen(basename); - char *file_name = - calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char)); + // calculate lengths + int basename_len = strlen(basename); + char *file_name = + calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char)); - // coy filename and add extension - strncpy(file_name, basename, basename_len - ALPHA_OFFSET); - strcat(file_name, "."); - strcat(file_name, arg + 1); + // coy filename and add extension + strncpy(file_name, basename, basename_len - ALPHA_OFFSET); + strcat(file_name, "."); + strcat(file_name, arg + 1); - if (strcmp(arg, "-tok") == 0) { - tok_flag = fopen(file_name, "w"); - } else if (strcmp(arg, "-st") == 0) { - st_flag = fopen(file_name, "w"); - - } else if (strcmp(arg, "-tc") == 0) { - tc_flag = fopen(file_name, "w"); - } - return 0; + if (strcmp(arg, "-tok") == 0) { + tok_flag = fopen(file_name, "w"); + } else if (strcmp(arg, "-st") == 0) { + st_flag = fopen(file_name, "w"); + } else if (strcmp(arg, "-asc") == 0) { + asc_flag = fopen(file_name, "w"); + } else if (strcmp(arg, "-tc") == 0) { + tc_flag = fopen(file_name, "w"); + } else if (strcmp(arg, "-ir") == 0) { + ir_flag = fopen(file_name, "w"); + } else if (strcmp(arg, "-cg") == 0) { + cg_flag = fopen(file_name, "w"); + } + return 0; } int is_alpha_file(char *alpha, int file_len) { - if (strcmp(".alpha", - alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) { - return -1; // not alpha file - } - return 0; // is alpha file + if (strcmp(".alpha", + alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) { + return -1; // not alpha file + } + return 0; // is alpha file } diff --git a/src/runner.h b/src/runner.h index 0483e12..0a878d9 100644 --- a/src/runner.h +++ b/src/runner.h @@ -5,20 +5,23 @@ #define TOK_LEN 3 #define ST_LEN 2 #define TC_LEN 2 -#define HELP \ - "HELP:\nHow to run the alpha compiler:\n./alpha [options] " \ - "program\nValid " \ - "options:\n-tok output the token number, token, line number, and " \ - "column " \ - "number for each of the tokens to the .tok file\n-st output the " \ - "symbol " \ - "table for the program to the .st file\n-help print this message " \ - "and exit " \ - "the alpha compiler\n-debug print debugging messages in grammar rules \n" +#define HELP \ + "HELP:\n" \ + " How to run the alpha compiler:\n" \ + " ./alpha [options] program\n" \ + "Valid options:\n" \ + " -tok output the token number, token, line number, and column number for each of the tokens to the .tok file\n" \ + " -st output the symbol table for the program to the .st file\n" \ + " -asc output the annotated source code for the program to the .asc file, including syntax errors\n" \ + " -tc run the type checker and report type errors to the .asc file\n" \ + " -ir run the intermediate representation generator, writing output to the .ir file\n" \ + " -cg run the (x86 assembly) code generator, writing output to the .s file\n" \ + " -debug produce debugging messages to stderr\n" \ + " -help print this message and exit the alpha compiler\n" -#define SET_FLAG 1 // Used to set flags for arg types -#define INVALID \ - "INVALID INPUT: Include a .alpha file or use -help for more inputs \n" +#define SET_FLAG 1 // Used to set flags for arg types +#define INVALID \ + "INVALID INPUT: Include a .alpha file or use -help for more inputs \n" #include #include @@ -42,6 +45,9 @@ FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; FILE *tc_flag = NULL; +FILE *ir_flag = NULL; +FILE *cg_flag = NULL; +FILE *asc_flag = NULL; bool DEBUG = false; int no_flag = 0; int arg; From 90f9eb2f006a3136caa39aa61896dc0cd78f83c4 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 15 Apr 2025 19:44:46 -0400 Subject: [PATCH 114/137] added entries for reserve and release --- src/grammar.y | 1 + src/symbol_table.c | 28 ++++++++++++++++++++++++++-- tests/sprint2/test/sp2_simple.alpha | 2 +- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 4e2aa1d..0a03126 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -392,6 +392,7 @@ sblock: printdebug("Moving up a scope after seeing sblock with dblock"); cur = getParent(cur); //$$ = $5; + } R_BRACE {$$ = $5;} diff --git a/src/symbol_table.c b/src/symbol_table.c index 4232c16..cd44b40 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -605,20 +605,31 @@ SymbolTable *init(SymbolTable *start) { chara = (TableNode *)calloc(1, sizeof(TableNode)); stri = (TableNode *)calloc(1, sizeof(TableNode)); boo = (TableNode *)calloc(1, sizeof(TableNode)); + TableNode* reservetype = (TableNode *)calloc(1, sizeof(TableNode)); + TableNode* reserve = (TableNode *)calloc(1, sizeof(TableNode)); + TableNode* releasetype = (TableNode *)calloc(1, sizeof(TableNode)); + TableNode* release = (TableNode *)calloc(1, sizeof(TableNode)); // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; addr->next = chara; chara->next = stri; stri->next = boo; - // boo->next = arr; - boo->next = NULL; + boo->next = reservetype; + reservetype->next = reserve; + reserve->next = releasetype; + releasetype->next = release; + release->next = NULL; integ->theName = "integer"; addr->theName = "address"; chara->theName = "character"; boo->theName = "Boolean"; stri->theName = "string"; + reserve->theName = "reserve"; + reservetype->theName = "reserve type"; + releasetype->theName = "release type"; + release->theName = "release"; // arr->theName= "array" // root TableNode that all are pointing to but not in table @@ -685,6 +696,11 @@ SymbolTable *init(SymbolTable *start) { chara->theType = prime; stri->theType = arrayprim; boo->theType = prime; + reserve->theType = reservetype; + reservetype->theType = funtypeprime; + releasetype->theType = funtypeprime; + release->theType = releasetype; + // arr->theType=arrayprim; // filling in all the values for the additional info for initial types @@ -697,12 +713,20 @@ SymbolTable *init(SymbolTable *start) { chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR); stri->additionalinfo = CreateArrayInfo(1, chara); boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); + reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false); + reservetype->additionalinfo = CreateFunctionTypeInfo(integ, addr); + releasetype->additionalinfo = CreateFunctionTypeInfo(addr, integ); + release->additionalinfo = CreateFunctionDeclarationInfo(0, false); integ->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for integ addr->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for addr chara->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for chara stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri boo->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for boo + reserve->tag = TYPE_FUNCTION_DECLARATION; + reservetype->tag = TYPE_FUNCTION_TYPE; + releasetype->tag = TYPE_FUNCTION_TYPE; + release->tag = TYPE_FUNCTION_DECLARATION; // addr->additionalinfo = CreatePrimitiveInfo(8); start->Line_Number = 1; diff --git a/tests/sprint2/test/sp2_simple.alpha b/tests/sprint2/test/sp2_simple.alpha index 825fdcd..58934e6 100644 --- a/tests/sprint2/test/sp2_simple.alpha +++ b/tests/sprint2/test/sp2_simple.alpha @@ -4,4 +4,4 @@ function entry: main entry(arg) := { [integer : x] return 0; -} +} \ No newline at end of file From b023ac01330bfd5997347e601f5ade9f4e9ec9a8 Mon Sep 17 00:00:00 2001 From: Partho Date: Tue, 15 Apr 2025 20:22:24 -0400 Subject: [PATCH 115/137] commented out second yyparse() in runner in run --- src/grammar.y | 2 +- src/runner.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 0a03126..c6044fd 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -896,7 +896,7 @@ assignable: $$ = table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3); } - printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName((TableNode*)($$)), $1); + printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName((TableNode*)($$)), getName($1)); } ; diff --git a/src/runner.c b/src/runner.c index ba7f64e..03e1933 100644 --- a/src/runner.c +++ b/src/runner.c @@ -136,7 +136,7 @@ int run(FILE *alpha) { fclose(cg_flag); } - yyparse(); + //yyparse(); if (yyin != NULL) { fclose(yyin); From 5a23ef275696d5f34b3aabd51e15aed2ef835f1f Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 16 Apr 2025 11:44:02 -0400 Subject: [PATCH 116/137] Fixed -tok, spacings in -st, and validation tests --- src/runner.c | 9 +- src/runner.h | 8 +- src/symbol_table.c | 120 ++++++++-------- src/symbol_table.h | 89 ++++++------ .../expected/sp2_carls_mistake.expected | 66 ++++----- .../expected/sp2_function_types.expected | 55 ++++---- .../expected/sp2_integer_binary_op.expected | 38 +++--- ...sp2_invalid_multiple_params_no_as.expected | 20 +++ .../expected/sp2_invalid_recop.expected | 37 ++--- .../expected/sp2_invalid_release.expected | 31 +++-- tests/sprint2/expected/sp2_library.expected | 75 +++++----- tests/sprint2/expected/sp2_llnode.expected | 128 +++++++++--------- tests/sprint2/expected/sp2_one_line.expected | 59 ++++---- .../sprint2/expected/sp2_presidence.expected | 36 +++-- tests/sprint2/expected/sp2_simple.expected | 28 ++-- .../expected/sp2_sp2_arrayargs.expected | 17 +++ .../sp2_valid_assignable_and_mem.expected | 39 +++--- .../expected/sp3_and_or_type_check.expected | 34 +++++ .../sp3_boolean_binary_op_typecheck.expected | 37 ++--- .../sp3_boolean_unary_op_typecheck.expected | 37 ++--- .../sp3_carls_second_mistake.expected | 37 ++--- .../sp3_integer_binary_op_typecheck.expected | 44 +++--- .../sp3_integer_unary_op_typecheck.expected | 37 ++--- .../expected/sp3_multiple_args.expected | 25 ++++ .../sp3_primitive_type_check.expected | 19 +++ .../expected/sp3_record_size_check.expected | 29 ++++ 26 files changed, 677 insertions(+), 477 deletions(-) create mode 100644 tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected create mode 100644 tests/sprint2/expected/sp2_sp2_arrayargs.expected create mode 100644 tests/sprint3/expected/sp3_and_or_type_check.expected create mode 100644 tests/sprint3/expected/sp3_multiple_args.expected create mode 100644 tests/sprint3/expected/sp3_primitive_type_check.expected create mode 100644 tests/sprint3/expected/sp3_record_size_check.expected diff --git a/src/runner.c b/src/runner.c index 03e1933..6915d29 100644 --- a/src/runner.c +++ b/src/runner.c @@ -111,6 +111,13 @@ int run(FILE *alpha) { yyin = alpha; yyparse(); + if (tok_flag != NULL) { + while (0 != (token = yylex())) { + // Don't delete me 🥺 + } + fclose(tok_flag); + } + if (st_flag != NULL) { print_symbol_table(top, st_flag); fclose(st_flag); @@ -136,8 +143,6 @@ int run(FILE *alpha) { fclose(cg_flag); } - //yyparse(); - if (yyin != NULL) { fclose(yyin); } diff --git a/src/runner.h b/src/runner.h index 0a878d9..3e71a7a 100644 --- a/src/runner.h +++ b/src/runner.h @@ -5,11 +5,11 @@ #define TOK_LEN 3 #define ST_LEN 2 #define TC_LEN 2 -#define HELP \ - "HELP:\n" \ +#define HELP \ + "HELP:\n" \ " How to run the alpha compiler:\n" \ - " ./alpha [options] program\n" \ - "Valid options:\n" \ + " ./alpha [options] program\n" \ + "Valid options:\n" \ " -tok output the token number, token, line number, and column number for each of the tokens to the .tok file\n" \ " -st output the symbol table for the program to the .st file\n" \ " -asc output the annotated source code for the program to the .asc file, including syntax errors\n" \ diff --git a/src/symbol_table.c b/src/symbol_table.c index cd44b40..c1d3946 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -92,9 +92,9 @@ int getNumArrDim(TableNode *definition) { "function. Invalid."); return -1; } - if(getAdInfoType(definition) != TYPE_ARRAY_TYPE){ + if (getAdInfoType(definition) != TYPE_ARRAY_TYPE) { printdebug( - "passed an invalid node to getNumArrDim. Seeing tag %d in getNumArrDim. Invalid.",getAdInfoType(definition)); + "passed an invalid node to getNumArrDim. Seeing tag %d in getNumArrDim. Invalid.", getAdInfoType(definition)); return -1; } return definition->additionalinfo->ArrayAdInfo->numofdimensions; @@ -114,9 +114,9 @@ TableNode *getArrType(TableNode *definition) { "function. Invalid."); return undefined; } - if(getAdInfoType(definition) != TYPE_ARRAY_TYPE){ + if (getAdInfoType(definition) != TYPE_ARRAY_TYPE) { printdebug( - "passed an invalid node to getArrType. Seeing tag %d. Invalid.",getAdInfoType(definition)); + "passed an invalid node to getArrType. Seeing tag %d. Invalid.", getAdInfoType(definition)); return undefined; } return definition->additionalinfo->ArrayAdInfo->typeofarray; @@ -138,25 +138,25 @@ AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope) { // Perhaps this may not be needed since we need to iterate over all elements // anyways. -int getRecTotal(TableNode* node){ - if(node == NULL){ +int getRecTotal(TableNode *node) { + if (node == NULL) { printdebug( "passed a NULL node to getRecTotal. Invalid."); - return -1; + return -1; } - if(getAdInfoType(node) != TYPE_RECORD_TYPE){ + if (getAdInfoType(node) != TYPE_RECORD_TYPE) { printdebug( "passed an invalid node to getRecTotal. Invalid."); return -1; } - if(node->additionalinfo == NULL){ + if (node->additionalinfo == NULL) { printdebug( "node has NULL additionalinfo. Invalid."); return -1; } return node->additionalinfo->RecAdInfo->total_size; } -TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { +TableNode *setRecOffsetInfo(SymbolTable *scope, TableNode *node) { if (node == NULL) { printdebug( "passed a NULL node to setRecOffsetInfo. Invalid."); @@ -167,51 +167,47 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { "passed an NULL scope to setRecOffsetInfo. Invalid."); return undefined; } - if(getFirstEntry(scope) == NULL){ + if (getFirstEntry(scope) == NULL) { printdebug( "passed an empty scope to setRecOffsetInfo. Invalid."); return undefined; } - TableNode* this = getFirstEntry(scope); + TableNode *this = getFirstEntry(scope); int largest = 0; int k = getRecLength(node); int total_size = 0; int counter = 0; int *offsets = (int *)calloc(2 * k, sizeof(int)); - if(getAdInfoType(this) == TYPE_FUNCTION_DECLARATION){ + if (getAdInfoType(this) == TYPE_FUNCTION_DECLARATION) { offsets[counter] = 8; total_size = total_size + offsets[counter]; largest = 8; counter++; - } - else if((getAdInfoType(this) == TYPE_RECORD)){ + } else if ((getAdInfoType(this) == TYPE_RECORD)) { offsets[counter] = 8; printf("hitting record and adding to largest"); total_size = total_size + offsets[counter]; largest = offsets[counter]; counter++; - } - else if(getAdInfoType(this)==TYPE_PRIMITIVE){ + } else if (getAdInfoType(this) == TYPE_PRIMITIVE) { offsets[counter] = getPrimSize(getTypeEntry(this)); total_size = total_size + offsets[counter]; largest = offsets[counter]; counter++; - } - else if(getAdInfoType(this)==TYPE_ARRAY){ + } else if (getAdInfoType(this) == TYPE_ARRAY) { offsets[counter] = 8; total_size = total_size + offsets[counter]; largest = offsets[counter]; counter++; - } - else { + } else { printdebug( - "[TYPE CHECK] passed an invalid (first) parameter to a function definition. seeing %d. Type of entry is %s. Name attempted to pass is %s.",getAdInfoType(this),getType(this),getName(this)); + "[TYPE CHECK] passed an invalid (first) parameter to a function definition. seeing %d. Type of entry is %s. Name attempted to pass is %s.", getAdInfoType(this), getType(this), getName(this)); return undefined; } this = getNextEntry(this); - while(this != NULL){ - if(getAdInfoType(this) == TYPE_FUNCTION_DECLARATION){ + while (this != NULL) { + if (getAdInfoType(this) == TYPE_FUNCTION_DECLARATION) { int s = 8; if (s > largest) { largest = s; @@ -225,8 +221,7 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { total_size = total_size + offsets[counter]; counter++; this = getNextEntry(this); - } - else if(getAdInfoType(this) == TYPE_ARRAY){ + } else if (getAdInfoType(this) == TYPE_ARRAY) { int s = 8; if (s > largest) { largest = s; @@ -240,8 +235,7 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { total_size = total_size + offsets[counter]; counter++; this = getNextEntry(this); - } - else if((getAdInfoType(this) == TYPE_RECORD)){ + } else if ((getAdInfoType(this) == TYPE_RECORD)) { int s = 8; if (s > largest) { largest = s; @@ -257,8 +251,7 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { total_size = total_size + offsets[counter]; counter++; this = getNextEntry(this); - } - else if(getAdInfoType(this) == TYPE_PRIMITIVE){ + } else if (getAdInfoType(this) == TYPE_PRIMITIVE) { int s = getPrimSize(getTypeEntry(this)); if (s > largest) { largest = s; @@ -272,9 +265,9 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { total_size = total_size + offsets[counter]; counter++; this = getNextEntry(this); - }else{ + } else { printdebug( - "[TYPE CHECK] passed an invalid parameter at position %d in record.",((counter+1)/2)); + "[TYPE CHECK] passed an invalid parameter at position %d in record.", ((counter + 1) / 2)); return undefined; } } @@ -286,18 +279,18 @@ TableNode *setRecOffsetInfo(SymbolTable* scope, TableNode *node) { return node; } -int* getRecOffsets(TableNode* node){ - if(node == NULL){ +int *getRecOffsets(TableNode *node) { + if (node == NULL) { printdebug( "passed a NULL node to getRecTotal. Invalid."); - return NULL; + return NULL; } - if(getAdInfoType(node) != TYPE_RECORD_TYPE){ + if (getAdInfoType(node) != TYPE_RECORD_TYPE) { printdebug( "passed an invalid node to getRecTotal. Invalid."); return NULL; } - if(node->additionalinfo == NULL){ + if (node->additionalinfo == NULL) { printdebug( "node has NULL additionalinfo. Invalid."); return NULL; @@ -341,7 +334,8 @@ SymbolTable *getRecList(TableNode *definition) { if (strcmp(getType(definition), "record") != 0) { printdebug( "not checking the list of types of a record -- invalid " - "op of type %s", getType(definition)); + "op of type %s", + getType(definition)); return NULL; } return definition->additionalinfo->RecAdInfo->recordScope; @@ -521,7 +515,7 @@ TableNode *getParameter(TableNode *definition) { "function. Invalid."); return undefined; } - if(definition->additionalinfo == NULL){ + if (definition->additionalinfo == NULL) { printdebug( "node has NULL additionalinfo. Invalid."); return undefined; @@ -552,7 +546,7 @@ TableNode *getReturn(TableNode *definition) { "not checking the return of a function -- invalid op"); return undefined; } - if(definition->additionalinfo == NULL){ + if (definition->additionalinfo == NULL) { printdebug( "node has NULL additionalinfo. Invalid."); return undefined; @@ -605,10 +599,10 @@ SymbolTable *init(SymbolTable *start) { chara = (TableNode *)calloc(1, sizeof(TableNode)); stri = (TableNode *)calloc(1, sizeof(TableNode)); boo = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode* reservetype = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode* reserve = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode* releasetype = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode* release = (TableNode *)calloc(1, sizeof(TableNode)); + TableNode *reservetype = (TableNode *)calloc(1, sizeof(TableNode)); + TableNode *reserve = (TableNode *)calloc(1, sizeof(TableNode)); + TableNode *releasetype = (TableNode *)calloc(1, sizeof(TableNode)); + TableNode *release = (TableNode *)calloc(1, sizeof(TableNode)); // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; @@ -721,7 +715,7 @@ SymbolTable *init(SymbolTable *start) { integ->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for integ addr->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for addr chara->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for chara - stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri + stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri boo->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for boo reserve->tag = TYPE_FUNCTION_DECLARATION; reservetype->tag = TYPE_FUNCTION_TYPE; @@ -1064,7 +1058,7 @@ TableNode *table_lookup(SymbolTable *table, char *x) { // check current table and all parents TableNode *look_up(SymbolTable *table, char *x) { if (table == NULL) { - printdebug("Could not find %s in any scope using lookup",x); + printdebug("Could not find %s in any scope using lookup", x); return undefined; } TableNode *ret = table_lookup(table, x); @@ -1157,33 +1151,33 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } } if (getAdInfoType(entry) == TYPE_ARRAY) { - char *arrayType = (char *)malloc(100); - //sprintf(arrayType, " %d -> %s", getNumArrDim(entry), - // getName(getArrType(entry))); - + char *arrayType = (char *)malloc(sizeof(getType(entry) + 1)); + sprintf(arrayType, " %s", getType(entry)); if (parentScopeNum == 0) { - st_fprint(file_ptr, getName(entry), currentScopeNum, -100, getType(entry), " Array Instance"); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, arrayType, " Array Instance"); } else { - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, getType(entry), " Array Instance"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, arrayType, " Array Instance"); } } if (getAdInfoType(entry) == TYPE_RECORD_TYPE) { char *recordAdInfo = (char *)malloc(100); sprintf(recordAdInfo, " elements-%d size-%d bytes", getRecLength(entry), getRecTotal(entry)); if (parentScopeNum == 0) { - st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " record type", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " Record Type", recordAdInfo); } else { - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, " record type", recordAdInfo); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, " Record Type", recordAdInfo); } } if (getAdInfoType(entry) == TYPE_RECORD) { char *recordAdInfo = (char *)malloc(100); sprintf(recordAdInfo, " elements-%d", getRecLength(entry)); + char *recordType = (char *)malloc(sizeof(getType(entry) + 1)); + sprintf(recordType, " %s", getType(entry)); if (parentScopeNum == 0) { - st_fprint(file_ptr, getName(entry), currentScopeNum, -100, getType(entry), "record instance"); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, recordType, " Record Instance"); } else { - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, getType(entry), "record instance"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, recordType, " Record Instance"); } } @@ -1193,8 +1187,6 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parentScopeNum == 0) { st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " Primitive Type", primAdInfo); } else { - //printdebug("%sTHIS ONE", COLOR_RED); - printTableNode(entry); char *primType = (char *)malloc(sizeof(getType(entry) + 1)); sprintf(primType, " %s", getType(entry)); st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, primType, primAdInfo); @@ -1206,11 +1198,9 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (parentScopeNum == 0) { st_fprint(file_ptr, getName(entry), currentScopeNum, -100, " Primitive", primAdInfo); } else { - printdebug("%sTHIS ONE", COLOR_RED); - printTableNode(entry); char *primType = (char *)malloc(sizeof(getType(entry) + 1)); sprintf(primType, " %s", getType(entry)); - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, getType(entry), "Primitive Instance"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, primType, " Primitive Instance"); } } @@ -1226,10 +1216,12 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) { + char *functiontype = (char *)malloc(100); + sprintf(functiontype, " %s", getName(getReturn(entry))); if (parentScopeNum == 0) { - st_fprint(file_ptr, getName(entry), currentScopeNum, -100, getType(entry), " Function Definition"); + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, " Function Definition"); } else { - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, getType(entry), " Function Definition"); + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, functiontype, " Function Definition"); } } @@ -1393,7 +1385,7 @@ TableNode *getNextEntry(TableNode *tn) { // Uses pointers to the table node to print the info TableNode *printTableNode(TableNode *tn) { if (DEBUG == 0) { - return tn; + return tn; } if (tn == NULL) { diff --git a/src/symbol_table.h b/src/symbol_table.h index 6a33974..01d4458 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -7,80 +7,79 @@ #define SIZE_INT 4 #define SIZE_ADDR 8 #define SIZE_CHAR 1 -#define SIZE_BOOL 4 //TODO: Ask Carl what this size should be - +#define SIZE_BOOL 4 //TODO: Ask Carl what this size should be struct TableNode; typedef struct { - int size; + int size; } primitive_info; typedef struct { - int numofdimensions; - struct TableNode *typeofarray; + int numofdimensions; + struct TableNode *typeofarray; } array_info; typedef struct { - int numofelements; - struct SymbolTable *recordScope; - int total_size; - int* offsets; + int numofelements; + struct SymbolTable *recordScope; + int total_size; + int *offsets; } record_info; typedef struct { - int startlinenumber; - bool regularoras; + int startlinenumber; + bool regularoras; } function_declaration_info; typedef struct { - struct TableNode *parameter; - struct TableNode *returntype; + struct TableNode *parameter; + struct TableNode *returntype; } function_type_info; typedef union { - primitive_info *PrimAdInfo; - array_info *ArrayAdInfo; - record_info *RecAdInfo; - function_declaration_info *FunDecAdInfo; - function_type_info *FunTypeAdInfo; + primitive_info *PrimAdInfo; + array_info *ArrayAdInfo; + record_info *RecAdInfo; + function_declaration_info *FunDecAdInfo; + function_type_info *FunTypeAdInfo; } AdInfo; typedef struct ListOfTable { - struct SymbolTable *table; - struct ListOfTable *next; + struct SymbolTable *table; + struct ListOfTable *next; } ListOfTable; //Table node to store typedef struct TableNode { - struct TableNode *theType; - int tag; - char *theName; - AdInfo *additionalinfo; - struct TableNode *next; + struct TableNode *theType; + int tag; + char *theName; + AdInfo *additionalinfo; + struct TableNode *next; } TableNode; typedef struct SymbolTable { - TableNode *entries; - struct SymbolTable *Parent_Scope; - struct ListOfTable *Children_Scope; - int Line_Number; - int Column_Number; + TableNode *entries; + struct SymbolTable *Parent_Scope; + struct ListOfTable *Children_Scope; + int Line_Number; + int Column_Number; } SymbolTable; typedef enum { - TYPE_STRING = 1, - TYPE_ARRAY_TYPE = 2, - TYPE_RECORD_TYPE = 3, - TYPE_FUNCTION_DECLARATION = 4, - TYPE_FUNCTION_TYPE = 5, - TYPE_PRIMITIVE = 6, - TYPE_ALL_ELSE = 7, - TYPE_UNDEFINED = 8, - TYPE_RECORD = 9, - TYPE_ARRAY = 10, - TYPE_SYSTEM_DEFINED = 11, - TYPE_PRIMITIVE_TYPE = 12 + TYPE_STRING = 1, + TYPE_ARRAY_TYPE = 2, + TYPE_RECORD_TYPE = 3, + TYPE_FUNCTION_DECLARATION = 4, + TYPE_FUNCTION_TYPE = 5, + TYPE_PRIMITIVE = 6, + TYPE_ALL_ELSE = 7, + TYPE_UNDEFINED = 8, + TYPE_RECORD = 9, + TYPE_ARRAY = 10, + TYPE_SYSTEM_DEFINED = 11, + TYPE_PRIMITIVE_TYPE = 12 } types; AdInfo *CreatePrimitiveInfo(int size); @@ -128,10 +127,10 @@ ListOfTable *getRestOfChildren(ListOfTable *lt); TableNode *getFirstEntry(SymbolTable *st); TableNode *getNextEntry(TableNode *tn); -TableNode * printTableNode(TableNode * tn); +TableNode *printTableNode(TableNode *tn); void printdebug_impl(char *file, int line, const char *format, ...); -#define printdebug(format, ...) \ - printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) +#define printdebug(format, ...) \ + printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) extern int yylex(void); extern char *yytext; diff --git a/tests/sprint2/expected/sp2_carls_mistake.expected b/tests/sprint2/expected/sp2_carls_mistake.expected index 23a8694..cee5d6f 100644 --- a/tests/sprint2/expected/sp2_carls_mistake.expected +++ b/tests/sprint2/expected/sp2_carls_mistake.expected @@ -1,31 +1,35 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -bar2 : 001001 : : T2 : User Defined -bar1 : 001001 : : T2 : User Defined -foo : 001001 : : T1 : User Defined -arr : 001001 : : 1 -> integer : Type of Array -T2 : 001001 : : primitive function type : User Defined -T1 : 001001 : : primitive function type : User Defined -rec : 001001 : : record : elements-2 -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -w : 026000 : 001001 : rec : User Defined -result : 026000 : 001001 : integer : User Defined -arg : 026000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -r : 021000 : 001001 : integer : User Defined -s : 021000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -a : 017000 : 001001 : rec : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -x : 013000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -y : 004000 : 001001 : integer : User Defined -x : 004000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +bar2 : 001001 : : undefined : Function Definition +bar1 : 001001 : : undefined : Function Definition +foo : 001001 : : undefined : Function Definition +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +arr : 001001 : : 1 -> integer : Type of Array +T2 : 001001 : : rec -> integer : Type of Function +T1 : 001001 : : integer -> integer : Type of Function +rec : 001001 : : Record Type : elements-2 size-8 bytes +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +w : 025000 : 001001 : rec : Record Instance +result : 025000 : 001001 : integer : Primitive Instance +arg : 025000 : 001001 : string : Array Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +r : 021000 : 001001 : integer : Primitive Instance +s : 021000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 017000 : 001001 : integer : Primitive Instance +y : 017000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 013000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 001000 : 001001 : integer : Primitive Instance +x : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_function_types.expected b/tests/sprint2/expected/sp2_function_types.expected index bd1d2ce..391690b 100644 --- a/tests/sprint2/expected/sp2_function_types.expected +++ b/tests/sprint2/expected/sp2_function_types.expected @@ -1,26 +1,29 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -entry : 001001 : : string2integer : User Defined -integer2integer2integerFunc: 001001 : : integer2integer2integer : User Defined -released : 001001 : : address2integer : User Defined -reserved : 001001 : : integer2address : User Defined -printBoolean : 001001 : : Boolean2integer : User Defined -printCharacter : 001001 : : character2integer : User Defined -printInteger : 001001 : : integer2integer : User Defined -integer2integer2integer : 001001 : : primitive function type : User Defined -address2integer : 001001 : : primitive function type : User Defined -integer2address : 001001 : : primitive function type : User Defined -Boolean2Boolean2Boolean : 001001 : : primitive function type : User Defined -character2character2Boolean: 001001 : : primitive function type : User Defined -integer2integer2Boolean : 001001 : : primitive function type : User Defined -string2integer : 001001 : : primitive function type : User Defined -Boolean2integer : 001001 : : primitive function type : User Defined -character2integer : 001001 : : primitive function type : User Defined -integer2integer : 001001 : : primitive function type : User Defined -Boolean2Boolean : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +entry : 001001 : : undefined : Function Definition +integer2integer2integerFunc : 001001 : : undefined : Function Definition +released : 001001 : : undefined : Function Definition +reserved : 001001 : : undefined : Function Definition +printBoolean : 001001 : : undefined : Function Definition +printCharacter : 001001 : : undefined : Function Definition +printInteger : 001001 : : undefined : Function Definition +integer2integer2integer : 001001 : : integer2integer -> integer : Type of Function +address2integer : 001001 : : address -> integer : Type of Function +integer2address : 001001 : : integer -> address : Type of Function +Boolean2Boolean2Boolean : 001001 : : Boolean2Boolean -> Boolean : Type of Function +character2character2Boolean : 001001 : : undefined -> undefined : Type of Function +integer2integer2Boolean : 001001 : : integer2integer -> Boolean : Type of Function +string2integer : 001001 : : string -> integer : Type of Function +Boolean2integer : 001001 : : Boolean -> integer : Type of Function +character2integer : 001001 : : character -> integer : Type of Function +integer2integer : 001001 : : integer -> integer : Type of Function +Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition diff --git a/tests/sprint2/expected/sp2_integer_binary_op.expected b/tests/sprint2/expected/sp2_integer_binary_op.expected index 299c09d..d24c170 100644 --- a/tests/sprint2/expected/sp2_integer_binary_op.expected +++ b/tests/sprint2/expected/sp2_integer_binary_op.expected @@ -1,17 +1,21 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -b1 : 005000 : 001001 : Boolean : User Defined -b2 : 005000 : 001001 : Boolean : User Defined -arr2 : 005000 : 001001 : address : User Defined -arr : 005000 : 001001 : address : User Defined -x : 005000 : 001001 : integer : User Defined -arg : 005000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +testarr : 001001 : : 1 -> integer : Type of Array +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +b1 : 005000 : 001001 : Boolean : Primitive Instance +b2 : 005000 : 001001 : Boolean : Primitive Instance +arr2 : 005000 : 001001 : testarr : Array Instance +arr : 005000 : 001001 : testarr : Array Instance +x : 005000 : 001001 : integer : Primitive Instance +arg : 005000 : 001001 : string : Array Instance diff --git a/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected b/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected new file mode 100644 index 0000000..509c6eb --- /dev/null +++ b/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected @@ -0,0 +1,20 @@ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +test : 001001 : : undefined : Function Definition +main : 001001 : : rec -> integer : Type of Function +rec : 001001 : : Record Type : elements-2 size-8 bytes +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +arg : 005000 : 001001 : integer : Primitive Instance +arg2 : 005000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 001000 : 001001 : integer : Primitive Instance +x : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_invalid_recop.expected b/tests/sprint2/expected/sp2_invalid_recop.expected index 5274102..642ad85 100644 --- a/tests/sprint2/expected/sp2_invalid_recop.expected +++ b/tests/sprint2/expected/sp2_invalid_recop.expected @@ -1,17 +1,20 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -rec : 001001 : : record : elements-2 -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -w : 007000 : 001001 : rec : User Defined -arg : 007000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -y : 004000 : 001001 : integer : User Defined -x : 004000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +rec : 001001 : : Record Type : elements-2 size-8 bytes +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +w : 006000 : 001001 : rec : Record Instance +arg : 006000 : 001001 : string : Array Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 004000 : 001001 : integer : Primitive Instance +x : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_invalid_release.expected b/tests/sprint2/expected/sp2_invalid_release.expected index de26852..1ac0274 100644 --- a/tests/sprint2/expected/sp2_invalid_release.expected +++ b/tests/sprint2/expected/sp2_invalid_release.expected @@ -1,14 +1,17 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -rec : 001001 : : record : elements-2 -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -w : 004000 : 001001 : rec : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -y : 001000 : 001001 : integer : User Defined -x : 001000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +rec : 001001 : : Record Type : elements-2 size-8 bytes +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +w : 003000 : 001001 : rec : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 001000 : 001001 : integer : Primitive Instance +x : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_library.expected b/tests/sprint2/expected/sp2_library.expected index a1318bd..80a9611 100644 --- a/tests/sprint2/expected/sp2_library.expected +++ b/tests/sprint2/expected/sp2_library.expected @@ -1,36 +1,39 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -entry : 001001 : : string2integer : User Defined -printBoolean : 001001 : : Boolean2integer : User Defined -printCharacter : 001001 : : character2integer : User Defined -printInteger : 001001 : : integer2integer : User Defined -address2integer : 001001 : : primitive function type : User Defined -integer2address : 001001 : : primitive function type : User Defined -BooleanXBoolean2Boolean : 001001 : : primitive function type : User Defined -characterXcharacter2Boolean: 001001 : : primitive function type : User Defined -integerXinteger2Boolean : 001001 : : primitive function type : User Defined -integerXinteger2integer : 001001 : : primitive function type : User Defined -string2integer : 001001 : : primitive function type : User Defined -Boolean2integer : 001001 : : primitive function type : User Defined -character2integer : 001001 : : primitive function type : User Defined -integer2integer : 001001 : : primitive function type : User Defined -Boolean2Boolean : 001001 : : primitive function type : User Defined -integerXinteger : 001001 : : record : elements-2 -characterXcharacter : 001001 : : record : elements-2 -BooleanXBoolean : 001001 : : record : elements-2 -string : 001001 : : 1 -> character : Type of Array -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -y : 015000 : 001001 : integer : User Defined -x : 015000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -y : 014000 : 001001 : character : User Defined -x : 014000 : 001001 : character : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -y : 013000 : 001001 : Boolean : User Defined -x : 013000 : 001001 : Boolean : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +entry : 001001 : : undefined : Function Definition +printBoolean : 001001 : : undefined : Function Definition +printCharacter : 001001 : : undefined : Function Definition +printInteger : 001001 : : undefined : Function Definition +address2integer : 001001 : : address -> integer : Type of Function +integer2address : 001001 : : integer -> address : Type of Function +BooleanXBoolean2Boolean : 001001 : : BooleanXBoolean -> Boolean : Type of Function +characterXcharacter2Boolean : 001001 : : characterXcharacter -> Boolean : Type of Function +integerXinteger2Boolean : 001001 : : integerXinteger -> Boolean : Type of Function +integerXinteger2integer : 001001 : : integerXinteger -> integer : Type of Function +string2integer : 001001 : : string -> integer : Type of Function +Boolean2integer : 001001 : : Boolean -> integer : Type of Function +character2integer : 001001 : : character -> integer : Type of Function +integer2integer : 001001 : : integer -> integer : Type of Function +Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function +integerXinteger : 001001 : : Record Type : elements-2 size-8 bytes +characterXcharacter : 001001 : : Record Type : elements-2 size-2 bytes +BooleanXBoolean : 001001 : : Record Type : elements-2 size-8 bytes +string : 001001 : : 1 -> character : Type of Array +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 015000 : 001001 : integer : Primitive Instance +x : 015000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 014000 : 001001 : character : Primitive Instance +x : 014000 : 001001 : character : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 013000 : 001001 : Boolean : Primitive Instance +x : 013000 : 001001 : Boolean : Primitive Instance diff --git a/tests/sprint2/expected/sp2_llnode.expected b/tests/sprint2/expected/sp2_llnode.expected index dfe8d53..ab13e6f 100644 --- a/tests/sprint2/expected/sp2_llnode.expected +++ b/tests/sprint2/expected/sp2_llnode.expected @@ -1,62 +1,66 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -make_list : 001001 : : list : User Defined -bar2 : 001001 : : T2 : User Defined -bar1 : 001001 : : T2 : User Defined -foo : 001001 : : T1 : User Defined -list : 001001 : : primitive function type : User Defined -llnode : 001001 : : record : elements-3 -T2 : 001001 : : primitive function type : User Defined -T1 : 001001 : : primitive function type : User Defined -rec : 001001 : : record : elements-2 -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -li : 070000 : 001001 : llnode : User Defined -w : 070000 : 001001 : rec : User Defined -result : 070000 : 001001 : integer : User Defined -arg : 070000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -r : 054000 : 001001 : integer : User Defined -s : 054000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -x : 060009 : 054000 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ - : 062028 : 060009 : : Empty Scope --------------------------:--------:--------:--------------------------:------------------------------ - : 055021 : 054000 : : Empty Scope --------------------------:--------:--------:--------------------------:------------------------------ - : 056026 : 055021 : : Empty Scope --------------------------:--------:--------:--------------------------:------------------------------ -a : 050000 : 001001 : rec : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -x : 046000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -temp : 017000 : 001001 : address : User Defined -curr : 017000 : 001001 : address : User Defined -ret : 017000 : 001001 : address : User Defined -orig_a : 017000 : 001001 : integer : User Defined -a : 017000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ - : 021012 : 017000 : : Empty Scope --------------------------:--------:--------:--------------------------:------------------------------ - : 026023 : 021012 : : Empty Scope --------------------------:--------:--------:--------------------------:------------------------------ - : 035020 : 026023 : : Empty Scope --------------------------:--------:--------:--------------------------:------------------------------ - : 031034 : 026023 : : Empty Scope --------------------------:--------:--------:--------------------------:------------------------------ - : 019029 : 017000 : : Empty Scope --------------------------:--------:--------:--------------------------:------------------------------ -next : 008000 : 001001 : llnode : User Defined -val : 008000 : 001001 : integer : User Defined -prev : 008000 : 001001 : llnode : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -y : 004000 : 001001 : integer : User Defined -x : 004000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +make_list : 001001 : : undefined : Function Definition +bar2 : 001001 : : undefined : Function Definition +bar1 : 001001 : : undefined : Function Definition +foo : 001001 : : undefined : Function Definition +list : 001001 : : integer -> llnode : Type of Function +llnode : 001001 : : Record Type : elements-3 size-24 bytes +T2 : 001001 : : rec -> integer : Type of Function +T1 : 001001 : : integer -> integer : Type of Function +rec : 001001 : : Record Type : elements-2 size-8 bytes +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +li : 069000 : 001001 : llnode : Record Instance +w : 069000 : 001001 : rec : Record Instance +result : 069000 : 001001 : integer : Primitive Instance +arg : 069000 : 001001 : string : Array Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +r : 054000 : 001001 : integer : Primitive Instance +s : 054000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 059012 : 054000 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 062028 : 059012 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 055021 : 054000 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 056026 : 055021 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +a : 050000 : 001001 : integer : Primitive Instance +b : 050000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 046000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +temp : 016000 : 001001 : address : Primitive Instance +curr : 016000 : 001001 : address : Primitive Instance +ret : 016000 : 001001 : address : Primitive Instance +orig_a : 016000 : 001001 : integer : Primitive Instance +a : 016000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 021012 : 016000 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 026023 : 021012 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 035020 : 026023 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 031034 : 026023 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 019029 : 016000 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +next : 008000 : 001001 : llnode : Record Instance +val : 008000 : 001001 : integer : Primitive Instance +prev : 008000 : 001001 : llnode : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 004000 : 001001 : integer : Primitive Instance +x : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_one_line.expected b/tests/sprint2/expected/sp2_one_line.expected index 8dde170..dcdd20a 100644 --- a/tests/sprint2/expected/sp2_one_line.expected +++ b/tests/sprint2/expected/sp2_one_line.expected @@ -1,30 +1,29 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -bar2 : 001001 : : T2 : User Defined -bar1 : 001001 : : T2 : User Defined -foo : 001001 : : T1 : User Defined -T2 : 001001 : : primitive function type : User Defined -T1 : 001001 : : primitive function type : User Defined -rec : 001001 : : record : elements-2 -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -w : 001000 : 001001 : rec : User Defined -result : 001000 : 001001 : integer : User Defined -arg : 001000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -r : 001000 : 001001 : integer : User Defined -s : 001000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -a : 001000 : 001001 : rec : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -x : 001000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -y : 001000 : 001001 : integer : User Defined -x : 001000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +bar2 : 001001 : : undefined : Function Definition +bar1 : 001001 : : undefined : Function Definition +foo : 001001 : : undefined : Function Definition +T2 : 001001 : : rec -> integer : Type of Function +T1 : 001001 : : integer -> integer : Type of Function +rec : 001001 : : Record Type : elements-2 size-8 bytes +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 000000 : 001001 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +a : 001000 : 001001 : integer : Primitive Instance +undefined : 001000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 001000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 001000 : 001001 : integer : Primitive Instance +x : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_presidence.expected b/tests/sprint2/expected/sp2_presidence.expected index 70d9f83..80d2312 100644 --- a/tests/sprint2/expected/sp2_presidence.expected +++ b/tests/sprint2/expected/sp2_presidence.expected @@ -1,13 +1,23 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -x : 005000 : 001001 : integer : User Defined -arg : 005000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +entry : 001001 : : undefined : Function Definition +rec : 001001 : : Record Type : elements-2 size-8 bytes +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +arg_bool : 006000 : 001001 : Boolean : Primitive Instance +arg_record : 006000 : 001001 : rec : Record Instance +arg_y : 006000 : 001001 : integer : Primitive Instance +arg_x : 006000 : 001001 : integer : Primitive Instance +arg : 006000 : 001001 : string : Array Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +rec_y : 002000 : 001001 : integer : Primitive Instance +rec_x : 002000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_simple.expected b/tests/sprint2/expected/sp2_simple.expected index 8d55a97..649bea7 100644 --- a/tests/sprint2/expected/sp2_simple.expected +++ b/tests/sprint2/expected/sp2_simple.expected @@ -1,12 +1,16 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -arg : 005000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 004000 : 001001 : integer : Primitive Instance +arg : 004000 : 001001 : string : Array Instance diff --git a/tests/sprint2/expected/sp2_sp2_arrayargs.expected b/tests/sprint2/expected/sp2_sp2_arrayargs.expected new file mode 100644 index 0000000..0db9d5a --- /dev/null +++ b/tests/sprint2/expected/sp2_sp2_arrayargs.expected @@ -0,0 +1,17 @@ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +a_of_s : 001001 : : 1 -> string : Type of Array +string : 001001 : : 1 -> character : Type of Array +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +many_names : 006000 : 001001 : a_of_s : Array Instance +another_name : 006000 : 001001 : string : Array Instance +one_name : 006000 : 001001 : string : Array Instance diff --git a/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected b/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected index ab5cb2a..aa4b733 100644 --- a/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected +++ b/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected @@ -1,18 +1,21 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -T2 : 001001 : : primitive function type : User Defined -rec : 001001 : : record : elements-2 -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -w : 008000 : 001001 : rec : User Defined -arg : 008000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ -y : 004000 : 001001 : integer : User Defined -x : 004000 : 001001 : integer : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +T2 : 001001 : : rec -> integer : Type of Function +rec : 001001 : : Record Type : elements-2 size-8 bytes +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +w : 007000 : 001001 : rec : Record Instance +arg : 007000 : 001001 : string : Array Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 004000 : 001001 : integer : Primitive Instance +x : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint3/expected/sp3_and_or_type_check.expected b/tests/sprint3/expected/sp3_and_or_type_check.expected new file mode 100644 index 0000000..600a1f9 --- /dev/null +++ b/tests/sprint3/expected/sp3_and_or_type_check.expected @@ -0,0 +1,34 @@ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +test : 001001 : : undefined : Function Definition +main : 001001 : : rec -> integer : Type of Function +rec : 001001 : : Record Type : elements-2 size-8 bytes +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +b : 005000 : 001001 : Boolean : Primitive Instance +x : 005000 : 001001 : integer : Primitive Instance +arg : 005000 : 001001 : integer : Primitive Instance +undefined : 005000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 023009 : 005000 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 021014 : 005000 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 017009 : 005000 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 015017 : 005000 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 011012 : 005000 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 007015 : 005000 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 001000 : 001001 : integer : Primitive Instance +x : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected index 299c09d..1653f88 100644 --- a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected @@ -1,17 +1,20 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -b1 : 005000 : 001001 : Boolean : User Defined -b2 : 005000 : 001001 : Boolean : User Defined -arr2 : 005000 : 001001 : address : User Defined -arr : 005000 : 001001 : address : User Defined -x : 005000 : 001001 : integer : User Defined -arg : 005000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +b1 : 004000 : 001001 : Boolean : Primitive Instance +b2 : 004000 : 001001 : Boolean : Primitive Instance +arr2 : 004000 : 001001 : address : Primitive Instance +arr : 004000 : 001001 : address : Primitive Instance +x : 004000 : 001001 : integer : Primitive Instance +arg : 004000 : 001001 : string : Array Instance diff --git a/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected index 299c09d..1653f88 100644 --- a/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected @@ -1,17 +1,20 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -b1 : 005000 : 001001 : Boolean : User Defined -b2 : 005000 : 001001 : Boolean : User Defined -arr2 : 005000 : 001001 : address : User Defined -arr : 005000 : 001001 : address : User Defined -x : 005000 : 001001 : integer : User Defined -arg : 005000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +b1 : 004000 : 001001 : Boolean : Primitive Instance +b2 : 004000 : 001001 : Boolean : Primitive Instance +arr2 : 004000 : 001001 : address : Primitive Instance +arr : 004000 : 001001 : address : Primitive Instance +x : 004000 : 001001 : integer : Primitive Instance +arg : 004000 : 001001 : string : Array Instance diff --git a/tests/sprint3/expected/sp3_carls_second_mistake.expected b/tests/sprint3/expected/sp3_carls_second_mistake.expected index 5d0682f..6f509e0 100644 --- a/tests/sprint3/expected/sp3_carls_second_mistake.expected +++ b/tests/sprint3/expected/sp3_carls_second_mistake.expected @@ -1,17 +1,20 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -a_of_s : 001001 : : 1 -> string : Type of Array -string : 001001 : : 1 -> character : Type of Array -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -many_names : 010000 : 001001 : a_of_s : User Defined -another_name : 010000 : 001001 : string : User Defined -one_name : 010000 : 001001 : string : User Defined -arg : 010000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +a_of_s : 001001 : : 1 -> string : Type of Array +string : 001001 : : 1 -> character : Type of Array +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +many_names : 009000 : 001001 : a_of_s : Array Instance +another_name : 009000 : 001001 : string : Array Instance +one_name : 009000 : 001001 : string : Array Instance +arg : 009000 : 001001 : string : Array Instance diff --git a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected index a183cf5..8344120 100644 --- a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected @@ -1,18 +1,26 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -a : 005000 : 001001 : character : User Defined -b1 : 005000 : 001001 : Boolean : User Defined -b2 : 005000 : 001001 : Boolean : User Defined -arr2 : 005000 : 001001 : address : User Defined -arr : 005000 : 001001 : address : User Defined -x : 005000 : 001001 : integer : User Defined -arg : 005000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +entry : 001001 : : undefined : Function Definition +rec : 001001 : : Record Type : elements-2 size-8 bytes +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +r : 006000 : 001001 : rec : Record Instance +a : 006000 : 001001 : character : Primitive Instance +b1 : 006000 : 001001 : Boolean : Primitive Instance +b2 : 006000 : 001001 : Boolean : Primitive Instance +arr2 : 006000 : 001001 : address : Primitive Instance +arr : 006000 : 001001 : address : Primitive Instance +x : 006000 : 001001 : integer : Primitive Instance +arg : 006000 : 001001 : string : Array Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 003000 : 001001 : integer : Primitive Instance +x : 003000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected index 299c09d..1653f88 100644 --- a/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected @@ -1,17 +1,20 @@ -NAME : SCOPE : PARENT : TYPE : Extra annotation --------------------------:--------:--------:--------------------------:------------------------------ -entry : 001001 : : main : User Defined -main : 001001 : : primitive function type : User Defined -integer : 001001 : : Primitive : size-4 bytes -address : 001001 : : Primitive : size-8 bytes -character : 001001 : : Primitive : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive : size-1 bytes --------------------------:--------:--------:--------------------------:------------------------------ -b1 : 005000 : 001001 : Boolean : User Defined -b2 : 005000 : 001001 : Boolean : User Defined -arr2 : 005000 : 001001 : address : User Defined -arr : 005000 : 001001 : address : User Defined -x : 005000 : 001001 : integer : User Defined -arg : 005000 : 001001 : string : User Defined --------------------------:--------:--------:--------------------------:------------------------------ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +b1 : 004000 : 001001 : Boolean : Primitive Instance +b2 : 004000 : 001001 : Boolean : Primitive Instance +arr2 : 004000 : 001001 : address : Primitive Instance +arr : 004000 : 001001 : address : Primitive Instance +x : 004000 : 001001 : integer : Primitive Instance +arg : 004000 : 001001 : string : Array Instance diff --git a/tests/sprint3/expected/sp3_multiple_args.expected b/tests/sprint3/expected/sp3_multiple_args.expected new file mode 100644 index 0000000..c0128e1 --- /dev/null +++ b/tests/sprint3/expected/sp3_multiple_args.expected @@ -0,0 +1,25 @@ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +bar : 001001 : : undefined : Function Definition +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +T2 : 001001 : : rec -> integer : Type of Function +rec : 001001 : : Record Type : elements-2 size-6 bytes +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +w : 013000 : 001001 : rec : Record Instance +result : 013000 : 001001 : integer : Primitive Instance +arg : 013000 : 001001 : string : Array Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: + : 009000 : 001001 : : Empty Scope +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 001000 : 001001 : integer : Primitive Instance +x : 001000 : 001001 : character : Primitive Instance diff --git a/tests/sprint3/expected/sp3_primitive_type_check.expected b/tests/sprint3/expected/sp3_primitive_type_check.expected new file mode 100644 index 0000000..0a57752 --- /dev/null +++ b/tests/sprint3/expected/sp3_primitive_type_check.expected @@ -0,0 +1,19 @@ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +entry : 001001 : : undefined : Function Definition +main : 001001 : : string -> integer : Type of Function +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +bool : 015000 : 001001 : Boolean : Primitive Instance +char : 015000 : 001001 : character : Primitive Instance +add : 015000 : 001001 : address : Primitive Instance +i : 015000 : 001001 : integer : Primitive Instance +arg : 015000 : 001001 : string : Array Instance diff --git a/tests/sprint3/expected/sp3_record_size_check.expected b/tests/sprint3/expected/sp3_record_size_check.expected new file mode 100644 index 0000000..a061979 --- /dev/null +++ b/tests/sprint3/expected/sp3_record_size_check.expected @@ -0,0 +1,29 @@ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +tricky : 001001 : : Record Type : elements-4 size-16 bytes +rec : 001001 : : Record Type : elements-6 size-24 bytes +tom : 001001 : : Record Type : elements-2 size-8 bytes +integer : 001001 : : Primitive Type : size-4 bytes +address : 001001 : : Primitive Type : size-8 bytes +character : 001001 : : Primitive Type : size-1 bytes +string : 001001 : : 1 -> character : Type of Array +Boolean : 001001 : : Primitive Type : size-4 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : undefined : Function Definition +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : undefined : Function Definition +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +k2 : 003000 : 001001 : integer : Primitive Instance +b2 : 003000 : 001001 : Boolean : Primitive Instance +k1 : 003000 : 001001 : integer : Primitive Instance +b1 : 003000 : 001001 : Boolean : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 002000 : 001001 : integer : Primitive Instance +b : 002000 : 001001 : Boolean : Primitive Instance +d : 002000 : 001001 : character : Primitive Instance +c : 002000 : 001001 : character : Primitive Instance +prev : 002000 : 001001 : tom : Record Instance +x : 002000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +y : 001000 : 001001 : integer : Primitive Instance +x : 001000 : 001001 : integer : Primitive Instance From c72e7a2a284e88a39ec6ee6d486c765351cb9cc6 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 16 Apr 2025 16:30:58 -0400 Subject: [PATCH 117/137] Type check errors --- src/grammar.y | 163 +++++++++++++-------- src/runner.c | 36 +++-- src/runner.h | 6 +- src/symbol_table.c | 1 - tests/sprint2/test/sp2_carls_mistake.alpha | 2 +- tests/sprint2/test/sp2_llnode.alpha | 9 +- 6 files changed, 128 insertions(+), 89 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index c6044fd..a7d173e 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -19,9 +19,11 @@ %{ #include "../src/symbol_table.c" void yyerror(const char *err); + extern FILE *asc_flag; + extern bool tc_flag; int token_tracker; TableNode * tn; -// int counter; + void error_type(TableNode * left, TableNode * right, const char *format, ...); %} %union { @@ -169,10 +171,9 @@ definition: printdebug("see function def rule 1\n"); TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { - - printdebug(" [TYPE CHECK] undefined nodedeclared at line %d, column %d", @1.first_line, @1.first_column); + error_type(undefined, undefined, "Undefined node declared."); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - printdebug("[TYPE CHECK] not a valid function declaration at line %d, column %d", @1.first_line, @1.first_column); + error_type(undefined, undefined, "Not a valid function declaration."); } else { printdebug("setting as keyword to true"); @@ -186,7 +187,7 @@ definition: //TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); printdebug("type of parameter: %s", getName(parameter)); if (parameter == undefined) { - printdebug("[TYPE CHECK] function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column); + error_type(undefined, undefined, "Undefined parameter in function definition."); }else if(getAdInfoType(parameter) != TYPE_RECORD_TYPE){ int type_of_param_type = getAdInfoType(parameter);//this is an enum value defined in symbol_table.h if( type_of_param_type == TYPE_UNDEFINED @@ -197,7 +198,7 @@ definition: || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_RECORD || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("[TYPE CHECK] type of parameter being passed in to function definition is %s which is invalid", getAdInfo(parameter)); + error_type(parameter, undefined, "Invalid type (%s) of parameter in function definition.", getAdInfo(parameter)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases } if(type_of_param_type == TYPE_UNDEFINED){ @@ -225,7 +226,7 @@ definition: || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_RECORD_TYPE || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - printdebug("[TYPE CHECK] type of parameter (if record) inside record being passed in to function definition is %s which is invalid", getType(entry)); + error_type(entry, undefined, "Invalid type (%s) of parameter in function definition.", getAdInfo(entry)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getType(entry)); @@ -256,9 +257,9 @@ definition: } idlist R_PAREN ASSIGN sblock { TableNode *expected = getReturn(getTypeEntry(look_up(cur, $1))); if ($8 == undefined) { - printdebug("sblock return type is undefined"); + error_type(undefined, undefined, "Expected %s as return type but got undefined (possibly NULL). Differing return types in function.", getName(expected)); } else if ($8 != expected) { - printdebug("expected %s as return type but got %s", getName(expected), getName($8)); + error_type(undefined, undefined, "Expected %s as return type but got %s. Differing return types in function.", getName(expected), getName($8)); } else { printdebug("CORRECT RETURN TYPE!!!"); } @@ -273,7 +274,7 @@ function_declaration: CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); } else{ - printdebug("[TYPE CHECK] function declaration of %s is not a valid function type at line %d, column %d", $2, @1.first_line, @1.first_column); + error_type(undefined, undefined, "Function declatation (%s) is not a valid function type", $2); CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); } @@ -285,7 +286,7 @@ function_declaration: CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); } else{ - printdebug("[TYPE CHECK] function declaration of %s is not a valid function type at line %d, column %d", $3, @1.first_line, @1.first_column); + error_type(undefined, undefined, "Function declatation (%s) is not a valid function type", $3); CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); } @@ -430,7 +431,7 @@ declaration: printdebug("ID/TYPE: %s, ID: %s", getName((TableNode*)$1), $3) ; int d = getAdInfoType((TableNode*)$1); if(d == TYPE_UNDEFINED) { - printdebug("[TYPE CHECK] undefined type at line %d and column %d", @2.first_line, @2.first_column); + error_type(undefined, undefined, "Undefined type passed in declaration list"); CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } else if(d == TYPE_FUNCTION_TYPE) { @@ -453,7 +454,7 @@ declaration: d = TYPE_PRIMITIVE; CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); }else { - printdebug("[TYPE CHECK] other invalid type passed at %d and column %d", @2.first_line, @2.first_column); + error_type(undefined, undefined, "Invalid type passed in declaration list."); CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } } @@ -537,51 +538,39 @@ WHILE L_PAREN expression R_PAREN sblock { simple_statement: assignable ASSIGN expression - { - bool passCheck = false; - TableNode * left = (TableNode*)$1; - TableNode * right = (TableNode*)$3; - - printTableNode((TableNode*)$1); - printTableNode((TableNode*)$3); + { + TableNode* node; + if((getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE|| + getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_TYPE)){ + node = (TableNode*)$1; + }else if((getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION)|| + (getAdInfoType((TableNode*)$1) == TYPE_ARRAY)|| + (getAdInfoType((TableNode*)$1) == TYPE_RECORD)|| + (getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE)){ - if (strcmp(getType(right), "primitive") == 0) { - if (strcmp((getType(left)),(getName(right))) == 0) { - printdebug("%s[☺] Passed primitive type check; %s = %s", COLOR_GREEN, getName(left), getName(right)); - passCheck = true; + node = getTypeEntry((TableNode*)$1); + } else{ + error_type(undefined, undefined, "Invalid type passed to assignable."); + node = undefined; } - } - if(strcmp(getName(left), getName(right)) == 0) { - printdebug("Passed standard type check; assignable = expression"); - passCheck = true; - } - - if((strcmp(getType(left), "array") == 0) && (strcmp(getName(right), "address") == 0)) { - printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, getName(left), getName(right)); - passCheck = true; - } - - if((strcmp(getType(left), "record") == 0) && (strcmp(getName(right), "address") == 0)) { - printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, getName(left), getName(right)); - passCheck = true; - } - - if((strcmp(getType(left), "function type primitive") == 0) && (strcmp(getName(right), "address") == 0)) { - printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, getName(left), getName(right)); - passCheck = true; - } - - // Type check fails: - if (!passCheck) { - printdebug("%s[TYPE CHECK] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE); - printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType(left), getType(right), COLOR_WHITE); - printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(left)); + if((getAdInfoType(node) == TYPE_ARRAY_TYPE|| + getAdInfoType(node) == TYPE_RECORD_TYPE) && + (strcmp(getName((TableNode*)$3),"address") == 0)){ + printdebug("%s[☺] Passed array/record type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); + } + else if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); + } else { + error_type(node, (TableNode*)$3, ""); } $$ = undefined; } + | RETURN expression {$$ = $2;} ; @@ -644,7 +633,7 @@ expression: $$=(TableNode*)$2; } else { $$=undefined; - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,getName((TableNode*)$2)); + error_type((TableNode*)$2, boo, ""); } } @@ -654,8 +643,8 @@ expression: if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { $$=(TableNode*)$1; } else { - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; + error_type((TableNode*)$1, (TableNode*)$3, ""); } } @@ -665,8 +654,8 @@ expression: if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { $$=(TableNode*)$1; } else { - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; + error_type((TableNode*)$1, (TableNode*)$3, ""); } } @@ -676,8 +665,8 @@ expression: if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { $$=(TableNode*)$1; } else{ - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName($1),getName($3)); $$=undefined; + error_type((TableNode*)$1, (TableNode*)$3, ""); } } @@ -687,8 +676,8 @@ expression: if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && ((TableNode*)$1 == integ)) { $$=(TableNode*)$1; } else { - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; + error_type((TableNode*)$1, (TableNode*)$3, ""); } } @@ -698,8 +687,8 @@ expression: if($1 == $3 && $1 == integ) { $$=$1; } else { - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; + error_type((TableNode*)$1, (TableNode*)$3, ""); } } @@ -709,8 +698,8 @@ expression: if($1 == $3 && $1 == boo){ $$=$1; } else{ - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; + error_type((TableNode*)$1, (TableNode*)$3, ""); } } @@ -720,8 +709,8 @@ expression: if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && $1 == boo) { $$=$1; } else { - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; + error_type((TableNode*)$1, (TableNode*)$3, ""); } } @@ -731,8 +720,8 @@ expression: if($1 == $3 && $1==integ) { $$=boo; } else { - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$=undefined; + error_type((TableNode*)$1, (TableNode*)$3, ""); } } @@ -742,8 +731,8 @@ expression: if($1 == $3 && $1 != undefined) { $$=boo; } else { - printdebug("[TYPE CHECK] mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,getName((TableNode*)$1),getName((TableNode*)$3)); $$ = undefined; + error_type((TableNode*)$1, (TableNode*)$3, ""); } } @@ -766,7 +755,7 @@ expression: $$= ((TableNode*)$1); } else { - printdebug("[TYPE CHECK] assignable passing up an invalid type to expression"); + error_type(undefined, undefined, "Invalid type passed to expression."); $$= ((TableNode*)$1); } @@ -782,10 +771,9 @@ expression: { int d = getAdInfoType((TableNode*)$2); if(d == TYPE_ARRAY_TYPE || d == TYPE_ARRAY || d == TYPE_RECORD_TYPE || d == TYPE_RECORD) { - //printdebug("[TYPE CHECK] valid memOp expression"); $$ = addr; } else { - printdebug("[TYPE CHECK] invalid memOp expression at line %d and column %d.", @2.first_line,@2.first_column,getName((TableNode*)$2)); + error_type(undefined, undefined, "Invalid memOp expression (%s).", getName((TableNode*)$2)); $$=undefined; } } @@ -989,6 +977,51 @@ types: -void yyerror(const char *err) { - fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column); +void error_type(TableNode * left, TableNode * right, const char *format, ...) { + int line = yylloc.first_line; + int column = yylloc.first_column; + + if (tc_flag) { + yyerror(""); + if (strcmp(format, "") == 0) { + if (asc_flag != NULL) { + fprintf(asc_flag, "(%d:%d) ** TYPE ERROR: %s != %s\n", line, column, getName(left), getName(right)); + } else { + fprintf(stderr, "%s(%d:%d) ** TYPE ERROR%s: %s%s %s!= %s%s\n", + COLOR_RED, line, column, COLOR_WHITE, COLOR_YELLOW, getName(left), COLOR_WHITE, COLOR_YELLOW, getName(right), COLOR_WHITE); + } + } else { + if (asc_flag != NULL) { + fprintf(asc_flag, "(%d:%d) ** TYPE ERROR: ", line, column); + va_list args; + va_start(args, format); + vfprintf(asc_flag, format, args); + va_end(args); + fprintf(asc_flag, "\n"); + } else { + fprintf(stderr, "%s(%d:%d) ** TYPE ERROR%s: %s", COLOR_RED, line, column, COLOR_WHITE, COLOR_YELLOW); + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "%s\n", COLOR_WHITE); + } + } + } +} + +void yyerror(const char *err) { + int line = yylloc.first_line; + int column = yylloc.first_column; + + // Grammar Fallback Case + if (strcmp(err, "syntax error") == 0) { + if (asc_flag != NULL) { + fprintf(asc_flag, "(%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n", line, column, yytext); + } + else { + fprintf(stderr, "%s(%d:%d) ** SYNTAX ERROR%s: Incorrect syntax at token '%s%s%s'\n", + COLOR_RED, line, column, COLOR_WHITE, COLOR_YELLOW, yytext, COLOR_WHITE); + } + } } diff --git a/src/runner.c b/src/runner.c index 6915d29..3fa35ca 100644 --- a/src/runner.c +++ b/src/runner.c @@ -59,8 +59,9 @@ int check_flag(char *arg, char *alpha) { fprintf(stderr, "FLAGS REPEAT\n"); return -1; } else if (strcmp("-tc", arg) == 0) { - if (tc_flag == NULL) { - return new_file(arg, alpha); + if (tc_flag == false) { + tc_flag = true; + return 0; } fprintf(stderr, "FLAGS REPEAT\n"); return -1; @@ -124,13 +125,12 @@ int run(FILE *alpha) { } if (asc_flag != NULL) { - printf("Flag -asc is not implemented yet\n"); + printdebug("[-asc] Annotated Source Code is enabled."); fclose(asc_flag); } - if (tc_flag != NULL) { - printf("Flag -tc is not implemented yet\n"); - fclose(tc_flag); + if (tc_flag != false) { + printdebug("[-tc] Type checking is enabled."); } if (ir_flag != NULL) { @@ -180,8 +180,12 @@ int new_file(char *arg, char *alpha) { type_len = TOK_LEN; } else if (strcmp(arg, "-st") == 0) { type_len = ST_LEN; - } else if (strcmp(arg, "-tc") == 0) { - type_len = TC_LEN; + } else if (strcmp(arg, "-asc") == 0) { + type_len = ASC_LEN; + } else if (strcmp(arg, "-ir") == 0) { + type_len = IR_LEN; + } else if (strcmp(arg, "-cg") == 0) { + type_len = CG_LEN; } else { fprintf(stderr, INVALID); return -1; @@ -189,13 +193,17 @@ int new_file(char *arg, char *alpha) { // calculate lengths int basename_len = strlen(basename); - char *file_name = - calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char)); + char *file_name = calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char)); // coy filename and add extension - strncpy(file_name, basename, basename_len - ALPHA_OFFSET); - strcat(file_name, "."); - strcat(file_name, arg + 1); + if (strcmp(arg, "-cg") == 0) { + strncpy(file_name, basename, basename_len - ALPHA_OFFSET); + strcat(file_name, ".s"); + } else { + strncpy(file_name, basename, basename_len - ALPHA_OFFSET); + strcat(file_name, "."); + strcat(file_name, arg + 1); + } if (strcmp(arg, "-tok") == 0) { tok_flag = fopen(file_name, "w"); @@ -203,8 +211,6 @@ int new_file(char *arg, char *alpha) { st_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-asc") == 0) { asc_flag = fopen(file_name, "w"); - } else if (strcmp(arg, "-tc") == 0) { - tc_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-ir") == 0) { ir_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-cg") == 0) { diff --git a/src/runner.h b/src/runner.h index 3e71a7a..7989473 100644 --- a/src/runner.h +++ b/src/runner.h @@ -4,7 +4,9 @@ #define ALPHA_OFFSET 6 #define TOK_LEN 3 #define ST_LEN 2 -#define TC_LEN 2 +#define ASC_LEN 3 +#define IR_LEN 2 +#define CG_LEN 1 #define HELP \ "HELP:\n" \ " How to run the alpha compiler:\n" \ @@ -44,10 +46,10 @@ SymbolTable *cur; FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; -FILE *tc_flag = NULL; FILE *ir_flag = NULL; FILE *cg_flag = NULL; FILE *asc_flag = NULL; +bool tc_flag = false; bool DEBUG = false; int no_flag = 0; int arg; diff --git a/src/symbol_table.c b/src/symbol_table.c index c1d3946..21669b5 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -185,7 +185,6 @@ TableNode *setRecOffsetInfo(SymbolTable *scope, TableNode *node) { counter++; } else if ((getAdInfoType(this) == TYPE_RECORD)) { offsets[counter] = 8; - printf("hitting record and adding to largest"); total_size = total_size + offsets[counter]; largest = offsets[counter]; counter++; diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index 26b8725..b7fa8ee 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -28,7 +28,7 @@ entry (arg) := { w := reserve w; (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*) w.x := 5; w.y := 7; - result := bar1(w); (* pass w (a rec type value) to bar1 *) + ressult := bar1(w); (* pass w (a rec type value) to bar1 *) result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *) return 0; } diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index b102ba8..3ecfb11 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -14,20 +14,20 @@ function bar2 : T2 function make_list : list make_list (a) := { - [integer:orig_a; address: ret; address: curr; address: temp] + [integer:orig_a; llnode: ret; llnode: curr; llnode: temp] if (a < 0 | a = 0) then { return null; } else { - ret := reserve llnode; + ret := reserve ret; ret.prev := null; ret.next := null; ret.val := a; while (0 < a) { - temp := reserve llnode; + temp := reserve temp; temp.prev := null; temp.next := null; - temp.val := val; + temp.val := ret.val; if (a = orig_a) then { ret.next := temp; temp.prev := ret; @@ -68,7 +68,6 @@ bar2(r,s) := { entry (arg) := { [ integer: result ; rec: w; llnode: li] - li := make_list(6); result := foo(5); w := reserve w; From b8f468c94a698139eadd6fa98b8bad6fd0edebd0 Mon Sep 17 00:00:00 2001 From: Meyer Simon Date: Thu, 17 Apr 2025 11:14:38 -0400 Subject: [PATCH 118/137] It seems that I had for gotten to fix one of the signatures --- src/intermediate_code.c | 70 +++++++++++++++++++++++++---------------- src/intermediate_code.h | 49 +++++++++++++++-------------- 2 files changed, 68 insertions(+), 51 deletions(-) diff --git a/src/intermediate_code.c b/src/intermediate_code.c index cd967cc..6ac5429 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -1,6 +1,5 @@ #include #include "intermediate_code.h" -#include "symbol_table.h" Instruction * begin; Instruction * current; @@ -11,7 +10,31 @@ char * temp = NULL; // check if start is NULL if it is assign it to the start globle variable // otherwise make it next of current and set cur to your instruction. -TNodeOrConst * tn_or_const(Op op, RegConstUnion r); +TNodeOrConst * tn_or_const(Op op, void * tnc) { + TNodeOrConst * count = calloc(1, sizeof(*count)); + count->d = op; + switch (op) { + case NODE: + count->tnc_union->node = tnc; + break; + case ADDRESS: + count->tnc_union->address = tnc; + break; + case STRING: + count->tnc_union->string = tnc; + break; + case INTEGER: + count->tnc_union->integer = *(int*)tnc; + break; + case CHARACTER: + count->tnc_union->character = *(char*)tnc; + break; + case BOOLEAN: + count->tnc_union->Boolean = *(bool*)tnc; + break; + } + return count; +} static void emit_helper(void){ Instruction * inst = calloc(1, sizeof(*inst)); @@ -26,7 +49,7 @@ static void emit_helper(void){ } } -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TableNode * arg2){ +void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2){ emit_helper(); current->opcode = op; current->result = result; @@ -61,35 +84,29 @@ void emit_as_file(FILE * out_file, Instruction * instr_arr){ } -void emit_label(char* label){ +void emit_label(int label){ emit_helper(); current->opcode = E_LABEL; current->label = label; return; } -void emit_jump(char* label){ +void emit_jump(int label){ emit_helper(); current->opcode = E_GOTO; current->label = label; return; } -void emit_conditional_jump(int count, ...){ - // it apears that I cant do what I want So we will have to deal with - // the limitations presented. - // arg_count is the number of args passed to the function - // from there the sequence is Op, char * , TableNode * , and an optional - // extra TableNode *. - // when this instruction is a conditional jump then ... is 1 - // when the inst is a cond with a Relational op then ... is 2 + +void emit_conditional_jump(Op condition, int label, ...){ + // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). + // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) emit_helper(); va_list argptr; - va_start(argptr, count); - Op condition = va_arg(argptr, Op); - char * label = va_arg(argptr, char *); + va_start(argptr, label); current->opcode = condition; current->label = label; TNodeOrConst * n1; - TableNode * n2; + TNodeOrConst * n2; switch (condition) { case E_IF_X_TRUE: case E_IF_X_FALSE: n1 = va_arg(argptr, TNodeOrConst *); @@ -97,21 +114,23 @@ void emit_conditional_jump(int count, ...){ break; case E_LESSTHEN: case E_EQUALTO: n1 = va_arg(argptr, TNodeOrConst *); - n2 = va_arg(argptr, TableNode *); + n2 = va_arg(argptr, TNodeOrConst *); current->operand1 = n1; current->operand2 = n2; break; } + va_end(argptr); return; } -void emit_function_start(char * name){ - emit_helper(); // actualy what is this? +void emit_function_start(int name){ + emit_helper(); current->opcode = E_LABEL; // I think this is right TODO: ask - current->label = name; // wait what is a function start + current->label = name; // this is probabaly a func decleration return; } + void emit_parameter(TNodeOrConst * param){ emit_helper(); current->opcode = E_PARAM; @@ -119,13 +138,10 @@ void emit_parameter(TNodeOrConst * param){ return; } -void emit_function_call(TableNode * result, int param_count, TableNode * name){ +void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name){ emit_helper(); current->opcode = E_CALL; - TNodeOrConst * count = calloc(1, sizeof(*count)); - count->d = INTEGER; - count->rc_union->integer = param_count; - current->operand1 = count; + current->operand1 = tn_or_const(INTEGER, ¶m_count); current->operand2 = name; current->result = result; return; @@ -168,7 +184,7 @@ char * temp_var_gen(){ return ret; } -char * lable_gen(){ +char * label_gen(){ char * ret = calloc( 9, sizeof(*ret)); sprintf(ret, "L_%d", label_count); label_count++; diff --git a/src/intermediate_code.h b/src/intermediate_code.h index 8b8edb5..fc3cdc4 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -2,7 +2,7 @@ // * Add Bison actions for arithmetic expressions: // - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); // - Subtraction, multiplication, division, modulo -#include "symbol_table.h" +#include "runner.h" #include // these are from page 364 @@ -44,42 +44,43 @@ typedef enum { } Discriminant; typedef union { - TableNode * node; - int integer; - char * string; - char character; - void * address; - bool Boolean; -} RegConstUnion; + TableNode * node; + int integer; + char * string; + char character; + void * address; + bool Boolean; +} TNConstUnion; typedef struct { Discriminant d; - RegConstUnion * rc_union; + TNConstUnion * tnc_union; } TNodeOrConst; typedef struct Instruction Instruction; typedef struct Instruction { Op opcode; - TableNode * result; + TableNode * result; TNodeOrConst * operand1; - TableNode * operand2; - char * label; + TNodeOrConst * operand2; + int label; + int index; - int index; - - Instruction * prev; - Instruction * next; + Instruction * prev; + Instruction * next; } Instruction; -extern Instruction * begin; -extern Instruction * current; +extern Instruction * begin; +extern Instruction * current; int temp_count = 0; int label_count = 0; bool code_gen = true; -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TableNode * arg2); +TNodeOrConst * tn_or_const(Op op, void * tnc); + +void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2); void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); void emit_assignment(TableNode * target, TNodeOrConst * source); // TODO: Find out what these are suposed to do. Guess is create an entry in @@ -93,13 +94,13 @@ void emit_as_file(FILE * out_file, Instruction * instr_arr); // * Implement instruction array storage for backpatching -void emit_label(char* label); -void emit_jump(char* label); -void emit_conditional_jump(int count, ...); +void emit_label(int label); +void emit_jump(int label); +void emit_conditional_jump(Op condition, int label, ...); -void emit_function_start(char* name); +void emit_function_start(int name); void emit_parameter(TNodeOrConst * param); -void emit_function_call(TNodeOrConst * result, TNodeOrConst * name); +void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); void emit_return(TNodeOrConst * value); void emit_reserve(char* result, char* type_name, int size); void emit_release(char* pointer); From ecafbf713a07a6eb9a79dbf036b0cf734ff3578e Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 23 Apr 2025 15:55:08 -0400 Subject: [PATCH 119/137] init branch --- src/grammar.h | 10 ++++++++++ src/lexicalStructure.h | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/grammar.h create mode 100644 src/lexicalStructure.h diff --git a/src/grammar.h b/src/grammar.h new file mode 100644 index 0000000..58cedbd --- /dev/null +++ b/src/grammar.h @@ -0,0 +1,10 @@ +#ifndef GRAMMAR_H +#define GRAMMAR_H + +#include "../src/runner.h" + +void yyerror(const char *err); +int token_tracker; +TableNode * tn; + +#endif \ No newline at end of file diff --git a/src/lexicalStructure.h b/src/lexicalStructure.h new file mode 100644 index 0000000..c7baafe --- /dev/null +++ b/src/lexicalStructure.h @@ -0,0 +1,33 @@ +#ifndef LEXICALSTRUCTURE_H +#define LEXICALSTRUCTURE_H + +#include "../tmp/grammar.tab.h" +#include "../src/symbol_table.h" + +extern SymbolTable * cur; +extern FILE* tok_flag; +extern TableNode *funprime; +extern TableNode *funtypeprime; +extern TableNode *arrayprim; +extern TableNode *recprime; +extern TableNode *integ; +extern TableNode *addr; +extern TableNode *chara; +extern TableNode *stri; +extern TableNode *boo; +extern TableNode *undefined; +extern void incr(int lnum,int cnum, int tok); +extern void print_tok(int tok); + +extern int line_number; +extern int column_number; +extern int yycolumn; +#define YY_USER_ACTION { \ + yylloc.first_line = yylineno; \ + yylloc.last_line = yylineno; \ + yylloc.first_column = yycolumn; \ + yylloc.last_column = yycolumn + yyleng - 1; \ + yycolumn += yyleng; \ +} + +#endif \ No newline at end of file From 945dda59d045133fc7dbfdda596298578f80c6dc Mon Sep 17 00:00:00 2001 From: Scarlett Date: Wed, 23 Apr 2025 17:11:43 -0400 Subject: [PATCH 120/137] throw_error() function implemented --- src/grammar.y | 117 +++++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 49 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index a7d173e..e98f9d0 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -23,7 +23,13 @@ extern bool tc_flag; int token_tracker; TableNode * tn; - void error_type(TableNode * left, TableNode * right, const char *format, ...); + typedef enum { + ERROR_RUNTIME = 1, + ERROR_SYNTAX = 2, + ERROR_TYPE = 3, + ERROR_UNDEFINED = 4 + } ErrorType; + void throw_error(ErrorType error_type, const char *format, ...); %} %union { @@ -171,9 +177,9 @@ definition: printdebug("see function def rule 1\n"); TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { - error_type(undefined, undefined, "Undefined node declared."); + printdebug("Undefined node declared."); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ - error_type(undefined, undefined, "Not a valid function declaration."); + throw_error(ERROR_SYNTAX, "Not a valid function declaration."); } else { printdebug("setting as keyword to true"); @@ -187,7 +193,7 @@ definition: //TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $1)))); printdebug("type of parameter: %s", getName(parameter)); if (parameter == undefined) { - error_type(undefined, undefined, "Undefined parameter in function definition."); + throw_error(ERROR_TYPE, "Undefined parameter in function definition."); }else if(getAdInfoType(parameter) != TYPE_RECORD_TYPE){ int type_of_param_type = getAdInfoType(parameter);//this is an enum value defined in symbol_table.h if( type_of_param_type == TYPE_UNDEFINED @@ -198,7 +204,7 @@ definition: || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_RECORD || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - error_type(parameter, undefined, "Invalid type (%s) of parameter in function definition.", getAdInfo(parameter)); + throw_error(ERROR_TYPE, "Invalid type (%s) of parameter in function definition.", getAdInfo(parameter)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases } if(type_of_param_type == TYPE_UNDEFINED){ @@ -226,7 +232,7 @@ definition: || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_RECORD_TYPE || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused - error_type(entry, undefined, "Invalid type (%s) of parameter in function definition.", getAdInfo(entry)); + throw_error(ERROR_TYPE, "Invalid type (%s) of parameter in function definition.", getAdInfo(entry)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ printdebug("type of parameter correctly being passed in to AS function definition is %s which is valid", getType(entry)); @@ -257,9 +263,9 @@ definition: } idlist R_PAREN ASSIGN sblock { TableNode *expected = getReturn(getTypeEntry(look_up(cur, $1))); if ($8 == undefined) { - error_type(undefined, undefined, "Expected %s as return type but got undefined (possibly NULL). Differing return types in function.", getName(expected)); + throw_error(ERROR_TYPE, "Expected %s as return type but got undefined (possibly NULL). Differing return types in function.", getName(expected)); } else if ($8 != expected) { - error_type(undefined, undefined, "Expected %s as return type but got %s. Differing return types in function.", getName(expected), getName($8)); + throw_error(ERROR_TYPE, "Expected %s as return type but got %s. Differing return types in function.", getName(expected), getName($8)); } else { printdebug("CORRECT RETURN TYPE!!!"); } @@ -274,7 +280,7 @@ function_declaration: CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); } else{ - error_type(undefined, undefined, "Function declatation (%s) is not a valid function type", $2); + throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $2); CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); } @@ -286,7 +292,7 @@ function_declaration: CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); } else{ - error_type(undefined, undefined, "Function declatation (%s) is not a valid function type", $3); + throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $3); CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); } @@ -431,7 +437,7 @@ declaration: printdebug("ID/TYPE: %s, ID: %s", getName((TableNode*)$1), $3) ; int d = getAdInfoType((TableNode*)$1); if(d == TYPE_UNDEFINED) { - error_type(undefined, undefined, "Undefined type passed in declaration list"); + printdebug("Undefined type passed in declaration list"); CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } else if(d == TYPE_FUNCTION_TYPE) { @@ -454,7 +460,7 @@ declaration: d = TYPE_PRIMITIVE; CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); }else { - error_type(undefined, undefined, "Invalid type passed in declaration list."); + printdebug("Invalid type passed in declaration list."); CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } } @@ -552,7 +558,7 @@ simple_statement: node = getTypeEntry((TableNode*)$1); } else{ - error_type(undefined, undefined, "Invalid type passed to assignable."); + printdebug("Invalid type passed to assignable."); node = undefined; } @@ -564,7 +570,7 @@ simple_statement: else if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); } else { - error_type(node, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName(node), getName((TableNode*)$3)); } $$ = undefined; @@ -633,7 +639,7 @@ expression: $$=(TableNode*)$2; } else { $$=undefined; - error_type((TableNode*)$2, boo, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$2), getName(boo)); } } @@ -644,7 +650,7 @@ expression: $$=(TableNode*)$1; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); } } @@ -655,7 +661,7 @@ expression: $$=(TableNode*)$1; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); } } @@ -666,7 +672,7 @@ expression: $$=(TableNode*)$1; } else{ $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); } } @@ -677,7 +683,7 @@ expression: $$=(TableNode*)$1; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); } } @@ -688,7 +694,7 @@ expression: $$=$1; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); } } @@ -699,7 +705,7 @@ expression: $$=$1; } else{ $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); } } @@ -710,7 +716,7 @@ expression: $$=$1; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); } } @@ -721,7 +727,7 @@ expression: $$=boo; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); } } @@ -732,7 +738,7 @@ expression: $$=boo; } else { $$ = undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); } } @@ -755,7 +761,7 @@ expression: $$= ((TableNode*)$1); } else { - error_type(undefined, undefined, "Invalid type passed to expression."); + printdebug("Invalid type passed to expression."); $$= ((TableNode*)$1); } @@ -773,7 +779,7 @@ expression: if(d == TYPE_ARRAY_TYPE || d == TYPE_ARRAY || d == TYPE_RECORD_TYPE || d == TYPE_RECORD) { $$ = addr; } else { - error_type(undefined, undefined, "Invalid memOp expression (%s).", getName((TableNode*)$2)); + throw_error(ERROR_TYPE, "Invalid memOp expression (%s).", getName((TableNode*)$2)); $$=undefined; } } @@ -977,35 +983,48 @@ types: -void error_type(TableNode * left, TableNode * right, const char *format, ...) { +void throw_error(ErrorType error_type, const char *format, ...) { int line = yylloc.first_line; int column = yylloc.first_column; + char * error_name = ""; + + switch (error_type) { + case ERROR_RUNTIME: + error_name = malloc(strlen("RUNTIME") + 1); + strcpy(error_name, "RUNTIME"); + break; + case ERROR_SYNTAX: + error_name = malloc(strlen("SYNTAX") + 1); + strcpy(error_name, "SYNTAX"); + break; + case ERROR_TYPE: + error_name = malloc(strlen("TYPE") + 1); + strcpy(error_name, "TYPE"); + break; + case ERROR_UNDEFINED: + error_name = malloc(strlen("UNDEFINED") + 1); + strcpy(error_name, "UNDEFINED"); + break; + } + + if (tc_flag) { yyerror(""); - if (strcmp(format, "") == 0) { - if (asc_flag != NULL) { - fprintf(asc_flag, "(%d:%d) ** TYPE ERROR: %s != %s\n", line, column, getName(left), getName(right)); - } else { - fprintf(stderr, "%s(%d:%d) ** TYPE ERROR%s: %s%s %s!= %s%s\n", - COLOR_RED, line, column, COLOR_WHITE, COLOR_YELLOW, getName(left), COLOR_WHITE, COLOR_YELLOW, getName(right), COLOR_WHITE); - } + if (asc_flag != NULL) { + fprintf(asc_flag, "(%d:%d) ** %s ERROR: ", line, column, error_name); + va_list args; + va_start(args, format); + vfprintf(asc_flag, format, args); + va_end(args); + fprintf(asc_flag, "\n"); } else { - if (asc_flag != NULL) { - fprintf(asc_flag, "(%d:%d) ** TYPE ERROR: ", line, column); - va_list args; - va_start(args, format); - vfprintf(asc_flag, format, args); - va_end(args); - fprintf(asc_flag, "\n"); - } else { - fprintf(stderr, "%s(%d:%d) ** TYPE ERROR%s: %s", COLOR_RED, line, column, COLOR_WHITE, COLOR_YELLOW); - va_list args; - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "%s\n", COLOR_WHITE); - } + fprintf(stderr, "%s(%d:%d) ** %s ERROR%s: %s", COLOR_RED, line, column, error_name, COLOR_WHITE, COLOR_YELLOW); + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "%s\n", COLOR_WHITE); } } } From e0c577a7ef2d8fdc779fdb6f784e6a93b12bb046 Mon Sep 17 00:00:00 2001 From: Partho Date: Wed, 23 Apr 2025 18:49:09 -0400 Subject: [PATCH 121/137] updated grammar to pass up instances. Still need IR to compile to properly emit --- src/grammar.y | 327 +++++++++++++++++++--------- src/lexicalStructure.lex | 4 +- src/symbol_table.c | 73 +++++++ src/symbol_table.h | 10 +- tests/sprint2/test/sp2_simple.alpha | 2 +- 5 files changed, 305 insertions(+), 111 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index a7d173e..110ffb4 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -29,6 +29,7 @@ %union { int integ; char* words; + char letter; void* tn; } @@ -538,30 +539,22 @@ WHILE L_PAREN expression R_PAREN sblock { simple_statement: assignable ASSIGN expression - { + { printdebug("simple statement"); TableNode* node; - if((getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_TYPE)){ - node = (TableNode*)$1; - }else if((getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION)|| + if((getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION)|| (getAdInfoType((TableNode*)$1) == TYPE_ARRAY)|| (getAdInfoType((TableNode*)$1) == TYPE_RECORD)|| (getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE)){ - - node = getTypeEntry((TableNode*)$1); + + node = ((TableNode*)$1); } else{ error_type(undefined, undefined, "Invalid type passed to assignable."); node = undefined; } - if((getAdInfoType(node) == TYPE_ARRAY_TYPE|| - getAdInfoType(node) == TYPE_RECORD_TYPE) && - (strcmp(getName((TableNode*)$3),"address") == 0)){ - printdebug("%s[☺] Passed array/record type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); - } - else if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ + + if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ + //EMIT ASSIGN INSTRUCTION HERE printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); } else { error_type(node, (TableNode*)$3, ""); @@ -571,7 +564,7 @@ simple_statement: } -| RETURN expression {$$ = $2;} +| RETURN expression {$$ = getTypeEntry((TableNode*)$2);} ; @@ -592,6 +585,7 @@ ablock: argument_list: + //NEED TO EMIT PARAMETERS HERE. MAYBE USE STACK STRUCTURE expression COMMA argument_list { CreateEntry(cur,getAdInfoType((TableNode*)$1), (TableNode*)$1, getName((TableNode*)$1), NULL); @@ -618,160 +612,188 @@ expression: | SUB_OR_NEG expression %prec UMINUS { printdebug("negative expression"); - if((TableNode*)$2 != integ) { - printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column); - $$=undefined; + if(getTypeEntry((TableNode*)$2) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of unary operation + $$ = node; } else { - $$=(TableNode*)$2; + $$=undefined; + error_type(getTypeEntry((TableNode*)$2), integ, ""); } } | NOT expression { printdebug("not expression"); - if((TableNode*)$2 == boo) { - $$=(TableNode*)$2; + if(getTypeEntry((TableNode*)$2) == boo) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of unary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$2, boo, ""); + error_type(getTypeEntry((TableNode*)$2), boo, ""); } } | expression ADD expression { printdebug("add expression"); - if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { - $$=(TableNode*)$1; + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression SUB_OR_NEG expression { printdebug("sub or neg expression"); - if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { - $$=(TableNode*)$1; + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression MUL expression { printdebug("multiply expression"); - if((TableNode*)$1 == (TableNode*)$3 && (TableNode*)$1 == integ) { - $$=(TableNode*)$1; - } else{ + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; + } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression DIV expression { printdebug("divide expression"); - if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && ((TableNode*)$1 == integ)) { - $$=(TableNode*)$1; + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression REM expression { printdebug("remainder expression"); - if($1 == $3 && $1 == integ) { - $$=$1; + if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of binary operation + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression AND expression { - printdebug("AND expression"); - if($1 == $3 && $1 == boo){ - $$=$1; - } else{ + printdebug("AND"); + if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of comparison + $$ = node; + } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression OR expression { printdebug("OR"); - if((strcmp(getName((TableNode*)$1),getName((TableNode*)$3))==0) && $1 == boo) { - $$=$1; + if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of comparison + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression LESS_THAN expression { printdebug("less than expression"); - if($1 == $3 && $1==integ) { - $$=boo; + if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of comparison + $$ = node; } else { $$=undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | expression EQUAL_TO expression { printdebug("equals check expression"); - if($1 == $3 && $1 != undefined) { - $$=boo; + if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //result of compariosn + $$ = node; + } else { $$ = undefined; - error_type((TableNode*)$1, (TableNode*)$3, ""); + error_type(getTypeEntry((TableNode*)$1), getTypeEntry((TableNode*)$3), ""); } } | assignable { - printdebug("assignable expression. current type is %s",getName((TableNode*)$1)); - if(getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE|| - getAdInfoType((TableNode*)$1) == TYPE_ARRAY || - getAdInfoType((TableNode*)$1) == TYPE_RECORD){ - printdebug("assignable passing up to expression is primitive, array instance, or record instance. Passing up its type"); - $$= getTypeEntry((TableNode*)$1); - } - - else if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_TYPE|| - getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE_TYPE || - getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ - printdebug("assignable passing up to expression is array type, record type, function type, or function declaration"); - $$= ((TableNode*)$1); - } - else { - error_type(undefined, undefined, "Invalid type passed to expression."); - $$= ((TableNode*)$1); - } - + $$ = $1; } | L_PAREN expression R_PAREN { - printdebug("paren expression. current type is %s",getName((TableNode*)$2)); + printdebug("paren expression. current type is %s",getType((TableNode*)$2)); $$=$2; } | memOp assignable { int d = getAdInfoType((TableNode*)$2); - if(d == TYPE_ARRAY_TYPE || d == TYPE_ARRAY || d == TYPE_RECORD_TYPE || d == TYPE_RECORD) { - $$ = addr; + if(d == TYPE_ARRAY ||d == TYPE_RECORD) { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + $$ = node; } else { error_type(undefined, undefined, "Invalid memOp expression (%s).", getName((TableNode*)$2)); $$=undefined; @@ -788,8 +810,9 @@ expression: assignable: ID { - $$ = getTypeEntry(look_up(cur,$1)); - printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getName((TableNode*)$$), $1); + TableNode* pass = look_up(cur,$1); + $$ = pass; + printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getType(pass), getName(pass)); } | assignable @@ -797,22 +820,24 @@ assignable: printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); cur = CreateScope(cur, -1,-1); } + //we have to consider emmissions in ablocks ablock { - int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); + //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); + int type = getAdInfoType(getTypeEntry((TableNode*)$1)); printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", getName((TableNode*)$1)); if (type == TYPE_FUNCTION_TYPE) { printdebug("%sEntering function call", COLOR_LIGHTGREEN); - if (look_up(getParent(cur), getName((TableNode*)$1))->additionalinfo->FunDecAdInfo->regularoras) { + if (look_up(getParent(cur), getType((TableNode*)$1))->additionalinfo->FunDecAdInfo->regularoras) { printdebug("as function"); //char *funtype = getType(look_up(cur, $1)); -// printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); + //printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); - TableNode * typeNode = $1; + TableNode * typeNode = getTypeEntry((TableNode*)$1); TableNode *param = getParameter(typeNode); printTableNode(param); @@ -853,7 +878,7 @@ assignable: } } } else { - char *expected = getName(getParameter(look_up(getParent(cur), getName((TableNode*)$1)))); + char *expected = getName(getParameter(look_up(getParent(cur), getType((TableNode*)$1)))); char *actual = getType(getFirstEntry(cur)); if (strcmp(expected, actual) != 0) { printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); @@ -862,29 +887,99 @@ assignable: printdebug("expected 1 argument but got %d", $3); } } - printTableNode(getReturn($1)); - $$ = getReturn($1); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); + printTableNode(getReturn(getTypeEntry((TableNode*)$1))); + // + char* temp = temp_var_gen(); + TableNode* typeNode2 = getReturn(getTypeEntry($1)); + int t = -1; + if(getAdInfoType(typeNode2) == TYPE_PRIMITIVE_TYPE){ + t = TYPE_PRIMITIVE; + } + else if(getAdInfoType(typeNode2) == TYPE_ARRAY_TYPE){ + t = TYPE_ARRAY; + } + else if(getAdInfoType(typeNode2) == TYPE_RECORD_TYPE){ + t = TYPE_RECORD; + } + else if(getAdInfoType(typeNode2) == TYPE_FUNCTION_TYPE){ + t = TYPE_FUNCTION_DECLARATION; + }else{ + t= TYPE_UNDEFINED; + printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + } + TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); + $$ = node; + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK for function call) + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName(typeNode2), getName((TableNode*)$1)); } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); - if (getNumArrDim(look_up(getParent(cur), getName((TableNode*)$1))) != $2) { + if (getNumArrDim(look_up(getParent(cur), getType((TableNode*)$1))) != $2) { printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $2, @2.first_line, @2.first_column); } - $$ = getArrType(look_up(cur, getName((TableNode*)$1))); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); - printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1)); + + char* temp = temp_var_gen(); + TableNode* typeNode2 = getArrType(look_up(getAncestor(cur), getType((TableNode*)$1))); + int t = -1; + if(getAdInfoType(typeNode2) == TYPE_PRIMITIVE_TYPE){ + t = TYPE_PRIMITIVE; + } + else if(getAdInfoType(typeNode2) == TYPE_ARRAY_TYPE){ + t = TYPE_ARRAY; + } + else if(getAdInfoType(typeNode2) == TYPE_RECORD_TYPE){ + t = TYPE_RECORD; + } + else if(getAdInfoType(typeNode2) == TYPE_FUNCTION_TYPE){ + t = TYPE_FUNCTION_DECLARATION; + }else{ + t= TYPE_UNDEFINED; + printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + } + TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); + //emit assign here + //emit_array_access(char* node, char* array, ...) + $$ = node; + printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getType((TableNode*)$1), getName((TableNode*)$1)); } cur = getParent(cur); } | assignable rec_op ID - { - if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3)) { + { + if(getAdInfoType((TableNode*)$1) != TYPE_RECORD_TYPE){ + printdebug("CHANGE ME [TYPE CHECK]Invalid type passed to record access"); + } + else if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)) { - $$ = table_lookup(getRecList(table_lookup(getAncestor(cur), getName((TableNode*)$1))), $3); + TableNode* type = table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3); + char* temp = temp_var_gen(); + int t = -1; + if(getAdInfoType(type) == TYPE_PRIMITIVE_TYPE){ + t = TYPE_PRIMITIVE; + } + else if(getAdInfoType(type) == TYPE_ARRAY_TYPE){ + t = TYPE_ARRAY; + } + else if(getAdInfoType(type) == TYPE_RECORD_TYPE){ + t = TYPE_RECORD; + } + else if(getAdInfoType(type) == TYPE_FUNCTION_TYPE){ + t = TYPE_FUNCTION_DECLARATION; + }else{ + t= TYPE_UNDEFINED; + printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + } + + TableNode* node = CreateEntry(cur,t, type, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + //emit_field_access(char* node, char* record, $3) + $$=node; + }else{ + printdebug("CHANGE ME [TYPE CHECK] undefined type (Field Access Lookup failed)"); + $$=undefined; } - printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", getName((TableNode*)($$)), getName($1)); + printdebug("[ASSIGNABLE - RULE 3] record = name: %s | field = %s", getName((TableNode*)($1)), getName((TableNode*)$3)); } ; @@ -908,38 +1003,56 @@ memOp: constant: C_STRING { - $$ = $1; - printdebug("string of C_STRING in constant is %s",getName((TableNode*)$1)); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, stri, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("string of C_STRING in constant is %s", $1); + $$ = node; } | C_INTEGER { - $$ = integ; - printdebug("string of C_INTEGER in constant is integer"); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("number of C_INTEGER in constant is %d", $1); + $$ = node; } | C_NULL { - $$ = $1; - printdebug("string of C_NULL in constant is %s",getName((TableNode*)$1)); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("string of C_NULL in constant is NULL"); + $$ = node; } | C_CHARACTER { - $$ = $1; - printdebug("string of C_CHARACTER in constant is %s",getName((TableNode*)$1)); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, chara, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("string of C_CHARACTER in constant is %s",$1); + $$ = node; } | C_TRUE { - $$ = $1; - printdebug("string of C_TRUE in constant is %s",getName((TableNode*)$1)); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("string of C_TRUE in constant is true"); + $$ = node; } | C_FALSE { - $$ = $1; - printdebug("string of C_FALSE in constant is %s",getName((TableNode*)$1)); + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + printdebug("string of C_FALSE in constant is false"); + $$ = node; } ; diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index e11ef39..5e54f55 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -83,8 +83,8 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {if(tok_flag != NULL){print_tok(ARROW);}incr(line_number,column_number,ARROW);return ARROW;}} {DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytext)/*words = strdup("integer")*/;return C_INTEGER;}} -'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.tn = chara;return C_CHARACTER;}} -\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.tn = stri;return C_STRING;}} +'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);char* token = strdup(yytext)/*yylval.tn = chara*/;yylval.letter = token[1];return C_CHARACTER;}} +\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);int k = strlen(yytext);yytext[k-1] = '\0';yylval.words = strdup(&yytext[1]);return C_STRING;}} {COMMENT} {if(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}} "(" {if(DEBUG) {printf( "L_PAREN: %s (%d)\n", yytext, L_PAREN);} else {if(tok_flag != NULL){print_tok(L_PAREN);}incr(line_number,column_number,L_PAREN);return L_PAREN;}} diff --git a/src/symbol_table.c b/src/symbol_table.c index 21669b5..de7d3f6 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -3,6 +3,9 @@ #include "symbol_table.h" +Constant_Stack* head = NULL; +int temp2_count = 0; + void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { printf("%s<%s> [%d]%s ", COLOR_DARKGRAY, file, line, @@ -15,6 +18,76 @@ void printdebug_impl(char *file, int line, const char *format, ...) { } } +char * temp_var_gen(){ + char * ret = calloc(9, sizeof(*ret)); + sprintf(ret, "$t%d", temp2_count); + temp2_count++; + return ret; +} + +Constant_Stack *Push(TableNode *type, void *value, bool isConst) { + if (type == NULL || type == undefined) { + printdebug( + "passed a NULL reference/undefined reference to " + "CreateConstantStack. Invalid."); + return NULL; + } + Constant_Stack *cs = (Constant_Stack *)malloc(sizeof(Constant_Stack)); + cs->theType = type; + cs->theValue = value; + cs->isConst = isConst; + if(head == NULL){ + head = cs; + cs->next = NULL; + }else{ + cs->next = head; + head = cs; + } + return cs; +} + +Constant_Stack *Pop() { + if (head == NULL) { + printf("cannot pop from an empty stack. Invalid.\n"); + return NULL; + } + Constant_Stack *cs = head; + head = head->next; + printf("Popped something of type %s\n", getName(cs->theType)); + return cs; +} + +Constant_Stack* Print_Stack(){ + if (head == NULL) { + printdebug("cannot print an empty stack. Invalid."); + return NULL; + } + Constant_Stack *cs = head; + while (cs != NULL) { + if(cs->theValue == NULL){ + printf("Type: %s, Value: NULL", getName(cs->theType)); + } + if(cs->theType == stri){ + printf("Type: %s, Value: %s\n", getName(cs->theType), *(char*)(cs->theValue)); + } + if(cs->theType == integ){ + printf("Type: %s, Value: %d\n", getName(cs->theType), (int *)(cs->theValue)); + } + if(cs->theType == chara){ + printf("Type: %s, Value: %c\n", getName(cs->theType), *(char *)cs->theValue); + } + if(cs->theType == boo){ + if(*(bool *)cs->theValue == true){ + printf("Type: %s, Value: true\n", getName(cs->theType));} + else{ + printf("Type: %s, Value: false\n", getName(cs->theType)); + } + } + cs = cs->next; + } + return cs; + } + // primitive additional info only stores the size of that type AdInfo *CreatePrimitiveInfo(int size) { AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); diff --git a/src/symbol_table.h b/src/symbol_table.h index 01d4458..6a41551 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -11,6 +11,13 @@ struct TableNode; +typedef struct Constant_Stack { + struct TableNode *theType; + void *theValue; + struct Constant_Stack *next; + bool isConst; +} Constant_Stack; + typedef struct { int size; } primitive_info; @@ -141,7 +148,7 @@ extern int line_number; extern int column_number; extern FILE *yyin; extern bool DEBUG; - +extern int temp2_count; extern TableNode *funprime; extern TableNode *arrayprim; extern TableNode *integ; @@ -152,6 +159,7 @@ extern TableNode *boo; extern TableNode *recprime; extern TableNode *funtypeprime; extern TableNode *undefined; +extern Constant_Stack *head; extern char *COLOR_RED; extern char *COLOR_GREEN; diff --git a/tests/sprint2/test/sp2_simple.alpha b/tests/sprint2/test/sp2_simple.alpha index 58934e6..4042a5a 100644 --- a/tests/sprint2/test/sp2_simple.alpha +++ b/tests/sprint2/test/sp2_simple.alpha @@ -3,5 +3,5 @@ function entry: main entry(arg) := { [integer : x] - return 0; + return 2; } \ No newline at end of file From 2c712ed2217f2f05b68abb43695128a55ea3c02f Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 12:46:07 -0400 Subject: [PATCH 122/137] Makefile rewrite --- Makefile | 81 +++++++----- src/grammar.h | 10 -- src/grammar.y | 11 +- src/intermediate_code.c | 268 ++++++++++++++++++++++++++++++++++------ src/intermediate_code.h | 99 +++++++++++---- src/lexicalStructure.h | 33 ----- src/runner.h | 2 + src/symbol_table.c | 2 - src/symbol_table.h | 22 ++-- test.alpha | 29 ----- 10 files changed, 380 insertions(+), 177 deletions(-) delete mode 100644 src/grammar.h delete mode 100644 src/lexicalStructure.h delete mode 100644 test.alpha diff --git a/Makefile b/Makefile index c9797be..bb5c7bb 100644 --- a/Makefile +++ b/Makefile @@ -1,39 +1,73 @@ +# ----- Definitions ----- CC := gcc FLEX := flex +BISON = bison + +CFLAGS := -ggdb +BISONFLAGS := -d + LEX := src/lexicalStructure.lex +YACC := src/grammar.y EXE := alpha -CFLAGS := -YACC := bison + +OBJS := tmp/runner.o tmp/symbol_table.o tmp/grammar.tab.o tmp/lex.yy.o tmp/intermediate_code.o +# tmp/intermediate_code.o codegen.o TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha) TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha) TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha) TESTS-S4 := $(wildcard tests/sprint4/test/*.alpha) +# ---------- -compiler: clean runner -tmp/grammar.tab.c: src/grammar.y + +# ----- Targets ----- +all: compiler + +compiler: clean tmp $(OBJS) + $(CC) $(CFLAGS) -o $(EXE) $(OBJS) + +clean: + rm -f $(EXE) + rm -rf out + rm -rf tmp + +tmp: mkdir -p tmp - $(YACC) -d src/grammar.y - mv grammar.tab.c tmp/ - mv grammar.tab.h tmp/ -tmp/lex.yy.c: src/lexicalStructure.lex tmp/grammar.tab.c +tmp/grammar.tab.c tmp/grammar.tab.h: $(YACC) + $(BISON) $(BISONFLAGS) -o tmp/grammar.tab.c $(YACC) + +tmp/lex.yy.c tmp/flex.h: $(LEX) tmp/grammar.tab.h $(FLEX) -o tmp/lex.yy.c $(LEX) - mv flex.h tmp/ + mv flex.h tmp/flex.h +# ----------- -tmp/runner.o: src/runner.c src/runner.h tmp/flex.h - $(CC) $(CFLAGS) -o tmp/runner.o -c src/runner.c + + +# ----- Create Objs ----- +tmp/grammar.tab.o: tmp/grammar.tab.c + $(CC) $(CFLAGS) -c tmp/grammar.tab.c -o tmp/grammar.tab.o + +tmp/lex.yy.o: tmp/lex.yy.c + $(CC) $(CFLAGS) -c tmp/lex.yy.c -o tmp/lex.yy.o tmp/symbol_table.o: src/symbol_table.c src/symbol_table.h - $(CC) $(CFLAGS) -o tmp/symbol_table.o -c src/symbol_table.c + $(CC) $(CFLAGS) -c src/symbol_table.c -o tmp/symbol_table.o -runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o - $(CC) $(CFLAGS) -o $(EXE) -g -ggdb tmp/runner.o tmp/grammar.tab.c tmp/lex.yy.c +tmp/intermediate_code.o: src/intermediate_code.c src/intermediate_code.h + $(CC) $(CFLAGS) -c src/intermediate_code.c -o tmp/intermediate_code.o -debug: CFLAGS += -DDEBUG=1 -debug: clean compiler +# tmp/codegen.o: src/codegen.c src/codegen.h +# $(CC) $(CFLAGS) -c src/codegen.c -o tmp/codegen.o +tmp/runner.o: src/runner.c src/runner.h tmp/flex.h tmp/grammar.tab.h + $(CC) $(CFLAGS) -c src/runner.c -o tmp/runner.o +# ----------- + + + +# ----- Tests ----- test: chmod +x ./check.sh chmod +x ./test.sh @@ -67,15 +101,6 @@ test-s4: ./test.sh sp4 ./check.sh sp4 -clean: - rm -f *.o - rm -f lex.yy.c - rm -f $(EXE) - rm -f flex.h - rm -f *.tok - rm -f grammar.tab.c - rm -f grammar.tab.h - rm -f *.st - rm -rf out - rm -rf tmp - rm -f parser +# Temprorary test ~ Scarlett +test-make: clean tmp tmp/grammar.tab.c tmp/grammar.tab.h tmp/lex.yy.c tmp/flex.h tmp/grammar.tab.o tmp/lex.yy.o tmp/symbol_table.o tmp/runner.o +# ----------- \ No newline at end of file diff --git a/src/grammar.h b/src/grammar.h deleted file mode 100644 index 58cedbd..0000000 --- a/src/grammar.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef GRAMMAR_H -#define GRAMMAR_H - -#include "../src/runner.h" - -void yyerror(const char *err); -int token_tracker; -TableNode * tn; - -#endif \ No newline at end of file diff --git a/src/grammar.y b/src/grammar.y index e98f9d0..c7220c3 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -17,18 +17,21 @@ // Please ask Scarlett if you are unsure of how to format something. Thanks! 😀 %{ - #include "../src/symbol_table.c" - void yyerror(const char *err); + #include "../src/symbol_table.h" extern FILE *asc_flag; extern bool tc_flag; - int token_tracker; - TableNode * tn; + typedef enum { ERROR_RUNTIME = 1, ERROR_SYNTAX = 2, ERROR_TYPE = 3, ERROR_UNDEFINED = 4 } ErrorType; + + int token_tracker; + TableNode * tn; + + void yyerror(const char *err); void throw_error(ErrorType error_type, const char *format, ...); %} diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 6ac5429..6b1b32f 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -1,4 +1,3 @@ -#include #include "intermediate_code.h" Instruction * begin; @@ -9,11 +8,42 @@ char * temp = NULL; // TODO: this is here to bring your attention to the comment bellow. // check if start is NULL if it is assign it to the start globle variable // otherwise make it next of current and set cur to your instruction. +TNodeOrConst * getOperand1(Instruction * i){ + return i->operand1; +} -TNodeOrConst * tn_or_const(Op op, void * tnc) { +TNodeOrConst * getOperand2(Instruction * i){ + return i->operand2; +} + +TableNode * get_result(Instruction * i){ + return i->result; +} + +Op getOp(Instruction * i){ + return i->opcode; +} + +int getLabel(Instruction * i){ + return i->label; +} + +int get_index(Instruction * i){ + return i->index; +} + +void set_label(Instruction * i, int label){ + i->label = label; +} + +bool isConst(TNodeOrConst * tnc) { + return tnc->d != NODE; +} + +TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { TNodeOrConst * count = calloc(1, sizeof(*count)); - count->d = op; - switch (op) { + count->d = d; + switch (d) { case NODE: count->tnc_union->node = tnc; break; @@ -52,10 +82,10 @@ static void emit_helper(void){ void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2){ emit_helper(); current->opcode = op; + // TODO: create temp and remove result from param list current->result = result; current->operand1 = arg1; current->operand2 = arg2; - return; } void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ @@ -63,38 +93,162 @@ void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ current->opcode = op; current->result = result; current->operand1 = arg; - return; } void emit_assignment(TableNode * target, TNodeOrConst * source){ emit_helper(); - current->opcode = E_ASSIGN; // TODO: replace with move + current->opcode = E_ASSIGN; current->result = target; current->operand1 = source; - return; } -void emit_as_file(FILE * out_file, Instruction * instr_arr){ - if(instr_arr == NULL){ - return; +char * get_string(TNodeOrConst * tc){ + char * s; + switch (tc->d) { + case NODE: + return getName(tc->tnc_union->node); + case ADDRESS: + return strdup("null"); + case STRING: + return tc->tnc_union->string; + case INTEGER: + s = calloc(10, sizeof(char)); + sprintf(s, "%d", tc->tnc_union->integer); + return s; + case CHARACTER: + s = calloc(2, sizeof(char)); + sprintf(s, "%c", tc->tnc_union->character); + return s; + case BOOLEAN: + if(tc->tnc_union->Boolean){ + return strdup("true"); + } + return strdup("false"); } - - //fprintf(out_file, - return; } +void emit_as_file(FILE * out_file, Instruction * i){ + if(!i){ + return; + } + switch(i->opcode){ + case E_LABEL: + // this is a terrible one to start with + // fprintf(out_file, "%04.d: %d ", i->index, i->label); + case E_ADD: + fprintf(out_file, "%4.d: %s = %s + %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_SUB: + fprintf(out_file, "%4.d: %s = %s - %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MUL: + fprintf(out_file, "%4.d: %s = %s * %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_DIV: + fprintf(out_file, "%4.d: %s = %s / %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MOD: + fprintf(out_file, "%4.d: %s = %s %% %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_OR: + fprintf(out_file, "%4.d: %s = %s | %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_AND: + fprintf(out_file, "%4.d: %s = %s & %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_NEG: + fprintf(out_file, "%4.d: %s = -%s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_NOT: + fprintf(out_file, "%4.d: %s = !%s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_ASSIGN: + fprintf(out_file, "%4.d: %s = %s\n", + i->index, getName(i->result), + get_string(i->operand2)); + break; + case E_GOTO: + // are we ever going to use this? + // yes we do look at bounds checking + case E_IF_X_TRUE: + fprintf(out_file, "%4.d: if %s goto %d\n", + i->index, get_string(i->operand1), + i->label); + break; + case E_IF_X_FALSE: + fprintf(out_file, "%4.d: if %s false goto %d\n", + i->index, get_string(i->operand1), + i->label); + break; + case E_LESS_THAN: + fprintf(out_file, "%4.d: if %s < %s goto %d\n", + i->index, get_string(i->operand1), + get_string(i->operand2), i->label); + break; + case E_EQUAL_TO: + fprintf(out_file, "%4.d: if %s = %s goto %d\n", + i->index, get_string(i->operand1), + get_string(i->operand2), i->label); + break; + case E_CALL: + fprintf(out_file, "%4.d: call %s %s\n", + i->index, get_string(i->operand1), + get_string(i->operand2)); + break; + + case E_PARAM: + fprintf(out_file, "%4.d: param %s \n", + i->index, get_string(i->operand1)); + break; + case E_RETURN: + + case E_INDEX_COPY_RIGHT: + case E_INDEX_COPY_LEFT: + + case E_ADDRESS_OF: + + case E_DEREF_RIGHT: + case E_DEREF_LEFT: + } + + emit_as_file(out_file, i->next); +} void emit_label(int label){ emit_helper(); current->opcode = E_LABEL; current->label = label; - return; } + void emit_jump(int label){ emit_helper(); current->opcode = E_GOTO; current->label = label; - return; } void emit_conditional_jump(Op condition, int label, ...){ @@ -112,7 +266,7 @@ void emit_conditional_jump(Op condition, int label, ...){ n1 = va_arg(argptr, TNodeOrConst *); current->operand1 = n1; break; - case E_LESSTHEN: case E_EQUALTO: + case E_LESS_THAN: case E_EQUAL_TO: n1 = va_arg(argptr, TNodeOrConst *); n2 = va_arg(argptr, TNodeOrConst *); current->operand1 = n1; @@ -120,7 +274,6 @@ void emit_conditional_jump(Op condition, int label, ...){ break; } va_end(argptr); - return; } void emit_function_start(int name){ @@ -128,14 +281,12 @@ void emit_function_start(int name){ current->opcode = E_LABEL; // I think this is right TODO: ask current->label = name; // this is probabaly a func decleration - return; } void emit_parameter(TNodeOrConst * param){ emit_helper(); current->opcode = E_PARAM; current->operand1 = param; - return; } void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name){ @@ -144,37 +295,80 @@ void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name current->operand1 = tn_or_const(INTEGER, ¶m_count); current->operand2 = name; current->result = result; - return; } + void emit_return(TNodeOrConst * value){ emit_helper(); current->opcode = E_RETURN; current->operand1 = value; - return; } -void emit_reserve(char* result, char* type_name, int size){ - emit_helper(); - return; + +void emit_reserve(TableNode * result, TNodeOrConst * size){ + emit_parameter(size); + emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); } -void emit_release(char* pointer){ - emit_helper(); + +void emit_release(TableNode * pointer){ + emit_parameter(tn_or_const(NODE, pointer)); + emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); +} + +void emit_deref_right(){ return; } +void emit_deref_left(){ + return; +} void emit_field_access(char* result, char* record, char* field){ emit_helper(); - return; -} -void emit_array_access(char* result, char* array, char* index, char* dimension){ - emit_helper(); - return; -} -void emit_bounds_check(char* index, char* size, char* error_label){ - emit_helper(); - return; } +void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index){ + emit_helper(); + current->opcode; + current->result = result; + current->operand1 = array; + current->operand2 = index; + // TODO: Still don't know what to do with the dimentions +} + +void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ + /* + {[string: 5] + . + . + s:= reserve s(5); + s(0) := 'H'; + s(1) := 'e'; + . + . + s._0 num of dims Known at compile time + s._1 size Known at run time + s._1 int | 1 byte + +-------+---+---+---+---+---+ + | 5 | H | e | l | l | o | + +-------+---+---+---+---+---+ + size + ^ + | + p + s._0 ok + s._1 ok + s._2 not ok + t_0 is index + t_1 = *(int *)p = s._1 + if t_0 < 0 GOTO ERROR + if t_0 < s._1 GOTO access array + GOTO ERROR + */ + emit_conditional_jump(E_LESS_THAN, ); + emit_conditional_jump(E_LESS_THAN, ); + emit_jump(); + /* We need a label ERROR to jump to + */ +} // * Implement temp variable generator function that produces unique names (t1, t2, etc.) char * temp_var_gen(){ @@ -189,4 +383,4 @@ char * label_gen(){ sprintf(ret, "L_%d", label_count); label_count++; return ret; -} +} \ No newline at end of file diff --git a/src/intermediate_code.h b/src/intermediate_code.h index fc3cdc4..b6e6fd4 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -2,12 +2,15 @@ // * Add Bison actions for arithmetic expressions: // - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); // - Subtraction, multiplication, division, modulo -#include "runner.h" +#pragma once + +#include "symbol_table.h" +#include #include // these are from page 364 typedef enum { - E_LABEL = 10000, // this is not in the book + E_LABEL = 10000, // this is not in the book E_ADD, // 1 from the list E_SUB, // 1 E_MUL, // 1 @@ -22,16 +25,16 @@ typedef enum { E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got E_IF_X_TRUE, // 5 E_IF_X_FALSE, // 5 - E_LESSTHEN, // 6 rule 1 + 5 - E_EQUALTO, // 6 rule 1 + 5 + E_LESS_THAN, // 6 rule 1 + 5 + E_EQUAL_TO, // 6 rule 1 + 5 E_CALL, // 7 E_PARAM, // 7 E_RETURN, // 7 - E_INDEX_COPY_RIGHT, // 8 - E_INDEX_COPY_LEFT, // 8 - E_ADDRESS_OF // 9 - /* for x = *y and *y = x we can just use index copy right and left with - index 0*/ + E_INDEX_COPY_RIGHT, // 8 this is x = y[i] + E_INDEX_COPY_LEFT, // 8 x[i] = y + E_ADDRESS_OF, // 9 x = &y + E_DEREF_RIGHT, // 9 x = *y + E_DEREF_LEFT // 9 x* = y } Op; typedef enum { @@ -70,6 +73,20 @@ typedef struct Instruction { Instruction * next; } Instruction; + +typedef struct TFList { + Instruction * i; + TFList * next; +} TFList; + +TFList * make_list(Instruction * i); + // - makelist(i) function to create instruction lists +void merge(TFList * l1, TFList * l2); + // - merge(p1,p2) function to concatenate lists +void backpatch(TFList * l, int label); + // - backpatch(p,i) function to fill in jump targets + + extern Instruction * begin; extern Instruction * current; int temp_count = 0; @@ -77,34 +94,62 @@ int label_count = 0; bool code_gen = true; - -TNodeOrConst * tn_or_const(Op op, void * tnc); - +TNodeOrConst * tn_or_const(Discriminant , void * ); void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2); void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); void emit_assignment(TableNode * target, TNodeOrConst * source); -// TODO: Find out what these are suposed to do. Guess is create an entry in -// the list of instructions. Guess is that its suposed to ret a struct ptr - -// * Implement integer/boolean/character specific operation handling -// TODO: Find out what this means. - -// * Create output function to write instructions to file with line formatting void emit_as_file(FILE * out_file, Instruction * instr_arr); - -// * Implement instruction array storage for backpatching - void emit_label(int label); void emit_jump(int label); + void emit_conditional_jump(Op condition, int label, ...); void emit_function_start(int name); void emit_parameter(TNodeOrConst * param); void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); void emit_return(TNodeOrConst * value); -void emit_reserve(char* result, char* type_name, int size); -void emit_release(char* pointer); - +void emit_reserve(TableNode * result, TNodeOrConst * size); +void emit_release(TableNode * pointer); void emit_field_access(char* result, char* record, char* field); -void emit_array_access(char* result, char* array, char* index, char* dimension); -void emit_bounds_check(char* index, char* size, char* error_label); +void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index); +void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr, int error_label); + +// * Implement instruction array storage for backpatching +/* +Track 2: Control Flow & Boolean Expressions +* Implement backpatching infrastructure: +* Create truelist and falselist attributes for Boolean expressions +* Create control flow emission functions: +* Add Bison actions for control structures: + - if-then-else with backpatching + - while loops with backpatching +* Implement short-circuit Boolean operations (&&, ||, !) +* Add marker (M) nonterminal for recording instruction positions +*/ + + +/* + Track 3: Functions & Complex Types +* Implement function-related emission: +* Add Bison actions for the 'as' clause +* Create memory layout calculation functions: + - calculate_record_size(Record_Type* type) → returns bytes needed + - calculate_array_size(Array_Type* type, int dimensions[]) → returns total bytes + - calculate_field_offset(Record_Type* type, char* field_name) → returns offset +* Add Bison actions for arrays and records + */ + +/* + Track 4: Memory Access & Integration +* Implement array and record access code: + - emit_field_access(char* result, char* record, char* field) + - emit_array_access(char* result, char* array, char* index, char* dimension) +* Add array dimension access (a._1, a._2, etc.) +* Implement bounds checking emission: + - emit_bounds_check(char* index, char* size, char* error_label) +* Create the code generation driver function +* Implement common error handling +* Document the complete intermediate instruction set +* Build integration test suite covering all language features +* Implement row-major/column-major array layout calculation + */ \ No newline at end of file diff --git a/src/lexicalStructure.h b/src/lexicalStructure.h deleted file mode 100644 index c7baafe..0000000 --- a/src/lexicalStructure.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef LEXICALSTRUCTURE_H -#define LEXICALSTRUCTURE_H - -#include "../tmp/grammar.tab.h" -#include "../src/symbol_table.h" - -extern SymbolTable * cur; -extern FILE* tok_flag; -extern TableNode *funprime; -extern TableNode *funtypeprime; -extern TableNode *arrayprim; -extern TableNode *recprime; -extern TableNode *integ; -extern TableNode *addr; -extern TableNode *chara; -extern TableNode *stri; -extern TableNode *boo; -extern TableNode *undefined; -extern void incr(int lnum,int cnum, int tok); -extern void print_tok(int tok); - -extern int line_number; -extern int column_number; -extern int yycolumn; -#define YY_USER_ACTION { \ - yylloc.first_line = yylineno; \ - yylloc.last_line = yylineno; \ - yylloc.first_column = yycolumn; \ - yylloc.last_column = yycolumn + yyleng - 1; \ - yycolumn += yyleng; \ -} - -#endif \ No newline at end of file diff --git a/src/runner.h b/src/runner.h index 7989473..16b505b 100644 --- a/src/runner.h +++ b/src/runner.h @@ -1,6 +1,8 @@ /* Runner File - Compiles alpha Compiler */ /* The Translators - Spring 2025 */ +#pragma once + #define ALPHA_OFFSET 6 #define TOK_LEN 3 #define ST_LEN 2 diff --git a/src/symbol_table.c b/src/symbol_table.c index 21669b5..a464b93 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1072,7 +1072,6 @@ TableNode *look_up(SymbolTable *table, char *x) { } int col_widths[5] = {30, 8, 8, 35, 35}; -void printline(FILE *file_ptr, bool b); void printline(FILE *file_ptr, bool b) { if (b) { fprintf(file_ptr, "oop\n"); @@ -1087,7 +1086,6 @@ void printline(FILE *file_ptr, bool b) { fprintf(file_ptr, "\n"); } -void st_fprint(FILE *file_ptr, char *label1, int label2, int label3, char *label4, char *label5); void st_fprint(FILE *file_ptr, char *label1, int label2, int label3, char *label4, char *label5) { if (label3 == -100) { fprintf(file_ptr, "%-*s: %0*d : %*s :%-*s:%-*s\n", diff --git a/src/symbol_table.h b/src/symbol_table.h index 01d4458..1712676 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include @@ -82,12 +84,20 @@ typedef enum { TYPE_PRIMITIVE_TYPE = 12 } types; +void printdebug_impl(char *file, int line, const char *format, ...); +#define printdebug(format, ...) \ + printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) + +void printdebug_impl(char *file, int line, const char *format, ...); AdInfo *CreatePrimitiveInfo(int size); int getPrimSize(TableNode *definition); AdInfo *CreateArrayInfo(int dim, TableNode *type); int getNumArrDim(TableNode *definition); TableNode *getArrType(TableNode *definition); AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope); +int getRecTotal(TableNode *node); +TableNode *setRecOffsetInfo(SymbolTable *scope, TableNode *node); +int *getRecOffsets(TableNode *node); int getRecLength(TableNode *definition); SymbolTable *getRecList(TableNode *definition); TableNode *setRecSize(TableNode *tn, int n); @@ -103,19 +113,21 @@ TableNode *getReturn(TableNode *definition); SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column); SymbolTable *init(SymbolTable *start); TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info); +AdInfo *getAdInfo(TableNode *tn); int getAdInfoType(TableNode *tn); -TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, - AdInfo *ad); +TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, AdInfo *ad); +TableNode *getTypeEntry(TableNode *tn); char *getType(TableNode *tn); char *getName(TableNode *tn); int getLine(SymbolTable *st); int getColumn(SymbolTable *st); -TableNode *getTypeEntry(TableNode *tn); TableNode *addName(TableNode *tn, char *str); SymbolTable *setLineNumber(SymbolTable *st, int line); SymbolTable *setColumnNumber(SymbolTable *st, int column); TableNode *table_lookup(SymbolTable *table, char *x); TableNode *look_up(SymbolTable *table, char *x); +void printline(FILE *file_ptr, bool b); +void st_fprint(FILE *file_ptr, char *label1, int label2, int label3, char *label4, char *label5); void print_symbol_table(SymbolTable *table, FILE *file_ptr); SymbolTable *getAncestor(SymbolTable *table); SymbolTable *removeEntry(SymbolTable *scope, char *search); @@ -126,11 +138,7 @@ SymbolTable *getFirstChild(ListOfTable *lt); ListOfTable *getRestOfChildren(ListOfTable *lt); TableNode *getFirstEntry(SymbolTable *st); TableNode *getNextEntry(TableNode *tn); - TableNode *printTableNode(TableNode *tn); -void printdebug_impl(char *file, int line, const char *format, ...); -#define printdebug(format, ...) \ - printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) extern int yylex(void); extern char *yytext; diff --git a/test.alpha b/test.alpha deleted file mode 100644 index 7b06a5e..0000000 --- a/test.alpha +++ /dev/null @@ -1,29 +0,0 @@ - - - -type a : 1 -> integers -type t : integer -> a -type r : integer -> integer - - - -function foo : t -function bar : r -function entry : - -bar(a) := { - 5 + bar(a - 1); - return a * bar(a-1); -} - -foo(c) := { - [a: arg] - arg := reserve arg(c); - return arg; -} - -entry(args) := { - [a: b] - b := foo(8); -} - From f0d81ff5fdedb6ec54b639057755cbf42b1a98cb Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 25 Apr 2025 13:01:31 -0400 Subject: [PATCH 123/137] combined symbol table with IR in this branch --- src/grammar.y | 14 +- src/intermediate_code.c | 5 - src/intermediate_code.h | 3 +- src/runner.c | 3 +- src/runner.h | 1 + src/symbol_table.c | 390 +++++++++++++++++++++++++++++++++++++++- src/symbol_table.h | 152 ++++++++++++++++ 7 files changed, 552 insertions(+), 16 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 110ffb4..74d7e92 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1005,7 +1005,7 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, stri, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + emit_assignment(node, tn_or_const(STRING,$1)); printdebug("string of C_STRING in constant is %s", $1); $$ = node; } @@ -1014,7 +1014,7 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + emit_assignment(node, tn_or_const(INTEGER,&$1)); printdebug("number of C_INTEGER in constant is %d", $1); $$ = node; } @@ -1023,7 +1023,7 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + emit_assignment(node, tn_or_const(ADDRESS,$1)); printdebug("string of C_NULL in constant is NULL"); $$ = node; } @@ -1032,7 +1032,7 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, chara, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + emit_assignment(node, tn_or_const(CHARACTER,&$1)); printdebug("string of C_CHARACTER in constant is %s",$1); $$ = node; } @@ -1041,7 +1041,8 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + uint_least8_t b = 1; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); printdebug("string of C_TRUE in constant is true"); $$ = node; } @@ -1050,7 +1051,8 @@ constant: { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + uint_least8_t b = 0; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); printdebug("string of C_FALSE in constant is false"); $$ = node; } diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 6ac5429..3ccec2c 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -1,9 +1,4 @@ -#include -#include "intermediate_code.h" -Instruction * begin; -Instruction * current; -char * temp = NULL; // TODO: this is here to bring your attention to the comment bellow. diff --git a/src/intermediate_code.h b/src/intermediate_code.h index fc3cdc4..2bb423a 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -2,8 +2,7 @@ // * Add Bison actions for arithmetic expressions: // - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); // - Subtraction, multiplication, division, modulo -#include "runner.h" -#include + // these are from page 364 typedef enum { diff --git a/src/runner.c b/src/runner.c index 3fa35ca..9ca6cfa 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,7 +2,7 @@ /* The Translators - Spring 2025 */ #include "runner.h" - +//Constant_Stack *head = NULL; int main(int argc, char *argv[]) { if (argc == 1) { fprintf(stderr, INVALID); @@ -121,6 +121,7 @@ int run(FILE *alpha) { if (st_flag != NULL) { print_symbol_table(top, st_flag); + //emit_as_file(stdout, begin); fclose(st_flag); } diff --git a/src/runner.h b/src/runner.h index 7989473..74a7ecf 100644 --- a/src/runner.h +++ b/src/runner.h @@ -64,6 +64,7 @@ TableNode *boo; TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; +extern Instruction* begin; int main(int argc, char *argv[]); int check_flag(char *arg, char *alpha); diff --git a/src/symbol_table.c b/src/symbol_table.c index de7d3f6..5fe39c3 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -3,8 +3,13 @@ #include "symbol_table.h" -Constant_Stack* head = NULL; +Constant_Stack * head = NULL; int temp2_count = 0; +bool code_gen = true; +char* temp = NULL; +int label_count=0; +Instruction* begin = NULL; +Instruction* current = NULL; void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { @@ -1143,7 +1148,6 @@ TableNode *look_up(SymbolTable *table, char *x) { x, getLine(table), getColumn(table)); return look_up(table->Parent_Scope, x); } - int col_widths[5] = {30, 8, 8, 35, 35}; void printline(FILE *file_ptr, bool b); void printline(FILE *file_ptr, bool b) { @@ -1556,3 +1560,385 @@ TableNode *printTableNode(TableNode *tn) { return tn; } +//________________________________________________________________________ + + +// TODO: this is here to bring your attention to the comment bellow. +// check if start is NULL if it is assign it to the start globle variable +// otherwise make it next of current and set cur to your instruction. +TNodeOrConst * getOperand1(Instruction * i){ + return i->operand1; +} + +TNodeOrConst * getOperand2(Instruction * i){ + return i->operand2; +} + +TableNode * get_result(Instruction * i){ + return i->result; +} + +Op getOp(Instruction * i){ + return i->opcode; +} + +int getLabel(Instruction * i){ + return i->label; +} + +int get_index(Instruction * i){ + return i->index; +} + +void set_label(Instruction * i, int label){ + i->label = label; +} + +bool isConst(TNodeOrConst * tnc) { + return tnc->d != NODE; +} + +TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { + TNodeOrConst * count = calloc(1, sizeof(*count)); + count->d = d; + switch (d) { + case NODE: + count->tnc_union->node = tnc; + break; + case ADDRESS: + count->tnc_union->address = tnc; + break; + case STRING: + count->tnc_union->string = tnc; + break; + case INTEGER: + count->tnc_union->integer = *(int*)tnc; + break; + case CHARACTER: + count->tnc_union->character = *(char*)tnc; + break; + case BOOLEAN: + count->tnc_union->Boolean = *( uint_least8_t*)tnc; + break; + } + return count; +} + +static void emit_helper(void){ + Instruction * inst = calloc(1, sizeof(*inst)); + if(begin == NULL){ + begin = current = inst; + current->index = 1; + } else { + current->next = inst; + inst->prev = current; + inst->index = current->index++; + current = inst; + } +} + +void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2){ + emit_helper(); + current->opcode = op; + // TODO: create temp and remove result from param list + current->result = result; + current->operand1 = arg1; + current->operand2 = arg2; + } + +void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ + emit_helper(); + current->opcode = op; + current->result = result; + current->operand1 = arg; + } + +void emit_assignment(TableNode * target, TNodeOrConst * source){ + emit_helper(); + current->opcode = E_ASSIGN; + current->result = target; + current->operand1 = source; + } + +char * get_string(TNodeOrConst * tc){ + char * s; + switch (tc->d) { + case NODE: + return getName(tc->tnc_union->node); + case ADDRESS: + return strdup("null"); + case STRING: + return tc->tnc_union->string; + case INTEGER: + s = calloc(10, sizeof(char)); + sprintf(s, "%d", tc->tnc_union->integer); + return s; + case CHARACTER: + s = calloc(2, sizeof(char)); + sprintf(s, "%c", tc->tnc_union->character); + return s; + case BOOLEAN: + if(tc->tnc_union->Boolean){ + return strdup("true"); + } + return strdup("false"); + } +} + +void emit_as_file(FILE * out_file, Instruction * i){ + if(!i){ + return; + } + switch(i->opcode){ + case E_LABEL: + // this is a terrible one to start with + // fprintf(out_file, "%04.d: %d ", i->index, i->label); + case E_ADD: + fprintf(out_file, "%4.d: %s = %s + %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_SUB: + fprintf(out_file, "%4.d: %s = %s - %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MUL: + fprintf(out_file, "%4.d: %s = %s * %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_DIV: + fprintf(out_file, "%4.d: %s = %s / %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MOD: + fprintf(out_file, "%4.d: %s = %s %% %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_OR: + fprintf(out_file, "%4.d: %s = %s | %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_AND: + fprintf(out_file, "%4.d: %s = %s & %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_NEG: + fprintf(out_file, "%4.d: %s = -%s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_NOT: + fprintf(out_file, "%4.d: %s = !%s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_ASSIGN: + fprintf(out_file, "%4.d: %s = %s\n", + i->index, getName(i->result), + get_string(i->operand2)); + break; + case E_GOTO: + // are we ever going to use this? + // yes we do look at bounds checking + case E_IF_X_TRUE: + fprintf(out_file, "%4.d: if %s goto %d\n", + i->index, get_string(i->operand1), + i->label); + break; + case E_IF_X_FALSE: + fprintf(out_file, "%4.d: if %s false goto %d\n", + i->index, get_string(i->operand1), + i->label); + break; + case E_LESS_THAN: + fprintf(out_file, "%4.d: if %s < %s goto %d\n", + i->index, get_string(i->operand1), + get_string(i->operand2), i->label); + break; + case E_EQUAL_TO: + fprintf(out_file, "%4.d: if %s = %s goto %d\n", + i->index, get_string(i->operand1), + get_string(i->operand2), i->label); + break; + case E_CALL: + fprintf(out_file, "%4.d: call %s %s\n", + i->index, get_string(i->operand1), + get_string(i->operand2)); + break; + + case E_PARAM: + fprintf(out_file, "%4.d: param %s \n", + i->index, get_string(i->operand1)); + break; + case E_RETURN: + + case E_INDEX_COPY_RIGHT: + case E_INDEX_COPY_LEFT: + + case E_ADDRESS_OF: + + case E_DEREF_RIGHT: + case E_DEREF_LEFT: + } + + emit_as_file(out_file, i->next); +} + +void emit_label(int label){ + emit_helper(); + current->opcode = E_LABEL; + current->label = label; +} + +void emit_jump(int label){ + emit_helper(); + current->opcode = E_GOTO; + current->label = label; +} + +void emit_conditional_jump(Op condition, int label, ...){ + // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). + // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) + emit_helper(); + va_list argptr; + va_start(argptr, label); + current->opcode = condition; + current->label = label; + TNodeOrConst * n1; + TNodeOrConst * n2; + switch (condition) { + case E_IF_X_TRUE: case E_IF_X_FALSE: + n1 = va_arg(argptr, TNodeOrConst *); + current->operand1 = n1; + break; + case E_LESS_THAN: case E_EQUAL_TO: + n1 = va_arg(argptr, TNodeOrConst *); + n2 = va_arg(argptr, TNodeOrConst *); + current->operand1 = n1; + current->operand2 = n2; + break; + } + va_end(argptr); +} + +void emit_function_start(int name){ + emit_helper(); + current->opcode = E_LABEL; // I think this is right TODO: ask + current->label = name; + // this is probabaly a func decleration +} + +void emit_parameter(TNodeOrConst * param){ + emit_helper(); + current->opcode = E_PARAM; + current->operand1 = param; +} + +void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name){ + emit_helper(); + current->opcode = E_CALL; + current->operand1 = tn_or_const(INTEGER, ¶m_count); + current->operand2 = name; + current->result = result; +} + +void emit_return(TNodeOrConst * value){ + emit_helper(); + current->opcode = E_RETURN; + current->operand1 = value; +} + +void emit_reserve(TableNode * result, TNodeOrConst * size){ + emit_parameter(size); + emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); +} + +void emit_release(TableNode * pointer){ + emit_parameter(tn_or_const(NODE, pointer)); + emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); +} + +void emit_deref_right(){ + return; +} + +void emit_deref_left(){ + return; +} + +void emit_field_access(char* result, char* record, char* field){ + emit_helper(); +} + +void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index){ + emit_helper(); + current->opcode; + current->result = result; + current->operand1 = array; + current->operand2 = index; + // TODO: Still don't know what to do with the dimentions +} + +void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ + /* + {[string: 5] + . + . + s:= reserve s(5); + s(0) := 'H'; + s(1) := 'e'; + . + . + s._0 num of dims Known at compile time + s._1 size Known at run time + s._1 int | 1 byte + +-------+---+---+---+---+---+ + | 5 | H | e | l | l | o | + +-------+---+---+---+---+---+ + size + ^ + | + p + s._0 ok + s._1 ok + s._2 not ok + t_0 is index + t_1 = *(int *)p = s._1 + if t_0 < 0 GOTO ERROR + if t_0 < s._1 GOTO access array + GOTO ERROR + */ + //emit_conditional_jump(E_LESS_THAN, ); + //emit_conditional_jump(E_LESS_THAN, ); + //emit_jump(); + /* We need a label ERROR to jump to + */ +} + +/*// * Implement temp variable generator function that produces unique names (t1, t2, etc.) +char * temp_var_gen(){ + char * ret = calloc(9, sizeof(*ret)); + sprintf(ret, "$t%d", temp_count); + temp_count++; + return ret; +} +*/ +char * label_gen(){ + char * ret = calloc( 9, sizeof(*ret)); + sprintf(ret, "L_%d", label_count); + label_count++; + return ret; +} \ No newline at end of file diff --git a/src/symbol_table.h b/src/symbol_table.h index 6a41551..4a9d88b 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -3,6 +3,8 @@ #include #include #include +#include +#include #define SIZE_INT 4 #define SIZE_ADDR 8 @@ -10,6 +12,7 @@ #define SIZE_BOOL 4 //TODO: Ask Carl what this size should be struct TableNode; +typedef struct TFList TFList; typedef struct Constant_Stack { struct TableNode *theType; @@ -176,3 +179,152 @@ extern char *COLOR_LIGHTBLUE; extern char *COLOR_LIGHTPURPLE; extern char *COLOR_LIGHTCYAN; extern char *COLOR_WHITE; +//_____________________________________________________________ +// these are from page 364 +typedef enum { + E_LABEL = 10000, // this is not in the book + E_ADD, // 1 from the list + E_SUB, // 1 + E_MUL, // 1 + E_DIV, // 1 + E_MOD, // 1 + E_OR, // 1 + E_AND, // 1 + E_NEG, // 2 + E_NOT, // 2 + E_ASSIGN, // 3 + E_GOTO, // 4 + E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got + E_IF_X_TRUE, // 5 + E_IF_X_FALSE, // 5 + E_LESS_THAN, // 6 rule 1 + 5 + E_EQUAL_TO, // 6 rule 1 + 5 + E_CALL, // 7 + E_PARAM, // 7 + E_RETURN, // 7 + E_INDEX_COPY_RIGHT, // 8 this is x = y[i] + E_INDEX_COPY_LEFT, // 8 x[i] = y + E_ADDRESS_OF, // 9 x = &y + E_DEREF_RIGHT, // 9 x = *y + E_DEREF_LEFT // 9 x* = y +} Op; + +typedef enum { + NODE = 11000, // TableNode + INTEGER, // int + STRING, // char * + CHARACTER, // char + ADDRESS, // void * + BOOLEAN // bool +} Discriminant; + +typedef union { + TableNode * node; + int integer; + char * string; + char character; + void * address; + bool Boolean; +} TNConstUnion; + +typedef struct { + Discriminant d; + TNConstUnion * tnc_union; +} TNodeOrConst; + + +typedef struct Instruction Instruction; +typedef struct Instruction { + Op opcode; + TableNode * result; + TNodeOrConst * operand1; + TNodeOrConst * operand2; + int label; + int index; + + Instruction * prev; + Instruction * next; +} Instruction; + + +typedef struct TFList { + Instruction * i; + TFList * next; +} TFList; + +TFList * make_list(Instruction * i); +// - makelist(i) function to create instruction lists +void merge(TFList * l1, TFList * l2); +// - merge(p1,p2) function to concatenate lists +void backpatch(TFList * l, int label); +// - backpatch(p,i) function to fill in jump targets + + +//int temp_count; +//int label_count; +//bool code_gen; +//Instruction * begin; +//Instruction * current; +//char * temp; + + + +TNodeOrConst * tn_or_const(Discriminant d, void * tnc); +void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2); +void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); +void emit_assignment(TableNode * target, TNodeOrConst * source); +void emit_as_file(FILE * out_file, Instruction * instr_arr); +void emit_label(int label); +void emit_jump(int label); + +void emit_conditional_jump(Op condition, int label, ...); + +void emit_function_start(int name); +void emit_parameter(TNodeOrConst * param); +void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); +void emit_return(TNodeOrConst * value); +void emit_reserve(TableNode * result, TNodeOrConst * size); +void emit_release(TableNode * pointer); +void emit_field_access(char* result, char* record, char* field); +void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index); +void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr); + +// * Implement instruction array storage for backpatching +/* +Track 2: Control Flow & Boolean Expressions +* Implement backpatching infrastructure: +* Create truelist and falselist attributes for Boolean expressions +* Create control flow emission functions: +* Add Bison actions for control structures: +- if-then-else with backpatching +- while loops with backpatching +* Implement short-circuit Boolean operations (&&, ||, !) +* Add marker (M) nonterminal for recording instruction positions +*/ + + +/* +Track 3: Functions & Complex Types +* Implement function-related emission: +* Add Bison actions for the 'as' clause +* Create memory layout calculation functions: +- calculate_record_size(Record_Type* type) → returns bytes needed +- calculate_array_size(Array_Type* type, int dimensions[]) → returns total bytes +- calculate_field_offset(Record_Type* type, char* field_name) → returns offset +* Add Bison actions for arrays and records +*/ + +/* +Track 4: Memory Access & Integration +* Implement array and record access code: +- emit_field_access(char* result, char* record, char* field) +- emit_array_access(char* result, char* array, char* index, char* dimension) +* Add array dimension access (a._1, a._2, etc.) +* Implement bounds checking emission: +- emit_bounds_check(char* index, char* size, char* error_label) +* Create the code generation driver function +* Implement common error handling +* Document the complete intermediate instruction set +* Build integration test suite covering all language features +* Implement row-major/column-major array layout calculation +*/ \ No newline at end of file From 95c37db9ff79e3de1a98c123eda4cc2115b6ff84 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 25 Apr 2025 13:37:32 -0400 Subject: [PATCH 124/137] fixing still --- src/grammar.y | 2 ++ src/runner.c | 2 +- src/symbol_table.c | 6 +++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 74d7e92..72aa3b3 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -615,6 +615,7 @@ expression: if(getTypeEntry((TableNode*)$2) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + emit_unary_op(E_NEG,node,tn_or_const(NODE,$2)); //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) //result of unary operation $$ = node; @@ -630,6 +631,7 @@ expression: if(getTypeEntry((TableNode*)$2) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); + emit_unary_op(E_NOT,node,tn_or_const(NODE,$2)); //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) //result of unary operation $$ = node; diff --git a/src/runner.c b/src/runner.c index 9ca6cfa..c10cd6a 100644 --- a/src/runner.c +++ b/src/runner.c @@ -121,7 +121,7 @@ int run(FILE *alpha) { if (st_flag != NULL) { print_symbol_table(top, st_flag); - //emit_as_file(stdout, begin); + emit_as_file(stdout, begin); fclose(st_flag); } diff --git a/src/symbol_table.c b/src/symbol_table.c index 5fe39c3..db7523e 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1601,6 +1601,7 @@ bool isConst(TNodeOrConst * tnc) { TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { TNodeOrConst * count = calloc(1, sizeof(*count)); count->d = d; + count->tnc_union = calloc(1, sizeof(*count->tnc_union)); switch (d) { case NODE: count->tnc_union->node = tnc; @@ -1632,7 +1633,7 @@ static void emit_helper(void){ } else { current->next = inst; inst->prev = current; - inst->index = current->index++; + inst->index = current->index+1; current = inst; } } @@ -1661,6 +1662,7 @@ void emit_assignment(TableNode * target, TNodeOrConst * source){ } char * get_string(TNodeOrConst * tc){ + char * s; switch (tc->d) { case NODE: @@ -1670,10 +1672,12 @@ char * get_string(TNodeOrConst * tc){ case STRING: return tc->tnc_union->string; case INTEGER: + return getName(integ); s = calloc(10, sizeof(char)); sprintf(s, "%d", tc->tnc_union->integer); return s; case CHARACTER: + return getName(chara); s = calloc(2, sizeof(char)); sprintf(s, "%c", tc->tnc_union->character); return s; From 49a0330d08f79f94235be95403f74e6328db1690 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 15:04:20 -0400 Subject: [PATCH 125/137] Lexxer cleanup --- Makefile | 10 ++-- src/lexicalStructure.lex | 118 +++++++++++++++++++-------------------- src/runner.c | 3 +- 3 files changed, 66 insertions(+), 65 deletions(-) diff --git a/Makefile b/Makefile index bb5c7bb..8798f2e 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,8 @@ LEX := src/lexicalStructure.lex YACC := src/grammar.y EXE := alpha -OBJS := tmp/runner.o tmp/symbol_table.o tmp/grammar.tab.o tmp/lex.yy.o tmp/intermediate_code.o -# tmp/intermediate_code.o codegen.o +OBJS := tmp/runner.o tmp/symbol_table.o tmp/grammar.tab.o tmp/lex.yy.o +# tmp/intermediate_code.o codegen.o <--- Add to line above TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha) TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha) @@ -55,8 +55,10 @@ tmp/lex.yy.o: tmp/lex.yy.c tmp/symbol_table.o: src/symbol_table.c src/symbol_table.h $(CC) $(CFLAGS) -c src/symbol_table.c -o tmp/symbol_table.o -tmp/intermediate_code.o: src/intermediate_code.c src/intermediate_code.h - $(CC) $(CFLAGS) -c src/intermediate_code.c -o tmp/intermediate_code.o +# Uncomment rules when ready + +# tmp/intermediate_code.o: src/intermediate_code.c src/intermediate_code.h +# $(CC) $(CFLAGS) -c src/intermediate_code.c -o tmp/intermediate_code.o # tmp/codegen.o: src/codegen.c src/codegen.h # $(CC) $(CFLAGS) -c src/codegen.c -o tmp/codegen.o diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index e11ef39..8d92cdd 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -8,9 +8,6 @@ %{ #include "../tmp/grammar.tab.h" #include "../src/symbol_table.h" - #ifndef DEBUG - #define DEBUG 0 - #endif extern SymbolTable * cur; extern FILE* tok_flag; extern TableNode *funprime; @@ -26,14 +23,17 @@ extern void incr(int lnum,int cnum, int tok); extern void print_tok(int tok); - int line_number = 1, column_number = 1; + int line_number = 1; + int column_number = 1; int yycolumn = 1; - #define YY_USER_ACTION { \ - yylloc.first_line = yylineno; \ - yylloc.last_line = yylineno; \ - yylloc.first_column = yycolumn; \ - yylloc.last_column = yycolumn + yyleng - 1; \ - yycolumn += yyleng; } + + #define YY_USER_ACTION { \ + yylloc.first_line = yylineno; \ + yylloc.last_line = yylineno; \ + yylloc.first_column = yycolumn; \ + yylloc.last_column = yycolumn + yyleng - 1; \ + yycolumn += yyleng; \ + } %} STARCOM [^\*]|\*+[^\)\*]+ @@ -46,63 +46,63 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] %% -"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.tn = integ;return T_INTEGER;}} -"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {if(tok_flag != NULL){print_tok(T_ADDRESS);}incr(line_number,column_number,T_ADDRESS);yylval.tn = addr;return T_ADDRESS;}} -"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.tn = boo;return T_BOOLEAN;}} -"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {if(tok_flag != NULL){print_tok(T_CHARACTER);}incr(line_number,column_number,T_CHARACTER);yylval.tn = chara;return T_CHARACTER;}} +"integer" { if(tok_flag != NULL) {print_tok(T_INTEGER);} incr(line_number,column_number,T_INTEGER); yylval.tn = integ; return T_INTEGER; } +"address" { if(tok_flag != NULL) {print_tok(T_ADDRESS);} incr(line_number,column_number,T_ADDRESS); yylval.tn = addr; return T_ADDRESS; } +"Boolean" { if(tok_flag != NULL) {print_tok(T_INTEGER);} incr(line_number,column_number,T_INTEGER); yylval.tn = boo; return T_BOOLEAN; } +"character" { if(tok_flag != NULL) {print_tok(T_CHARACTER);} incr(line_number,column_number,T_CHARACTER); yylval.tn = chara; return T_CHARACTER; } -"while" {if(DEBUG) {printf( "WHILE: %s (%d)\n", yytext, WHILE);} else {if(tok_flag != NULL){print_tok(WHILE);}incr(line_number,column_number,WHILE);return WHILE;}} -"if" {if(DEBUG) {printf( "IF: %s (%d)\n", yytext, IF);} else {if(tok_flag != NULL){print_tok(IF);}incr(line_number,column_number,IF);return IF;}} -"then" {if(DEBUG) {printf( "THEN: %s (%d)\n", yytext, THEN);} else {if(tok_flag != NULL){print_tok(THEN);}incr(line_number,column_number,THEN);return THEN;}} -"else" {if(DEBUG) {printf( "ELSE: %s (%d)\n", yytext, ELSE);} else {if(tok_flag != NULL){print_tok(ELSE);}incr(line_number,column_number,ELSE);return ELSE;}} -"type" {if(DEBUG) {printf( "TYPE: %s (%d)\n", yytext, TYPE);} else {if(tok_flag != NULL){print_tok(TYPE);}incr(line_number,column_number,TYPE);return TYPE;}} -"function" {if(DEBUG) {printf( "FUNCTION: %s (%d)\n", yytext, FUNCTION);} else {if(tok_flag != NULL){print_tok(FUNCTION);}incr(line_number,column_number,FUNCTION);return FUNCTION;}} -"return" {if(DEBUG) {printf( "RETURN: %s (%d)\n", yytext, RETURN);} else {if(tok_flag != NULL){print_tok(RETURN);}incr(line_number,column_number,RETURN);return RETURN;}} -"external" {if(DEBUG) {printf( "EXTERNAL: %s (%d)\n", yytext, EXTERNAL);} else {if(tok_flag != NULL){print_tok(EXTERNAL);}incr(line_number,column_number,EXTERNAL);return EXTERNAL;}} -"as" {if(DEBUG) {printf( "AS: %s (%d)\n", yytext, AS);} else {if(tok_flag != NULL){print_tok(AS);}incr(line_number,column_number,AS);return AS;}} +"while" { if(tok_flag != NULL) {print_tok(WHILE);} incr(line_number,column_number,WHILE); return WHILE; } +"if" { if(tok_flag != NULL) {print_tok(IF);} incr(line_number,column_number,IF); return IF; } +"then" { if(tok_flag != NULL) {print_tok(THEN);} incr(line_number,column_number,THEN); return THEN; } +"else" { if(tok_flag != NULL) {print_tok(ELSE);} incr(line_number,column_number,ELSE); return ELSE; } +"type" { if(tok_flag != NULL) {print_tok(TYPE);} incr(line_number,column_number,TYPE); return TYPE; } +"function" { if(tok_flag != NULL) {print_tok(FUNCTION);} incr(line_number,column_number,FUNCTION); return FUNCTION; } +"return" { if(tok_flag != NULL) {print_tok(RETURN);} incr(line_number,column_number,RETURN); return RETURN; } +"external" { if(tok_flag != NULL) {print_tok(EXTERNAL);} incr(line_number,column_number,EXTERNAL); return EXTERNAL; } +"as" { if(tok_flag != NULL) {print_tok(AS);} incr(line_number,column_number,AS); return AS; } -"release" {if(DEBUG) {printf( "RELEASE: %s (%d)\n", yytext, RELEASE);} else {if(tok_flag != NULL){print_tok(RELEASE);}incr(line_number,column_number,RELEASE);return RELEASE;}} -"reserve" {if(DEBUG) {printf( "RESERVE: %s (%d)\n", yytext, RESERVE);} else {if(tok_flag != NULL){print_tok(RESERVE);}incr(line_number,column_number,RESERVE);return RESERVE;}} +"release" { if(tok_flag != NULL) {print_tok(RELEASE);} incr(line_number,column_number,RELEASE); return RELEASE; } +"reserve" { if(tok_flag != NULL) {print_tok(RESERVE);} incr(line_number,column_number,RESERVE); return RESERVE; } -"+" {if(DEBUG) {printf( "ADD: %s (%d)\n", yytext, ADD);} else {if(tok_flag != NULL){print_tok(ADD);}incr(line_number,column_number,ADD);return ADD;}} -"-" {if(DEBUG) {printf( "SUB_OR_NEG: %s (%d)\n", yytext, SUB_OR_NEG);} else {if(tok_flag != NULL){print_tok(SUB_OR_NEG);}incr(line_number,column_number,SUB_OR_NEG);return SUB_OR_NEG;}} -"*" {if(DEBUG) {printf( "MUL: %s (%d)\n", yytext, MUL);} else {if(tok_flag != NULL){print_tok(MUL);}incr(line_number,column_number,MUL);return MUL;}} -"/" {if(DEBUG) {printf( "DIV: %s (%d)\n", yytext, DIV);} else {if(tok_flag != NULL){print_tok(DIV);}incr(line_number,column_number,DIV);return DIV;}} -"%" {if(DEBUG) {printf( "REM: %s (%d)\n", yytext, REM);} else {if(tok_flag != NULL){print_tok(REM);}incr(line_number,column_number,REM);return REM;}} -"<" {if(DEBUG) {printf( "LESS_THAN: %s (%d)\n", yytext, LESS_THAN);} else {if(tok_flag != NULL){print_tok(LESS_THAN);}incr(line_number,column_number,LESS_THAN);return LESS_THAN;}} -"=" {if(DEBUG) {printf( "EQUAL_TO: %s (%d)\n", yytext, EQUAL_TO);} else {if(tok_flag != NULL){print_tok(EQUAL_TO);}incr(line_number,column_number,EQUAL_TO);return EQUAL_TO;}} -":=" {if(DEBUG) {printf( "ASSIGN: %s (%d)\n", yytext, ASSIGN);} else {if(tok_flag != NULL){print_tok(ASSIGN);}incr(line_number,column_number,ASSIGN);return ASSIGN;}} -"!" {if(DEBUG) {printf( "NOT: %s (%d)\n", yytext, NOT);} else {if(tok_flag != NULL){print_tok(NOT);}incr(line_number,column_number,NOT);return NOT;}} -"&" {if(DEBUG) {printf( "AND: %s (%d)\n", yytext, AND);} else {if(tok_flag != NULL){print_tok(AND);}incr(line_number,column_number,AND);return AND;}} -"|" {if(DEBUG) {printf( "OR: %s (%d)\n", yytext, OR);} else {if(tok_flag != NULL){print_tok(OR);}incr(line_number,column_number,OR);return OR;}} -"." {if(DEBUG) {printf( "DOT: %s (%d)\n", yytext, DOT);} else {if(tok_flag != NULL){print_tok(DOT);}incr(line_number,column_number,DOT);return DOT;}} +"+" { if(tok_flag != NULL) {print_tok(ADD);} incr(line_number,column_number,ADD); return ADD; } +"-" { if(tok_flag != NULL) {print_tok(SUB_OR_NEG);} incr(line_number,column_number,SUB_OR_NEG); return SUB_OR_NEG; } +"*" { if(tok_flag != NULL) {print_tok(MUL);} incr(line_number,column_number,MUL); return MUL; } +"/" { if(tok_flag != NULL) {print_tok(DIV);} incr(line_number,column_number,DIV); return DIV; } +"%" { if(tok_flag != NULL) {print_tok(REM);} incr(line_number,column_number,REM); return REM; } +"<" { if(tok_flag != NULL) {print_tok(LESS_THAN);} incr(line_number,column_number,LESS_THAN); return LESS_THAN; } +"=" { if(tok_flag != NULL) {print_tok(EQUAL_TO);} incr(line_number,column_number,EQUAL_TO); return EQUAL_TO; } +":=" { if(tok_flag != NULL) {print_tok(ASSIGN);} incr(line_number,column_number,ASSIGN); return ASSIGN; } +"!" { if(tok_flag != NULL) {print_tok(NOT);} incr(line_number,column_number,NOT); return NOT; } +"&" { if(tok_flag != NULL) {print_tok(AND);} incr(line_number,column_number,AND); return AND; } +"|" { if(tok_flag != NULL) {print_tok(OR);} incr(line_number,column_number,OR); return OR; } +"." { if(tok_flag != NULL) {print_tok(DOT);} incr(line_number,column_number,DOT); return DOT; } -";" {if(DEBUG) {printf( "SEMI_COLON: %s (%d)\n", yytext, SEMI_COLON);} else {if(tok_flag != NULL){print_tok(SEMI_COLON);}incr(line_number,column_number,SEMI_COLON);return SEMI_COLON;}} -":" {if(DEBUG) {printf( "COLON: %s (%d)\n", yytext, COLON);} else {if(tok_flag != NULL){print_tok(COLON);}incr(line_number,column_number,COLON);return COLON;}} -"," {if(DEBUG) {printf( "COMMA: %s (%d)\n", yytext, COMMA);} else {if(tok_flag != NULL){print_tok(COMMA);}incr(line_number,column_number,COMMA);return COMMA;}} -"->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {if(tok_flag != NULL){print_tok(ARROW);}incr(line_number,column_number,ARROW);return ARROW;}} +";" { if(tok_flag != NULL) {print_tok(SEMI_COLON);} incr(line_number,column_number,SEMI_COLON); return SEMI_COLON; } +":" { if(tok_flag != NULL) {print_tok(COLON);} incr(line_number,column_number,COLON); return COLON; } +"," { if(tok_flag != NULL) {print_tok(COMMA);} incr(line_number,column_number,COMMA); return COMMA; } +"->" { if(tok_flag != NULL) {print_tok(ARROW);} incr(line_number,column_number,ARROW); return ARROW; } -{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytext)/*words = strdup("integer")*/;return C_INTEGER;}} -'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.tn = chara;return C_CHARACTER;}} -\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.tn = stri;return C_STRING;}} -{COMMENT} {if(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}} +{DIGIT}+ { if(tok_flag != NULL) {print_tok(C_INTEGER);} incr(line_number,column_number,C_INTEGER); yylval.integ = atoi(yytext); return C_INTEGER; } +'{CHAR}' { if(tok_flag != NULL) {print_tok(C_CHARACTER);} incr(line_number,column_number,C_CHARACTER); yylval.tn = chara; return C_CHARACTER; } +\"{SCHAR}*\" { if(tok_flag != NULL) {print_tok(C_STRING);} incr(line_number,column_number,C_STRING); yylval.tn = stri; return C_STRING; } +{COMMENT} { if(tok_flag != NULL) {print_tok(COMMENT);} incr(line_number,column_number,COMMENT);} -"(" {if(DEBUG) {printf( "L_PAREN: %s (%d)\n", yytext, L_PAREN);} else {if(tok_flag != NULL){print_tok(L_PAREN);}incr(line_number,column_number,L_PAREN);return L_PAREN;}} -")" {if(DEBUG) {printf( "R_PAREN: %s (%d)\n", yytext, R_PAREN);} else {if(tok_flag != NULL){print_tok(R_PAREN);}incr(line_number,column_number,R_PAREN);return R_PAREN;}} -"[" {if(DEBUG) {printf( "L_BRACKET: %s (%d)\n", yytext, L_BRACKET);} else {if(tok_flag != NULL){print_tok(L_BRACKET);}incr(line_number,column_number,L_BRACKET);return L_BRACKET;}} -"]" {if(DEBUG) {printf( "R_BRACKET: %s (%d)\n", yytext, R_BRACKET);} else {if(tok_flag != NULL){print_tok(R_BRACKET);}incr(line_number,column_number,R_BRACKET);return R_BRACKET;}} -"{" {if(DEBUG) {printf( "L_BRACE: %s (%d)\n", yytext, L_BRACE);} else {if(tok_flag != NULL){print_tok(L_BRACE);}incr(line_number,column_number,L_BRACE);return L_BRACE;}} -"}" {if(DEBUG) {printf( "R_BRACE: %s (%d)\n", yytext, R_BRACE);} else {if(tok_flag != NULL){print_tok(R_BRACE);}incr(line_number,column_number,R_BRACE);return R_BRACE;}} +"(" { if(tok_flag != NULL) {print_tok(L_PAREN);} incr(line_number,column_number,L_PAREN); return L_PAREN; } +")" { if(tok_flag != NULL) {print_tok(R_PAREN);} incr(line_number,column_number,R_PAREN); return R_PAREN; } +"[" { if(tok_flag != NULL) {print_tok(L_BRACKET);} incr(line_number,column_number,L_BRACKET); return L_BRACKET; } +"]" { if(tok_flag != NULL) {print_tok(R_BRACKET);} incr(line_number,column_number,R_BRACKET); return R_BRACKET; } +"{" { if(tok_flag != NULL) {print_tok(L_BRACE);} incr(line_number,column_number,L_BRACE); return L_BRACE; } +"}" { if(tok_flag != NULL) {print_tok(R_BRACE);} incr(line_number,column_number,R_BRACE); return R_BRACE; } -"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.tn = boo;return C_TRUE;}} -"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.tn = boo;return C_FALSE;}} -"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.tn = addr;return C_NULL;}} +"true" { if(tok_flag != NULL) {print_tok(C_TRUE);} incr(line_number,column_number,C_TRUE); yylval.tn = boo; return C_TRUE; } +"false" { if(tok_flag != NULL) {print_tok(C_FALSE);} incr(line_number,column_number,C_FALSE); yylval.tn = boo; return C_FALSE; } +"null" { if(tok_flag != NULL) {print_tok(C_NULL);} incr(line_number,column_number,C_NULL); yylval.tn = addr; return C_NULL; } -{ID} {if(DEBUG) {printf( "ID: %s (%d)\n", yytext, ID);} else {if(tok_flag != NULL){print_tok(ID);}incr(line_number,column_number,ID);yylval.words = strdup(yytext); return ID;}} +{ID} { if(tok_flag != NULL) {print_tok(ID);} incr(line_number,column_number,ID); yylval.words = strdup(yytext); return ID; } -\n {yycolumn=1;incr(line_number,column_number,0);} -\t {incr(line_number,column_number,0);} -" " {incr(line_number,column_number,0);} -. {incr(line_number,column_number,0);} +\n { yycolumn = 1; incr(line_number,column_number,0); } +\t { incr(line_number,column_number,0); } +" " { incr(line_number,column_number,0); } +. { incr(line_number,column_number,0); } %% diff --git a/src/runner.c b/src/runner.c index 3fa35ca..0ccb74f 100644 --- a/src/runner.c +++ b/src/runner.c @@ -22,8 +22,7 @@ int main(int argc, char *argv[]) { } else { - if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != - 0) { + if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != 0) { fprintf(stderr, INVALID); return -1; } else { From 46d8a852a64b2cfdf1c59f958379c02f6502f844 Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 25 Apr 2025 15:36:31 -0400 Subject: [PATCH 126/137] trying to get annie's to work --- src/grammar.y | 28 +- src/intermediate_code.c | 1 + src/runner.c | 2 + src/runner.h | 5 +- src/symbol_table.c | 532 +++++++++++++++++- src/symbol_table.h | 39 +- .../sp3_integer_binary_op_typecheck.alpha | 2 +- 7 files changed, 581 insertions(+), 28 deletions(-) diff --git a/src/grammar.y b/src/grammar.y index 72aa3b3..00a294f 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -647,8 +647,7 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_ADD,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -662,8 +661,8 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_SUB,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); + $$ = node; } else { $$=undefined; @@ -677,8 +676,7 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_MUL,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -692,8 +690,7 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_DIV,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -707,8 +704,7 @@ expression: if((getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of binary operation + emit_binary_op(E_MOD,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -722,8 +718,7 @@ expression: if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of comparison + emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -737,8 +732,7 @@ expression: if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of comparison + emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -752,8 +746,7 @@ expression: if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of comparison + emit_binary_op(E_LESS_THAN,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; @@ -767,8 +760,7 @@ expression: if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //result of compariosn + emit_binary_op(E_EQUAL_TO,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 3ccec2c..6349054 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -5,6 +5,7 @@ // check if start is NULL if it is assign it to the start globle variable // otherwise make it next of current and set cur to your instruction. + TNodeOrConst * tn_or_const(Op op, void * tnc) { TNodeOrConst * count = calloc(1, sizeof(*count)); count->d = op; diff --git a/src/runner.c b/src/runner.c index c10cd6a..736be1c 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,6 +2,8 @@ /* The Translators - Spring 2025 */ #include "runner.h" +FILE *ir_flag = NULL; +FILE *cg_flag = NULL; //Constant_Stack *head = NULL; int main(int argc, char *argv[]) { if (argc == 1) { diff --git a/src/runner.h b/src/runner.h index 74a7ecf..7e134f2 100644 --- a/src/runner.h +++ b/src/runner.h @@ -35,7 +35,8 @@ #include "../tmp/grammar.tab.h" #include "symbol_table.h" -extern int line_number, column_number; +extern int line_number; +extern int column_number; extern char *yytext; extern FILE *yyin; extern bool DEBUG; @@ -46,8 +47,6 @@ SymbolTable *cur; FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; -FILE *ir_flag = NULL; -FILE *cg_flag = NULL; FILE *asc_flag = NULL; bool tc_flag = false; bool DEBUG = false; diff --git a/src/symbol_table.c b/src/symbol_table.c index db7523e..4ec3e70 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -10,6 +10,9 @@ char* temp = NULL; int label_count=0; Instruction* begin = NULL; Instruction* current = NULL; +int offset = 0; +int currentsp = 0; +CGNode *cgList = NULL; void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { @@ -1574,7 +1577,7 @@ TNodeOrConst * getOperand2(Instruction * i){ return i->operand2; } -TableNode * get_result(Instruction * i){ +TableNode * getResult(Instruction * i){ return i->result; } @@ -1672,12 +1675,10 @@ char * get_string(TNodeOrConst * tc){ case STRING: return tc->tnc_union->string; case INTEGER: - return getName(integ); s = calloc(10, sizeof(char)); sprintf(s, "%d", tc->tnc_union->integer); return s; case CHARACTER: - return getName(chara); s = calloc(2, sizeof(char)); sprintf(s, "%c", tc->tnc_union->character); return s; @@ -1690,11 +1691,12 @@ char * get_string(TNodeOrConst * tc){ } void emit_as_file(FILE * out_file, Instruction * i){ - if(!i){ + if(i == NULL){ return; } switch(i->opcode){ case E_LABEL: + break; // this is a terrible one to start with // fprintf(out_file, "%04.d: %d ", i->index, i->label); case E_ADD: @@ -1752,7 +1754,7 @@ void emit_as_file(FILE * out_file, Instruction * i){ case E_ASSIGN: fprintf(out_file, "%4.d: %s = %s\n", i->index, getName(i->result), - get_string(i->operand2)); + get_string(i->operand1)); break; case E_GOTO: // are we ever going to use this? @@ -1945,4 +1947,524 @@ char * label_gen(){ sprintf(ret, "L_%d", label_count); label_count++; return ret; +} +//------------------------------------------------------------------------------------- +int generate(){ + offset = 0; + Instruction* i = begin; + while (i != NULL) { + switch(getOp(i)) { + case E_LABEL: + generateLabel(i); + break; + case E_ADD: + generateAdd(i); + break; + case E_SUB: + generateSub(i); + break; + case E_MUL: + generateMult(i); + break; + case E_DIV: + generateDiv(i); + break; + case E_MOD: + generateMod(i); + break; + case E_OR: + generateOr(i); + break; + case E_AND: + generateAnd(i); + break; + case E_NEG: + generateNeg(i); + break; + case E_NOT: + generateNot(i); + break; + case E_ASSIGN: + generateAssign(i); + break; + case E_GOTO: + generateGoto(i); + break; + case E_IF_X_TRUE: + generateIfTrue(i); + break; + case E_IF_X_FALSE: + generateIfFalse(i); + break; + case E_LESS_THAN: + generateLessThan(i); + break; + case E_EQUAL_TO: + generateEqualTo(i); + break; + case E_CALL: + generateCall(i); + break; + case E_PARAM: + generateParam(i); + break; + case E_RETURN: + generateReturn(i); + break; + case E_INDEX_COPY_RIGHT: + generateCopyRight(i); + break; + case E_INDEX_COPY_LEFT: + generateCopyLeft(i); + break; + case E_ADDRESS_OF: + generateAddressOf(i); + break; + default: + ; + } + } + return -1; +} + +CGNode *getNextCG(CGNode *cg) { + if (cg == NULL) { + return NULL; + } + return cg->next; +} + +int getAddress(CGNode *cg) { + if (cg == NULL) { + return -1; + } + return currentsp - cg->address; +} + +TableNode *getTNofCG(CGNode *cg) { + if (cg == NULL) { + return NULL; + } + return cg->tn; +} +/* +movl $1, -4(%rbp) +add -4(%rbp), $2 +*/ +CGNode *findCG(TableNode *tn) { + CGNode *cg = cgList; + while (cg != NULL) { + if (getTNofCG(cg) == tn) { + return cg; + } + cg = getNextCG(cg); + } + return NULL; +} + +CGNode *addCG(TableNode *tn, int sp) { + CGNode *cg = calloc(1, sizeof(CGNode)); + cg->tn = tn; + cg->address = sp; + offset += getPrimSize(tn); //not sure if this is the correct amount to add to the offset + cg->next = cgList; + cgList = cg; + return cg; +} + + +int generateLabel(Instruction *inst) { + fprintf(cg_flag, ".L%d:\n", getLabel(inst)); + return 0; +} +int generateAdd(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateAdd failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1))); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\taddl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateSub(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateSub failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateSub failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateMult(Instruction *instruction){ + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateMult failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateMult failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateMult failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateDiv(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateDiv failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateDiv failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateDiv failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax + fprintf(cg_flag, "\tidivl\t%d(\%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); //stores result + return 0; +} + +int generateMod(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateMod failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateMod failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax + fprintf(cg_flag, "\tidivl\t%d(\%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t\%edx, %d(\%rbp)\n", getAddress(cg)); //stores result from edx (remainder) + return 0; +} + +int generateOr(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateOr failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateOr failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateOr failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\torll\t%d(\%rbp), %eax\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); //stores result + return 0; +} + +int generateAnd(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateNeg failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tandl\t%d(\%rbp), %eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} +int generateNeg(Instruction *instruction) { + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateNeg failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateNeg failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnegl\t%d %eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} +int generateNot(Instruction *instruction) { + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *result = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateNot failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(op1); + CGNode *op2CG = findCG(op2); + if (op1CG == NULL) { + printdebug("generateNot failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateNot failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnotl\t\%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateAssign(Instruction *instruction) { + TNodeOrConst *op1 = getOperand1(inst); + CGNode *result = findCG(getResult(inst)); + + + if (op1 == NULL) { + printdebug("generateAssign failed, NULL operand"); + return -1; + } + + if (result == NULL) { + result = addCG(getResult(inst), offset); + } + + + //add option for constant assignment (should be easy) + + + CGNode *op1CG = findCG(op1); + if (op1CG == NULL) { + printdebug("generateAssign failed, op1 is not constant but not in CGlist"); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + return 0; +} + +int generateGoto(Instruction *instruction){ + return -1; +} + +int generateCondGoto(Instruciton *instruction) { + return -1; +} + +int generateIfTrue(Instruction *instruction){ + return -1; +} + +int generateIfFalse(Instruction *instruction){ + return -1; +} + +int generateLessThan(Instruction *instruction){ + return -1; +} +int generateEqualTo(Instruction *instruction){ + return -1; +} +int generateCall(Instruction *instruction){ + return -1; +} +int generateReturn(Instruction *instruction){ + return -1; +} +int generateCopyRight(Instruction *instruction){ + return -1; +} +int generateCopyLeft(Instruction *instruction){ + return -1; +} +int generateAddressOf(Instruction *instruction){ + return -1; +} +int generateParam(Instruction *instruction){ + return -1; } \ No newline at end of file diff --git a/src/symbol_table.h b/src/symbol_table.h index 4a9d88b..41138b8 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -13,6 +13,7 @@ struct TableNode; typedef struct TFList TFList; +typedef struct CGNode CGNode; typedef struct Constant_Stack { struct TableNode *theType; @@ -327,4 +328,40 @@ Track 4: Memory Access & Integration * Document the complete intermediate instruction set * Build integration test suite covering all language features * Implement row-major/column-major array layout calculation -*/ \ No newline at end of file +*/ +//------------------------------------------------------------- +extern FILE *cg_flag; +typedef struct CGNode { + TableNode *tn; + int address; + CGNode *next; +}CGNode; + +int generate(); +CGNode *getNextCG(CGNode *cg); +int getAddress(CGNode *cg); +TableNode *getTNofCG(CGNode *cg); +int generateLabel(Instruction *instruction); +int generateAdd(Instruction *instruction); +int generateSub(Instruction *instruction); +int generateMult(Instruction *instruction); +int generateDiv(Instruction *instruction); +int generateMod(Instruction *instruction); +int generateOr(Instruction *instruction); +int generateAnd(Instruction *instruction); +int generateNeg(Instruction *instruction); +int generateNot(Instruction *instruction); +int generateDiv(Instruction *instruction); +int generateAssign(Instruction *instruction); // is this for something like x = 1? +int generateGoto(Instruction *instruction); +int generateCondGoto(Instruction *instruction); +int generateIfTrue(Instruction *instruction); +int generateIfFalse(Instruction *instruction); +int generateLessThan(Instruction *instruction); +int generateEqualTo(Instruction *instruction); +int generateCall(Instruction *instruction); +int generateReturn(Instruction *instruction); +int generateCopyRight(Instruction *instruction); +int generateCopyLeft(Instruction *instruction); +int generateAddressOf(Instruction *instruction); +int generateParam(Instruction *instruction); \ No newline at end of file diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha index bc88a72..2adb394 100644 --- a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -7,7 +7,7 @@ entry (arg) := { [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a; rec : r] x := 3 + 2 * 8; - x := 3 - 2 / 8; + x := 3 - 2 / 8; x := a * 2 % 8; b2 := 3 * 2 % 8; x := 3 % 2 * 8; From 1999230265bac512c9aa8d190af15d77f5e57e8d Mon Sep 17 00:00:00 2001 From: Partho Date: Fri, 25 Apr 2025 16:55:27 -0400 Subject: [PATCH 127/137] got compilation to work --- cg.s | 44 +++++++ src/runner.c | 12 +- src/runner.h | 1 + src/symbol_table.c | 289 +++++++++++++++++++++++++++++---------------- 4 files changed, 241 insertions(+), 105 deletions(-) create mode 100644 cg.s diff --git a/cg.s b/cg.s new file mode 100644 index 0000000..47bbe30 --- /dev/null +++ b/cg.s @@ -0,0 +1,44 @@ + movl $3, 0(%rbp) + movl $2, 1(%rbp) + movl $8, 2(%rbp) + movl 1(%rbp), %eax + subl 2(%rbp), %eax + movl %eax, 3(%rbp) + movl 0(%rbp), %eax + addl 0(%rbp), %eax + movl %eax, 4(%rbp) + movl $3, 5(%rbp) + movl $2, 6(%rbp) + movl $8, 7(%rbp) + movl 6(%rbp), %eax + cltd + idivl 7(%rbp) + movl %eax, 8(%rbp) + movl 5(%rbp), %eax + subl 8(%rbp), %eax + movl %eax, 9(%rbp) + movl $2, 10(%rbp) + movl $8, 11(%rbp) + movl $3, 12(%rbp) + movl $2, 13(%rbp) + movl 12(%rbp), %eax + subl 13(%rbp), %eax + movl %eax, 14(%rbp) + movl $8, 15(%rbp) + movl 14(%rbp), %eax + cltd + idivl 15(%rbp) + movl %edx, 16(%rbp) + movl $3, 17(%rbp) + movl $2, 18(%rbp) + movl 17(%rbp), %eax + cltd + idivl 18(%rbp) + movl %edx, 19(%rbp) + movl $8, 20(%rbp) + movl 19(%rbp), %eax + subl 20(%rbp), %eax + movl %eax, 21(%rbp) + movl $3, 22(%rbp) + movl $8, 23(%rbp) + movl $0, 24(%rbp) diff --git a/src/runner.c b/src/runner.c index 736be1c..2253b73 100644 --- a/src/runner.c +++ b/src/runner.c @@ -3,7 +3,6 @@ #include "runner.h" FILE *ir_flag = NULL; -FILE *cg_flag = NULL; //Constant_Stack *head = NULL; int main(int argc, char *argv[]) { if (argc == 1) { @@ -38,6 +37,7 @@ int main(int argc, char *argv[]) { alpha_file = fopen(argv[argc - 1], "r"); } } + cg_flag = fopen("cg.s", "w"); return run(alpha_file); } @@ -125,6 +125,8 @@ int run(FILE *alpha) { print_symbol_table(top, st_flag); emit_as_file(stdout, begin); fclose(st_flag); + generate(); + fclose(cg_flag); } if (asc_flag != NULL) { @@ -141,10 +143,10 @@ int run(FILE *alpha) { fclose(ir_flag); } - if (cg_flag != NULL) { - printf("Flag -cg is not implemented yet\n"); - fclose(cg_flag); - } + //if (cg_flag != NULL) { + // printf("Flag -cg is not implemented yet\n"); + //fclose(cg_flag); + //} if (yyin != NULL) { fclose(yyin); diff --git a/src/runner.h b/src/runner.h index 7e134f2..503b319 100644 --- a/src/runner.h +++ b/src/runner.h @@ -48,6 +48,7 @@ FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; FILE *asc_flag = NULL; +FILE *cg_flag = NULL; bool tc_flag = false; bool DEBUG = false; int no_flag = 0; diff --git a/src/symbol_table.c b/src/symbol_table.c index 4ec3e70..441eb5c 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -1948,10 +1948,24 @@ char * label_gen(){ label_count++; return ret; } + +TableNode* getTN(TNodeOrConst * tnc){ + if(tnc->d == NODE){ + return tnc->tnc_union->node; + } + return NULL; +} +//we must fix this +int getConst(TNodeOrConst * tnc){ + if(tnc->d == INTEGER){ + return tnc->tnc_union->integer; + } + return -1; +} //------------------------------------------------------------------------------------- int generate(){ offset = 0; - Instruction* i = begin; + Instruction *i = begin; while (i != NULL) { switch(getOp(i)) { case E_LABEL: @@ -2023,6 +2037,7 @@ int generate(){ default: ; } + i = i->next; } return -1; } @@ -2038,6 +2053,7 @@ int getAddress(CGNode *cg) { if (cg == NULL) { return -1; } + return currentsp - cg->address; } @@ -2047,10 +2063,7 @@ TableNode *getTNofCG(CGNode *cg) { } return cg->tn; } -/* -movl $1, -4(%rbp) -add -4(%rbp), $2 -*/ + CGNode *findCG(TableNode *tn) { CGNode *cg = cgList; while (cg != NULL) { @@ -2085,20 +2098,20 @@ int generateAdd(Instruction *inst) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateAdd failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op1)); if (op1CG == NULL) { printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1))); return -1; @@ -2109,9 +2122,9 @@ int generateAdd(Instruction *inst) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\taddl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\taddl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } @@ -2121,21 +2134,21 @@ int generateSub(Instruction *instruction) { One immediate: Neither immediate: */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + TNodeOrConst *op1 = getOperand1(instruction); + TNodeOrConst *op2 = getOperand2(instruction); + CGNode *cg = findCG(getResult(instruction)); if (op1 == NULL || op2 == NULL) { printdebug("generateSub failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(instruction), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateSub failed, op1 is not constant but not in CGlist"); return -1; @@ -2146,13 +2159,13 @@ int generateSub(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tsubl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateMult(Instruction *instruction){ +int generateMult(Instruction *inst){ /* Both immediate: One immediate: @@ -2160,18 +2173,18 @@ int generateMult(Instruction *instruction){ */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateMult failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateMult failed, op1 is not constant but not in CGlist"); return -1; @@ -2182,13 +2195,13 @@ int generateMult(Instruction *instruction){ return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tsubl\t%d(\%rbp), \%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateDiv(Instruction *instruction) { +int generateDiv(Instruction *inst) { /* Both immediate: One immediate: @@ -2196,19 +2209,19 @@ int generateDiv(Instruction *instruction) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateDiv failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateDiv failed, op1 is not constant but not in CGlist"); return -1; @@ -2219,14 +2232,14 @@ int generateDiv(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax - fprintf(cg_flag, "\tidivl\t%d(\%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); //stores result + fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result return 0; } -int generateMod(Instruction *instruction) { +int generateMod(Instruction *inst) { /* Both immediate: One immediate: @@ -2234,18 +2247,18 @@ int generateMod(Instruction *instruction) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateMod failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateMod failed, op1 is not constant but not in CGlist"); return -1; @@ -2256,14 +2269,14 @@ int generateMod(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax - fprintf(cg_flag, "\tidivl\t%d(\%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t\%edx, %d(\%rbp)\n", getAddress(cg)); //stores result from edx (remainder) + fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\n", getAddress(cg)); //stores result from edx (remainder) return 0; } -int generateOr(Instruction *instruction) { +int generateOr(Instruction *inst) { /* Both immediate: One immediate: @@ -2271,19 +2284,19 @@ int generateOr(Instruction *instruction) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateOr failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateOr failed, op1 is not constant but not in CGlist"); return -1; @@ -2294,13 +2307,13 @@ int generateOr(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\torll\t%d(\%rbp), %eax\n", getAddress(op2CG));//divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); //stores result + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\torll\t%d(%%rbp), %%eax\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result return 0; } -int generateAnd(Instruction *instruction) { +int generateAnd(Instruction *inst) { /* Both immediate: One immediate: @@ -2308,50 +2321,50 @@ int generateAnd(Instruction *instruction) { */ TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { - printdebug("generateNeg failed, op1 is not constant but not in CGlist"); + printdebug("generateAnd failed, op1 is not constant but not in CGlist"); return -1; } if (op2CG == NULL) { - printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2))); + printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tandl\t%d(\%rbp), %eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tandl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateNeg(Instruction *instruction) { +int generateNeg(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateNeg failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateNeg failed, op1 is not constant but not in CGlist"); return -1; @@ -2362,27 +2375,27 @@ int generateNeg(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tnegl\t%d %eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnegl\t%d %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateNot(Instruction *instruction) { +int generateNot(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL || op2 == NULL) { printdebug("generateNot failed, NULL operand"); return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } - CGNode *op1CG = findCG(op1); - CGNode *op2CG = findCG(op2); + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateNot failed, op1 is not constant but not in CGlist"); return -1; @@ -2393,15 +2406,15 @@ int generateNot(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tnotl\t\%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnotl\t%%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } -int generateAssign(Instruction *instruction) { +int generateAssign(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); - CGNode *result = findCG(getResult(inst)); + CGNode *cg = findCG(getResult(inst)); if (op1 == NULL) { @@ -2409,22 +2422,25 @@ int generateAssign(Instruction *instruction) { return -1; } - if (result == NULL) { - result = addCG(getResult(inst), offset); + if (cg == NULL) { + cg = addCG(getResult(inst), offset); } //add option for constant assignment (should be easy) + if (isConst(op1) == true) { + fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\n", getConst(op1), getAddress(cg)); + } - CGNode *op1CG = findCG(op1); + CGNode *op1CG = findCG(getTN(op1)); if (op1CG == NULL) { printdebug("generateAssign failed, op1 is not constant but not in CGlist"); return -1; } - fprintf(cg_flag, "\tmovl\t%d(\%rbp), \%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tmovl\t\%eax, %d(\%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); return 0; } @@ -2432,29 +2448,101 @@ int generateGoto(Instruction *instruction){ return -1; } -int generateCondGoto(Instruciton *instruction) { +int generateCondGoto(Instruction *instruction) { return -1; } int generateIfTrue(Instruction *instruction){ return -1; + // might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case } int generateIfFalse(Instruction *instruction){ return -1; } -int generateLessThan(Instruction *instruction){ - return -1; +int generateLessThan(Instruction *inst){ + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tsetl\t%%al\n"); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + return 0; } -int generateEqualTo(Instruction *instruction){ - return -1; + +int generateEqualTo(Instruction *inst){ + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tsete\t%%al\n"); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + return 0; } int generateCall(Instruction *instruction){ return -1; + //will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg } int generateReturn(Instruction *instruction){ return -1; + //will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value } int generateCopyRight(Instruction *instruction){ return -1; @@ -2466,5 +2554,6 @@ int generateAddressOf(Instruction *instruction){ return -1; } int generateParam(Instruction *instruction){ + //need to check if op1 is null, then add it to the appropriate register/cg node. need a way to keep track of this, maybe just have global count of params generated return -1; } \ No newline at end of file From f256a90e3e4d34d7559ca2984e80ba53d1b6a8a7 Mon Sep 17 00:00:00 2001 From: Moroseui <157774170+Moroseui@users.noreply.github.com> Date: Fri, 25 Apr 2025 17:21:49 -0400 Subject: [PATCH 128/137] deleted extra files --- cg.s | 44 ---------- check.sh | 0 src/intermediate_code.c | 188 ---------------------------------------- src/intermediate_code.h | 109 ----------------------- test.alpha | 29 ------- test.sh | 0 6 files changed, 370 deletions(-) delete mode 100644 cg.s mode change 100755 => 100644 check.sh delete mode 100644 src/intermediate_code.c delete mode 100644 src/intermediate_code.h delete mode 100644 test.alpha mode change 100755 => 100644 test.sh diff --git a/cg.s b/cg.s deleted file mode 100644 index 47bbe30..0000000 --- a/cg.s +++ /dev/null @@ -1,44 +0,0 @@ - movl $3, 0(%rbp) - movl $2, 1(%rbp) - movl $8, 2(%rbp) - movl 1(%rbp), %eax - subl 2(%rbp), %eax - movl %eax, 3(%rbp) - movl 0(%rbp), %eax - addl 0(%rbp), %eax - movl %eax, 4(%rbp) - movl $3, 5(%rbp) - movl $2, 6(%rbp) - movl $8, 7(%rbp) - movl 6(%rbp), %eax - cltd - idivl 7(%rbp) - movl %eax, 8(%rbp) - movl 5(%rbp), %eax - subl 8(%rbp), %eax - movl %eax, 9(%rbp) - movl $2, 10(%rbp) - movl $8, 11(%rbp) - movl $3, 12(%rbp) - movl $2, 13(%rbp) - movl 12(%rbp), %eax - subl 13(%rbp), %eax - movl %eax, 14(%rbp) - movl $8, 15(%rbp) - movl 14(%rbp), %eax - cltd - idivl 15(%rbp) - movl %edx, 16(%rbp) - movl $3, 17(%rbp) - movl $2, 18(%rbp) - movl 17(%rbp), %eax - cltd - idivl 18(%rbp) - movl %edx, 19(%rbp) - movl $8, 20(%rbp) - movl 19(%rbp), %eax - subl 20(%rbp), %eax - movl %eax, 21(%rbp) - movl $3, 22(%rbp) - movl $8, 23(%rbp) - movl $0, 24(%rbp) diff --git a/check.sh b/check.sh old mode 100755 new mode 100644 diff --git a/src/intermediate_code.c b/src/intermediate_code.c deleted file mode 100644 index 6349054..0000000 --- a/src/intermediate_code.c +++ /dev/null @@ -1,188 +0,0 @@ - - - -// TODO: this is here to bring your attention to the comment bellow. -// check if start is NULL if it is assign it to the start globle variable -// otherwise make it next of current and set cur to your instruction. - - -TNodeOrConst * tn_or_const(Op op, void * tnc) { - TNodeOrConst * count = calloc(1, sizeof(*count)); - count->d = op; - switch (op) { - case NODE: - count->tnc_union->node = tnc; - break; - case ADDRESS: - count->tnc_union->address = tnc; - break; - case STRING: - count->tnc_union->string = tnc; - break; - case INTEGER: - count->tnc_union->integer = *(int*)tnc; - break; - case CHARACTER: - count->tnc_union->character = *(char*)tnc; - break; - case BOOLEAN: - count->tnc_union->Boolean = *(bool*)tnc; - break; - } - return count; -} - -static void emit_helper(void){ - Instruction * inst = calloc(1, sizeof(*inst)); - if(begin == NULL){ - begin = current = inst; - current->index = 1; - } else { - current->next = inst; - inst->prev = current; - inst->index = current->index++; - current = inst; - } -} - -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2){ - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = arg1; - current->operand2 = arg2; - return; - } - -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = arg; - return; - } - -void emit_assignment(TableNode * target, TNodeOrConst * source){ - emit_helper(); - current->opcode = E_ASSIGN; // TODO: replace with move - current->result = target; - current->operand1 = source; - return; - } - -void emit_as_file(FILE * out_file, Instruction * instr_arr){ - if(instr_arr == NULL){ - return; - } - - //fprintf(out_file, - return; -} - - -void emit_label(int label){ - emit_helper(); - current->opcode = E_LABEL; - current->label = label; - return; -} -void emit_jump(int label){ - emit_helper(); - current->opcode = E_GOTO; - current->label = label; - return; -} - -void emit_conditional_jump(Op condition, int label, ...){ - // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). - // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) - emit_helper(); - va_list argptr; - va_start(argptr, label); - current->opcode = condition; - current->label = label; - TNodeOrConst * n1; - TNodeOrConst * n2; - switch (condition) { - case E_IF_X_TRUE: case E_IF_X_FALSE: - n1 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - break; - case E_LESSTHEN: case E_EQUALTO: - n1 = va_arg(argptr, TNodeOrConst *); - n2 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - current->operand2 = n2; - break; - } - va_end(argptr); - return; -} - -void emit_function_start(int name){ - emit_helper(); - current->opcode = E_LABEL; // I think this is right TODO: ask - current->label = name; - // this is probabaly a func decleration - return; -} - -void emit_parameter(TNodeOrConst * param){ - emit_helper(); - current->opcode = E_PARAM; - current->operand1 = param; - return; -} - -void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name){ - emit_helper(); - current->opcode = E_CALL; - current->operand1 = tn_or_const(INTEGER, ¶m_count); - current->operand2 = name; - current->result = result; - return; -} -void emit_return(TNodeOrConst * value){ - emit_helper(); - current->opcode = E_RETURN; - current->operand1 = value; - return; -} -void emit_reserve(char* result, char* type_name, int size){ - emit_helper(); - return; -} -void emit_release(char* pointer){ - emit_helper(); - return; -} - - -void emit_field_access(char* result, char* record, char* field){ - emit_helper(); - return; -} -void emit_array_access(char* result, char* array, char* index, char* dimension){ - emit_helper(); - return; -} -void emit_bounds_check(char* index, char* size, char* error_label){ - emit_helper(); - return; -} - - -// * Implement temp variable generator function that produces unique names (t1, t2, etc.) -char * temp_var_gen(){ - char * ret = calloc(9, sizeof(*ret)); - sprintf(ret, "$t%d", temp_count); - temp_count++; - return ret; -} - -char * label_gen(){ - char * ret = calloc( 9, sizeof(*ret)); - sprintf(ret, "L_%d", label_count); - label_count++; - return ret; -} diff --git a/src/intermediate_code.h b/src/intermediate_code.h deleted file mode 100644 index 2bb423a..0000000 --- a/src/intermediate_code.h +++ /dev/null @@ -1,109 +0,0 @@ -// Track 1: Core Infrastructure & Basic Expressions -// * Add Bison actions for arithmetic expressions: -// - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); -// - Subtraction, multiplication, division, modulo - - -// these are from page 364 -typedef enum { - E_LABEL = 10000, // this is not in the book - E_ADD, // 1 from the list - E_SUB, // 1 - E_MUL, // 1 - E_DIV, // 1 - E_MOD, // 1 - E_OR, // 1 - E_AND, // 1 - E_NEG, // 2 - E_NOT, // 2 - E_ASSIGN, // 3 - E_GOTO, // 4 - E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got - E_IF_X_TRUE, // 5 - E_IF_X_FALSE, // 5 - E_LESSTHEN, // 6 rule 1 + 5 - E_EQUALTO, // 6 rule 1 + 5 - E_CALL, // 7 - E_PARAM, // 7 - E_RETURN, // 7 - E_INDEX_COPY_RIGHT, // 8 - E_INDEX_COPY_LEFT, // 8 - E_ADDRESS_OF // 9 - /* for x = *y and *y = x we can just use index copy right and left with - index 0*/ -} Op; - -typedef enum { - NODE = 11000, // TableNode - INTEGER, // int - STRING, // char * - CHARACTER, // char - ADDRESS, // void * - BOOLEAN // bool -} Discriminant; - -typedef union { - TableNode * node; - int integer; - char * string; - char character; - void * address; - bool Boolean; -} TNConstUnion; - -typedef struct { - Discriminant d; - TNConstUnion * tnc_union; -} TNodeOrConst; - -typedef struct Instruction Instruction; -typedef struct Instruction { - Op opcode; - TableNode * result; - TNodeOrConst * operand1; - TNodeOrConst * operand2; - int label; - int index; - - Instruction * prev; - Instruction * next; -} Instruction; - -extern Instruction * begin; -extern Instruction * current; -int temp_count = 0; -int label_count = 0; -bool code_gen = true; - - - -TNodeOrConst * tn_or_const(Op op, void * tnc); - -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2); -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); -void emit_assignment(TableNode * target, TNodeOrConst * source); -// TODO: Find out what these are suposed to do. Guess is create an entry in -// the list of instructions. Guess is that its suposed to ret a struct ptr - -// * Implement integer/boolean/character specific operation handling -// TODO: Find out what this means. - -// * Create output function to write instructions to file with line formatting -void emit_as_file(FILE * out_file, Instruction * instr_arr); - -// * Implement instruction array storage for backpatching - -void emit_label(int label); -void emit_jump(int label); -void emit_conditional_jump(Op condition, int label, ...); - -void emit_function_start(int name); -void emit_parameter(TNodeOrConst * param); -void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); -void emit_return(TNodeOrConst * value); -void emit_reserve(char* result, char* type_name, int size); -void emit_release(char* pointer); - -void emit_field_access(char* result, char* record, char* field); -void emit_array_access(char* result, char* array, char* index, char* dimension); -void emit_bounds_check(char* index, char* size, char* error_label); diff --git a/test.alpha b/test.alpha deleted file mode 100644 index 7b06a5e..0000000 --- a/test.alpha +++ /dev/null @@ -1,29 +0,0 @@ - - - -type a : 1 -> integers -type t : integer -> a -type r : integer -> integer - - - -function foo : t -function bar : r -function entry : - -bar(a) := { - 5 + bar(a - 1); - return a * bar(a-1); -} - -foo(c) := { - [a: arg] - arg := reserve arg(c); - return arg; -} - -entry(args) := { - [a: b] - b := foo(8); -} - diff --git a/test.sh b/test.sh old mode 100755 new mode 100644 From 666f68823883c71bd705e9d0a5c17b0ab3360e87 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 17:25:38 -0400 Subject: [PATCH 129/137] Ready to rebase --- a.out | 0 src/codegen.c | 0 src/codegen.h | 0 src/runner.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/runner.h | 14 +++++++++ 5 files changed, 92 insertions(+) create mode 100644 a.out create mode 100644 src/codegen.c create mode 100644 src/codegen.h diff --git a/a.out b/a.out new file mode 100644 index 0000000..e69de29 diff --git a/src/codegen.c b/src/codegen.c new file mode 100644 index 0000000..e69de29 diff --git a/src/codegen.h b/src/codegen.h new file mode 100644 index 0000000..e69de29 diff --git a/src/runner.c b/src/runner.c index 0ccb74f..5833e3e 100644 --- a/src/runner.c +++ b/src/runner.c @@ -108,6 +108,26 @@ int run(FILE *alpha) { fprintf(stderr, "INPUT FILE NOT FOUND\n"); return -1; } + + char *line; + int i = 1; + while ((line = file_read_line(alpha)) != NULL) { + CodeLine *code_line = malloc(sizeof(CodeLine)); + code_line->line_number = i; + code_line->line = malloc(strlen(line) + 1); + strcpy(code_line->line, line); + code_line->next = NULL; + code_line->is_error = false; + append_code_line(code_line); + free(line); + i++; + } + + fseek(alpha, 0, SEEK_SET); + + + // print_code_lines(); + yyin = alpha; yyparse(); @@ -225,3 +245,61 @@ int is_alpha_file(char *alpha, int file_len) { } return 0; // is alpha file } + +void insert_code_line(char *line, int line_number) { +} + +void append_code_line(CodeLine *code_line) { + if (code_line == NULL) return; + + if (code_head == NULL) { + code_head = code_line; + } else { + CodeLine *current = code_head; + while (current->next != NULL) { + current = current->next; + } + current->next = code_line; + } +} + +void print_code_lines() { + CodeLine *current = code_head; + while (current != NULL) { + printf("%d %03d: %s",current->line_number, current->line); + current = current->next; + } +} + +char *file_read_line(FILE *fp) { + if (fp == NULL) return NULL; + + size_t size = 128; + size_t len = 0; + char *str = malloc(size); + if (!str) return NULL; + + int c; + while ((c = fgetc(fp)) != EOF) { + if (len + 1 >= size) { + size *= 2; + char *new_buffer = realloc(str, size); + if (!new_buffer) { + free(str); + return NULL; + } + str = new_buffer; + } + + str[len++] = (char)c; + if (c == '\n') break; + } + + if (len == 0 && c == EOF) { + free(str); + return NULL; + } + + str[len] = '\0'; + return str; +} \ No newline at end of file diff --git a/src/runner.h b/src/runner.h index 16b505b..0573255 100644 --- a/src/runner.h +++ b/src/runner.h @@ -91,3 +91,17 @@ char *COLOR_LIGHTBLUE = "\033[1;34m"; char *COLOR_LIGHTPURPLE = "\033[1;35m"; char *COLOR_LIGHTCYAN = "\033[1;36m"; char *COLOR_WHITE = "\033[1;37m"; + +typedef struct CodeLine { + char *line; + int line_number; + bool is_error; + struct CodeLine *next; +} CodeLine; + +CodeLine *code_head; + +char *file_read_line(FILE *fp); +void insert_code_line(char *line, int line_number); +void append_code_line(CodeLine *code_line); +void print_code_lines(); \ No newline at end of file From ab406471cc41e30acec36aa7a79395947fe83b2e Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 17:39:49 -0400 Subject: [PATCH 130/137] Now ready for rebase --- a.out | 0 src/intermediate_code.c | 386 ---------------------------------------- src/intermediate_code.h | 155 ---------------- 3 files changed, 541 deletions(-) delete mode 100644 a.out diff --git a/a.out b/a.out deleted file mode 100644 index e69de29..0000000 diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 6b1b32f..e69de29 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -1,386 +0,0 @@ -#include "intermediate_code.h" - -Instruction * begin; -Instruction * current; -char * temp = NULL; - - -// TODO: this is here to bring your attention to the comment bellow. -// check if start is NULL if it is assign it to the start globle variable -// otherwise make it next of current and set cur to your instruction. -TNodeOrConst * getOperand1(Instruction * i){ - return i->operand1; -} - -TNodeOrConst * getOperand2(Instruction * i){ - return i->operand2; -} - -TableNode * get_result(Instruction * i){ - return i->result; -} - -Op getOp(Instruction * i){ - return i->opcode; -} - -int getLabel(Instruction * i){ - return i->label; -} - -int get_index(Instruction * i){ - return i->index; -} - -void set_label(Instruction * i, int label){ - i->label = label; -} - -bool isConst(TNodeOrConst * tnc) { - return tnc->d != NODE; -} - -TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { - TNodeOrConst * count = calloc(1, sizeof(*count)); - count->d = d; - switch (d) { - case NODE: - count->tnc_union->node = tnc; - break; - case ADDRESS: - count->tnc_union->address = tnc; - break; - case STRING: - count->tnc_union->string = tnc; - break; - case INTEGER: - count->tnc_union->integer = *(int*)tnc; - break; - case CHARACTER: - count->tnc_union->character = *(char*)tnc; - break; - case BOOLEAN: - count->tnc_union->Boolean = *(bool*)tnc; - break; - } - return count; -} - -static void emit_helper(void){ - Instruction * inst = calloc(1, sizeof(*inst)); - if(begin == NULL){ - begin = current = inst; - current->index = 1; - } else { - current->next = inst; - inst->prev = current; - inst->index = current->index++; - current = inst; - } -} - -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2){ - emit_helper(); - current->opcode = op; - // TODO: create temp and remove result from param list - current->result = result; - current->operand1 = arg1; - current->operand2 = arg2; - } - -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = arg; - } - -void emit_assignment(TableNode * target, TNodeOrConst * source){ - emit_helper(); - current->opcode = E_ASSIGN; - current->result = target; - current->operand1 = source; - } - -char * get_string(TNodeOrConst * tc){ - char * s; - switch (tc->d) { - case NODE: - return getName(tc->tnc_union->node); - case ADDRESS: - return strdup("null"); - case STRING: - return tc->tnc_union->string; - case INTEGER: - s = calloc(10, sizeof(char)); - sprintf(s, "%d", tc->tnc_union->integer); - return s; - case CHARACTER: - s = calloc(2, sizeof(char)); - sprintf(s, "%c", tc->tnc_union->character); - return s; - case BOOLEAN: - if(tc->tnc_union->Boolean){ - return strdup("true"); - } - return strdup("false"); - } -} - -void emit_as_file(FILE * out_file, Instruction * i){ - if(!i){ - return; - } - switch(i->opcode){ - case E_LABEL: - // this is a terrible one to start with - // fprintf(out_file, "%04.d: %d ", i->index, i->label); - case E_ADD: - fprintf(out_file, "%4.d: %s = %s + %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_SUB: - fprintf(out_file, "%4.d: %s = %s - %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_MUL: - fprintf(out_file, "%4.d: %s = %s * %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_DIV: - fprintf(out_file, "%4.d: %s = %s / %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_MOD: - fprintf(out_file, "%4.d: %s = %s %% %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_OR: - fprintf(out_file, "%4.d: %s = %s | %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_AND: - fprintf(out_file, "%4.d: %s = %s & %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_NEG: - fprintf(out_file, "%4.d: %s = -%s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_NOT: - fprintf(out_file, "%4.d: %s = !%s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_ASSIGN: - fprintf(out_file, "%4.d: %s = %s\n", - i->index, getName(i->result), - get_string(i->operand2)); - break; - case E_GOTO: - // are we ever going to use this? - // yes we do look at bounds checking - case E_IF_X_TRUE: - fprintf(out_file, "%4.d: if %s goto %d\n", - i->index, get_string(i->operand1), - i->label); - break; - case E_IF_X_FALSE: - fprintf(out_file, "%4.d: if %s false goto %d\n", - i->index, get_string(i->operand1), - i->label); - break; - case E_LESS_THAN: - fprintf(out_file, "%4.d: if %s < %s goto %d\n", - i->index, get_string(i->operand1), - get_string(i->operand2), i->label); - break; - case E_EQUAL_TO: - fprintf(out_file, "%4.d: if %s = %s goto %d\n", - i->index, get_string(i->operand1), - get_string(i->operand2), i->label); - break; - case E_CALL: - fprintf(out_file, "%4.d: call %s %s\n", - i->index, get_string(i->operand1), - get_string(i->operand2)); - break; - - case E_PARAM: - fprintf(out_file, "%4.d: param %s \n", - i->index, get_string(i->operand1)); - break; - case E_RETURN: - - case E_INDEX_COPY_RIGHT: - case E_INDEX_COPY_LEFT: - - case E_ADDRESS_OF: - - case E_DEREF_RIGHT: - case E_DEREF_LEFT: - } - - emit_as_file(out_file, i->next); -} - -void emit_label(int label){ - emit_helper(); - current->opcode = E_LABEL; - current->label = label; -} - -void emit_jump(int label){ - emit_helper(); - current->opcode = E_GOTO; - current->label = label; -} - -void emit_conditional_jump(Op condition, int label, ...){ - // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). - // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) - emit_helper(); - va_list argptr; - va_start(argptr, label); - current->opcode = condition; - current->label = label; - TNodeOrConst * n1; - TNodeOrConst * n2; - switch (condition) { - case E_IF_X_TRUE: case E_IF_X_FALSE: - n1 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - break; - case E_LESS_THAN: case E_EQUAL_TO: - n1 = va_arg(argptr, TNodeOrConst *); - n2 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - current->operand2 = n2; - break; - } - va_end(argptr); -} - -void emit_function_start(int name){ - emit_helper(); - current->opcode = E_LABEL; // I think this is right TODO: ask - current->label = name; - // this is probabaly a func decleration -} - -void emit_parameter(TNodeOrConst * param){ - emit_helper(); - current->opcode = E_PARAM; - current->operand1 = param; -} - -void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name){ - emit_helper(); - current->opcode = E_CALL; - current->operand1 = tn_or_const(INTEGER, ¶m_count); - current->operand2 = name; - current->result = result; -} - -void emit_return(TNodeOrConst * value){ - emit_helper(); - current->opcode = E_RETURN; - current->operand1 = value; -} - -void emit_reserve(TableNode * result, TNodeOrConst * size){ - emit_parameter(size); - emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); -} - -void emit_release(TableNode * pointer){ - emit_parameter(tn_or_const(NODE, pointer)); - emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); -} - -void emit_deref_right(){ - return; -} - -void emit_deref_left(){ - return; -} - -void emit_field_access(char* result, char* record, char* field){ - emit_helper(); -} - -void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index){ - emit_helper(); - current->opcode; - current->result = result; - current->operand1 = array; - current->operand2 = index; - // TODO: Still don't know what to do with the dimentions -} - -void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ - /* - {[string: 5] - . - . - s:= reserve s(5); - s(0) := 'H'; - s(1) := 'e'; - . - . - s._0 num of dims Known at compile time - s._1 size Known at run time - s._1 int | 1 byte - +-------+---+---+---+---+---+ - | 5 | H | e | l | l | o | - +-------+---+---+---+---+---+ - size - ^ - | - p - s._0 ok - s._1 ok - s._2 not ok - t_0 is index - t_1 = *(int *)p = s._1 - if t_0 < 0 GOTO ERROR - if t_0 < s._1 GOTO access array - GOTO ERROR - */ - emit_conditional_jump(E_LESS_THAN, ); - emit_conditional_jump(E_LESS_THAN, ); - emit_jump(); - /* We need a label ERROR to jump to - */ -} - -// * Implement temp variable generator function that produces unique names (t1, t2, etc.) -char * temp_var_gen(){ - char * ret = calloc(9, sizeof(*ret)); - sprintf(ret, "$t%d", temp_count); - temp_count++; - return ret; -} - -char * label_gen(){ - char * ret = calloc( 9, sizeof(*ret)); - sprintf(ret, "L_%d", label_count); - label_count++; - return ret; -} \ No newline at end of file diff --git a/src/intermediate_code.h b/src/intermediate_code.h index b6e6fd4..e69de29 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -1,155 +0,0 @@ -// Track 1: Core Infrastructure & Basic Expressions -// * Add Bison actions for arithmetic expressions: -// - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); -// - Subtraction, multiplication, division, modulo -#pragma once - -#include "symbol_table.h" -#include -#include - -// these are from page 364 -typedef enum { - E_LABEL = 10000, // this is not in the book - E_ADD, // 1 from the list - E_SUB, // 1 - E_MUL, // 1 - E_DIV, // 1 - E_MOD, // 1 - E_OR, // 1 - E_AND, // 1 - E_NEG, // 2 - E_NOT, // 2 - E_ASSIGN, // 3 - E_GOTO, // 4 - E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got - E_IF_X_TRUE, // 5 - E_IF_X_FALSE, // 5 - E_LESS_THAN, // 6 rule 1 + 5 - E_EQUAL_TO, // 6 rule 1 + 5 - E_CALL, // 7 - E_PARAM, // 7 - E_RETURN, // 7 - E_INDEX_COPY_RIGHT, // 8 this is x = y[i] - E_INDEX_COPY_LEFT, // 8 x[i] = y - E_ADDRESS_OF, // 9 x = &y - E_DEREF_RIGHT, // 9 x = *y - E_DEREF_LEFT // 9 x* = y -} Op; - -typedef enum { - NODE = 11000, // TableNode - INTEGER, // int - STRING, // char * - CHARACTER, // char - ADDRESS, // void * - BOOLEAN // bool -} Discriminant; - -typedef union { - TableNode * node; - int integer; - char * string; - char character; - void * address; - bool Boolean; -} TNConstUnion; - -typedef struct { - Discriminant d; - TNConstUnion * tnc_union; -} TNodeOrConst; - -typedef struct Instruction Instruction; -typedef struct Instruction { - Op opcode; - TableNode * result; - TNodeOrConst * operand1; - TNodeOrConst * operand2; - int label; - int index; - - Instruction * prev; - Instruction * next; -} Instruction; - - -typedef struct TFList { - Instruction * i; - TFList * next; -} TFList; - -TFList * make_list(Instruction * i); - // - makelist(i) function to create instruction lists -void merge(TFList * l1, TFList * l2); - // - merge(p1,p2) function to concatenate lists -void backpatch(TFList * l, int label); - // - backpatch(p,i) function to fill in jump targets - - -extern Instruction * begin; -extern Instruction * current; -int temp_count = 0; -int label_count = 0; -bool code_gen = true; - - -TNodeOrConst * tn_or_const(Discriminant , void * ); -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2); -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); -void emit_assignment(TableNode * target, TNodeOrConst * source); -void emit_as_file(FILE * out_file, Instruction * instr_arr); -void emit_label(int label); -void emit_jump(int label); - -void emit_conditional_jump(Op condition, int label, ...); - -void emit_function_start(int name); -void emit_parameter(TNodeOrConst * param); -void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); -void emit_return(TNodeOrConst * value); -void emit_reserve(TableNode * result, TNodeOrConst * size); -void emit_release(TableNode * pointer); -void emit_field_access(char* result, char* record, char* field); -void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index); -void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr, int error_label); - -// * Implement instruction array storage for backpatching -/* -Track 2: Control Flow & Boolean Expressions -* Implement backpatching infrastructure: -* Create truelist and falselist attributes for Boolean expressions -* Create control flow emission functions: -* Add Bison actions for control structures: - - if-then-else with backpatching - - while loops with backpatching -* Implement short-circuit Boolean operations (&&, ||, !) -* Add marker (M) nonterminal for recording instruction positions -*/ - - -/* - Track 3: Functions & Complex Types -* Implement function-related emission: -* Add Bison actions for the 'as' clause -* Create memory layout calculation functions: - - calculate_record_size(Record_Type* type) → returns bytes needed - - calculate_array_size(Array_Type* type, int dimensions[]) → returns total bytes - - calculate_field_offset(Record_Type* type, char* field_name) → returns offset -* Add Bison actions for arrays and records - */ - -/* - Track 4: Memory Access & Integration -* Implement array and record access code: - - emit_field_access(char* result, char* record, char* field) - - emit_array_access(char* result, char* array, char* index, char* dimension) -* Add array dimension access (a._1, a._2, etc.) -* Implement bounds checking emission: - - emit_bounds_check(char* index, char* size, char* error_label) -* Create the code generation driver function -* Implement common error handling -* Document the complete intermediate instruction set -* Build integration test suite covering all language features -* Implement row-major/column-major array layout calculation - */ \ No newline at end of file From 086c8ba1703994e0b438b0c52f24c34cb109d1b2 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 19:29:05 -0400 Subject: [PATCH 131/137] Project restucture with IR and CG --- Makefile | 17 +- check.sh | 0 src/codegen.c | 590 ++++++++++++++++++++++ src/codegen.h | 57 +++ src/grammar.h | 28 ++ src/grammar.y | 19 +- src/intermediate_code.c | 399 +++++++++++++++ src/intermediate_code.h | 121 +++++ src/lexicalStructure.h | 29 ++ src/lexicalStructure.lex | 29 +- src/runner.c | 7 +- src/runner.h | 4 +- src/symbol_table.c | 1034 +------------------------------------- src/symbol_table.h | 198 +------- test.sh | 0 15 files changed, 1262 insertions(+), 1270 deletions(-) mode change 100644 => 100755 check.sh create mode 100644 src/grammar.h create mode 100644 src/lexicalStructure.h mode change 100644 => 100755 test.sh diff --git a/Makefile b/Makefile index 8798f2e..e91f705 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,7 @@ LEX := src/lexicalStructure.lex YACC := src/grammar.y EXE := alpha -OBJS := tmp/runner.o tmp/symbol_table.o tmp/grammar.tab.o tmp/lex.yy.o -# tmp/intermediate_code.o codegen.o <--- Add to line above +OBJS := tmp/runner.o tmp/symbol_table.o tmp/grammar.tab.o tmp/lex.yy.o tmp/intermediate_code.o tmp/codegen.o TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha) TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha) @@ -31,6 +30,7 @@ clean: rm -f $(EXE) rm -rf out rm -rf tmp + rm -f *.s tmp: mkdir -p tmp @@ -55,13 +55,11 @@ tmp/lex.yy.o: tmp/lex.yy.c tmp/symbol_table.o: src/symbol_table.c src/symbol_table.h $(CC) $(CFLAGS) -c src/symbol_table.c -o tmp/symbol_table.o -# Uncomment rules when ready +tmp/intermediate_code.o: src/intermediate_code.c src/intermediate_code.h + $(CC) $(CFLAGS) -c src/intermediate_code.c -o tmp/intermediate_code.o -# tmp/intermediate_code.o: src/intermediate_code.c src/intermediate_code.h -# $(CC) $(CFLAGS) -c src/intermediate_code.c -o tmp/intermediate_code.o - -# tmp/codegen.o: src/codegen.c src/codegen.h -# $(CC) $(CFLAGS) -c src/codegen.c -o tmp/codegen.o +tmp/codegen.o: src/codegen.c src/codegen.h + $(CC) $(CFLAGS) -c src/codegen.c -o tmp/codegen.o tmp/runner.o: src/runner.c src/runner.h tmp/flex.h tmp/grammar.tab.h $(CC) $(CFLAGS) -c src/runner.c -o tmp/runner.o @@ -102,7 +100,4 @@ test-s4: chmod +x ./test.sh ./test.sh sp4 ./check.sh sp4 - -# Temprorary test ~ Scarlett -test-make: clean tmp tmp/grammar.tab.c tmp/grammar.tab.h tmp/lex.yy.c tmp/flex.h tmp/grammar.tab.o tmp/lex.yy.o tmp/symbol_table.o tmp/runner.o # ----------- \ No newline at end of file diff --git a/check.sh b/check.sh old mode 100644 new mode 100755 diff --git a/src/codegen.c b/src/codegen.c index e69de29..358f3bd 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -0,0 +1,590 @@ +#include "codegen.h" + +int generate() { + offset = 0; + Instruction *i = begin; + while (i != NULL) { + switch (getOp(i)) { + case E_LABEL: + generateLabel(i); + break; + case E_ADD: + generateAdd(i); + break; + case E_SUB: + generateSub(i); + break; + case E_MUL: + generateMult(i); + break; + case E_DIV: + generateDiv(i); + break; + case E_MOD: + generateMod(i); + break; + case E_OR: + generateOr(i); + break; + case E_AND: + generateAnd(i); + break; + case E_NEG: + generateNeg(i); + break; + case E_NOT: + generateNot(i); + break; + case E_ASSIGN: + generateAssign(i); + break; + case E_GOTO: + generateGoto(i); + break; + case E_IF_X_TRUE: + generateIfTrue(i); + break; + case E_IF_X_FALSE: + generateIfFalse(i); + break; + case E_LESS_THAN: + generateLessThan(i); + break; + case E_EQUAL_TO: + generateEqualTo(i); + break; + case E_CALL: + generateCall(i); + break; + case E_PARAM: + generateParam(i); + break; + case E_RETURN: + generateReturn(i); + break; + case E_INDEX_COPY_RIGHT: + generateCopyRight(i); + break; + case E_INDEX_COPY_LEFT: + generateCopyLeft(i); + break; + case E_ADDRESS_OF: + generateAddressOf(i); + break; + default:; + } + i = i->next; + } + return -1; +} + +CGNode *getNextCG(CGNode *cg) { + if (cg == NULL) { + return NULL; + } + return cg->next; +} + +int getAddress(CGNode *cg) { + if (cg == NULL) { + return -1; + } + + return currentsp - cg->address; +} + +TableNode *getTNofCG(CGNode *cg) { + if (cg == NULL) { + return NULL; + } + return cg->tn; +} + +CGNode *findCG(TableNode *tn) { + CGNode *cg = cgList; + while (cg != NULL) { + if (getTNofCG(cg) == tn) { + return cg; + } + cg = getNextCG(cg); + } + return NULL; +} + +CGNode *addCG(TableNode *tn, int sp) { + CGNode *cg = calloc(1, sizeof(CGNode)); + cg->tn = tn; + cg->address = sp; + offset += getPrimSize(tn); //not sure if this is the correct amount to add to the offset + cg->next = cgList; + cgList = cg; + return cg; +} + +int generateLabel(Instruction *inst) { + fprintf(cg_flag, ".L%d:\n", getLabel(inst)); + return 0; +} +int generateAdd(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateAdd failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op1)); + if (op1CG == NULL) { + printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1))); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\taddl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + return 0; +} + +int generateSub(Instruction *instruction) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(instruction); + TNodeOrConst *op2 = getOperand2(instruction); + CGNode *cg = findCG(getResult(instruction)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateSub failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(instruction), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateSub failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + return 0; +} + +int generateMult(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateMult failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateMult failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateMult failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + return 0; +} + +int generateDiv(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateDiv failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateDiv failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateDiv failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax + fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG)); //divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result + return 0; +} + +int generateMod(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateMod failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateMod failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax + fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG)); //divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\n", getAddress(cg)); //stores result from edx (remainder) + return 0; +} + +int generateOr(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateOr failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateOr failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateOr failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\torll\t%d(%%rbp), %%eax\n", getAddress(op2CG)); //divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result + return 0; +} + +int generateAnd(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateAnd failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tandl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + return 0; +} +int generateNeg(Instruction *inst) { + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateNeg failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateNeg failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnegl\t%d %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + return 0; +} +int generateNot(Instruction *inst) { + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("generateNot failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateNot failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateNot failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnotl\t%%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + return 0; +} + +int generateAssign(Instruction *inst) { + TNodeOrConst *op1 = getOperand1(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL) { + printdebug("generateAssign failed, NULL operand"); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + //add option for constant assignment (should be easy) + if (isConst(op1) == true) { + fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\n", getConst(op1), getAddress(cg)); + } + + CGNode *op1CG = findCG(getTN(op1)); + if (op1CG == NULL) { + printdebug("generateAssign failed, op1 is not constant but not in CGlist"); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + return 0; +} + +int generateGoto(Instruction *instruction) { + return -1; +} + +int generateCondGoto(Instruction *instruction) { + return -1; +} + +int generateIfTrue(Instruction *instruction) { + return -1; + // might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case +} + +int generateIfFalse(Instruction *instruction) { + return -1; +} + +int generateLessThan(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tsetl\t%%al\n"); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + return 0; +} + +int generateEqualTo(Instruction *inst) { + /* + Both immediate: + One immediate: + Neither immediate: + */ + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + CGNode *cg = findCG(getResult(inst)); + + if (op1 == NULL || op2 == NULL) { + printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); + return -1; + } + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + CGNode *op1CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); + if (op1CG == NULL) { + printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); + return -1; + } + + if (op2CG == NULL) { + printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); + return -1; + } + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tsete\t%%al\n"); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + return 0; +} +int generateCall(Instruction *instruction) { + return -1; + //will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg +} +int generateReturn(Instruction *instruction) { + return -1; + //will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value +} +int generateCopyRight(Instruction *instruction) { + return -1; +} +int generateCopyLeft(Instruction *instruction) { + return -1; +} +int generateAddressOf(Instruction *instruction) { + return -1; +} +int generateParam(Instruction *instruction) { + //need to check if op1 is null, then add it to the appropriate register/cg node. need a way to keep track of this, maybe just have global count of params generated + return -1; +} \ No newline at end of file diff --git a/src/codegen.h b/src/codegen.h index e69de29..a228b94 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "intermediate_code.h" +#include "symbol_table.h" + +extern FILE *cg_flag; + +typedef struct CGNode { + TableNode *tn; + int address; + CGNode *next; +} CGNode; + +int generate(); +CGNode *getNextCG(CGNode *cg); +int getAddress(CGNode *cg); +TableNode *getTNofCG(CGNode *cg); +CGNode *findCG(TableNode *tn); +CGNode *addCG(TableNode *tn, int sp); +int generateLabel(Instruction *inst); +int generateAdd(Instruction *inst); +int generateSub(Instruction *instruction); +int generateMult(Instruction *inst); +int generateDiv(Instruction *inst); +int generateMod(Instruction *inst); +int generateOr(Instruction *inst); +int generateAnd(Instruction *inst); +int generateNeg(Instruction *inst); +int generateNot(Instruction *inst); +int generateAssign(Instruction *inst); +int generateGoto(Instruction *instruction); +int generateCondGoto(Instruction *instruction); +int generateIfTrue(Instruction *instruction); +int generateIfFalse(Instruction *instruction); +int generateLessThan(Instruction *inst); +int generateEqualTo(Instruction *inst); +int generateCall(Instruction *instruction); +int generateReturn(Instruction *instruction); +int generateCopyRight(Instruction *instruction); +int generateCopyLeft(Instruction *instruction); +int generateAddressOf(Instruction *instruction); +int generateParam(Instruction *instruction); + +extern int label_count; +extern Instruction *begin; +extern Instruction *current; + +extern int offset; +extern int currentsp; +extern CGNode *cgList; \ No newline at end of file diff --git a/src/grammar.h b/src/grammar.h new file mode 100644 index 0000000..018974e --- /dev/null +++ b/src/grammar.h @@ -0,0 +1,28 @@ +#pragma once + +#include "../src/codegen.h" +#include "../src/intermediate_code.h" +#include "../src/symbol_table.h" +extern FILE *asc_flag; +extern bool tc_flag; + +typedef enum { + ERROR_RUNTIME = 1, + ERROR_SYNTAX = 2, + ERROR_TYPE = 3, + ERROR_UNDEFINED = 4 +} ErrorType; + +int token_tracker; +TableNode *tn; + +void yyerror(const char *err); +void throw_error(ErrorType error_type, const char *format, ...); + +int label_count; +Instruction *begin; +Instruction *current; + +int offset; +int currentsp; +CGNode *cgList; \ No newline at end of file diff --git a/src/grammar.y b/src/grammar.y index 90ba7a4..75e70ec 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -17,22 +17,7 @@ // Please ask Scarlett if you are unsure of how to format something. Thanks! 😀 %{ - #include "../src/symbol_table.h" - extern FILE *asc_flag; - extern bool tc_flag; - - typedef enum { - ERROR_RUNTIME = 1, - ERROR_SYNTAX = 2, - ERROR_TYPE = 3, - ERROR_UNDEFINED = 4 - } ErrorType; - - int token_tracker; - TableNode * tn; - - void yyerror(const char *err); - void throw_error(ErrorType error_type, const char *format, ...); + #include "../src/grammar.h" %} %union { @@ -630,7 +615,7 @@ expression: $$ = node; } else { $$=undefined; - error_type(getTypeEntry((TableNode*)$2), integ, ""); + throw_error(ERROR_TYPE, "%s != %s", getName(getTypeEntry((TableNode*)$2)), getName(integ)); } } diff --git a/src/intermediate_code.c b/src/intermediate_code.c index e69de29..65458cf 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -0,0 +1,399 @@ +#include "intermediate_code.h" + +// TODO: this is here to bring your attention to the comment bellow. +// check if start is NULL if it is assign it to the start globle variable +// otherwise make it next of current and set cur to your instruction. +TNodeOrConst* getOperand1(Instruction* i) { + return i->operand1; +} + +TNodeOrConst* getOperand2(Instruction* i) { + return i->operand2; +} + +TableNode* getResult(Instruction* i) { + return i->result; +} + +Op getOp(Instruction* i) { + return i->opcode; +} + +int getLabel(Instruction* i) { + return i->label; +} + +int get_index(Instruction* i) { + return i->index; +} + +void set_label(Instruction* i, int label) { + i->label = label; +} + +bool isConst(TNodeOrConst* tnc) { + return tnc->d != NODE; +} + +TNodeOrConst* tn_or_const(Discriminant d, void* tnc) { + TNodeOrConst* count = calloc(1, sizeof(*count)); + count->d = d; + count->tnc_union = calloc(1, sizeof(*count->tnc_union)); + switch (d) { + case NODE: + count->tnc_union->node = tnc; + break; + case ADDRESS: + count->tnc_union->address = tnc; + break; + case STRING: + count->tnc_union->string = tnc; + break; + case INTEGER: + count->tnc_union->integer = *(int*)tnc; + break; + case CHARACTER: + count->tnc_union->character = *(char*)tnc; + break; + case BOOLEAN: + count->tnc_union->Boolean = *(uint_least8_t*)tnc; + break; + } + return count; +} + +static void emit_helper(void) { + Instruction* inst = calloc(1, sizeof(*inst)); + if (begin == NULL) { + begin = current = inst; + current->index = 1; + } else { + current->next = inst; + inst->prev = current; + inst->index = current->index + 1; + current = inst; + } +} + +void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* arg2) { + emit_helper(); + current->opcode = op; + // TODO: create temp and remove result from param list + current->result = result; + current->operand1 = arg1; + current->operand2 = arg2; +} + +void emit_unary_op(Op op, TableNode* result, TNodeOrConst* arg) { + emit_helper(); + current->opcode = op; + current->result = result; + current->operand1 = arg; +} + +void emit_assignment(TableNode* target, TNodeOrConst* source) { + emit_helper(); + current->opcode = E_ASSIGN; + current->result = target; + current->operand1 = source; +} + +char* get_string(TNodeOrConst* tc) { + char* s; + switch (tc->d) { + case NODE: + return getName(tc->tnc_union->node); + case ADDRESS: + return strdup("null"); + case STRING: + return tc->tnc_union->string; + case INTEGER: + s = calloc(10, sizeof(char)); + sprintf(s, "%d", tc->tnc_union->integer); + return s; + case CHARACTER: + s = calloc(2, sizeof(char)); + sprintf(s, "%c", tc->tnc_union->character); + return s; + case BOOLEAN: + if (tc->tnc_union->Boolean) { + return strdup("true"); + } + return strdup("false"); + } +} + +void emit_as_file(FILE* out_file, Instruction* i) { + if (i == NULL) { + return; + } + switch (i->opcode) { + case E_LABEL: + break; + // this is a terrible one to start with + // fprintf(out_file, "%04.d: %d ", i->index, i->label); + case E_ADD: + fprintf(out_file, "%4.d: %s = %s + %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_SUB: + fprintf(out_file, "%4.d: %s = %s - %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MUL: + fprintf(out_file, "%4.d: %s = %s * %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_DIV: + fprintf(out_file, "%4.d: %s = %s / %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_MOD: + fprintf(out_file, "%4.d: %s = %s %% %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_OR: + fprintf(out_file, "%4.d: %s = %s | %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_AND: + fprintf(out_file, "%4.d: %s = %s & %s\n", + i->index, getName(i->result), + get_string(i->operand1), + get_string(i->operand2)); + break; + case E_NEG: + fprintf(out_file, "%4.d: %s = -%s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_NOT: + fprintf(out_file, "%4.d: %s = !%s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_ASSIGN: + fprintf(out_file, "%4.d: %s = %s\n", + i->index, getName(i->result), + get_string(i->operand1)); + break; + case E_GOTO: + // are we ever going to use this? + // yes we do look at bounds checking + case E_IF_X_TRUE: + fprintf(out_file, "%4.d: if %s goto %d\n", + i->index, get_string(i->operand1), + i->label); + break; + case E_IF_X_FALSE: + fprintf(out_file, "%4.d: if %s false goto %d\n", + i->index, get_string(i->operand1), + i->label); + break; + case E_LESS_THAN: + fprintf(out_file, "%4.d: if %s < %s goto %d\n", + i->index, get_string(i->operand1), + get_string(i->operand2), i->label); + break; + case E_EQUAL_TO: + fprintf(out_file, "%4.d: if %s = %s goto %d\n", + i->index, get_string(i->operand1), + get_string(i->operand2), i->label); + break; + case E_CALL: + fprintf(out_file, "%4.d: call %s %s\n", + i->index, get_string(i->operand1), + get_string(i->operand2)); + break; + + case E_PARAM: + fprintf(out_file, "%4.d: param %s \n", + i->index, get_string(i->operand1)); + break; + case E_RETURN: + + case E_INDEX_COPY_RIGHT: + case E_INDEX_COPY_LEFT: + + case E_ADDRESS_OF: + + case E_DEREF_RIGHT: + case E_DEREF_LEFT: + } + + emit_as_file(out_file, i->next); +} + +void emit_label(int label) { + emit_helper(); + current->opcode = E_LABEL; + current->label = label; +} + +void emit_jump(int label) { + emit_helper(); + current->opcode = E_GOTO; + current->label = label; +} + +void emit_conditional_jump(Op condition, int label, ...) { + // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). + // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) + emit_helper(); + va_list argptr; + va_start(argptr, label); + current->opcode = condition; + current->label = label; + TNodeOrConst* n1; + TNodeOrConst* n2; + switch (condition) { + case E_IF_X_TRUE: + case E_IF_X_FALSE: + n1 = va_arg(argptr, TNodeOrConst*); + current->operand1 = n1; + break; + case E_LESS_THAN: + case E_EQUAL_TO: + n1 = va_arg(argptr, TNodeOrConst*); + n2 = va_arg(argptr, TNodeOrConst*); + current->operand1 = n1; + current->operand2 = n2; + break; + } + va_end(argptr); +} + +void emit_function_start(int name) { + emit_helper(); + current->opcode = E_LABEL; // I think this is right TODO: ask + current->label = name; + // this is probabaly a func decleration +} + +void emit_parameter(TNodeOrConst* param) { + emit_helper(); + current->opcode = E_PARAM; + current->operand1 = param; +} + +void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name) { + emit_helper(); + current->opcode = E_CALL; + current->operand1 = tn_or_const(INTEGER, ¶m_count); + current->operand2 = name; + current->result = result; +} + +void emit_return(TNodeOrConst* value) { + emit_helper(); + current->opcode = E_RETURN; + current->operand1 = value; +} + +void emit_reserve(TableNode* result, TNodeOrConst* size) { + emit_parameter(size); + emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); +} + +void emit_release(TableNode* pointer) { + emit_parameter(tn_or_const(NODE, pointer)); + emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); +} + +void emit_deref_right() { + return; +} + +void emit_deref_left() { + return; +} + +void emit_field_access(char* result, char* record, char* field) { + emit_helper(); +} + +void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index) { + emit_helper(); + current->opcode; + current->result = result; + current->operand1 = array; + current->operand2 = index; + // TODO: Still don't know what to do with the dimentions +} + +void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr) { + /* + {[string: 5] + . + . + s:= reserve s(5); + s(0) := 'H'; + s(1) := 'e'; + . + . + s._0 num of dims Known at compile time + s._1 size Known at run time + s._1 int | 1 byte + +-------+---+---+---+---+---+ + | 5 | H | e | l | l | o | + +-------+---+---+---+---+---+ + size + ^ + | + p + s._0 ok + s._1 ok + s._2 not ok + t_0 is index + t_1 = *(int *)p = s._1 + if t_0 < 0 GOTO ERROR + if t_0 < s._1 GOTO access array + GOTO ERROR + */ + //emit_conditional_jump(E_LESS_THAN, ); + //emit_conditional_jump(E_LESS_THAN, ); + //emit_jump(); + /* We need a label ERROR to jump to + */ +} + +/*// * Implement temp variable generator function that produces unique names (t1, t2, etc.) +char * temp_var_gen(){ + char * ret = calloc(9, sizeof(*ret)); + sprintf(ret, "$t%d", temp_count); + temp_count++; + return ret; +} +*/ +char* label_gen() { + char* ret = calloc(9, sizeof(*ret)); + sprintf(ret, "L_%d", label_count); + label_count++; + return ret; +} + +TableNode* getTN(TNodeOrConst* tnc) { + if (tnc->d == NODE) { + return tnc->tnc_union->node; + } + return NULL; +} +//we must fix this +int getConst(TNodeOrConst* tnc) { + if (tnc->d == INTEGER) { + return tnc->tnc_union->integer; + } + return -1; +} \ No newline at end of file diff --git a/src/intermediate_code.h b/src/intermediate_code.h index e69de29..fd654e0 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -0,0 +1,121 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "symbol_table.h" + +// these are from page 364 +typedef enum { + E_LABEL = 10000, // this is not in the book + E_ADD, // 1 from the list + E_SUB, // 1 + E_MUL, // 1 + E_DIV, // 1 + E_MOD, // 1 + E_OR, // 1 + E_AND, // 1 + E_NEG, // 2 + E_NOT, // 2 + E_ASSIGN, // 3 + E_GOTO, // 4 + E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got + E_IF_X_TRUE, // 5 + E_IF_X_FALSE, // 5 + E_LESS_THAN, // 6 rule 1 + 5 + E_EQUAL_TO, // 6 rule 1 + 5 + E_CALL, // 7 + E_PARAM, // 7 + E_RETURN, // 7 + E_INDEX_COPY_RIGHT, // 8 this is x = y[i] + E_INDEX_COPY_LEFT, // 8 x[i] = y + E_ADDRESS_OF, // 9 x = &y + E_DEREF_RIGHT, // 9 x = *y + E_DEREF_LEFT // 9 x* = y +} Op; + +typedef enum { + NODE = 11000, // TableNode + INTEGER, // int + STRING, // char * + CHARACTER, // char + ADDRESS, // void * + BOOLEAN // bool +} Discriminant; + +typedef union { + TableNode* node; + int integer; + char* string; + char character; + void* address; + bool Boolean; +} TNConstUnion; + +typedef struct { + Discriminant d; + TNConstUnion* tnc_union; +} TNodeOrConst; + +typedef struct Instruction Instruction; +typedef struct Instruction { + Op opcode; + TableNode* result; + TNodeOrConst* operand1; + TNodeOrConst* operand2; + int label; + int index; + + Instruction* prev; + Instruction* next; +} Instruction; + +typedef struct TFList { + Instruction* i; + TFList* next; +} TFList; + +TNodeOrConst* getOperand1(Instruction* i); +TNodeOrConst* getOperand2(Instruction* i); +TableNode* getResult(Instruction* i); +Op getOp(Instruction* i); +int getLabel(Instruction* i); +int get_index(Instruction* i); +void set_label(Instruction* i, int label); +bool isConst(TNodeOrConst* tnc); +TNodeOrConst* tn_or_const(Discriminant d, void* tnc); +static void emit_helper(void); +void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* arg2); +void emit_unary_op(Op op, TableNode* result, TNodeOrConst* arg); +void emit_assignment(TableNode* target, TNodeOrConst* source); +char* get_string(TNodeOrConst* tc); +void emit_as_file(FILE* out_file, Instruction* i); +void emit_label(int label); +void emit_jump(int label); +void emit_conditional_jump(Op condition, int label, ...); +void emit_function_start(int name); +void emit_parameter(TNodeOrConst* param); +void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name); +void emit_return(TNodeOrConst* value); +void emit_reserve(TableNode* result, TNodeOrConst* size); +void emit_release(TableNode* pointer); +void emit_deref_right(); +void emit_deref_left(); +void emit_field_access(char* result, char* record, char* field); +void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index); +void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr); +char* label_gen(); +TableNode* getTN(TNodeOrConst* tnc); +int getConst(TNodeOrConst* tnc); + +extern int label_count; +extern Instruction* begin; +extern Instruction* current; + +extern int offset; +extern int currentsp; +extern CGNode* cgList; \ No newline at end of file diff --git a/src/lexicalStructure.h b/src/lexicalStructure.h new file mode 100644 index 0000000..1b77a94 --- /dev/null +++ b/src/lexicalStructure.h @@ -0,0 +1,29 @@ +#include "../src/symbol_table.h" +#include "../tmp/grammar.tab.h" + +extern SymbolTable *cur; +extern FILE *tok_flag; +extern TableNode *funprime; +extern TableNode *funtypeprime; +extern TableNode *arrayprim; +extern TableNode *recprime; +extern TableNode *integ; +extern TableNode *addr; +extern TableNode *chara; +extern TableNode *stri; +extern TableNode *boo; +extern TableNode *undefined; +extern void incr(int lnum, int cnum, int tok); +extern void print_tok(int tok); + +int line_number = 1; +int column_number = 1; +int yycolumn = 1; + +#define YY_USER_ACTION { \ + yylloc.first_line = yylineno; \ + yylloc.last_line = yylineno; \ + yylloc.first_column = yycolumn; \ + yylloc.last_column = yycolumn + yyleng - 1; \ + yycolumn += yyleng; \ +} diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index 2aaf6d2..cd1b56e 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -6,34 +6,7 @@ %option yylineno %{ - #include "../tmp/grammar.tab.h" - #include "../src/symbol_table.h" - extern SymbolTable * cur; - extern FILE* tok_flag; - extern TableNode *funprime; - extern TableNode *funtypeprime; - extern TableNode *arrayprim; - extern TableNode *recprime; - extern TableNode *integ; - extern TableNode *addr; - extern TableNode *chara; - extern TableNode *stri; - extern TableNode *boo; - extern TableNode *undefined; - extern void incr(int lnum,int cnum, int tok); - extern void print_tok(int tok); - - int line_number = 1; - int column_number = 1; - int yycolumn = 1; - - #define YY_USER_ACTION { \ - yylloc.first_line = yylineno; \ - yylloc.last_line = yylineno; \ - yylloc.first_column = yycolumn; \ - yylloc.last_column = yycolumn + yyleng - 1; \ - yycolumn += yyleng; \ - } + #include "../src/lexicalStructure.h" %} STARCOM [^\*]|\*+[^\)\*]+ diff --git a/src/runner.c b/src/runner.c index 3f8a8c5..afeeb73 100644 --- a/src/runner.c +++ b/src/runner.c @@ -127,7 +127,6 @@ int run(FILE *alpha) { fseek(alpha, 0, SEEK_SET); - // print_code_lines(); yyin = alpha; @@ -163,8 +162,8 @@ int run(FILE *alpha) { } //if (cg_flag != NULL) { - // printf("Flag -cg is not implemented yet\n"); - //fclose(cg_flag); + // printf("Flag -cg is not implemented yet\n"); + //fclose(cg_flag); //} if (yyin != NULL) { @@ -271,7 +270,7 @@ void append_code_line(CodeLine *code_line) { void print_code_lines() { CodeLine *current = code_head; while (current != NULL) { - printf("%d %03d: %s",current->line_number, current->line); + printf("%d %03d: %s", current->line_number, current->line); current = current->next; } } diff --git a/src/runner.h b/src/runner.h index d20776b..d5531bd 100644 --- a/src/runner.h +++ b/src/runner.h @@ -35,6 +35,8 @@ #include "../tmp/flex.h" #include "../tmp/grammar.tab.h" +#include "codegen.h" +#include "intermediate_code.h" #include "symbol_table.h" extern int line_number; @@ -66,7 +68,7 @@ TableNode *boo; TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; -extern Instruction* begin; +extern Instruction *begin; int main(int argc, char *argv[]); int check_flag(char *arg, char *alpha); diff --git a/src/symbol_table.c b/src/symbol_table.c index e1e8ea4..2fc926c 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -3,16 +3,8 @@ #include "symbol_table.h" -Constant_Stack * head = NULL; +Constant_Stack *head = NULL; int temp2_count = 0; -bool code_gen = true; -char* temp = NULL; -int label_count=0; -Instruction* begin = NULL; -Instruction* current = NULL; -int offset = 0; -int currentsp = 0; -CGNode *cgList = NULL; void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { @@ -26,8 +18,8 @@ void printdebug_impl(char *file, int line, const char *format, ...) { } } -char * temp_var_gen(){ - char * ret = calloc(9, sizeof(*ret)); +char *temp_var_gen() { + char *ret = calloc(9, sizeof(*ret)); sprintf(ret, "$t%d", temp2_count); temp2_count++; return ret; @@ -44,10 +36,10 @@ Constant_Stack *Push(TableNode *type, void *value, bool isConst) { cs->theType = type; cs->theValue = value; cs->isConst = isConst; - if(head == NULL){ + if (head == NULL) { head = cs; cs->next = NULL; - }else{ + } else { cs->next = head; head = cs; } @@ -65,36 +57,36 @@ Constant_Stack *Pop() { return cs; } -Constant_Stack* Print_Stack(){ +Constant_Stack *Print_Stack() { if (head == NULL) { printdebug("cannot print an empty stack. Invalid."); return NULL; } Constant_Stack *cs = head; while (cs != NULL) { - if(cs->theValue == NULL){ + if (cs->theValue == NULL) { printf("Type: %s, Value: NULL", getName(cs->theType)); } - if(cs->theType == stri){ - printf("Type: %s, Value: %s\n", getName(cs->theType), *(char*)(cs->theValue)); + if (cs->theType == stri) { + printf("Type: %s, Value: %s\n", getName(cs->theType), *(char *)(cs->theValue)); } - if(cs->theType == integ){ + if (cs->theType == integ) { printf("Type: %s, Value: %d\n", getName(cs->theType), (int *)(cs->theValue)); } - if(cs->theType == chara){ + if (cs->theType == chara) { printf("Type: %s, Value: %c\n", getName(cs->theType), *(char *)cs->theValue); } - if(cs->theType == boo){ - if(*(bool *)cs->theValue == true){ - printf("Type: %s, Value: true\n", getName(cs->theType));} - else{ + if (cs->theType == boo) { + if (*(bool *)cs->theValue == true) { + printf("Type: %s, Value: true\n", getName(cs->theType)); + } else { printf("Type: %s, Value: false\n", getName(cs->theType)); } } cs = cs->next; } return cs; - } +} // primitive additional info only stores the size of that type AdInfo *CreatePrimitiveInfo(int size) { @@ -1561,997 +1553,3 @@ TableNode *printTableNode(TableNode *tn) { return tn; } -//________________________________________________________________________ - - -// TODO: this is here to bring your attention to the comment bellow. -// check if start is NULL if it is assign it to the start globle variable -// otherwise make it next of current and set cur to your instruction. -TNodeOrConst * getOperand1(Instruction * i){ - return i->operand1; -} - -TNodeOrConst * getOperand2(Instruction * i){ - return i->operand2; -} - -TableNode * getResult(Instruction * i){ - return i->result; -} - -Op getOp(Instruction * i){ - return i->opcode; -} - -int getLabel(Instruction * i){ - return i->label; -} - -int get_index(Instruction * i){ - return i->index; -} - -void set_label(Instruction * i, int label){ - i->label = label; -} - -bool isConst(TNodeOrConst * tnc) { - return tnc->d != NODE; -} - -TNodeOrConst * tn_or_const(Discriminant d, void * tnc) { - TNodeOrConst * count = calloc(1, sizeof(*count)); - count->d = d; - count->tnc_union = calloc(1, sizeof(*count->tnc_union)); - switch (d) { - case NODE: - count->tnc_union->node = tnc; - break; - case ADDRESS: - count->tnc_union->address = tnc; - break; - case STRING: - count->tnc_union->string = tnc; - break; - case INTEGER: - count->tnc_union->integer = *(int*)tnc; - break; - case CHARACTER: - count->tnc_union->character = *(char*)tnc; - break; - case BOOLEAN: - count->tnc_union->Boolean = *( uint_least8_t*)tnc; - break; - } - return count; -} - -static void emit_helper(void){ - Instruction * inst = calloc(1, sizeof(*inst)); - if(begin == NULL){ - begin = current = inst; - current->index = 1; - } else { - current->next = inst; - inst->prev = current; - inst->index = current->index+1; - current = inst; - } -} - -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2){ - emit_helper(); - current->opcode = op; - // TODO: create temp and remove result from param list - current->result = result; - current->operand1 = arg1; - current->operand2 = arg2; - } - -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg){ - emit_helper(); - current->opcode = op; - current->result = result; - current->operand1 = arg; - } - -void emit_assignment(TableNode * target, TNodeOrConst * source){ - emit_helper(); - current->opcode = E_ASSIGN; - current->result = target; - current->operand1 = source; - } - -char * get_string(TNodeOrConst * tc){ - - char * s; - switch (tc->d) { - case NODE: - return getName(tc->tnc_union->node); - case ADDRESS: - return strdup("null"); - case STRING: - return tc->tnc_union->string; - case INTEGER: - s = calloc(10, sizeof(char)); - sprintf(s, "%d", tc->tnc_union->integer); - return s; - case CHARACTER: - s = calloc(2, sizeof(char)); - sprintf(s, "%c", tc->tnc_union->character); - return s; - case BOOLEAN: - if(tc->tnc_union->Boolean){ - return strdup("true"); - } - return strdup("false"); - } -} - -void emit_as_file(FILE * out_file, Instruction * i){ - if(i == NULL){ - return; - } - switch(i->opcode){ - case E_LABEL: - break; - // this is a terrible one to start with - // fprintf(out_file, "%04.d: %d ", i->index, i->label); - case E_ADD: - fprintf(out_file, "%4.d: %s = %s + %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_SUB: - fprintf(out_file, "%4.d: %s = %s - %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_MUL: - fprintf(out_file, "%4.d: %s = %s * %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_DIV: - fprintf(out_file, "%4.d: %s = %s / %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_MOD: - fprintf(out_file, "%4.d: %s = %s %% %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_OR: - fprintf(out_file, "%4.d: %s = %s | %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_AND: - fprintf(out_file, "%4.d: %s = %s & %s\n", - i->index, getName(i->result), - get_string(i->operand1), - get_string(i->operand2)); - break; - case E_NEG: - fprintf(out_file, "%4.d: %s = -%s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_NOT: - fprintf(out_file, "%4.d: %s = !%s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_ASSIGN: - fprintf(out_file, "%4.d: %s = %s\n", - i->index, getName(i->result), - get_string(i->operand1)); - break; - case E_GOTO: - // are we ever going to use this? - // yes we do look at bounds checking - case E_IF_X_TRUE: - fprintf(out_file, "%4.d: if %s goto %d\n", - i->index, get_string(i->operand1), - i->label); - break; - case E_IF_X_FALSE: - fprintf(out_file, "%4.d: if %s false goto %d\n", - i->index, get_string(i->operand1), - i->label); - break; - case E_LESS_THAN: - fprintf(out_file, "%4.d: if %s < %s goto %d\n", - i->index, get_string(i->operand1), - get_string(i->operand2), i->label); - break; - case E_EQUAL_TO: - fprintf(out_file, "%4.d: if %s = %s goto %d\n", - i->index, get_string(i->operand1), - get_string(i->operand2), i->label); - break; - case E_CALL: - fprintf(out_file, "%4.d: call %s %s\n", - i->index, get_string(i->operand1), - get_string(i->operand2)); - break; - - case E_PARAM: - fprintf(out_file, "%4.d: param %s \n", - i->index, get_string(i->operand1)); - break; - case E_RETURN: - - case E_INDEX_COPY_RIGHT: - case E_INDEX_COPY_LEFT: - - case E_ADDRESS_OF: - - case E_DEREF_RIGHT: - case E_DEREF_LEFT: - } - - emit_as_file(out_file, i->next); -} - -void emit_label(int label){ - emit_helper(); - current->opcode = E_LABEL; - current->label = label; -} - -void emit_jump(int label){ - emit_helper(); - current->opcode = E_GOTO; - current->label = label; -} - -void emit_conditional_jump(Op condition, int label, ...){ - // when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *). - // when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *) - emit_helper(); - va_list argptr; - va_start(argptr, label); - current->opcode = condition; - current->label = label; - TNodeOrConst * n1; - TNodeOrConst * n2; - switch (condition) { - case E_IF_X_TRUE: case E_IF_X_FALSE: - n1 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - break; - case E_LESS_THAN: case E_EQUAL_TO: - n1 = va_arg(argptr, TNodeOrConst *); - n2 = va_arg(argptr, TNodeOrConst *); - current->operand1 = n1; - current->operand2 = n2; - break; - } - va_end(argptr); -} - -void emit_function_start(int name){ - emit_helper(); - current->opcode = E_LABEL; // I think this is right TODO: ask - current->label = name; - // this is probabaly a func decleration -} - -void emit_parameter(TNodeOrConst * param){ - emit_helper(); - current->opcode = E_PARAM; - current->operand1 = param; -} - -void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name){ - emit_helper(); - current->opcode = E_CALL; - current->operand1 = tn_or_const(INTEGER, ¶m_count); - current->operand2 = name; - current->result = result; -} - -void emit_return(TNodeOrConst * value){ - emit_helper(); - current->opcode = E_RETURN; - current->operand1 = value; -} - -void emit_reserve(TableNode * result, TNodeOrConst * size){ - emit_parameter(size); - emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); -} - -void emit_release(TableNode * pointer){ - emit_parameter(tn_or_const(NODE, pointer)); - emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release"))); -} - -void emit_deref_right(){ - return; -} - -void emit_deref_left(){ - return; -} - -void emit_field_access(char* result, char* record, char* field){ - emit_helper(); -} - -void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index){ - emit_helper(); - current->opcode; - current->result = result; - current->operand1 = array; - current->operand2 = index; - // TODO: Still don't know what to do with the dimentions -} - -void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr){ - /* - {[string: 5] - . - . - s:= reserve s(5); - s(0) := 'H'; - s(1) := 'e'; - . - . - s._0 num of dims Known at compile time - s._1 size Known at run time - s._1 int | 1 byte - +-------+---+---+---+---+---+ - | 5 | H | e | l | l | o | - +-------+---+---+---+---+---+ - size - ^ - | - p - s._0 ok - s._1 ok - s._2 not ok - t_0 is index - t_1 = *(int *)p = s._1 - if t_0 < 0 GOTO ERROR - if t_0 < s._1 GOTO access array - GOTO ERROR - */ - //emit_conditional_jump(E_LESS_THAN, ); - //emit_conditional_jump(E_LESS_THAN, ); - //emit_jump(); - /* We need a label ERROR to jump to - */ -} - -/*// * Implement temp variable generator function that produces unique names (t1, t2, etc.) -char * temp_var_gen(){ - char * ret = calloc(9, sizeof(*ret)); - sprintf(ret, "$t%d", temp_count); - temp_count++; - return ret; -} -*/ -char * label_gen(){ - char * ret = calloc( 9, sizeof(*ret)); - sprintf(ret, "L_%d", label_count); - label_count++; - return ret; -} - -TableNode* getTN(TNodeOrConst * tnc){ - if(tnc->d == NODE){ - return tnc->tnc_union->node; - } - return NULL; -} -//we must fix this -int getConst(TNodeOrConst * tnc){ - if(tnc->d == INTEGER){ - return tnc->tnc_union->integer; - } - return -1; -} -//------------------------------------------------------------------------------------- -int generate(){ - offset = 0; - Instruction *i = begin; - while (i != NULL) { - switch(getOp(i)) { - case E_LABEL: - generateLabel(i); - break; - case E_ADD: - generateAdd(i); - break; - case E_SUB: - generateSub(i); - break; - case E_MUL: - generateMult(i); - break; - case E_DIV: - generateDiv(i); - break; - case E_MOD: - generateMod(i); - break; - case E_OR: - generateOr(i); - break; - case E_AND: - generateAnd(i); - break; - case E_NEG: - generateNeg(i); - break; - case E_NOT: - generateNot(i); - break; - case E_ASSIGN: - generateAssign(i); - break; - case E_GOTO: - generateGoto(i); - break; - case E_IF_X_TRUE: - generateIfTrue(i); - break; - case E_IF_X_FALSE: - generateIfFalse(i); - break; - case E_LESS_THAN: - generateLessThan(i); - break; - case E_EQUAL_TO: - generateEqualTo(i); - break; - case E_CALL: - generateCall(i); - break; - case E_PARAM: - generateParam(i); - break; - case E_RETURN: - generateReturn(i); - break; - case E_INDEX_COPY_RIGHT: - generateCopyRight(i); - break; - case E_INDEX_COPY_LEFT: - generateCopyLeft(i); - break; - case E_ADDRESS_OF: - generateAddressOf(i); - break; - default: - ; - } - i = i->next; - } - return -1; -} - -CGNode *getNextCG(CGNode *cg) { - if (cg == NULL) { - return NULL; - } - return cg->next; -} - -int getAddress(CGNode *cg) { - if (cg == NULL) { - return -1; - } - - return currentsp - cg->address; -} - -TableNode *getTNofCG(CGNode *cg) { - if (cg == NULL) { - return NULL; - } - return cg->tn; -} - -CGNode *findCG(TableNode *tn) { - CGNode *cg = cgList; - while (cg != NULL) { - if (getTNofCG(cg) == tn) { - return cg; - } - cg = getNextCG(cg); - } - return NULL; -} - -CGNode *addCG(TableNode *tn, int sp) { - CGNode *cg = calloc(1, sizeof(CGNode)); - cg->tn = tn; - cg->address = sp; - offset += getPrimSize(tn); //not sure if this is the correct amount to add to the offset - cg->next = cgList; - cgList = cg; - return cg; -} - - -int generateLabel(Instruction *inst) { - fprintf(cg_flag, ".L%d:\n", getLabel(inst)); - return 0; -} -int generateAdd(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("generateAdd failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op1)); - if (op1CG == NULL) { - printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1))); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\taddl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); - return 0; -} - -int generateSub(Instruction *instruction) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - TNodeOrConst *op1 = getOperand1(instruction); - TNodeOrConst *op2 = getOperand2(instruction); - CGNode *cg = findCG(getResult(instruction)); - - if (op1 == NULL || op2 == NULL) { - printdebug("generateSub failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(instruction), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateSub failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); - return 0; -} - -int generateMult(Instruction *inst){ - /* - Both immediate: - One immediate: - Neither immediate: - */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("generateMult failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateMult failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateMult failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); - return 0; -} - -int generateDiv(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("generateDiv failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateDiv failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateDiv failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax - fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax - fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result - return 0; -} - -int generateMod(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("generateMod failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateMod failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax - fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax - fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\n", getAddress(cg)); //stores result from edx (remainder) - return 0; -} - -int generateOr(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("generateOr failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateOr failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateOr failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\torll\t%d(%%rbp), %%eax\n", getAddress(op2CG));//divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result - return 0; -} - -int generateAnd(Instruction *inst) { - /* - Both immediate: - One immediate: - Neither immediate: - */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateAnd failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tandl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); - return 0; -} -int generateNeg(Instruction *inst) { - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("generateNeg failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateNeg failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tnegl\t%d %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); - return 0; -} -int generateNot(Instruction *inst) { - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("generateNot failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateNot failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateNot failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tnotl\t%%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); - return 0; -} - -int generateAssign(Instruction *inst) { - TNodeOrConst *op1 = getOperand1(inst); - CGNode *cg = findCG(getResult(inst)); - - - if (op1 == NULL) { - printdebug("generateAssign failed, NULL operand"); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - - //add option for constant assignment (should be easy) - if (isConst(op1) == true) { - fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\n", getConst(op1), getAddress(cg)); - } - - - CGNode *op1CG = findCG(getTN(op1)); - if (op1CG == NULL) { - printdebug("generateAssign failed, op1 is not constant but not in CGlist"); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); - return 0; -} - -int generateGoto(Instruction *instruction){ - return -1; -} - -int generateCondGoto(Instruction *instruction) { - return -1; -} - -int generateIfTrue(Instruction *instruction){ - return -1; - // might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case -} - -int generateIfFalse(Instruction *instruction){ - return -1; -} - -int generateLessThan(Instruction *inst){ - /* - Both immediate: - One immediate: - Neither immediate: - */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tsetl\t%%al\n"); - fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); - return 0; -} - -int generateEqualTo(Instruction *inst){ - /* - Both immediate: - One immediate: - Neither immediate: - */ - TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); - CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { - printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); - return -1; - } - - if (cg == NULL) { - cg = addCG(getResult(inst), offset); - } - - CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); - if (op1CG == NULL) { - printdebug("generateLessThan failed, op1 is not constant but not in CGlist"); - return -1; - } - - if (op2CG == NULL) { - printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tsete\t%%al\n"); - fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); - return 0; -} -int generateCall(Instruction *instruction){ - return -1; - //will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg -} -int generateReturn(Instruction *instruction){ - return -1; - //will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value -} -int generateCopyRight(Instruction *instruction){ - return -1; -} -int generateCopyLeft(Instruction *instruction){ - return -1; -} -int generateAddressOf(Instruction *instruction){ - return -1; -} -int generateParam(Instruction *instruction){ - //need to check if op1 is null, then add it to the appropriate register/cg node. need a way to keep track of this, maybe just have global count of params generated - return -1; -} \ No newline at end of file diff --git a/src/symbol_table.h b/src/symbol_table.h index 0175541..aa9bb64 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -2,16 +2,15 @@ #include #include +#include #include #include #include -#include -#include #define SIZE_INT 4 #define SIZE_ADDR 8 #define SIZE_CHAR 1 -#define SIZE_BOOL 4 //TODO: Ask Carl what this size should be +#define SIZE_BOOL 1 struct TableNode; typedef struct TFList TFList; @@ -63,7 +62,6 @@ typedef struct ListOfTable { struct ListOfTable *next; } ListOfTable; -//Table node to store typedef struct TableNode { struct TableNode *theType; int tag; @@ -99,7 +97,10 @@ void printdebug_impl(char *file, int line, const char *format, ...); #define printdebug(format, ...) \ printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) -void printdebug_impl(char *file, int line, const char *format, ...); +char *temp_var_gen(); +Constant_Stack *Push(TableNode *type, void *value, bool isConst); +Constant_Stack *Pop(); +Constant_Stack *Print_Stack(); AdInfo *CreatePrimitiveInfo(int size); int getPrimSize(TableNode *definition); AdInfo *CreateArrayInfo(int dim, TableNode *type); @@ -187,189 +188,4 @@ extern char *COLOR_YELLOW; extern char *COLOR_LIGHTBLUE; extern char *COLOR_LIGHTPURPLE; extern char *COLOR_LIGHTCYAN; -extern char *COLOR_WHITE; -//_____________________________________________________________ -// these are from page 364 -typedef enum { - E_LABEL = 10000, // this is not in the book - E_ADD, // 1 from the list - E_SUB, // 1 - E_MUL, // 1 - E_DIV, // 1 - E_MOD, // 1 - E_OR, // 1 - E_AND, // 1 - E_NEG, // 2 - E_NOT, // 2 - E_ASSIGN, // 3 - E_GOTO, // 4 - E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got - E_IF_X_TRUE, // 5 - E_IF_X_FALSE, // 5 - E_LESS_THAN, // 6 rule 1 + 5 - E_EQUAL_TO, // 6 rule 1 + 5 - E_CALL, // 7 - E_PARAM, // 7 - E_RETURN, // 7 - E_INDEX_COPY_RIGHT, // 8 this is x = y[i] - E_INDEX_COPY_LEFT, // 8 x[i] = y - E_ADDRESS_OF, // 9 x = &y - E_DEREF_RIGHT, // 9 x = *y - E_DEREF_LEFT // 9 x* = y -} Op; - -typedef enum { - NODE = 11000, // TableNode - INTEGER, // int - STRING, // char * - CHARACTER, // char - ADDRESS, // void * - BOOLEAN // bool -} Discriminant; - -typedef union { - TableNode * node; - int integer; - char * string; - char character; - void * address; - bool Boolean; -} TNConstUnion; - -typedef struct { - Discriminant d; - TNConstUnion * tnc_union; -} TNodeOrConst; - - -typedef struct Instruction Instruction; -typedef struct Instruction { - Op opcode; - TableNode * result; - TNodeOrConst * operand1; - TNodeOrConst * operand2; - int label; - int index; - - Instruction * prev; - Instruction * next; -} Instruction; - - -typedef struct TFList { - Instruction * i; - TFList * next; -} TFList; - -TFList * make_list(Instruction * i); -// - makelist(i) function to create instruction lists -void merge(TFList * l1, TFList * l2); -// - merge(p1,p2) function to concatenate lists -void backpatch(TFList * l, int label); -// - backpatch(p,i) function to fill in jump targets - - -//int temp_count; -//int label_count; -//bool code_gen; -//Instruction * begin; -//Instruction * current; -//char * temp; - - - -TNodeOrConst * tn_or_const(Discriminant d, void * tnc); -void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2); -void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); -void emit_assignment(TableNode * target, TNodeOrConst * source); -void emit_as_file(FILE * out_file, Instruction * instr_arr); -void emit_label(int label); -void emit_jump(int label); - -void emit_conditional_jump(Op condition, int label, ...); - -void emit_function_start(int name); -void emit_parameter(TNodeOrConst * param); -void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); -void emit_return(TNodeOrConst * value); -void emit_reserve(TableNode * result, TNodeOrConst * size); -void emit_release(TableNode * pointer); -void emit_field_access(char* result, char* record, char* field); -void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index); -void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr); - -// * Implement instruction array storage for backpatching -/* -Track 2: Control Flow & Boolean Expressions -* Implement backpatching infrastructure: -* Create truelist and falselist attributes for Boolean expressions -* Create control flow emission functions: -* Add Bison actions for control structures: -- if-then-else with backpatching -- while loops with backpatching -* Implement short-circuit Boolean operations (&&, ||, !) -* Add marker (M) nonterminal for recording instruction positions -*/ - - -/* -Track 3: Functions & Complex Types -* Implement function-related emission: -* Add Bison actions for the 'as' clause -* Create memory layout calculation functions: -- calculate_record_size(Record_Type* type) → returns bytes needed -- calculate_array_size(Array_Type* type, int dimensions[]) → returns total bytes -- calculate_field_offset(Record_Type* type, char* field_name) → returns offset -* Add Bison actions for arrays and records -*/ - -/* -Track 4: Memory Access & Integration -* Implement array and record access code: -- emit_field_access(char* result, char* record, char* field) -- emit_array_access(char* result, char* array, char* index, char* dimension) -* Add array dimension access (a._1, a._2, etc.) -* Implement bounds checking emission: -- emit_bounds_check(char* index, char* size, char* error_label) -* Create the code generation driver function -* Implement common error handling -* Document the complete intermediate instruction set -* Build integration test suite covering all language features -* Implement row-major/column-major array layout calculation -*/ -//------------------------------------------------------------- -extern FILE *cg_flag; -typedef struct CGNode { - TableNode *tn; - int address; - CGNode *next; -}CGNode; - -int generate(); -CGNode *getNextCG(CGNode *cg); -int getAddress(CGNode *cg); -TableNode *getTNofCG(CGNode *cg); -int generateLabel(Instruction *instruction); -int generateAdd(Instruction *instruction); -int generateSub(Instruction *instruction); -int generateMult(Instruction *instruction); -int generateDiv(Instruction *instruction); -int generateMod(Instruction *instruction); -int generateOr(Instruction *instruction); -int generateAnd(Instruction *instruction); -int generateNeg(Instruction *instruction); -int generateNot(Instruction *instruction); -int generateDiv(Instruction *instruction); -int generateAssign(Instruction *instruction); // is this for something like x = 1? -int generateGoto(Instruction *instruction); -int generateCondGoto(Instruction *instruction); -int generateIfTrue(Instruction *instruction); -int generateIfFalse(Instruction *instruction); -int generateLessThan(Instruction *instruction); -int generateEqualTo(Instruction *instruction); -int generateCall(Instruction *instruction); -int generateReturn(Instruction *instruction); -int generateCopyRight(Instruction *instruction); -int generateCopyLeft(Instruction *instruction); -int generateAddressOf(Instruction *instruction); -int generateParam(Instruction *instruction); \ No newline at end of file +extern char *COLOR_WHITE; \ No newline at end of file diff --git a/test.sh b/test.sh old mode 100644 new mode 100755 From 55116599f8d4cf01535cbde4ccb4290cec1b38d7 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 19:39:52 -0400 Subject: [PATCH 132/137] pragma + watermarks --- src/codegen.c | 3 +++ src/codegen.h | 3 +++ src/grammar.h | 3 +++ src/grammar.y | 1 - src/intermediate_code.c | 3 +++ src/intermediate_code.h | 3 +++ src/lexicalStructure.h | 5 +++++ src/symbol_table.h | 3 +++ src/typedefs.h | 3 +++ 9 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/codegen.c b/src/codegen.c index 358f3bd..dfce1ff 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1,3 +1,6 @@ +/* Code Generator */ +/* The Translators - Spring 2025 */ + #include "codegen.h" int generate() { diff --git a/src/codegen.h b/src/codegen.h index a228b94..3203a52 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -1,3 +1,6 @@ +/* Code Generator */ +/* The Translators - Spring 2025 */ + #pragma once #include diff --git a/src/grammar.h b/src/grammar.h index 018974e..94f43b1 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -1,3 +1,6 @@ +/* Syntax Analyzer with Bison (3.8.2) */ +/* The Translators - Spring 2025 */ + #pragma once #include "../src/codegen.h" diff --git a/src/grammar.y b/src/grammar.y index 75e70ec..3dda42f 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1,4 +1,3 @@ - /* Syntax Analyzer with Bison (3.8.2) */ /* The Translators - Spring 2025 */ diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 65458cf..103df2b 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -1,3 +1,6 @@ +/* Intermediate Code */ +/* The Translators - Spring 2025 */ + #include "intermediate_code.h" // TODO: this is here to bring your attention to the comment bellow. diff --git a/src/intermediate_code.h b/src/intermediate_code.h index fd654e0..d2b5088 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -1,3 +1,6 @@ +/* Intermediate Code */ +/* The Translators - Spring 2025 */ + #pragma once #include diff --git a/src/lexicalStructure.h b/src/lexicalStructure.h index 1b77a94..bdd0db7 100644 --- a/src/lexicalStructure.h +++ b/src/lexicalStructure.h @@ -1,3 +1,8 @@ +/* Lexical Analyzer with Flex (1.6.0) */ +/* The Translators - Spring 2025 */ + +#pragma once + #include "../src/symbol_table.h" #include "../tmp/grammar.tab.h" diff --git a/src/symbol_table.h b/src/symbol_table.h index aa9bb64..391f05a 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -1,3 +1,6 @@ +/* Symbol Table */ +/* The Translators - Spring 2025 */ + #pragma once #include diff --git a/src/typedefs.h b/src/typedefs.h index 5405f66..5c476bf 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -1,3 +1,6 @@ +/* Type Definitions */ +/* The Translators - Spring 2025 */ + // identifier #define ID 101 // type names From 3ea41f40fa46f532d65c12a42b52027be31a2c0c Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 22:14:31 -0400 Subject: [PATCH 133/137] TC & ASC Implemented. yyerrors updated. --- Makefile | 1 + src/grammar.h | 1 + src/grammar.y | 126 ++++++++++++++---- src/runner.c | 55 +++++--- src/runner.h | 3 +- tests/sprint2/test/sp2_llnode.alpha | 2 +- .../sp3_integer_binary_op_typecheck.alpha | 6 +- 7 files changed, 148 insertions(+), 46 deletions(-) diff --git a/Makefile b/Makefile index e91f705..6fefed1 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ clean: rm -rf out rm -rf tmp rm -f *.s + rm -f *.out tmp: mkdir -p tmp diff --git a/src/grammar.h b/src/grammar.h index 94f43b1..2b7b03c 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -8,6 +8,7 @@ #include "../src/symbol_table.h" extern FILE *asc_flag; extern bool tc_flag; +extern void insert_code_line(char * error_message, int line_number); typedef enum { ERROR_RUNTIME = 1, diff --git a/src/grammar.y b/src/grammar.y index 3dda42f..2751080 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -106,6 +106,7 @@ program: prototype_or_definition_list + | error { yyerrok; } ; @@ -115,12 +116,17 @@ prototype_or_definition_list: | definition prototype_or_definition_list | prototype | definition + | error { yyerrok; } ; prototype: - L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID; + L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID + + | error { yyerrok; } + + ; @@ -259,7 +265,7 @@ definition: } } - ; + ; function_declaration: FUNCTION ID COLON ID @@ -285,6 +291,7 @@ function_declaration: } } + ; @@ -344,6 +351,9 @@ idlist: printdebug("Type of entry is %s", getType(entry)); printdebug("tag is %d", getAdInfoType(entry)); } + + | error { yyerrok; } + ; @@ -391,6 +401,9 @@ sblock: } R_BRACE {$$ = $5;} + + | error { yyerrok; } + ; @@ -408,13 +421,20 @@ dblock: printdebug("Created a new scope when seeing a dblock"); } } - declaration_list R_BRACKET; + declaration_list R_BRACKET + + | error { yyerrok; } + + ; declaration_list: declaration SEMI_COLON declaration_list | declaration + + | error { yyerrok; } + ; @@ -452,6 +472,9 @@ declaration: CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } } + + | error { yyerrok; } + ; @@ -468,6 +491,9 @@ id_or_types: printdebug("string of type is %s in types pattern of id_or_type rule.",getName((TableNode*)$1)); $$ = (TableNode*)$1; } + + | error { yyerrok; } + ; @@ -503,6 +529,7 @@ compound_statement statement_list { | simple_statement SEMI_COLON { $$ = $1; } + ; @@ -523,9 +550,11 @@ WHILE L_PAREN expression R_PAREN sblock { $$ = undefined; } } - | sblock { + + | sblock { $$ = $1; } + ; @@ -557,7 +586,10 @@ simple_statement: } -| RETURN expression {$$ = getTypeEntry((TableNode*)$2);} + | RETURN expression {$$ = getTypeEntry((TableNode*)$2);} + + | error { yyerrok; } + ; @@ -565,6 +597,9 @@ simple_statement: rec_op: DOT + | error { yyerrok; } + + ; ablock: @@ -573,6 +608,9 @@ ablock: $$ = $2; printdebug("ablock is %d", $$); } + + | error { yyerrok; } + ; @@ -591,6 +629,9 @@ argument_list: CreateEntry(cur,getAdInfoType((TableNode*)$1),(TableNode*)$1, getName((TableNode*)$1), NULL); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } + + | error { yyerrok; } + ; @@ -786,6 +827,8 @@ expression: $$=undefined; } } + + | error { yyerrok; } ; @@ -969,6 +1012,8 @@ assignable: printdebug("[ASSIGNABLE - RULE 3] record = name: %s | field = %s", getName((TableNode*)($1)), getName((TableNode*)$3)); } + | error { yyerrok; } + ; @@ -984,6 +1029,8 @@ memOp: printdebug("release expression"); } + | error { yyerrok; } + ; @@ -1043,7 +1090,7 @@ constant: printdebug("string of C_FALSE in constant is false"); $$ = node; } - + ; @@ -1071,8 +1118,7 @@ types: { $$ = $1; printdebug("string of T_BOOLEAN in types is %s",getName((TableNode*)$1)); - } - + } ; %% @@ -1104,24 +1150,50 @@ void throw_error(ErrorType error_type, const char *format, ...) { break; } + if (asc_flag) { + /* yyerror(""); */ + int needed = snprintf(NULL, 0, " LINE (%d:%d) ** %s ERROR: ", line, column, error_name); + char *error_message = malloc(needed + 1); + snprintf(error_message, needed + 1, " LINE (%d:%d) ** %s ERROR: ", line, column, error_name); - if (tc_flag) { - yyerror(""); - if (asc_flag != NULL) { - fprintf(asc_flag, "(%d:%d) ** %s ERROR: ", line, column, error_name); - va_list args; - va_start(args, format); - vfprintf(asc_flag, format, args); + va_list args; + va_start(args, format); + va_list args_copy; + va_copy(args_copy, args); + int needed2 = vsnprintf(NULL, 0, format, args_copy) + 1; + va_end(args_copy); + + char *error_message2 = malloc(needed2); + if (error_message2 == NULL) { + fprintf(stderr, "Memory allocation failed\n"); va_end(args); - fprintf(asc_flag, "\n"); - } else { - fprintf(stderr, "%s(%d:%d) ** %s ERROR%s: %s", COLOR_RED, line, column, error_name, COLOR_WHITE, COLOR_YELLOW); - va_list args; - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, "%s\n", COLOR_WHITE); + return; } + + vsnprintf(error_message2, needed2, format, args); + va_end(args); + + int total_needed = needed + needed2 + 2; + char *total_error_message = malloc(total_needed); + if (total_error_message == NULL) { + fprintf(stderr, "Memory allocation failed\n"); + free(error_message); + free(error_message2); + return; + } + + snprintf(total_error_message, total_needed, "%s%s\n\n", error_message, error_message2); + if (tc_flag) { + insert_code_line(total_error_message, line); + } else { + if (error_type != ERROR_TYPE) { + insert_code_line(total_error_message, line); + } + } + + free(error_message); + free(error_message2); + free(total_error_message); } } @@ -1132,11 +1204,13 @@ void yyerror(const char *err) { // Grammar Fallback Case if (strcmp(err, "syntax error") == 0) { if (asc_flag != NULL) { - fprintf(asc_flag, "(%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n", line, column, yytext); + int needed = snprintf(NULL, 0, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n\n", line, column, yytext); + char *error_message = malloc(needed + 1); + snprintf(error_message, needed + 1, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n\n", line, column, yytext); + insert_code_line(error_message, line); } else { - fprintf(stderr, "%s(%d:%d) ** SYNTAX ERROR%s: Incorrect syntax at token '%s%s%s'\n", - COLOR_RED, line, column, COLOR_WHITE, COLOR_YELLOW, yytext, COLOR_WHITE); + fprintf(stderr, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token %s\n\n", line, column, yytext); } } } diff --git a/src/runner.c b/src/runner.c index afeeb73..a74c424 100644 --- a/src/runner.c +++ b/src/runner.c @@ -2,8 +2,7 @@ /* The Translators - Spring 2025 */ #include "runner.h" -FILE *ir_flag = NULL; -//Constant_Stack *head = NULL; + int main(int argc, char *argv[]) { if (argc == 1) { fprintf(stderr, INVALID); @@ -36,7 +35,6 @@ int main(int argc, char *argv[]) { alpha_file = fopen(argv[argc - 1], "r"); } } - cg_flag = fopen("cg.s", "w"); return run(alpha_file); } @@ -127,8 +125,6 @@ int run(FILE *alpha) { fseek(alpha, 0, SEEK_SET); - // print_code_lines(); - yyin = alpha; yyparse(); @@ -140,15 +136,14 @@ int run(FILE *alpha) { } if (st_flag != NULL) { + printdebug("[-st] Symbol Table is enabled."); print_symbol_table(top, st_flag); - emit_as_file(stdout, begin); fclose(st_flag); - generate(); - fclose(cg_flag); } if (asc_flag != NULL) { printdebug("[-asc] Annotated Source Code is enabled."); + print_code_lines(); fclose(asc_flag); } @@ -157,14 +152,16 @@ int run(FILE *alpha) { } if (ir_flag != NULL) { - printf("Flag -ir is not implemented yet\n"); + printdebug("[-ir] Intermediate code is enabled."); + emit_as_file(ir_flag, begin); fclose(ir_flag); } - //if (cg_flag != NULL) { - // printf("Flag -cg is not implemented yet\n"); - //fclose(cg_flag); - //} + if (cg_flag != NULL) { + printdebug("[-cg] Code generation is enabled."); + generate(); + fclose(cg_flag); + } if (yyin != NULL) { fclose(yyin); @@ -250,7 +247,26 @@ int is_alpha_file(char *alpha, int file_len) { return 0; // is alpha file } -void insert_code_line(char *line, int line_number) { +void insert_code_line(char * error_message, int line_number) { + CodeLine *error_line = malloc(sizeof(CodeLine)); + error_line->line_number = line_number; + error_line->line = malloc(strlen(error_message) + 1); + strcpy(error_line->line, error_message); + error_line->next = NULL; + error_line->is_error = true; + + if (error_line == NULL || code_head == NULL) return; + + int line = error_line->line_number; + CodeLine *current = code_head; + while (current != NULL) { + if (current->line_number == line) { + CodeLine *next_code_line = current->next; + current->next = error_line; + error_line->next = next_code_line; + } + current = current->next; + } } void append_code_line(CodeLine *code_line) { @@ -268,9 +284,18 @@ void append_code_line(CodeLine *code_line) { } void print_code_lines() { + if (code_head == NULL) { + printf("No code lines to print.\n"); + return; + } + CodeLine *current = code_head; while (current != NULL) { - printf("%d %03d: %s", current->line_number, current->line); + if (current->is_error) { + fprintf(asc_flag, "%s", current->line); + } else { + fprintf(asc_flag, "%03d: %s", current->line_number, current->line); + } current = current->next; } } diff --git a/src/runner.h b/src/runner.h index d5531bd..9971eed 100644 --- a/src/runner.h +++ b/src/runner.h @@ -52,6 +52,7 @@ FILE *alpha_file; FILE *tok_flag = NULL; FILE *st_flag = NULL; FILE *asc_flag = NULL; +FILE *ir_flag = NULL; FILE *cg_flag = NULL; bool tc_flag = false; bool DEBUG = false; @@ -105,6 +106,6 @@ typedef struct CodeLine { CodeLine *code_head; char *file_read_line(FILE *fp); -void insert_code_line(char *line, int line_number); +void insert_code_line(char * error_message, int line_number); void append_code_line(CodeLine *code_line); void print_code_lines(); \ No newline at end of file diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index 3ecfb11..c611b3c 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -21,7 +21,7 @@ make_list (a) := { } else { ret := reserve ret; ret.prev := null; - ret.next := null; + ret.next :s= null;g ret.val := a; while (0 < a) { temp := reserve temp; diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha index 2adb394..a804c23 100644 --- a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -8,12 +8,12 @@ entry (arg) := { x := 3 + 2 * 8; x := 3 - 2 / 8; - x := a * 2 % 8; + x := a * 2 % 8;s b2 := 3 * 2 % 8; x := 3 % 2 * 8; x := 3 + arr - 8; - x := r.x; - x := a.x; + x := r.x; + x := a.x; return 0; } From 74dc4f568fdae02f2493a5325f061bb8b8e3daa1 Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 22:41:58 -0400 Subject: [PATCH 134/137] Quick throw --- src/grammar.y | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/grammar.y b/src/grammar.y index 2751080..cfcc476 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -445,6 +445,7 @@ declaration: printdebug("ID/TYPE: %s, ID: %s", getName((TableNode*)$1), $3) ; int d = getAdInfoType((TableNode*)$1); if(d == TYPE_UNDEFINED) { + throw_error(ERROR_TYPE, "Undefined type passed in declaration list"); printdebug("Undefined type passed in declaration list"); CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } @@ -468,7 +469,7 @@ declaration: d = TYPE_PRIMITIVE; CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); }else { - printdebug("Invalid type passed in declaration list."); + throw_error(ERROR_TYPE, "%s is being defined with an undefined type", $3); CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } } @@ -841,6 +842,9 @@ assignable: ID { TableNode* pass = look_up(cur,$1); + if(pass == undefined){ + throw_error(ERROR_TYPE, "Undefined variable %s", $1); + } $$ = pass; printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getType(pass), getName(pass)); } From 747a48b2117e8e7b96bd5f83bcf2c0fa6f0f1b5e Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 23:09:46 -0400 Subject: [PATCH 135/137] implemented annies and meyers stuff --- src/codegen.c | 355 +++++++++++++++++++++------------------- src/grammar.y | 2 +- src/intermediate_code.c | 14 +- src/intermediate_code.h | 4 +- 4 files changed, 199 insertions(+), 176 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index dfce1ff..825fd55 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -3,78 +3,79 @@ #include "codegen.h" -int generate() { +int generate(){ offset = 0; Instruction *i = begin; while (i != NULL) { - switch (getOp(i)) { - case E_LABEL: - generateLabel(i); - break; - case E_ADD: - generateAdd(i); - break; - case E_SUB: - generateSub(i); - break; - case E_MUL: - generateMult(i); - break; - case E_DIV: - generateDiv(i); - break; - case E_MOD: - generateMod(i); - break; - case E_OR: - generateOr(i); - break; - case E_AND: - generateAnd(i); - break; - case E_NEG: - generateNeg(i); - break; - case E_NOT: - generateNot(i); - break; - case E_ASSIGN: - generateAssign(i); - break; - case E_GOTO: - generateGoto(i); - break; - case E_IF_X_TRUE: - generateIfTrue(i); - break; - case E_IF_X_FALSE: - generateIfFalse(i); - break; - case E_LESS_THAN: - generateLessThan(i); - break; - case E_EQUAL_TO: - generateEqualTo(i); - break; - case E_CALL: - generateCall(i); - break; - case E_PARAM: - generateParam(i); - break; - case E_RETURN: - generateReturn(i); - break; - case E_INDEX_COPY_RIGHT: - generateCopyRight(i); - break; - case E_INDEX_COPY_LEFT: - generateCopyLeft(i); - break; - case E_ADDRESS_OF: - generateAddressOf(i); - break; - default:; + switch(getOp(i)) { + case E_LABEL: + generateLabel(i); + break; + case E_ADD: + generateAdd(i); + break; + case E_SUB: + generateSub(i); + break; + case E_MUL: + generateMult(i); + break; + case E_DIV: + generateDiv(i); + break; + case E_MOD: + generateMod(i); + break; + case E_OR: + generateOr(i); + break; + case E_AND: + generateAnd(i); + break; + case E_NEG: + generateNeg(i); + break; + case E_NOT: + generateNot(i); + break; + case E_ASSIGN: + generateAssign(i); + break; + case E_GOTO: + generateGoto(i); + break; + case E_IF_X_TRUE: + generateIfTrue(i); + break; + case E_IF_X_FALSE: + generateIfFalse(i); + break; + case E_LESS_THAN: + generateLessThan(i); + break; + case E_EQUAL_TO: + generateEqualTo(i); + break; + case E_CALL: + generateCall(i); + break; + case E_PARAM: + generateParam(i); + break; + case E_RETURN: + generateReturn(i); + break; + case E_INDEX_COPY_RIGHT: + generateCopyRight(i); + break; + case E_INDEX_COPY_LEFT: + generateCopyLeft(i); + break; + case E_ADDRESS_OF: + generateAddressOf(i); + break; + default: + ; } i = i->next; } @@ -117,13 +118,14 @@ CGNode *findCG(TableNode *tn) { CGNode *addCG(TableNode *tn, int sp) { CGNode *cg = calloc(1, sizeof(CGNode)); cg->tn = tn; - cg->address = sp; - offset += getPrimSize(tn); //not sure if this is the correct amount to add to the offset + offset += getPrimSize(getTypeEntry(tn)); + cg->address = offset; cg->next = cgList; cgList = cg; return cg; } + int generateLabel(Instruction *inst) { fprintf(cg_flag, ".L%d:\n", getLabel(inst)); return 0; @@ -137,7 +139,7 @@ int generateAdd(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateAdd failed, NULL operand"); return -1; @@ -146,7 +148,8 @@ int generateAdd(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op1)); if (op1CG == NULL) { @@ -158,15 +161,15 @@ int generateAdd(Instruction *inst) { printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\taddl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#addition start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\taddl\t%%edx, %%eax\n"); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#addition end\n", getAddress(cg)); return 0; } int generateSub(Instruction *instruction) { - /* + /* Both immediate: One immediate: Neither immediate: @@ -174,7 +177,7 @@ int generateSub(Instruction *instruction) { TNodeOrConst *op1 = getOperand1(instruction); TNodeOrConst *op2 = getOperand2(instruction); CGNode *cg = findCG(getResult(instruction)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateSub failed, NULL operand"); return -1; @@ -183,7 +186,7 @@ int generateSub(Instruction *instruction) { if (cg == NULL) { cg = addCG(getResult(instruction), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -196,14 +199,14 @@ int generateSub(Instruction *instruction) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#subtraction start\n", getAddress(op1CG)); fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#subtraction end\n", getAddress(cg)); return 0; } -int generateMult(Instruction *inst) { - /* +int generateMult(Instruction *inst){ + /* Both immediate: One immediate: Neither immediate: @@ -211,7 +214,7 @@ int generateMult(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateMult failed, NULL operand"); return -1; @@ -232,14 +235,14 @@ int generateMult(Instruction *inst) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#multiplication start\n", getAddress(op1CG)); + fprintf(cg_flag, "\timull\t%d(%%rbp), %%eax\n", getAddress(op2CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#multiplication end\n", getAddress(cg)); return 0; } int generateDiv(Instruction *inst) { - /* + /* Both immediate: One immediate: Neither immediate: @@ -247,7 +250,7 @@ int generateDiv(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateDiv failed, NULL operand"); return -1; @@ -256,7 +259,7 @@ int generateDiv(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -269,10 +272,10 @@ int generateDiv(Instruction *inst) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax - fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax - fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG)); //divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#division start\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax + fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#division end\n", getAddress(cg)); //stores result return 0; } @@ -285,7 +288,7 @@ int generateMod(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateMod failed, NULL operand"); return -1; @@ -300,21 +303,21 @@ int generateMod(Instruction *inst) { printdebug("generateMod failed, op1 is not constant but not in CGlist"); return -1; } - + if (op2CG == NULL) { printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); //moves dividend into eax - fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax - fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG)); //divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\n", getAddress(cg)); //stores result from edx (remainder) + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#mod start\n", getAddress(op1CG)); //moves dividend into eax + fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax + fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack + fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\t#mod end\n", getAddress(cg)); //stores result from edx (remainder) return 0; } int generateOr(Instruction *inst) { - /* + /* Both immediate: One immediate: Neither immediate: @@ -322,7 +325,7 @@ int generateOr(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("generateOr failed, NULL operand"); return -1; @@ -331,7 +334,7 @@ int generateOr(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -344,9 +347,24 @@ int generateOr(Instruction *inst) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\torll\t%d(%%rbp), %%eax\n", getAddress(op2CG)); //divides edx by value accessed from stack - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); //stores result + int label = label_gen(); + + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start or\n", getAddress(op1CG)); + fprintf(cg_flag, "\tjne\t.L%dor2\n", label); + + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG)); + fprintf(cg_flag, "\tje\t.L%dor3\n", label); + + fprintf(cg_flag, ".L%dor2:\n", label); + fprintf(cg_flag, "\tmovl\t$1, %%eax\n"); + fprintf(cg_flag, "\tjmp\t.L%dor4\n", label); + + fprintf(cg_flag, ".L%dor3:\n", label); + fprintf(cg_flag, "\tmovl\t$0, %%eax\n"); + + fprintf(cg_flag, ".L%dor4:\n", label); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#or end\n", getAddress(cg)); //stores result return 0; } @@ -359,7 +377,7 @@ int generateAnd(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED); return -1; @@ -368,7 +386,7 @@ int generateAnd(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -380,18 +398,30 @@ int generateAnd(Instruction *inst) { printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } + int label = label_gen(); - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tandl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start and\n", getAddress(op1CG)); + fprintf(cg_flag, "\tje\t.L%dor2\n", label); + + fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG)); + fprintf(cg_flag, "\tje\t.L%dor2\n", label); + + fprintf(cg_flag, "\tmovl\t$1, %%eax\n"); + fprintf(cg_flag, "\tjmp\t.L%dor3\n", label); + + fprintf(cg_flag, ".L%dor2:\n", label); + fprintf(cg_flag, "\tmovl\t$0, %%eax\n"); + + fprintf(cg_flag, ".L%dor3:\n", label); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#and end\n", getAddress(cg)); //stores result return 0; } int generateNeg(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { + + if (op1 == NULL) { printdebug("generateNeg failed, NULL operand"); return -1; } @@ -399,30 +429,23 @@ int generateNeg(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateNeg failed, op1 is not constant but not in CGlist"); return -1; } - if (op2CG == NULL) { - printdebug("generateNeg failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tnegl\t%d %%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#negation start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tnegl\t%%eax\n"); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#negation end\n", getAddress(cg)); return 0; } int generateNot(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); - TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - - if (op1 == NULL || op2 == NULL) { + + if (op1 == NULL) { printdebug("generateNot failed, NULL operand"); return -1; } @@ -430,22 +453,20 @@ int generateNot(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateNot failed, op1 is not constant but not in CGlist"); return -1; } - if (op2CG == NULL) { - printdebug("generateNot failed, %s is not initialized/in CG", getName(getTN(op2))); - return -1; - } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tnotl\t%%eax\n", getAddress(op2CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovzbl\t%d(%%rbp), %%eax\t#not start\n", getAddress(op1CG)); + fprintf(cg_flag, "\ttestl\t%%eax, %%eax\n"); + fprintf(cg_flag, "\tsetne\t%%al\n"); + fprintf(cg_flag, "\txorl\t$1, %%eax\n"); + fprintf(cg_flag, "\tmovzbl\t%%al, %%eax\n"); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#not end\n", getAddress(cg)); return 0; } @@ -453,6 +474,7 @@ int generateAssign(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); CGNode *cg = findCG(getResult(inst)); + if (op1 == NULL) { printdebug("generateAssign failed, NULL operand"); return -1; @@ -462,23 +484,26 @@ int generateAssign(Instruction *inst) { cg = addCG(getResult(inst), offset); } + //add option for constant assignment (should be easy) if (isConst(op1) == true) { - fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\n", getConst(op1), getAddress(cg)); + fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\t#constant assign\n", getConst(op1), getAddress(cg)); + return 0; } - + CGNode *op1CG = findCG(getTN(op1)); if (op1CG == NULL) { + printf("failed here\n"); printdebug("generateAssign failed, op1 is not constant but not in CGlist"); return -1; } - - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); - fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\n", getAddress(cg)); + + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#assign start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#assign end\n", getAddress(cg)); return 0; } -int generateGoto(Instruction *instruction) { +int generateGoto(Instruction *instruction){ return -1; } @@ -486,17 +511,17 @@ int generateCondGoto(Instruction *instruction) { return -1; } -int generateIfTrue(Instruction *instruction) { +int generateIfTrue(Instruction *instruction){ return -1; // might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case } -int generateIfFalse(Instruction *instruction) { +int generateIfFalse(Instruction *instruction){ return -1; } -int generateLessThan(Instruction *inst) { - /* +int generateLessThan(Instruction *inst){ + /* Both immediate: One immediate: Neither immediate: @@ -504,7 +529,7 @@ int generateLessThan(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); return -1; @@ -513,7 +538,7 @@ int generateLessThan(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -526,15 +551,15 @@ int generateLessThan(Instruction *inst) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#less than start\n", getAddress(op1CG)); fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); fprintf(cg_flag, "\tsetl\t%%al\n"); - fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#less than end\n", getAddress(cg)); return 0; } -int generateEqualTo(Instruction *inst) { - /* +int generateEqualTo(Instruction *inst){ + /* Both immediate: One immediate: Neither immediate: @@ -542,7 +567,7 @@ int generateEqualTo(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); TNodeOrConst *op2 = getOperand2(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL || op2 == NULL) { printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED); return -1; @@ -551,7 +576,7 @@ int generateEqualTo(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -564,30 +589,30 @@ int generateEqualTo(Instruction *inst) { return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#equal to start\n", getAddress(op1CG)); fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); fprintf(cg_flag, "\tsete\t%%al\n"); - fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg)); + fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg)); return 0; } -int generateCall(Instruction *instruction) { +int generateCall(Instruction *instruction){ return -1; //will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg } -int generateReturn(Instruction *instruction) { +int generateReturn(Instruction *instruction){ return -1; //will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value } -int generateCopyRight(Instruction *instruction) { +int generateCopyRight(Instruction *instruction){ return -1; } -int generateCopyLeft(Instruction *instruction) { +int generateCopyLeft(Instruction *instruction){ return -1; } -int generateAddressOf(Instruction *instruction) { +int generateAddressOf(Instruction *instruction){ return -1; } -int generateParam(Instruction *instruction) { +int generateParam(Instruction *instruction){ //need to check if op1 is null, then add it to the appropriate register/cg node. need a way to keep track of this, maybe just have global count of params generated return -1; } \ No newline at end of file diff --git a/src/grammar.y b/src/grammar.y index cfcc476..9f96a6c 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -577,7 +577,7 @@ simple_statement: if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ - //EMIT ASSIGN INSTRUCTION HERE + emit_assignment($1, tn_or_const(NODE, $3)); printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); } else { throw_error(ERROR_TYPE, "%s != %s", getName(node), getName((TableNode*)$3)); diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 103df2b..9948115 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -278,11 +278,11 @@ void emit_conditional_jump(Op condition, int label, ...) { va_end(argptr); } -void emit_function_start(int name) { +void emit_function_start(TNodeOrConst * name) { emit_helper(); current->opcode = E_LABEL; // I think this is right TODO: ask - current->label = name; - // this is probabaly a func decleration + current->operand1 = name; + // this is probabaly a func declaration } void emit_parameter(TNodeOrConst* param) { @@ -380,11 +380,9 @@ char * temp_var_gen(){ return ret; } */ -char* label_gen() { - char* ret = calloc(9, sizeof(*ret)); - sprintf(ret, "L_%d", label_count); +int label_gen(){ label_count++; - return ret; + return label_count; } TableNode* getTN(TNodeOrConst* tnc) { @@ -393,7 +391,7 @@ TableNode* getTN(TNodeOrConst* tnc) { } return NULL; } -//we must fix this + int getConst(TNodeOrConst* tnc) { if (tnc->d == INTEGER) { return tnc->tnc_union->integer; diff --git a/src/intermediate_code.h b/src/intermediate_code.h index d2b5088..c1efb76 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -100,7 +100,7 @@ void emit_as_file(FILE* out_file, Instruction* i); void emit_label(int label); void emit_jump(int label); void emit_conditional_jump(Op condition, int label, ...); -void emit_function_start(int name); +void emit_function_start(TNodeOrConst * name); void emit_parameter(TNodeOrConst* param); void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name); void emit_return(TNodeOrConst* value); @@ -111,7 +111,7 @@ void emit_deref_left(); void emit_field_access(char* result, char* record, char* field); void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index); void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr); -char* label_gen(); +int label_gen(); TableNode* getTN(TNodeOrConst* tnc); int getConst(TNodeOrConst* tnc); From 6e4841f0c1ff8a3b17f7fc01d69755fe604c296a Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 23:26:50 -0400 Subject: [PATCH 136/137] Big testing update --- src/codegen.c | 2 +- src/grammar.y | 2 +- test.sh | 4 ++-- tests/sprint2/test/sp2_llnode.alpha | 2 +- .../sp3_integer_binary_op_typecheck.alpha | 6 +++--- tests/sprint4/expected/sp4_cg_add.expected | 12 +++++++++++ tests/sprint4/expected/sp4_cg_and.expected | 20 ++++++++++++++++++ tests/sprint4/expected/sp4_cg_div.expected | 12 +++++++++++ .../sprint4/expected/sp4_cg_equal_to.expected | 13 ++++++++++++ .../expected/sp4_cg_less_than.expected | 13 ++++++++++++ tests/sprint4/expected/sp4_cg_mod.expected | 12 +++++++++++ tests/sprint4/expected/sp4_cg_mult.expected | 11 ++++++++++ tests/sprint4/expected/sp4_cg_neg.expected | 8 +++++++ tests/sprint4/expected/sp4_cg_not.expected | 13 ++++++++++++ tests/sprint4/expected/sp4_cg_or.expected | 21 +++++++++++++++++++ tests/sprint4/expected/sp4_cg_sub.expected | 11 ++++++++++ tests/sprint4/test/sp4_cg_add.alpha | 10 +++++++++ tests/sprint4/test/sp4_cg_and.alpha | 10 +++++++++ tests/sprint4/test/sp4_cg_div.alpha | 10 +++++++++ tests/sprint4/test/sp4_cg_equal_to.alpha | 10 +++++++++ tests/sprint4/test/sp4_cg_less_than.alpha | 10 +++++++++ tests/sprint4/test/sp4_cg_mod.alpha | 10 +++++++++ tests/sprint4/test/sp4_cg_mult.alpha | 10 +++++++++ tests/sprint4/test/sp4_cg_neg.alpha | 9 ++++++++ tests/sprint4/test/sp4_cg_not.alpha | 9 ++++++++ tests/sprint4/test/sp4_cg_or.alpha | 10 +++++++++ tests/sprint4/test/sp4_cg_sub.alpha | 10 +++++++++ 27 files changed, 262 insertions(+), 8 deletions(-) create mode 100644 tests/sprint4/expected/sp4_cg_add.expected create mode 100644 tests/sprint4/expected/sp4_cg_and.expected create mode 100644 tests/sprint4/expected/sp4_cg_div.expected create mode 100644 tests/sprint4/expected/sp4_cg_equal_to.expected create mode 100644 tests/sprint4/expected/sp4_cg_less_than.expected create mode 100644 tests/sprint4/expected/sp4_cg_mod.expected create mode 100644 tests/sprint4/expected/sp4_cg_mult.expected create mode 100644 tests/sprint4/expected/sp4_cg_neg.expected create mode 100644 tests/sprint4/expected/sp4_cg_not.expected create mode 100644 tests/sprint4/expected/sp4_cg_or.expected create mode 100644 tests/sprint4/expected/sp4_cg_sub.expected create mode 100644 tests/sprint4/test/sp4_cg_add.alpha create mode 100644 tests/sprint4/test/sp4_cg_and.alpha create mode 100644 tests/sprint4/test/sp4_cg_div.alpha create mode 100644 tests/sprint4/test/sp4_cg_equal_to.alpha create mode 100644 tests/sprint4/test/sp4_cg_less_than.alpha create mode 100644 tests/sprint4/test/sp4_cg_mod.alpha create mode 100644 tests/sprint4/test/sp4_cg_mult.alpha create mode 100644 tests/sprint4/test/sp4_cg_neg.alpha create mode 100644 tests/sprint4/test/sp4_cg_not.alpha create mode 100644 tests/sprint4/test/sp4_cg_or.alpha create mode 100644 tests/sprint4/test/sp4_cg_sub.alpha diff --git a/src/codegen.c b/src/codegen.c index 825fd55..250d2a4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -118,7 +118,7 @@ CGNode *findCG(TableNode *tn) { CGNode *addCG(TableNode *tn, int sp) { CGNode *cg = calloc(1, sizeof(CGNode)); cg->tn = tn; - offset += getPrimSize(getTypeEntry(tn)); + offset += 4; // <- quick fix getPrimSize(getTypeEntry(tn)) cg->address = offset; cg->next = cgList; cgList = cg; diff --git a/src/grammar.y b/src/grammar.y index 9f96a6c..7060c94 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1214,7 +1214,7 @@ void yyerror(const char *err) { insert_code_line(error_message, line); } else { - fprintf(stderr, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token %s\n\n", line, column, yytext); + fprintf(stderr, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token %s\n", line, column, yytext); } } } diff --git a/test.sh b/test.sh index 8443215..3f6f5a9 100755 --- a/test.sh +++ b/test.sh @@ -84,7 +84,7 @@ if [ $# -eq 0 ]; then if [ -f "$file" ]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st -debug "$file" + ./alpha -cg "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n${WHITE}" switchfunc fi @@ -154,7 +154,7 @@ else if [[ "$file" == *"$1"* ]]; then filename=$(basename -- "$file") echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}" - ./alpha -st -debug "$file" + ./alpha -cg -debug "$file" echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n" switchfunc fi diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index c611b3c..3ecfb11 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -21,7 +21,7 @@ make_list (a) := { } else { ret := reserve ret; ret.prev := null; - ret.next :s= null;g + ret.next := null; ret.val := a; while (0 < a) { temp := reserve temp; diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha index a804c23..2adb394 100644 --- a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -8,12 +8,12 @@ entry (arg) := { x := 3 + 2 * 8; x := 3 - 2 / 8; - x := a * 2 % 8;s + x := a * 2 % 8; b2 := 3 * 2 % 8; x := 3 % 2 * 8; x := 3 + arr - 8; - x := r.x; - x := a.x; + x := r.x; + x := a.x; return 0; } diff --git a/tests/sprint4/expected/sp4_cg_add.expected b/tests/sprint4/expected/sp4_cg_add.expected new file mode 100644 index 0000000..4764400 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_add.expected @@ -0,0 +1,12 @@ + movl $1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl $3, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %eax #addition start + movl -16(%rbp), %eax + addl %edx, %eax + movl %eax, -20(%rbp) #addition end + movl -20(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_and.expected b/tests/sprint4/expected/sp4_cg_and.expected new file mode 100644 index 0000000..be6a53e --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_and.expected @@ -0,0 +1,20 @@ + movl $-1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl $-1, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + cmpl $0, -8(%rbp) #start and + je .L1or2 + cmpl $0, -16(%rbp) + je .L1or2 + movl $1, %eax + jmp .L1or3 +.L1or2: + movl $0, %eax +.L1or3: + movb %al, -20(%rbp) + andb $1, -20(%rbp) #and end + movl -20(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $1, -24(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_div.expected b/tests/sprint4/expected/sp4_cg_div.expected new file mode 100644 index 0000000..1a71c6e --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_div.expected @@ -0,0 +1,12 @@ + movl $1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl $3, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %eax #division start + cltd + idivl -8(%rbp) + movl %eax, -20(%rbp) #division end + movl -20(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_equal_to.expected b/tests/sprint4/expected/sp4_cg_equal_to.expected new file mode 100644 index 0000000..e29c6c1 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_equal_to.expected @@ -0,0 +1,13 @@ + movl $1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl $2, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -8(%rbp), %eax #equal to start + cmpl -16(%rbp), %eax + sete %al + movb %al, -20(%rbp) #equal to end + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl $1, -28(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_less_than.expected b/tests/sprint4/expected/sp4_cg_less_than.expected new file mode 100644 index 0000000..b8d8904 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_less_than.expected @@ -0,0 +1,13 @@ + movl $1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl $2, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -8(%rbp), %eax #less than start + cmpl -16(%rbp), %eax + setl %al + movb %al, -20(%rbp) #less than end + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl $1, -28(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_mod.expected b/tests/sprint4/expected/sp4_cg_mod.expected new file mode 100644 index 0000000..97d4259 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mod.expected @@ -0,0 +1,12 @@ + movl $1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl $3, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %eax #mod start + cltd + idivl -8(%rbp) + movl %edx, -20(%rbp) #mod end + movl -20(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_mult.expected b/tests/sprint4/expected/sp4_cg_mult.expected new file mode 100644 index 0000000..20b0a57 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mult.expected @@ -0,0 +1,11 @@ + movl $1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl $3, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %eax #multiplication start + imull -16(%rbp), %eax + movl %eax, -20(%rbp) #multiplication end + movl -20(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_neg.expected b/tests/sprint4/expected/sp4_cg_neg.expected new file mode 100644 index 0000000..5f61770 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_neg.expected @@ -0,0 +1,8 @@ + movl $3, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl -8(%rbp), %eax #negation start + negl %eax + movl %eax, -12(%rbp) #negation end + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_not.expected b/tests/sprint4/expected/sp4_cg_not.expected new file mode 100644 index 0000000..b2e4bda --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_not.expected @@ -0,0 +1,13 @@ + movl $-1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movzbl -8(%rbp), %eax #not start + testl %eax, %eax + setne %al + xorl $1, %eax + movzbl %al, %eax + movb %al, -12(%rbp) + andb $1, -12(%rbp) #not end + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $1, -20(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_or.expected b/tests/sprint4/expected/sp4_cg_or.expected new file mode 100644 index 0000000..120058f --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_or.expected @@ -0,0 +1,21 @@ + movl $-1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl $-1, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + cmpl $0, -8(%rbp) #start or + jne .L1or2 + cmpl $0, -16(%rbp) + je .L1or3 +.L1or2: + movl $1, %eax + jmp .L1or4 +.L1or3: + movl $0, %eax +.L1or4: + movb %al, -20(%rbp) + andb $1, -20(%rbp) #or end + movl -20(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $1, -24(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_sub.expected b/tests/sprint4/expected/sp4_cg_sub.expected new file mode 100644 index 0000000..743ef59 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_sub.expected @@ -0,0 +1,11 @@ + movl $1, -4(%rbp) #constant assign + movl -4(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end + movl $3, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %eax #subtraction start + subl -8(%rbp), %eax + movl %eax, -20(%rbp) #subtraction end + movl -20(%rbp), %eax #assign start + movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/test/sp4_cg_add.alpha b/tests/sprint4/test/sp4_cg_add.alpha new file mode 100644 index 0000000..f4f8138 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_add.alpha @@ -0,0 +1,10 @@ +type main: integer -> integer +function test: main + +test (a) := { + [integer:x; integer:y] + y := 1; + x := 3; + y := x + y; + return y; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_and.alpha b/tests/sprint4/test/sp4_cg_and.alpha new file mode 100644 index 0000000..5017e35 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_and.alpha @@ -0,0 +1,10 @@ +type main: integer -> integer +function test: main + +test (a) := { + [Boolean:b; Boolean: c; Boolean: d] + c := true; + d := false; + d := c & d; + return 1; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_div.alpha b/tests/sprint4/test/sp4_cg_div.alpha new file mode 100644 index 0000000..32d3537 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_div.alpha @@ -0,0 +1,10 @@ +type main: integer -> integer +function test: main + +test (a) := { + [integer:x; integer:y] + y := 1; + x := 3; + y := x / y; + return y; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_equal_to.alpha b/tests/sprint4/test/sp4_cg_equal_to.alpha new file mode 100644 index 0000000..a3da50c --- /dev/null +++ b/tests/sprint4/test/sp4_cg_equal_to.alpha @@ -0,0 +1,10 @@ +type main: integer -> integer +function test: main + +test (a) := { + [Boolean: b; integer: x; integer: y] + x := 1; + y := 2; + b := x = y; + return 1; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_less_than.alpha b/tests/sprint4/test/sp4_cg_less_than.alpha new file mode 100644 index 0000000..8f41ced --- /dev/null +++ b/tests/sprint4/test/sp4_cg_less_than.alpha @@ -0,0 +1,10 @@ +type main: integer -> integer +function test: main + +test (a) := { + [Boolean: b; integer: x; integer: y] + x := 1; + y := 2; + b := x < y; + return 1; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_mod.alpha b/tests/sprint4/test/sp4_cg_mod.alpha new file mode 100644 index 0000000..1b579d5 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_mod.alpha @@ -0,0 +1,10 @@ +type main: integer -> integer +function test: main + +test (a) := { + [integer:x; integer:y] + y := 1; + x := 3; + y := x % y; + return y; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_mult.alpha b/tests/sprint4/test/sp4_cg_mult.alpha new file mode 100644 index 0000000..c151a6b --- /dev/null +++ b/tests/sprint4/test/sp4_cg_mult.alpha @@ -0,0 +1,10 @@ +type main: integer -> integer +function test: main + +test (a) := { + [integer:x; integer:y] + y := 1; + x := 3; + y := x * x; + return y; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_neg.alpha b/tests/sprint4/test/sp4_cg_neg.alpha new file mode 100644 index 0000000..345980b --- /dev/null +++ b/tests/sprint4/test/sp4_cg_neg.alpha @@ -0,0 +1,9 @@ +type main: integer -> integer +function test: main + +test (a) := { + [integer:x; integer:y] + x := 3; + y := -x; + return y; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_not.alpha b/tests/sprint4/test/sp4_cg_not.alpha new file mode 100644 index 0000000..40252f9 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_not.alpha @@ -0,0 +1,9 @@ +type main: integer -> integer +function test: main + +test (a) := { + [Boolean: c; Boolean: d] + c := true; + d := !c; + return 1; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_or.alpha b/tests/sprint4/test/sp4_cg_or.alpha new file mode 100644 index 0000000..b6d6766 --- /dev/null +++ b/tests/sprint4/test/sp4_cg_or.alpha @@ -0,0 +1,10 @@ +type main: integer -> integer +function test: main + +test (a) := { + [Boolean:b; Boolean: c; Boolean: d] + c := true; + d := false; + d := c | d; + return 1; +} \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_sub.alpha b/tests/sprint4/test/sp4_cg_sub.alpha new file mode 100644 index 0000000..f280c9d --- /dev/null +++ b/tests/sprint4/test/sp4_cg_sub.alpha @@ -0,0 +1,10 @@ +type main: integer -> integer +function test: main + +test (a) := { + [integer:x; integer:y] + y := 1; + x := 3; + y := x - y; + return y; +} \ No newline at end of file From 3e54a72f38d99d3a03ba11b8204c18a4844acf7a Mon Sep 17 00:00:00 2001 From: Scarlett Date: Fri, 25 Apr 2025 23:54:37 -0400 Subject: [PATCH 137/137] updated expected --- .../expected/sp3_and_or_type_check.expected | 84 +++++++++++-------- .../sp3_boolean_binary_op_typecheck.expected | 36 ++++---- .../sp3_boolean_unary_op_typecheck.expected | 33 +++----- .../sp3_integer_binary_op_typecheck.expected | 51 ++++++----- .../sp3_integer_unary_op_typecheck.expected | 34 ++++---- tests/sprint3/test/sp3_multiple_args.alpha | 5 +- tests/sprint3/test/sp3_multiple_args.alpha~ | 17 ---- 7 files changed, 121 insertions(+), 139 deletions(-) delete mode 100644 tests/sprint3/test/sp3_multiple_args.alpha~ diff --git a/tests/sprint3/expected/sp3_and_or_type_check.expected b/tests/sprint3/expected/sp3_and_or_type_check.expected index 600a1f9..493f53b 100644 --- a/tests/sprint3/expected/sp3_and_or_type_check.expected +++ b/tests/sprint3/expected/sp3_and_or_type_check.expected @@ -1,34 +1,50 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -test : 001001 : : undefined : Function Definition -main : 001001 : : rec -> integer : Type of Function -rec : 001001 : : Record Type : elements-2 size-8 bytes -integer : 001001 : : Primitive Type : size-4 bytes -address : 001001 : : Primitive Type : size-8 bytes -character : 001001 : : Primitive Type : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes -reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition -release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -b : 005000 : 001001 : Boolean : Primitive Instance -x : 005000 : 001001 : integer : Primitive Instance -arg : 005000 : 001001 : integer : Primitive Instance -undefined : 005000 : 001001 : integer : Primitive Instance -------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 023009 : 005000 : : Empty Scope -------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 021014 : 005000 : : Empty Scope -------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 017009 : 005000 : : Empty Scope -------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 015017 : 005000 : : Empty Scope -------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 011012 : 005000 : : Empty Scope -------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 007015 : 005000 : : Empty Scope -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance -x : 001000 : 001001 : integer : Primitive Instance +001: type rec: [integer: x; integer: y] +002: type main: rec -> integer +003: function test: main +004: +005: test (arg) := { +006: [integer:x; Boolean: b] +007: while (true) { +008: x := 0; +009: } +010: +011: while (7) { +012: x := 1; +013: } +014: +015: if (true) then { +016: x := 1; +017: } else { +018: x := 0; +019: } +020: +021: if (x) then { +022: x := 0; +023: } else { +024: x := 1; +025: } +026: +027: b := b | b; +028: b := b & b; +029: b := 1 | b; + LINE (29:12) ** TYPE ERROR: b != undefined + +030: b := b | 1; + LINE (30:12) ** TYPE ERROR: b != undefined + +031: b := b & 1; + LINE (31:12) ** TYPE ERROR: b != undefined + +032: b := 1 & b; + LINE (32:12) ** TYPE ERROR: b != undefined + +033: b := 1 = 1; +034: +035: +036: +037: b := 1 = b; + LINE (37:12) ** TYPE ERROR: b != undefined + +038: +039: return 0; +040: } diff --git a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected index 1653f88..f95e765 100644 --- a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected @@ -1,20 +1,16 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function -integer : 001001 : : Primitive Type : size-4 bytes -address : 001001 : : Primitive Type : size-8 bytes -character : 001001 : : Primitive Type : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes -reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition -release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -b1 : 004000 : 001001 : Boolean : Primitive Instance -b2 : 004000 : 001001 : Boolean : Primitive Instance -arr2 : 004000 : 001001 : address : Primitive Instance -arr : 004000 : 001001 : address : Primitive Instance -x : 004000 : 001001 : integer : Primitive Instance -arg : 004000 : 001001 : string : Array Instance +001: type main: string -> integer +002: function entry: main +003: +004: entry (arg) := { +005: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] +006: +007: b2 := 3 < x; +008: b1 := arr = 2; + LINE (8:18) ** TYPE ERROR: b1 != undefined + +009: b1 := 6<7 & arr2=7; + LINE (9:23) ** TYPE ERROR: b1 != undefined + +010: +011: return 0; +012: } diff --git a/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected index 1653f88..39237bc 100644 --- a/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected @@ -1,20 +1,13 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function -integer : 001001 : : Primitive Type : size-4 bytes -address : 001001 : : Primitive Type : size-8 bytes -character : 001001 : : Primitive Type : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes -reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition -release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -b1 : 004000 : 001001 : Boolean : Primitive Instance -b2 : 004000 : 001001 : Boolean : Primitive Instance -arr2 : 004000 : 001001 : address : Primitive Instance -arr : 004000 : 001001 : address : Primitive Instance -x : 004000 : 001001 : integer : Primitive Instance -arg : 004000 : 001001 : string : Array Instance +001: type main: string -> integer +002: function entry: main +003: +004: entry (arg) := { +005: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] +006: +007: b2 := !(3 < 2); +008: b1 := !5; + LINE (8:13) ** TYPE ERROR: b1 != undefined + +009: +010: return 0; +011: } diff --git a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected index 8344120..0b4c83f 100644 --- a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected @@ -1,26 +1,25 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -entry : 001001 : : undefined : Function Definition -rec : 001001 : : Record Type : elements-2 size-8 bytes -main : 001001 : : string -> integer : Type of Function -integer : 001001 : : Primitive Type : size-4 bytes -address : 001001 : : Primitive Type : size-8 bytes -character : 001001 : : Primitive Type : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes -reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition -release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -r : 006000 : 001001 : rec : Record Instance -a : 006000 : 001001 : character : Primitive Instance -b1 : 006000 : 001001 : Boolean : Primitive Instance -b2 : 006000 : 001001 : Boolean : Primitive Instance -arr2 : 006000 : 001001 : address : Primitive Instance -arr : 006000 : 001001 : address : Primitive Instance -x : 006000 : 001001 : integer : Primitive Instance -arg : 006000 : 001001 : string : Array Instance -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 003000 : 001001 : integer : Primitive Instance -x : 003000 : 001001 : integer : Primitive Instance +001: type main: string -> integer +002: +003: type rec: [integer: x; integer: y] +004: function entry: main +005: +006: entry (arg) := { +007: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a; rec : r] +008: +009: x := 3 + 2 * 8; +010: x := 3 - 2 / 8; +011: x := a * 2 % 8; + LINE (11:20) ** TYPE ERROR: x != undefined + +012: b2 := 3 * 2 % 8; +013: x := 3 % 2 * 8; +014: x := 3 + arr - 8; + LINE (14:22) ** TYPE ERROR: x != undefined + +015: x := r.x; + LINE (15:10) ** TYPE ERROR: x != r + +016: x := a.x; +017: +018: return 0; +019: } diff --git a/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected index 1653f88..18bd5a7 100644 --- a/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected @@ -1,20 +1,14 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function -integer : 001001 : : Primitive Type : size-4 bytes -address : 001001 : : Primitive Type : size-8 bytes -character : 001001 : : Primitive Type : size-1 bytes -string : 001001 : : 1 -> character : Type of Array -Boolean : 001001 : : Primitive Type : size-4 bytes -reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition -release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -b1 : 004000 : 001001 : Boolean : Primitive Instance -b2 : 004000 : 001001 : Boolean : Primitive Instance -arr2 : 004000 : 001001 : address : Primitive Instance -arr : 004000 : 001001 : address : Primitive Instance -x : 004000 : 001001 : integer : Primitive Instance -arg : 004000 : 001001 : string : Array Instance +001: type main: string -> integer +002: function entry: main +003: +004: entry (arg) := { +005: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1] +006: +007: x := -8; +008: x := -b1; + LINE (8:10) ** TYPE ERROR: x != undefined + +009: b2 := -x; +010: +011: return 0; +012: } diff --git a/tests/sprint3/test/sp3_multiple_args.alpha b/tests/sprint3/test/sp3_multiple_args.alpha index e59c4b6..8475d92 100644 --- a/tests/sprint3/test/sp3_multiple_args.alpha +++ b/tests/sprint3/test/sp3_multiple_args.alpha @@ -6,12 +6,13 @@ type main: string -> integer function entry: main function bar: T2 -bar2 (r,s) := { - return r; +bar (r,s) := { + return 0; } entry (arg) := { [ integer: result ; rec: w] + result := bar(1,2); result := bar('c', 7); return 0; } \ No newline at end of file diff --git a/tests/sprint3/test/sp3_multiple_args.alpha~ b/tests/sprint3/test/sp3_multiple_args.alpha~ deleted file mode 100644 index 641c654..0000000 --- a/tests/sprint3/test/sp3_multiple_args.alpha~ +++ /dev/null @@ -1,17 +0,0 @@ -type rec: [character: x; integer: y] - -type T2: rec -> integer - -type main: string -> integer -function entry: main -function bar: T2 - -bar2 (r,s) := { - return s; -} - -entry (arg) := { - [ integer: result ; rec: w] - result := bar('c', 7); - return 0; -} \ No newline at end of file