From cf1ea4223201b94fbabb21acd7ebda6855aac4d2 Mon Sep 17 00:00:00 2001 From: SpookyDervish <78246495+SpookyDervish@users.noreply.github.com> Date: Sun, 7 Sep 2025 11:58:01 +1000 Subject: [PATCH] labels work im pretty sure --- .vscode/settings.json | 8 +++++++ a.out | Bin 8872 -> 15960 bytes generators/generator.py | 1 + generators/x86_64.py | 19 +++++++++++++---- ground_ast.py | 11 ++++++---- out | Bin 8944 -> 4680 bytes out.asm | 35 ++++--------------------------- test | Bin 0 -> 4680 bytes test.c | 5 +++++ test.o | Bin 0 -> 576 bytes test.s | 45 ++++++++++++++++++++++++++++++++++++++++ test2.grnd | 7 ++----- 12 files changed, 87 insertions(+), 44 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 test create mode 100644 test.c create mode 100644 test.o create mode 100644 test.s diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..76bf544 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "files.associations": { + "*.embeddedhtml": "html", + "*.spk": "code-text-binary", + "*.mem": "code-text-binary", + "stdio.h": "c" + } +} \ No newline at end of file diff --git a/a.out b/a.out index dd7131b4ebfd4644eb7cbe6d136f910afcc260c3..193e80099b8636b43233288f84985a1e961cc397 100644 GIT binary patch literal 15960 zcmeHOeQX>@6`#Ari9?*&NfVk6h_BGlmew0Pv8@ycx%eYlgOeD?Q9+{JtbJ?yr2BC0 z_F6kC#So~7+EhVBG(wdq5>k<uOoaYqXtwKY*Jm!x&axYl)~!KEqs%jm;LE-BL7L5TTO+mc_!SEWOA zKl$djDWqv7UsHweIlf=nb=-AER+w(^fu56|gy^^EDD-Cau zoVuU5VgJm3^C2>FD-_E2WbP|h3c1^;+tk)&pXB$%{JyAZAqeNPRONTP&yYStsMfaZU%Tlu&8r`3oK<_b-23rex9iu1%>N>N&XOPA!Ld8*efpe< z>A5c+=W!a}HbT|Ew&l@u@0t}yX+SI|C5b>1fg}P+1d<3O5lAACL?DSk5`iQF@3ROX zuMl~J$PwgRMJ`PS!o=wEhFyqxT)o}V*jVeI1lOWe+I}0 zk2lyJeMpWQZz3b_^gwU#Co*>)9j%r8TBc){waaR6>#k{W=Oa5it@h5lM17OS$i#73 zuC4}gFOGYPERRcIGU9LxVLgAoE@{fXJrg@G=COW0rr#xcd@o4UWq^(;wMDgLjg0HY zS=K4_!7xA9Se1I1D%^hfJrlz>wExC1&lmpBQl;MbmpZTKbvql>LIy3|z{ikgNJ+e4LXPS??2K%;*9L; z8SE!Ud>=p->HhDM;?KJXLSNn*;CMOLca=UVYL*4F0f2h>ioQEa=vNF*qLwew z9)>ApmCC+nO_XZZRHZ!SRs5NVYP6Q8-6{E;sP^>?wDIiF?vrkHQdzl~5_MtFuNcdN zUZt8Zmlg>Q*(zSaWrEbE3cj-RFfFQD6J-*)QuW4^<$Kd4@^m5ZvW~OmP09qB%u#EQ zOdDpV7zXOpm0QeHV}?#4Ru)asBF((mH{-pDyq=-26y3v3iSIMRdPdCJ7j?#u(uda& z;4ihGiha3Y-C!i8c)MJbAKzES|9?jd?pM(9?^TqK-%DTyj)HOieWd>ftwAt;tkZz# zAA3LI<9CVAYc%k&jsyNc`sFcloWaL>Do;B8i3fjH1_;DDkX&@(HlpP?3B1MvAM2_R z#Tny=AMg>f^O_AZ)@{Ic;m5}>YQ0Y7A%l-~Bye6F(SQ8>pCUW+d&CdxQXt~Qe6Gj& z-y5X#bv5c8fv(Q3(tAj2O0N=47^I*<_I6pf%9#o zqyj%9-H@UGHyL>D;`s;bR_trV{#E||aRCq4@rR`2^9LX6*ts3-O>r;~9>E8$Aaazi zvf|oq5dEM5@E|u4nRVzN>$?`=$NjmlXjv!yi+gAS|L#y@D&R*koO==9tTcE`2KHgH r@m$1sa9>$PI*dI+SI_VR5|!VfBO~fqNmTbQ!NL@528Nqqoh* literal 8872 zcmeI2Jxc>Y5QZn056;RHECdTLpeP83+GrsX5G6&5ly=931Z<*^TR|&p3;&OuR_af& z%`Z52c4sc}{AjGicOm=EzB_Y!d9J$Ky*=rj2DKV#3+Ra4DC#)N_e5K5%^>Q~0o85a zqNdAj%%*Il6<*(DPL(2W@ET1HWlXZ3YU0yKRr9#6#d9%tw#6MMs_vTBQPn!1gdPMy z00ck)1V8`;KmY_l00ck)1pX(1?tNo}-<|s$@Jn;QFzex2_wLzhWcB6Y(7KOIXR&;# z<`EhQfB*=900@8p2!H?xfB*=900@A=KO$~x{ojZ_BZ~X_+cfVF0V|IIFJ#r$mS-3EI?6%LKa}SjWDPwQAwz20 zfa~jO=>LzsQRV&dOop$uPwP_)V{bjl4A=25l<|rvKkssF@mOACKiKzD_I$7NZOIP4 PsxM-nwK<<`<7)jovm-!V diff --git a/generators/generator.py b/generators/generator.py index 7e01c80..b3e5a96 100644 --- a/generators/generator.py +++ b/generators/generator.py @@ -10,6 +10,7 @@ class Generator: self.output_path = output_path self.variables = {} self.constants = {} + self.labels = [] self.constants_reverse = {} self.constant_counter = 0 diff --git a/generators/x86_64.py b/generators/x86_64.py index e611649..1316760 100644 --- a/generators/x86_64.py +++ b/generators/x86_64.py @@ -8,7 +8,7 @@ class X86_64Generator(Generator): self.stack_size = 0 def init(self): - self.lines.append("global _start\n\n") + self.lines.append("global _start\n") self.lines.append("_start:\n\t") # generate code @@ -105,7 +105,6 @@ class X86_64Generator(Generator): def change_variable(self, var_name: str, new_value): var_pos = self.get_var_pos(var_name) - print(self.variables[var_name]["type"]) if type(new_value) == IntNode: # we're changing a variable to a number self.lines.append(f"mov QWORD [rsp + {var_pos}], {new_value.value}\n\t") self.variables[var_name]["type"] = IntNode @@ -135,7 +134,10 @@ class X86_64Generator(Generator): elif type(new_value) == str: # we're changing a variable to the value of a register self.lines.append(f"mov QWORD [rsp + {var_pos}], {new_value}\n\t") self.variables[var_name]["type"] = IntNode - print(self.variables[var_name]["type"]) + + def generate_LabelDecNode(self, node: LabelDecNode): + self.labels.append(node.name) + self.lines.append("." + node.name + ":\n\t") def generate_InstructionNode(self, node: InstructionNode): ### MISC ### @@ -409,6 +411,15 @@ class X86_64Generator(Generator): self.lines.append("mov rdi, 1\n\t") # a file descriptor of 1 is stdout self.lines.append("syscall\n\t") + elif node.instruction == "jump": + if len(node.arguments) < 1: # example: "jump" + traceback(self.code, "TypeError", "jump expects atleast 1 argument.") + elif len(node.arguments) > 1: # example: "jump %label 123" + traceback(self.code, "TypeError", "jump expects at most 1 argument.") + elif not isinstance(node.arguments[0], LabelRefNode): + traceback(self.code, "TypeError", f"jump expects a label reference as the first argument, not \"{node.arguments[0]}\"") + + self.lines.append(f"jmp .{node.arguments[0].name}\n\t") else: self.lines.append("; FUCK\n\t") #raise NotImplementedError(f"A generate method hasn't been made for the \"{node.instruction}\" instruction.") @@ -431,5 +442,5 @@ class X86_64Generator(Generator): elif value_type == float or value_type == int: f.write(f"dq {float(value)}") f.write("\n") - f.write("\nsection .text\n") + f.write("section .text\n") f.writelines(self.lines) \ No newline at end of file diff --git a/ground_ast.py b/ground_ast.py index ba360a8..8365373 100644 --- a/ground_ast.py +++ b/ground_ast.py @@ -3,6 +3,7 @@ from dataclasses import dataclass from tokenizer import Token, TokenType from typing import Optional, Any from error import traceback +from console import console @dataclass @@ -100,8 +101,8 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode: # todo: this is the absolute WORST way i could do this, but i could not care less lmao # its not even performant...... for token in tokens: - #print(token.type) if token.type == TokenType.INSTRUCTION: + if current_node: scope.statements.append(current_node) @@ -125,6 +126,11 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode: else: current_node = FunctionNode([], [], scope) current_node_type = "func" + elif token.type == TokenType.LABEL_DECLERATION: + if current_node: + scope.statements.append(current_node) + current_node = None + scope.statements.append(LabelDecNode(token.value)) if current_node: if token.type == TokenType.STRING: @@ -199,9 +205,6 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode: current_node.arguments.append(FunctionCallNode(token.value)) else: traceback(code, "SyntaxError", "Expected instruction or function return type, got function reference.") - - elif token.type == TokenType.LABEL_DECLERATION: - scope.statements.append(LabelDecNode(token.value)) elif token.type == TokenType.COMMENT: continue diff --git a/out b/out index 40d3a2bae54c64c5f48d83f1ebe1fbd452b42eb3..e04ac5886bd598099c0e05addc7922e6231404fa 100644 GIT binary patch delta 264 zcmez1dO~G_hB${H0~|OoSTHa#I54m>uuQa9GuhkUU9-zRHe2WUTn@P9;RLi-Y3PvY0d8uX0nmU$ zC}3ZLqRw^FA+)%{=(`CjTxY`~ zLO=)z0U;m+gn$qb0zyCt2mv7=1pXy~_yL#Q4&IzPEkAg2Hfbl_j%jb+4koJZ29s(% zrfv5tbt}c-rD*ru&v^{Y55>onhCfWBUYZaP0zyCt2mv7=1cZPP5CTF#2nYco@Fxfi zhQlE&FMbr-^E)t|Wiys^01p7{Spbh$wK1J#_x~FVhKY^na80$=CaCHzX(v6|kAz5_x3#C+^MisZfojbY>K6~+Uop+WTp z4lozb1d@9bcKrL@4pWy&$NqTzL`L>GA QPxVb&7`81VNuRC%0=JP(-2eap diff --git a/out.asm b/out.asm index edd111a..ddd38ec 100644 --- a/out.asm +++ b/out.asm @@ -1,38 +1,11 @@ ; ~~~ Auto generated by the GroundPY compiler for Linux x86_64 targets. ~~~ section .data -.LC0: db "hiii", 0 -.LC1: equ $ - .LC0 -.LC2: db "", 10, 0 -.LC3: equ $ - .LC2 - section .text global _start - _start: - ; InstructionNode(instruction='set', parent=RootNode(statements=[..., InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='stdout', parent=..., arguments=[String]), InstructionNode(instruction='end', parent=..., arguments=[Int])]), arguments=[VariablePointer, Int]) - mov rax, 123 - push rax - ; InstructionNode(instruction='set', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), ..., InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='stdout', parent=..., arguments=[String]), InstructionNode(instruction='end', parent=..., arguments=[Int])]), arguments=[VariablePointer, String]) - mov QWORD [rsp + 0], 0 - lea rax, [.LC0] - push rax - mov rax, .LC1 - push rax - ; InstructionNode(instruction='stdout', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), ..., InstructionNode(instruction='stdout', parent=..., arguments=[String]), InstructionNode(instruction='end', parent=..., arguments=[Int])]), arguments=[VariableReference]) - mov rsi, [rsp + 8] - mov rdx, [rsp + 0] - mov rax, 1 - mov rdi, 1 - syscall - ; InstructionNode(instruction='stdout', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), ..., InstructionNode(instruction='end', parent=..., arguments=[Int])]), arguments=[String]) - mov rsi, .LC2 - mov rdx, .LC3 - mov rax, 1 - mov rdi, 1 - syscall - ; InstructionNode(instruction='end', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='stdout', parent=..., arguments=[String]), ...]), arguments=[Int]) - mov rax, 60 - mov rdi, 0 - syscall + ; LabelDecleration + .myLabel: + ; InstructionNode(instruction='jump', parent=RootNode(statements=[LabelDecleration, ...]), arguments=[LabelReference]) + jmp .myLabel \ No newline at end of file diff --git a/test b/test new file mode 100644 index 0000000000000000000000000000000000000000..3cd462875ab21365f8b544c2ab9c7cfbd728434a GIT binary patch literal 4680 zcmeI0u}Z{15QhJYiJT%B8xcfMu(3&PA(BQb-yv+cfW@7~?G{@3I+m8#`7AzyPoOiq zGcg7Na`h}^|DAtkvf)d$`+E0qpUq~_k>M6GD(h&a8JHhw1yJJ}8O;UqSeyT*Xr&!V z-zBGtG8w!_!AprD`>7tJGN|@-;+q%&BVYuKfDtePM!*Od0V7}pjDQg^0{Jp>lqO zYU$c;iKc12Z+vj;fTmlx;7FbpK;>Un!L_7eo%B&xp?eO0zGC~}lv*qI=>?*vm%xuX-mfc)#J`|HAJbk5B2p7$wI2KhS0< AYybcN literal 0 HcmV?d00001 diff --git a/test.c b/test.c new file mode 100644 index 0000000..23704de --- /dev/null +++ b/test.c @@ -0,0 +1,5 @@ +#include +int main() { + printf("Hello, World!\n"); + return 0; +} \ No newline at end of file diff --git a/test.o b/test.o new file mode 100644 index 0000000000000000000000000000000000000000..19dab4615d992cb197e884d239336f6b2abebdb6 GIT binary patch literal 576 zcmb<-^>JfjWMqH=Mg}_u1P><4z~F#jLfH-stPD&@qU13_c7ZS(n)U{$BY4on1GLos$UUJ4k`>66$G-d`QiXnVFFYo3y=n34k%v&N=pK1Z1yWa4F#Ex4AAZ0 zVFQ%i&jlp-S;6Y`N>VFI81#xWic5-05|e