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]: