diff --git a/generators/x86_64.py b/generators/x86_64.py index 894ea4d..8e47d02 100644 --- a/generators/x86_64.py +++ b/generators/x86_64.py @@ -29,6 +29,17 @@ class X86_64Generator(Generator): ) self.pop(reg) + def change_variable(self, var_name: str, new_value): + var_pos = (self.stack_size - self.variables.get(var_name)['stack_loc'] - 1) * 8 + + if type(new_value) == NumberNode: # we're changing a variable to a number + self.lines.append(f"mov rax, {new_value.value}\n\t") + self.lines.append(f"mov QWORD [rsp + {var_pos}], rax\n\t") + + elif type(new_value) == VarRefNode: # we're changing a variable to the value of another variable + self.get_variable(new_value.var_name, "rax") + self.lines.append(f"mov QWORD [rsp + {var_pos}], rax\n\t") + def generate_InstructionNode(self, node: InstructionNode): if node.instruction == "end": if len(node.arguments) == 0: # example: "end" @@ -53,13 +64,19 @@ class X86_64Generator(Generator): traceback(self.code, "TypeError", "set expects only 2 arguments.") if not isinstance(node.arguments[0], VarPointerNode): traceback(self.code, "TypeError", f"the first argument of set should be a variable pointer, not \"{type(node.arguments[0])}\"") - if type(node.arguments[1]) not in [NumberNode]: + if type(node.arguments[1]) not in [NumberNode, VarRefNode]: traceback(self.code, "TypeError", f"variables can't be of type \"{type(node.arguments[1])}\"") - self.variables[node.arguments[0].var_name] = {"stack_loc": self.stack_size} - if type(node.arguments[1]) == NumberNode: - self.lines.append(f"mov rax, {node.arguments[1].value}\n\t") - self.push("rax") + variable_exists = self.variables.get(node.arguments[0].var_name, None) != None + + if not variable_exists: # create a new variable + self.variables[node.arguments[0].var_name] = {"stack_loc": (self.stack_size), "type": type(node.arguments[1])} + if type(node.arguments[1]) == NumberNode: + self.lines.append(f"mov rax, {node.arguments[1].value}\n\t") + self.push("rax") + else: # modify the existing one + self.change_variable(node.arguments[0].var_name, node.arguments[1]) + else: self.lines.append("; FUCK\n\t") diff --git a/out b/out index e5db3ec..71a7881 100644 Binary files a/out and b/out differ diff --git a/out.asm b/out.asm index 2b25660..843d179 100644 --- a/out.asm +++ b/out.asm @@ -1,15 +1,16 @@ global _start _start: - ; InstructionNode(instruction='set', parent=RootNode(statements=[..., InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='add', parent=..., arguments=[VariableReference, Number, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[VariablePointer, Number]) + ; InstructionNode(instruction='set', parent=RootNode(statements=[..., InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[VariablePointer, Number]) mov rax, 66 push rax - ; InstructionNode(instruction='set', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), ..., InstructionNode(instruction='add', parent=..., arguments=[VariableReference, Number, VariablePointer]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[VariablePointer, Number]) + ; InstructionNode(instruction='set', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), ..., InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[VariablePointer, Number]) mov rax, 69 push rax - ; InstructionNode(instruction='add', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), ..., InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[VariableReference, Number, VariablePointer]) - ; FUCK - ; InstructionNode(instruction='end', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='add', parent=..., arguments=[VariableReference, Number, VariablePointer]), ...]), arguments=[VariableReference]) + ; InstructionNode(instruction='set', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), ..., InstructionNode(instruction='end', parent=..., arguments=[VariableReference])]), arguments=[VariablePointer, Number]) + mov rax, 123 + mov QWORD [rsp + 8], rax + ; InstructionNode(instruction='end', parent=RootNode(statements=[InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), InstructionNode(instruction='set', parent=..., arguments=[VariablePointer, Number]), ...]), arguments=[VariableReference]) mov rax, 60 push QWORD [rsp + 8] pop rdi diff --git a/test2.grnd b/test2.grnd index c6708e2..69e671d 100644 --- a/test2.grnd +++ b/test2.grnd @@ -1,4 +1,4 @@ set &x 66 set &y 69 -add $x 1 &x +set &x 123 end $x \ No newline at end of file