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):
|
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}]"
|
||||||
self.constants["LC" + str(self.constant_counter)] = {"value": value, "no_string": no_string}
|
self.constants["LC" + str(self.constant_counter)] = {"value": value, "no_string": no_string}
|
||||||
self.constants_reverse[value] = "LC" + str(self.constant_counter)
|
self.constants_reverse[value] = "LC" + str(self.constant_counter)
|
||||||
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):
|
def add_function(self, node: FunctionNode):
|
||||||
self.functions[node.name] = {
|
self.functions[node.name] = {
|
||||||
|
@@ -32,6 +32,14 @@ class X86_64Generator(Generator):
|
|||||||
var_pos = self.get_var_pos(var_name, scope)
|
var_pos = self.get_var_pos(var_name, scope)
|
||||||
|
|
||||||
if isinstance(var_pos, str): # in a reg, not on the stack
|
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:
|
if offset == 0:
|
||||||
lines.append(f"mov {reg}, {var_pos}\n\t")
|
lines.append(f"mov {reg}, {var_pos}\n\t")
|
||||||
elif offset == -8:
|
elif offset == -8:
|
||||||
@@ -248,7 +256,9 @@ class X86_64Generator(Generator):
|
|||||||
|
|
||||||
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)
|
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):
|
def generate_InstructionNode(self, node: InstructionNode, lines = None):
|
||||||
lines = lines or self.lines
|
lines = lines or self.lines
|
||||||
@@ -438,6 +448,7 @@ class X86_64Generator(Generator):
|
|||||||
if node.arguments[0].value != 0:
|
if node.arguments[0].value != 0:
|
||||||
lines.append(f"jmp .{node.arguments[1].name}\n\t")
|
lines.append(f"jmp .{node.arguments[1].name}\n\t")
|
||||||
elif isinstance(node.arguments[0], VarRefNode):
|
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")
|
self.get_variable(lines, node.arguments[0].var_name, "eax")
|
||||||
lines.append(f"test eax, eax\n\t")
|
lines.append(f"test eax, eax\n\t")
|
||||||
lines.append(f"jnz .{node.arguments[1].name}\n\t")
|
lines.append(f"jnz .{node.arguments[1].name}\n\t")
|
||||||
@@ -491,7 +502,7 @@ class X86_64Generator(Generator):
|
|||||||
"lesser": "setl"
|
"lesser": "setl"
|
||||||
}
|
}
|
||||||
lines.append(f"{instructions[node.instruction]} al\n\t")
|
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
|
var_name = node.arguments[2].var_name
|
||||||
@@ -513,7 +524,7 @@ class X86_64Generator(Generator):
|
|||||||
if isinstance(node.arguments[0], IntNode):
|
if isinstance(node.arguments[0], IntNode):
|
||||||
lines.append(f"mov rax, {node.arguments[0].value}")
|
lines.append(f"mov rax, {node.arguments[0].value}")
|
||||||
elif isinstance(node.arguments[0], BoolNode):
|
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):
|
elif isinstance(node.arguments[0], FloatNode):
|
||||||
lines.append(f"mov xmm0, {node.arguments[0].value}")
|
lines.append(f"mov xmm0, {node.arguments[0].value}")
|
||||||
#self.get_variable(lines, node.arguments[0].var_name, "rax")
|
#self.get_variable(lines, node.arguments[0].var_name, "rax")
|
||||||
@@ -526,10 +537,11 @@ class X86_64Generator(Generator):
|
|||||||
#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)
|
||||||
|
|
||||||
if var["type"] == StringNode:
|
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, "rax", offset=0, scope=func["scope"])
|
||||||
self.get_variable(self.function_lines, node.arguments[0].var_name, "rdx", offset=-8, 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:
|
else:
|
||||||
self.get_variable(self.function_lines, node.arguments[0].var_name, "rax", scope=func["scope"])
|
self.get_variable(self.function_lines, node.arguments[0].var_name, "rax", scope=func["scope"])
|
||||||
else:
|
else:
|
||||||
@@ -644,7 +656,7 @@ class X86_64Generator(Generator):
|
|||||||
f.write("section .data\n")
|
f.write("section .data\n")
|
||||||
for name, const in self.constants.items():
|
for name, const in self.constants.items():
|
||||||
value = const["value"]
|
value = const["value"]
|
||||||
f.write("." + name + ": ")
|
f.write(name + ": ")
|
||||||
value_type = type(value)
|
value_type = type(value)
|
||||||
if value_type == str:
|
if value_type == str:
|
||||||
if not const["no_string"]:
|
if not const["no_string"]:
|
||||||
|
@@ -128,6 +128,9 @@ def generate_ast(tokens: list[Token], code: str) -> RootNode:
|
|||||||
elif token.type == TokenType.LABEL_DECLERATION:
|
elif token.type == TokenType.LABEL_DECLERATION:
|
||||||
if current_node:
|
if current_node:
|
||||||
scope.statements.append(current_node)
|
scope.statements.append(current_node)
|
||||||
|
if current_node_type == "func":
|
||||||
|
scope = current_node
|
||||||
|
current_node_type = None
|
||||||
current_node = None
|
current_node = None
|
||||||
scope.statements.append(LabelDecNode(token.value))
|
scope.statements.append(LabelDecNode(token.value))
|
||||||
|
|
||||||
|
@@ -161,5 +161,5 @@ class X86_64Optimizer(Optimizer):
|
|||||||
PeepholeRule(
|
PeepholeRule(
|
||||||
match=[Instruction("mov", ["x", "x"])],
|
match=[Instruction("mov", ["x", "x"])],
|
||||||
replace=[]
|
replace=[]
|
||||||
)
|
),
|
||||||
]
|
]
|
38
out.asm
38
out.asm
@@ -1,19 +1,47 @@
|
|||||||
; ~~~ 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 "yep!", 10, 0
|
||||||
|
LC1: equ $ - LC0
|
||||||
|
LC2: db "nope...", 10, 0
|
||||||
|
LC3: equ $ - LC2
|
||||||
section .text
|
section .text
|
||||||
global _start
|
global _start
|
||||||
_start:
|
_start:
|
||||||
mov rdi, 1
|
mov rdi, 1
|
||||||
mov rsi, 4
|
mov rsi, 3
|
||||||
call add
|
call greater
|
||||||
mov rdi, rax
|
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
|
mov rax, 60
|
||||||
syscall
|
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
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
mov rax, rdi
|
mov rax, rdi
|
||||||
add rax, rsi
|
cmp rax, rsi
|
||||||
|
setg al
|
||||||
|
movzx eax, al
|
||||||
pop rbp
|
pop rbp
|
||||||
ret
|
ret
|
||||||
|
20
test2.grnd
20
test2.grnd
@@ -1,9 +1,17 @@
|
|||||||
fun -int !add -int &a -int &b
|
fun -bool !greater -int &x -int &y
|
||||||
add $a $b &a
|
greater $x $y &x
|
||||||
return $a
|
return $x
|
||||||
endfun
|
endfun
|
||||||
|
|
||||||
pusharg 1
|
pusharg 1
|
||||||
pusharg 4
|
pusharg 3
|
||||||
call !add &result
|
call !greater &bigger
|
||||||
end $result
|
|
||||||
|
if $bigger %yes
|
||||||
|
jump %no
|
||||||
|
@yes
|
||||||
|
stdout "yep!\n"
|
||||||
|
end 0
|
||||||
|
@no
|
||||||
|
stdout "nope...\n"
|
||||||
|
end 0
|
Reference in New Issue
Block a user