WE CAN RETURN VALUES FROM FUNCTIONS LESS GOOO
This commit is contained in:
@@ -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.")
|
||||||
|
@@ -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.")
|
||||||
|
|
||||||
|
10
out.asm
10
out.asm
@@ -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
|
||||||
|
11
test2.grnd
11
test2.grnd
@@ -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
|
|
Reference in New Issue
Block a user