functions basically work now, but they're extremely inneficient
This commit is contained in:
19
error.py
19
error.py
@@ -23,3 +23,22 @@ def traceback(code: str, error_type: str, error_message: str, line: Union[int, N
|
|||||||
|
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
def warning(code: str, warning_msg: str, note: str = None, line: Union[int, None] = None, start_column: Union[int, None] = None, end_column: Union[int, None] = None):
|
||||||
|
if line != None:
|
||||||
|
console.print(f"[bold cyan]warning:[/] {warning_msg}\n")
|
||||||
|
lines = code.split("\n")[line-1:line+2]
|
||||||
|
|
||||||
|
console.print(f"{line } > " + lines[0], highlight=False)
|
||||||
|
if start_column != None and end_column != None:
|
||||||
|
console.print(" " + (" " * start_column) + "[bold red]" + ("^" * (end_column-start_column+1)))
|
||||||
|
|
||||||
|
try:
|
||||||
|
console.print(f"{line+1} " + lines[1], highlight=False)
|
||||||
|
console.print(f"{line+2} " + lines[2], highlight=False)
|
||||||
|
console.print(" ...", highlight=False)
|
||||||
|
except IndexError: # the file is less than 3 lines i guess
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
console.print(f"[bold cyan]warning:[/] {warning_msg}")
|
||||||
|
if note != None:
|
||||||
|
console.print(f"[bold]note:[/] {note}")
|
@@ -1,6 +1,7 @@
|
|||||||
from ground_ast import RootNode
|
from ground_ast import RootNode
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from ground_ast import *
|
from ground_ast import *
|
||||||
|
from error import warning
|
||||||
|
|
||||||
|
|
||||||
class SymbolTable:
|
class SymbolTable:
|
||||||
@@ -74,7 +75,7 @@ class Generator:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def generate_node(self, node):
|
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]
|
node_type = str(type(node))[19:-2]
|
||||||
if not hasattr(self, f"generate_{node_type}"):
|
if not hasattr(self, f"generate_{node_type}"):
|
||||||
raise NotImplementedError(f"Generator has no generate method for {node_type}.")
|
raise NotImplementedError(f"Generator has no generate method for {node_type}.")
|
||||||
@@ -83,6 +84,9 @@ class Generator:
|
|||||||
def generate(self):
|
def generate(self):
|
||||||
for statement in self.ast.statements:
|
for statement in self.ast.statements:
|
||||||
self.generate_node(statement)
|
self.generate_node(statement)
|
||||||
|
for name, var in self.global_scope.table.items():
|
||||||
|
if not var["used"]:
|
||||||
|
warning(self.code, f"warning: \"{name}\" was defined but never used.")
|
||||||
|
|
||||||
def write(self):
|
def write(self):
|
||||||
with open(self.output_path + ".asm", "w") as f:
|
with open(self.output_path + ".asm", "w") as f:
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
from generators.generator import Generator, SymbolTable
|
from generators.generator import Generator, SymbolTable
|
||||||
from ground_ast import *
|
from ground_ast import *
|
||||||
from error import traceback
|
from error import traceback, warning
|
||||||
from optimizers.x86_64 import X86_64Optimizer
|
from optimizers.x86_64 import X86_64Optimizer
|
||||||
|
|
||||||
class X86_64Generator(Generator):
|
class X86_64Generator(Generator):
|
||||||
@@ -74,6 +74,8 @@ class X86_64Generator(Generator):
|
|||||||
except TypeError as e: # variable doesnt exist
|
except TypeError as e: # variable doesnt exist
|
||||||
traceback(self.code, "NameError", f"\"{var_name}\" is not defined.")
|
traceback(self.code, "NameError", f"\"{var_name}\" is not defined.")
|
||||||
|
|
||||||
|
scope.table[var_name]["used"] = True
|
||||||
|
|
||||||
return var["type"]
|
return var["type"]
|
||||||
|
|
||||||
def get_var_pos(self, var_name: str, scope: SymbolTable = None):
|
def get_var_pos(self, var_name: str, scope: SymbolTable = None):
|
||||||
@@ -131,12 +133,14 @@ class X86_64Generator(Generator):
|
|||||||
self.stack_size += 1
|
self.stack_size += 1
|
||||||
else:
|
else:
|
||||||
self.push(starting_value, lines)
|
self.push(starting_value, lines)
|
||||||
scope.define(var_name, {"stack_loc": stack_location, "type": var_type})
|
scope.define(var_name, {"stack_loc": stack_location, "type": var_type, "used": False})
|
||||||
|
|
||||||
def change_variable(self, lines, var_name: str, new_value, scope: SymbolTable = None):
|
def change_variable(self, lines, var_name: str, new_value, scope: SymbolTable = None):
|
||||||
scope = scope or self.current_var_scope
|
scope = scope or self.current_var_scope
|
||||||
var_pos = self.get_var_pos(var_name, scope)
|
var_pos = self.get_var_pos(var_name, scope)
|
||||||
|
|
||||||
|
old_var_type = scope.table[var_name]["type"]
|
||||||
|
|
||||||
if isinstance(var_pos, str):
|
if isinstance(var_pos, str):
|
||||||
if type(new_value) == IntNode: # we're changing a variable to a number
|
if type(new_value) == IntNode: # we're changing a variable to a number
|
||||||
#lines.append(f"mov QWORD [rsp + {var_pos}], {new_value.value}\n\t")
|
#lines.append(f"mov QWORD [rsp + {var_pos}], {new_value.value}\n\t")
|
||||||
@@ -213,6 +217,8 @@ class X86_64Generator(Generator):
|
|||||||
elif type(new_value) == str: # we're changing a variable to the value of a register
|
elif type(new_value) == str: # we're changing a variable to the value of a register
|
||||||
lines.append(f"mov QWORD [rsp + {var_pos}], {new_value}\n\t")
|
lines.append(f"mov QWORD [rsp + {var_pos}], {new_value}\n\t")
|
||||||
scope.table[var_name]["type"] = IntNode
|
scope.table[var_name]["type"] = IntNode
|
||||||
|
if scope.table[var_name]["type"] != old_var_type:
|
||||||
|
warning(self.code, f"Changing the type of \"{var_name}\" at runtime is considered bad practice.")
|
||||||
|
|
||||||
def generate_LabelDecNode(self, node: LabelDecNode, lines):
|
def generate_LabelDecNode(self, node: LabelDecNode, lines):
|
||||||
self.labels.append(node.name)
|
self.labels.append(node.name)
|
||||||
@@ -238,10 +244,10 @@ class X86_64Generator(Generator):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
traceback(self.code, "CallError", "Functions with more than 6 args aren't supported yet, sorry...")
|
traceback(self.code, "CallError", "Functions with more than 6 args aren't supported yet, sorry...")
|
||||||
|
|
||||||
self.current_var_scope.define(arg.name, {"stack_loc": stack_loc, "type": self.ground_type_to_node(arg.arg_type)})
|
self.current_var_scope.define(arg.name, {"stack_loc": stack_loc, "type": self.ground_type_to_node(arg.arg_type), "used": False})
|
||||||
|
|
||||||
for inst in node.statements:
|
for inst in node.statements:
|
||||||
self.function_lines.append(f"; {inst}\n\t")
|
#self.function_lines.append(f"; {inst}\n\t")
|
||||||
self.generate_InstructionNode(inst, self.function_lines)
|
self.generate_InstructionNode(inst, self.function_lines)
|
||||||
|
|
||||||
def generate_InstructionNode(self, node: InstructionNode, lines = None):
|
def generate_InstructionNode(self, node: InstructionNode, lines = None):
|
||||||
@@ -253,7 +259,6 @@ class X86_64Generator(Generator):
|
|||||||
if not type(node.arguments[0]) in [IntNode, VarRefNode]: # example: "end true"
|
if not type(node.arguments[0]) in [IntNode, VarRefNode]: # example: "end true"
|
||||||
traceback(self.code, "TypeError", f"end expects an integer, not {node.arguments[0]}")
|
traceback(self.code, "TypeError", f"end expects an integer, not {node.arguments[0]}")
|
||||||
|
|
||||||
lines.append("mov rax, 60\n\t")
|
|
||||||
if type(node.arguments[0]) in [IntNode,BoolNode]:
|
if type(node.arguments[0]) in [IntNode,BoolNode]:
|
||||||
lines.append("mov rdi, " + str(node.arguments[0].value) + "\n\t")
|
lines.append("mov rdi, " + str(node.arguments[0].value) + "\n\t")
|
||||||
elif isinstance(node.arguments[0], VarRefNode):
|
elif isinstance(node.arguments[0], VarRefNode):
|
||||||
@@ -263,7 +268,8 @@ class X86_64Generator(Generator):
|
|||||||
else:
|
else:
|
||||||
if var_type not in [IntNode,BoolNode]:
|
if var_type not in [IntNode,BoolNode]:
|
||||||
traceback(self.code, "TypeError", f"end expects an integer, not \"{var_type}\"")
|
traceback(self.code, "TypeError", f"end expects an integer, not \"{var_type}\"")
|
||||||
#lines.append("mov rdi, " + str(self.get_variable(lines, node.arguments[0].var_name)) + "\n\t")
|
|
||||||
|
lines.append("mov rax, 60\n\t")
|
||||||
lines.append("syscall\n\t")
|
lines.append("syscall\n\t")
|
||||||
|
|
||||||
### VARIABLE INSTRUCTIONS ###
|
### VARIABLE INSTRUCTIONS ###
|
||||||
@@ -516,7 +522,7 @@ class X86_64Generator(Generator):
|
|||||||
length = self.add_constant(f"equ $ - {string_pointer[1:-1]}", no_string=True)
|
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 rax, [rel {string_pointer[1:-1]}]\n\t")
|
||||||
lines.append(f"lea rdx, {length}\n\t")
|
lines.append(f"mov rdx, {length[1:-1]}\n\t")
|
||||||
#self.push("rax", lines)
|
#self.push("rax", lines)
|
||||||
elif isinstance(node.arguments[0], VarRefNode):
|
elif isinstance(node.arguments[0], VarRefNode):
|
||||||
var = func_scope.lookup(node.arguments[0].var_name)
|
var = func_scope.lookup(node.arguments[0].var_name)
|
||||||
@@ -529,9 +535,26 @@ class X86_64Generator(Generator):
|
|||||||
else:
|
else:
|
||||||
lines.append("mov rax, 0\n\t")
|
lines.append("mov rax, 0\n\t")
|
||||||
|
|
||||||
for _ in range(self.stack_size): # TODO: THIS IS THE WORST FUCKING BULLSHIT EVER, KILL IT NOW!!!!
|
size = 0
|
||||||
self.pop("rbp", lines)
|
for name, var in self.current_var_scope.table.items():
|
||||||
|
if type(var["stack_loc"]) == str:
|
||||||
|
continue # its in a register, we dont need to free up the stack
|
||||||
|
|
||||||
|
if var["type"] == StringNode:
|
||||||
|
size += 2
|
||||||
|
else:
|
||||||
|
size += 1
|
||||||
|
|
||||||
|
lines.append(f"add rsp, {8 * (size)}\n\t")
|
||||||
|
self.stack_size -= size - 1
|
||||||
|
lines.append("pop rbp")
|
||||||
lines.append("ret\n\t")
|
lines.append("ret\n\t")
|
||||||
|
|
||||||
|
# warn about unused variables
|
||||||
|
for name, var in self.current_var_scope.table.items():
|
||||||
|
if not var["used"]:
|
||||||
|
warning(self.code, f"\"{name}\" was defined but never used.")
|
||||||
|
|
||||||
old_scope = self.current_var_scope
|
old_scope = self.current_var_scope
|
||||||
self.current_var_scope = self.current_var_scope.parent
|
self.current_var_scope = self.current_var_scope.parent
|
||||||
del old_scope
|
del old_scope
|
||||||
@@ -549,7 +572,7 @@ class X86_64Generator(Generator):
|
|||||||
traceback(self.code, "TypeError", f"Function \"{node.arguments[0].func_name}\" takes {len(func.args)} arguments, but got {len(self.arg_list)}")
|
traceback(self.code, "TypeError", f"Function \"{node.arguments[0].func_name}\" takes {len(func.args)} arguments, but got {len(self.arg_list)}")
|
||||||
|
|
||||||
# stack alignment
|
# stack alignment
|
||||||
if self.stack_size % 2 == 0:
|
if self.stack_size % 2 != 0:
|
||||||
lines.append("sub rsp, 8\n\t") # align the stack to 16 bytes
|
lines.append("sub rsp, 8\n\t") # align the stack to 16 bytes
|
||||||
self.stack_size -= 1
|
self.stack_size -= 1
|
||||||
|
|
||||||
@@ -587,8 +610,8 @@ class X86_64Generator(Generator):
|
|||||||
traceback(self.code, "CallError", "Functions with more than 6 args aren't supported yet, sorry...")
|
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")
|
lines.append(f"call {node.arguments[0].func_name}\n\t")
|
||||||
|
|
||||||
if len(self.arg_list) > 0:
|
#if len(self.arg_list) > 0:
|
||||||
self.lines.append(f"add rsp, {len(self.arg_list) * 8}")
|
# lines.append(f"add rsp, {len(self.arg_list) * 8}")
|
||||||
self.stack_size += len(self.arg_list)
|
self.stack_size += len(self.arg_list)
|
||||||
self.arg_list.clear()
|
self.arg_list.clear()
|
||||||
|
|
||||||
@@ -599,7 +622,7 @@ class X86_64Generator(Generator):
|
|||||||
if self.current_var_scope.lookup(node.arguments[1].var_name):
|
if self.current_var_scope.lookup(node.arguments[1].var_name):
|
||||||
self.change_variable(lines, node.arguments[1].var_name, "rax")
|
self.change_variable(lines, node.arguments[1].var_name, "rax")
|
||||||
else:
|
else:
|
||||||
self.current_var_scope.define(node.arguments[1].var_name, {"stack_loc": "rax", "type": self.ground_type_to_node(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), "used": False})
|
||||||
#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.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":
|
elif node.instruction == "pusharg":
|
||||||
self.clamp_instruction_args(node, 1, 1)
|
self.clamp_instruction_args(node, 1, 1)
|
||||||
|
45
out.asm
45
out.asm
@@ -1,52 +1,19 @@
|
|||||||
; ~~~ Auto generated by the GroundPY compiler for Linux x86_64 targets. ~~~
|
; ~~~ Auto generated by the GroundPY compiler for Linux x86_64 targets. ~~~
|
||||||
|
|
||||||
section .data
|
section .data
|
||||||
.LC0: db "test of returning strings INSIDE a variable!", 10, 0
|
|
||||||
.LC1: equ $ - .LC0
|
|
||||||
section .text
|
section .text
|
||||||
global _start
|
global _start
|
||||||
_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
|
|
||||||
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
|
mov rdi, 1
|
||||||
syscall
|
mov rsi, 4
|
||||||
pop rdi
|
call add
|
||||||
; 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
|
mov rdi, rax
|
||||||
|
mov rax, 60
|
||||||
syscall
|
syscall
|
||||||
idk:
|
add:
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
; 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])
|
mov rax, rdi
|
||||||
lea rax, [.LC0]
|
add rax, rsi
|
||||||
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
|
pop rbp
|
||||||
ret
|
ret
|
||||||
|
19
test2.grnd
19
test2.grnd
@@ -1,14 +1,9 @@
|
|||||||
fun -string !idk
|
fun -int !add -int &a -int &b
|
||||||
set &var "test of returning strings INSIDE a variable!\n"
|
add $a $b &a
|
||||||
return $var
|
return $a
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
fun -int !function2
|
pusharg 1
|
||||||
set &intvar 123
|
pusharg 4
|
||||||
return $intvar
|
call !add &result
|
||||||
endfun
|
end $result
|
||||||
|
|
||||||
call !idk &var
|
|
||||||
stdout $var
|
|
||||||
call !function2 &lol
|
|
||||||
end $lol
|
|
Reference in New Issue
Block a user