diff --git a/generators/x86_64.py b/generators/x86_64.py index 3d8f89a..b7c3f2d 100644 --- a/generators/x86_64.py +++ b/generators/x86_64.py @@ -157,10 +157,7 @@ class X86_64Generator(Generator): def generate_InstructionNode(self, node: InstructionNode): ### MISC ### if node.instruction == "end": - if len(node.arguments) == 0: # example: "end" - traceback(self.code, "TypeError", "end expects atleast 1 argument.") - elif len(node.arguments) > 1: # example: "end 1 1" - traceback(self.code, "TypeError", "end expects only 1 argument.") + self.clamp_instruction_args(node, 1, 1) 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]}") @@ -256,11 +253,8 @@ class X86_64Generator(Generator): self.change_variable(node.arguments[2].var_name, starting_reg) elif node.instruction == "divide": - if len(node.arguments) < 3: # example: "divide" or "divide 1" or "divide 1 2" - traceback(self.code, "TypeError", "divide expects atleast 3 arguments.") - elif len(node.arguments) > 3: # example: "divide 1 2 3 4" - traceback(self.code, "TypeError", "divide expects only 3 arguments.") - elif type(node.arguments[2]) != VarPointerNode: + self.clamp_instruction_args(node, 3, 3) + if type(node.arguments[2]) != VarPointerNode: traceback(self.code, "TypeError", f"the destination of the divide command must be a variable pointer, not \"{node.arguments[2]}\"") # bro this entire god damn instruction is just error handling 😔 @@ -298,10 +292,7 @@ class X86_64Generator(Generator): self.change_variable(node.arguments[2].var_name, "xmm0") elif node.instruction == "stdout": - if len(node.arguments) < 1: # example: "stdout" - traceback(self.code, "TypeError", "stdout expects atleast 1 argument.") - elif len(node.arguments) > 1: # example: "stdout "hi" 123" - traceback(self.code, "TypeError", "stdout expects at most 1 argument.") + self.clamp_instruction_args(node, 1, 1) arg = node.arguments[0] @@ -324,19 +315,15 @@ class X86_64Generator(Generator): self.lines.append("syscall\n\t") elif node.instruction == "jump": - if len(node.arguments) < 1: # example: "jump" - traceback(self.code, "TypeError", "jump expects atleast 1 argument.") - elif len(node.arguments) > 1: # example: "jump %label 123" - traceback(self.code, "TypeError", "jump expects at most 1 argument.") - elif not isinstance(node.arguments[0], LabelRefNode): + self.clamp_instruction_args(node, 1, 1) + if not isinstance(node.arguments[0], LabelRefNode): traceback(self.code, "TypeError", f"jump expects a label reference as the first argument, not \"{node.arguments[0]}\"") self.lines.append(f"jmp .{node.arguments[0].name}\n\t") elif node.instruction == "if": - if len(node.arguments) != 2: # example: "jump" or "jump $bool" - traceback(self.code, "TypeError", "if expects exactly 2 arguments.") - elif not type(node.arguments[0]) in [VarRefNode,BoolNode,StringNode,FloatNode,IntNode]: + self.clamp_instruction_args(node, 2, 2) + if not type(node.arguments[0]) in [VarRefNode,BoolNode,StringNode,FloatNode,IntNode]: traceback(self.code, "TypeError", f"if expects a value or variable refernce as the first argument, not \"{node.arguments[0]}\"") elif not isinstance(node.arguments[1], LabelRefNode): traceback(self.code, "TypeError", f"if expects a label reference as the second argument, not \"{node.arguments[1]}\"") @@ -356,14 +343,13 @@ class X86_64Generator(Generator): self.lines.append(f"jnz .{node.arguments[1].name}\n\t") elif node.instruction in ["equal", "inequal", "greater", "lesser"]: - if len(node.arguments) != 3: # example: "equal" or "equal $bool" - traceback(self.code, "TypeError", "equal expects exactly 3 arguments.") - elif not type(node.arguments[0]) in [VarRefNode,BoolNode,FloatNode,IntNode]: - traceback(self.code, "TypeError", f"equal expects a value or variable refernce as the first argument, not \"{node.arguments[0].__repr__()}\"") + self.clamp_instruction_args(node, 3, 3) + if not type(node.arguments[0]) in [VarRefNode,BoolNode,FloatNode,IntNode]: + traceback(self.code, "TypeError", f"{node.instruction} expects a value or variable refernce as the first argument, not \"{node.arguments[0].__repr__()}\"") elif not type(node.arguments[1]) in [VarRefNode,BoolNode,FloatNode,IntNode]: - traceback(self.code, "TypeError", f"equal expects a value or variable refernce as the second argument, not \"{node.arguments[1].__repr__()}\"") + traceback(self.code, "TypeError", f"{node.instruction} expects a value or variable refernce as the second argument, not \"{node.arguments[1].__repr__()}\"") elif not isinstance(node.arguments[2], VarPointerNode): - traceback(self.code, "TypeError", f"the third argument of equal should be a variable pointer, not \"{node.arguments[2].__repr__()}\"") + traceback(self.code, "TypeError", f"the third argument of {node.instruction} should be a variable pointer, not \"{node.arguments[2].__repr__()}\"") arg1 = None arg2 = None