WE CAN RETURN VALUES FROM FUNCTIONS LESS GOOO

This commit is contained in:
SpookyDervish
2025-09-10 07:54:11 +10:00
parent 59bef834c4
commit 3103d17026
5 changed files with 46 additions and 15 deletions

View File

@@ -11,10 +11,24 @@ class Generator:
self.output_path = output_path self.output_path = output_path
self.variables = {} self.variables = {}
self.constants = {} self.constants = {}
self.structs = {}
self.functions: dict[str, FunctionNode] = {}
self.labels = [] self.labels = []
self.constants_reverse = {} self.constants_reverse = {}
self.constant_counter = 0 self.constant_counter = 0
def ground_type_to_node(self, ground_type: str):
if ground_type == "string":
return StringNode
elif ground_type == "int":
return IntNode
elif ground_type == "float":
return FloatNode
elif ground_type == "bool":
return BoolNode
else:
return ground_type
def add_constant(self, value: Any, no_string: bool = False): def add_constant(self, value: Any, no_string: bool = False):
existing_constant_name = self.constants_reverse.get(value, None) existing_constant_name = self.constants_reverse.get(value, None)
if existing_constant_name != None: return f"[.{existing_constant_name}]" if existing_constant_name != None: return f"[.{existing_constant_name}]"
@@ -23,6 +37,9 @@ class Generator:
self.constant_counter += 1 self.constant_counter += 1
return "[.LC" + str(self.constant_counter-1) + "]" return "[.LC" + str(self.constant_counter-1) + "]"
def add_function(self, node: FunctionNode):
self.functions[node.name] = node
def clamp_instruction_args(self, instruction: InstructionNode, min_args: int, max_args: int): def clamp_instruction_args(self, instruction: InstructionNode, min_args: int, max_args: int):
if len(instruction.arguments) < min_args: if len(instruction.arguments) < min_args:
traceback(self.code, "TypeError", f"{instruction.instruction} expects at least {min_args} arguments.") traceback(self.code, "TypeError", f"{instruction.instruction} expects at least {min_args} arguments.")

View File

@@ -167,6 +167,7 @@ class X86_64Generator(Generator):
self.function_lines.append(node.name + ":") self.function_lines.append(node.name + ":")
for inst in node.statements: for inst in node.statements:
self.generate_InstructionNode(inst, self.function_lines) self.generate_InstructionNode(inst, self.function_lines)
self.add_function(node)
def generate_InstructionNode(self, node: InstructionNode, lines = None): def generate_InstructionNode(self, node: InstructionNode, lines = None):
if lines == None: if lines == None:
@@ -420,14 +421,34 @@ class X86_64Generator(Generator):
elif node.instruction == "endfun": elif node.instruction == "endfun":
return return
elif node.instruction == "return": elif node.instruction == "return":
self.clamp_instruction_args(node, 0, 1)
if len(node.arguments) == 1:
if isinstance(node.arguments[0], IntNode):
lines.append(f"mov rax, {node.arguments[0].value}")
elif isinstance(node.arguments[0], BoolNode):
lines.append(f"mov rax, {int(node.arguments[0].value)}")
elif isinstance(node.arguments[0], FloatNode):
lines.append(f"mov xmm0, {node.arguments[0].value}")
else:
lines.append("mov rax, 0\n\t")
lines.append("ret\n\t") lines.append("ret\n\t")
elif node.instruction == "call": elif node.instruction == "call":
self.clamp_instruction_args(node, 1, 1) self.clamp_instruction_args(node, 1, 2)
if not isinstance(node.arguments[0], FunctionCallNode): 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 1 of call needs to be a function reference.")
if not isinstance(node.arguments[1], VarPointerNode):
traceback(self.code, "TypeError", "Argument 1 of call needs to be a variable pointer.")
lines.append(f"call {node.arguments[0].func_name}\n\t") lines.append(f"call {node.arguments[0].func_name}\n\t")
if len(node.arguments) == 2:
if self.variables.get(node.arguments[1].var_name, None):
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).return_type))
else: else:
raise NotImplementedError(f"A generate method hasn't been made for the \"{node.instruction}\" instruction.") raise NotImplementedError(f"A generate method hasn't been made for the \"{node.instruction}\" instruction.")

BIN
out

Binary file not shown.

10
out.asm
View File

@@ -7,14 +7,9 @@ section .text
global _start global _start
_start: _start:
call test call test
push 2 push rax
push 3
mov rax, [rsp + 8]
mov rbx, [rsp + 0]
add rax, rbx
mov QWORD [rsp + 8], rax
mov rax, 60 mov rax, 60
mov rdi, [rsp + 8] mov rdi, [rsp + 0]
syscall syscall
test: test:
mov rsi, .LC0 mov rsi, .LC0
@@ -22,4 +17,5 @@ mov rdx, .LC1
mov rax, 1 mov rax, 1
mov rdi, 1 mov rdi, 1
syscall syscall
mov rax, 123
ret ret

View File

@@ -1,10 +1,7 @@
fun -string !test fun -int !test
stdout "this was called by a function!!!!\n" stdout "this was called by a function!!!!\n"
return return 123
endfun endfun
call !test call !test &var
set &x 2 end $var
set &y 3
add $x $y &x
end $x