fixing quite a few bugs
This commit is contained in:
@@ -52,11 +52,11 @@ class Generator:
|
||||
|
||||
def add_constant(self, value: Any, no_string: bool = False):
|
||||
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}]"
|
||||
self.constants["LC" + str(self.constant_counter)] = {"value": value, "no_string": no_string}
|
||||
self.constants_reverse[value] = "LC" + str(self.constant_counter)
|
||||
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] = {
|
||||
|
@@ -32,6 +32,14 @@ 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
|
||||
waste = {
|
||||
"rax": "eax",
|
||||
"rdi": "edi",
|
||||
"rsi": "esi"
|
||||
}
|
||||
if waste[var_pos] == reg: # literally useless
|
||||
return
|
||||
|
||||
if offset == 0:
|
||||
lines.append(f"mov {reg}, {var_pos}\n\t")
|
||||
elif offset == -8:
|
||||
@@ -248,7 +256,9 @@ class X86_64Generator(Generator):
|
||||
|
||||
for inst in node.statements:
|
||||
#self.function_lines.append(f"; {inst}\n\t")
|
||||
self.generate_InstructionNode(inst, self.function_lines)
|
||||
node_type = str(type(inst))[19:-2]
|
||||
getattr(self, f"generate_{node_type}")(inst, self.function_lines)
|
||||
#self.generate_InstructionNode(inst, self.function_lines)
|
||||
|
||||
def generate_InstructionNode(self, node: InstructionNode, lines = None):
|
||||
lines = lines or self.lines
|
||||
@@ -438,6 +448,7 @@ class X86_64Generator(Generator):
|
||||
if node.arguments[0].value != 0:
|
||||
lines.append(f"jmp .{node.arguments[1].name}\n\t")
|
||||
elif isinstance(node.arguments[0], VarRefNode):
|
||||
self.current_var_scope.table[node.arguments[0].var_name]["used"] = True # putting a variable in an if statement means we're accessing it
|
||||
self.get_variable(lines, node.arguments[0].var_name, "eax")
|
||||
lines.append(f"test eax, eax\n\t")
|
||||
lines.append(f"jnz .{node.arguments[1].name}\n\t")
|
||||
@@ -491,7 +502,7 @@ class X86_64Generator(Generator):
|
||||
"lesser": "setl"
|
||||
}
|
||||
lines.append(f"{instructions[node.instruction]} al\n\t")
|
||||
lines.append("movzx rax, al\n\t")
|
||||
lines.append("movzx eax, al\n\t")
|
||||
|
||||
|
||||
var_name = node.arguments[2].var_name
|
||||
@@ -513,7 +524,7 @@ class X86_64Generator(Generator):
|
||||
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)}")
|
||||
lines.append(f"mov eax, {int(node.arguments[0].value)}")
|
||||
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")
|
||||
@@ -526,10 +537,11 @@ class X86_64Generator(Generator):
|
||||
#self.push("rax", lines)
|
||||
elif isinstance(node.arguments[0], VarRefNode):
|
||||
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"])
|
||||
elif var["type"] == BoolNode:
|
||||
self.get_variable(self.function_lines, node.arguments[0].var_name, "eax", scope=func["scope"])
|
||||
else:
|
||||
self.get_variable(self.function_lines, node.arguments[0].var_name, "rax", scope=func["scope"])
|
||||
else:
|
||||
@@ -644,7 +656,7 @@ class X86_64Generator(Generator):
|
||||
f.write("section .data\n")
|
||||
for name, const in self.constants.items():
|
||||
value = const["value"]
|
||||
f.write("." + name + ": ")
|
||||
f.write(name + ": ")
|
||||
value_type = type(value)
|
||||
if value_type == str:
|
||||
if not const["no_string"]:
|
||||
|
@@ -128,6 +128,9 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
|
||||
elif token.type == TokenType.LABEL_DECLERATION:
|
||||
if current_node:
|
||||
scope.statements.append(current_node)
|
||||
if current_node_type == "func":
|
||||
scope = current_node
|
||||
current_node_type = None
|
||||
current_node = None
|
||||
scope.statements.append(LabelDecNode(token.value))
|
||||
|
||||
|
@@ -161,5 +161,5 @@ class X86_64Optimizer(Optimizer):
|
||||
PeepholeRule(
|
||||
match=[Instruction("mov", ["x", "x"])],
|
||||
replace=[]
|
||||
)
|
||||
),
|
||||
]
|
38
out.asm
38
out.asm
@@ -1,19 +1,47 @@
|
||||
; ~~~ Auto generated by the GroundPY compiler for Linux x86_64 targets. ~~~
|
||||
|
||||
section .data
|
||||
LC0: db "yep!", 10, 0
|
||||
LC1: equ $ - LC0
|
||||
LC2: db "nope...", 10, 0
|
||||
LC3: equ $ - LC2
|
||||
section .text
|
||||
global _start
|
||||
_start:
|
||||
mov rdi, 1
|
||||
mov rsi, 4
|
||||
call add
|
||||
mov rdi, rax
|
||||
mov rsi, 3
|
||||
call greater
|
||||
test eax, eax
|
||||
jnz .yes
|
||||
jmp .no
|
||||
.yes:
|
||||
mov rsi, LC0
|
||||
mov rdx, LC1
|
||||
push rdi
|
||||
mov rax, 1
|
||||
mov rdi, 1
|
||||
syscall
|
||||
pop rdi
|
||||
mov rdi, 0
|
||||
mov rax, 60
|
||||
syscall
|
||||
add:
|
||||
.no:
|
||||
mov rsi, LC2
|
||||
mov rdx, LC3
|
||||
push rdi
|
||||
mov rax, 1
|
||||
mov rdi, 1
|
||||
syscall
|
||||
pop rdi
|
||||
mov rdi, 0
|
||||
mov rax, 60
|
||||
syscall
|
||||
greater:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
mov rax, rdi
|
||||
add rax, rsi
|
||||
cmp rax, rsi
|
||||
setg al
|
||||
movzx eax, al
|
||||
pop rbp
|
||||
ret
|
||||
|
20
test2.grnd
20
test2.grnd
@@ -1,9 +1,17 @@
|
||||
fun -int !add -int &a -int &b
|
||||
add $a $b &a
|
||||
return $a
|
||||
fun -bool !greater -int &x -int &y
|
||||
greater $x $y &x
|
||||
return $x
|
||||
endfun
|
||||
|
||||
pusharg 1
|
||||
pusharg 4
|
||||
call !add &result
|
||||
end $result
|
||||
pusharg 3
|
||||
call !greater &bigger
|
||||
|
||||
if $bigger %yes
|
||||
jump %no
|
||||
@yes
|
||||
stdout "yep!\n"
|
||||
end 0
|
||||
@no
|
||||
stdout "nope...\n"
|
||||
end 0
|
Reference in New Issue
Block a user