ok damn it nearly works

This commit is contained in:
SpookyDervish
2025-09-12 06:28:45 +10:00
parent 2ce71e7abb
commit 865a31827a
6 changed files with 107 additions and 27 deletions

View File

@@ -74,7 +74,7 @@ class Generator:
pass
def generate_node(self, node):
#self.lines.append(f"; {node}\n\t")
self.lines.append(f"; {node}\n\t")
node_type = str(type(node))[19:-2]
if not hasattr(self, f"generate_{node_type}"):
raise NotImplementedError(f"Generator has no generate method for {node_type}.")

View File

@@ -32,7 +32,12 @@ class X86_64Generator(Generator):
var_pos = self.get_var_pos(var_name, scope)
if isinstance(var_pos, str): # in a reg, not on the stack
lines.append(f"mov {reg}, {var_pos}\n\t")
if offset == 0:
lines.append(f"mov {reg}, {var_pos}\n\t")
elif offset == -8:
if var_pos == "rax": # according to the SysV ABI, the second return value of a function is stored in RDX
var_pos = "rdx"
lines.append(f"mov {reg}, {var_pos}\n\t")
else:
try:
#print(var["type"])
@@ -223,7 +228,7 @@ class X86_64Generator(Generator):
self.current_var_scope = func["scope"]
# function boilerplate
self.function_lines.append(node.name + ":")
self.function_lines.append(node.name + ":\n\t")
self.push("rbp", self.function_lines)
self.function_lines.append("mov rbp, rsp\n\t")
@@ -236,6 +241,7 @@ class X86_64Generator(Generator):
self.current_var_scope.define(arg.name, {"stack_loc": stack_loc, "type": self.ground_type_to_node(arg.arg_type)})
for inst in node.statements:
self.function_lines.append(f"; {inst}\n\t")
self.generate_InstructionNode(inst, self.function_lines)
def generate_InstructionNode(self, node: InstructionNode, lines = None):
@@ -495,6 +501,8 @@ class X86_64Generator(Generator):
func = self.functions.get(node.parent.name) # the return statement will be a parent of a function node, so we can get the current scope using that
func_scope: SymbolTable = func["scope"]
if len(node.arguments) == 1:
if isinstance(node.arguments[0], IntNode):
lines.append(f"mov rax, {node.arguments[0].value}")
@@ -503,13 +511,26 @@ class X86_64Generator(Generator):
elif isinstance(node.arguments[0], FloatNode):
lines.append(f"mov xmm0, {node.arguments[0].value}")
#self.get_variable(lines, node.arguments[0].var_name, "rax")
elif isinstance(node.arguments[0], StringNode):
string_pointer = self.add_constant(node.arguments[0].value)
length = self.add_constant(f"equ $ - {string_pointer[1:-1]}", no_string=True)
lines.append(f"lea rax, [rel {string_pointer[1:-1]}]\n\t")
lines.append(f"lea rdx, {length}\n\t")
#self.push("rax", lines)
elif isinstance(node.arguments[0], VarRefNode):
self.get_variable(self.function_lines, node.arguments[0].var_name, "rax", scope=func["scope"])
var = func_scope.lookup(node.arguments[0].var_name)
if var["type"] == StringNode:
self.get_variable(self.function_lines, node.arguments[0].var_name, "rax", offset=0, scope=func["scope"])
self.get_variable(self.function_lines, node.arguments[0].var_name, "rdx", offset=-8, scope=func["scope"])
else:
self.get_variable(self.function_lines, node.arguments[0].var_name, "rax", scope=func["scope"])
else:
lines.append("mov rax, 0\n\t")
self.pop("rbp", lines)
for _ in range(self.stack_size): # TODO: THIS IS THE WORST FUCKING BULLSHIT EVER, KILL IT NOW!!!!
self.pop("rbp", lines)
lines.append("ret\n\t")
old_scope = self.current_var_scope
self.current_var_scope = self.current_var_scope.parent
@@ -517,7 +538,7 @@ class X86_64Generator(Generator):
elif node.instruction == "call":
self.clamp_instruction_args(node, 1, 2)
if not isinstance(node.arguments[0], FunctionCallNode):
traceback(self.code, "TypeError", "Argument 1 of call needs to be a function reference.")
traceback(self.code, "TypeError", "Argument 2 of call needs to be a function reference.")
func = self.functions.get(node.arguments[0].func_name, None)
if not func:
@@ -530,6 +551,7 @@ class X86_64Generator(Generator):
# stack alignment
if self.stack_size % 2 == 0:
lines.append("sub rsp, 8\n\t") # align the stack to 16 bytes
self.stack_size -= 1
for i, arg in enumerate(self.arg_list):
#self.create_variable(lines, func.args[i].name, arg, func.args[i].arg_type)
@@ -565,7 +587,9 @@ class X86_64Generator(Generator):
traceback(self.code, "CallError", "Functions with more than 6 args aren't supported yet, sorry...")
lines.append(f"call {node.arguments[0].func_name}\n\t")
self.lines.append(f"add rsp, {len(self.arg_list) * 8}")
if len(self.arg_list) > 0:
self.lines.append(f"add rsp, {len(self.arg_list) * 8}")
self.stack_size += len(self.arg_list)
self.arg_list.clear()
if len(node.arguments) == 2:
@@ -575,7 +599,8 @@ class X86_64Generator(Generator):
if self.current_var_scope.lookup(node.arguments[1].var_name):
self.change_variable(lines, node.arguments[1].var_name, "rax")
else:
self.create_variable(lines, node.arguments[1].var_name, "rax", self.ground_type_to_node(self.functions.get(node.arguments[0].func_name)["func"].return_type))
self.current_var_scope.define(node.arguments[1].var_name, {"stack_loc": "rax", "type": self.ground_type_to_node(func.return_type)})
#self.create_variable(lines, node.arguments[1].var_name, "rax", self.ground_type_to_node(self.functions.get(node.arguments[0].func_name)["func"].return_type))
elif node.instruction == "pusharg":
self.clamp_instruction_args(node, 1, 1)
#if type(node.arguments[0]) not in [IntNode]:

View File

@@ -140,5 +140,26 @@ class X86_64Optimizer(Optimizer):
Instruction("mov", ["y", "x"])
],
replace=[]
),
PeepholeRule(
match=[
Instruction("mov", ["x", "y"]),
Instruction("add", ["z", "x"])
],
replace=[
Instruction("add", ["z", "y"])
]
),
PeepholeRule(
match=[
Instruction("add", ["x", "0"])
],
replace=[]
),
PeepholeRule(
match=[Instruction("mov", ["x", "x"])],
replace=[]
)
]

BIN
out

Binary file not shown.

51
out.asm
View File

@@ -1,23 +1,52 @@
; ~~~ Auto generated by the GroundPY compiler for Linux x86_64 targets. ~~~
section .data
.LC0: db "test of returning strings INSIDE a variable!", 10, 0
.LC1: equ $ - .LC0
section .text
global _start
_start:
; FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=RootNode(statements=[..., InstructionNode(instruction='endfun', parent=..., arguments=[]), FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='int', name='function2'), InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), return_type='string', name='idk')
; InstructionNode(instruction='endfun', parent=RootNode(statements=[FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='string', name='idk'), ..., FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='int', name='function2'), InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[])
; FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=RootNode(statements=[FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='string', name='idk'), InstructionNode(instruction='endfun', parent=..., arguments=[]), ..., InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), return_type='int', name='function2')
; InstructionNode(instruction='endfun', parent=RootNode(statements=[FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='string', name='idk'), InstructionNode(instruction='endfun', parent=..., arguments=[]), FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='int', name='function2'), ..., InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[])
; InstructionNode(instruction='call', parent=RootNode(statements=[FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='string', name='idk'), InstructionNode(instruction='endfun', parent=..., arguments=[]), FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='int', name='function2'), InstructionNode(instruction='endfun', parent=..., arguments=[]), ..., InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[FunctionCall, VariablePointer])
sub rsp, 8
mov rdi, 2
mov rsi, 3
call add
add rsp, 16
push rax
mov rax, 60
mov rdi, [rsp + 0]
call idk
; InstructionNode(instruction='stdout', parent=RootNode(statements=[FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='string', name='idk'), InstructionNode(instruction='endfun', parent=..., arguments=[]), FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='int', name='function2'), InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), ..., InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[VariableReference])
mov rsi, rax
push rdi
mov rax, 1
mov rdi, 1
syscall
add:
pop rdi
; InstructionNode(instruction='call', parent=RootNode(statements=[FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='string', name='idk'), InstructionNode(instruction='endfun', parent=..., arguments=[]), FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='int', name='function2'), InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), ..., InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[FunctionCall, VariablePointer])
call function2
; InstructionNode(instruction='end', parent=RootNode(statements=[FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='string', name='idk'), InstructionNode(instruction='endfun', parent=..., arguments=[]), FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='int', name='function2'), InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), ...]), arguments=[VariableReference])
mov rax, 60
mov rdi, rax
syscall
idk:
push rbp
mov rbp, rsp
mov rax, rdi
mov rbx, rsi
add rax, rbx
; InstructionNode(instruction='set', parent=FunctionNode(args=[], statements=[..., InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=RootNode(statements=[..., InstructionNode(instruction='endfun', parent=..., arguments=[]), FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='int', name='function2'), InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), return_type='string', name='idk'), arguments=[VariablePointer, String])
lea rax, [.LC0]
push rax
push .LC1
; InstructionNode(instruction='return', parent=FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), ...], parent=RootNode(statements=[..., InstructionNode(instruction='endfun', parent=..., arguments=[]), FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='int', name='function2'), InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), return_type='string', name='idk'), arguments=[VariableReference])
mov rax, [rsp + 8]
mov rdx, [rsp + 0]
pop rbp
pop rbp
pop rbp
ret
function2:
push rbp
mov rbp, rsp
; InstructionNode(instruction='set', parent=FunctionNode(args=[], statements=[..., InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=RootNode(statements=[FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='string', name='idk'), InstructionNode(instruction='endfun', parent=..., arguments=[]), ..., InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), return_type='int', name='function2'), arguments=[VariablePointer, Int])
push 123
; InstructionNode(instruction='return', parent=FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Int]), ...], parent=RootNode(statements=[FunctionNode(args=[], statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, String]), InstructionNode(instruction='return', parent=..., arguments=[VariableReference])], parent=..., return_type='string', name='idk'), InstructionNode(instruction='endfun', parent=..., arguments=[]), ..., InstructionNode(instruction='endfun', parent=..., arguments=[]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='stdout', parent=..., arguments=[VariableReference]), InstructionNode(instruction='call', parent=..., arguments=[FunctionCall, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), return_type='int', name='function2'), arguments=[VariableReference])
mov rax, [rsp + 0]
pop rbp
pop rbp
ret

View File

@@ -1,9 +1,14 @@
fun -int !add -int &x -int &y
add $x $y &x
return $x
fun -string !idk
set &var "test of returning strings INSIDE a variable!\n"
return $var
endfun
pusharg 2
pusharg 3
call !add &var
end $var
fun -int !function2
set &intvar 123
return $intvar
endfun
call !idk &var
stdout $var
call !function2 &lol
end $lol