def __generate_assembly(self, instruction, n_id=""): if instruction in JUMP_OPS: commands = [ """ CMP EAX, EBX""", f""" CALL binop_{instruction.lower()}""", """ CMP EBX, False""", f""" JE EXIT_{n_id}""" ] elif instruction in ARITHMETIC_OPS + LOGIC_OPS: if instruction == "IMUL" or instruction == "IDIV": if instruction == "IDIV": Assembly.append(""" MOV EDX, 0""") commands = [f""" {instruction} EBX""", """ MOV EBX, EAX"""] elif instruction == "SUB": commands = [ f""" {instruction} EAX, EBX""", """ MOV EBX, EAX""" ] else: commands = f""" {instruction} EBX, EAX""" elif instruction in STACK_OPS: if instruction == "PUSH": register = "EBX" elif instruction == "POP": register = "EAX" commands = f""" {instruction} {register}""" Assembly.append(commands)
def eval(self, st): if self.children: result = self.children[0].eval(st) if self.value == "PLUS": if not isinstance(result, bool): return result raise ValueError( "Incompatible types: got \"Boolean\" expected \"Integer\"") elif self.value == "MINUS": Assembly.append(""" NEG EBX""") if not isinstance(result, bool): return -result raise ValueError( "Incompatible types: got \"Boolean\" expected \"Integer\"") elif self.value == "NOT": Assembly.append(""" NOT EBX""") if isinstance(result, bool): return not result else: return ~result
def eval(self, st): for child in self.children: if st.is_global: self.__generate_assembly(child.value, st.identifier) child.eval(st) if st.is_global: Assembly.append(""" res RESB 1""")
def __generate_assembly(self, instruction, n_id=""): if instruction == "BEFORE_ELSE": commands = [ f""" JMP FALSE_{n_id}""", f""" EXIT_{n_id}:""" ] elif instruction == "AFTER_ELSE": commands = f""" FALSE_{n_id}:""" Assembly.append(commands)
def __generate_assembly(self, instruction): if instruction == "LOOP_ENTER": commands = f""" WHILE_{self.identifier}:""" elif instruction == "LOOP_EXIT": commands = [ f""" JMP WHILE_{self.identifier}""", f""" EXIT_{self.identifier}:""" ] Assembly.append(commands)
def __generate_assembly(self, op, n_id=""): if op in JUMP_OPS: commands = [ """ CMP EAX, EBX""", f""" CALL binop_{op.lower()}""", """ CMP EBX, False""", f""" JE EXIT_{n_id}""" ] elif op in ARITHMETIC_OPS or op in LOGIC_OPS: if op == "IMUL" or op == "DIV": commands = [f""" {op} EBX""", """ MOV EBX, EAX"""] elif op == "SUB": commands = [f""" {op} EAX, EBX""", """ MOV EBX, EAX"""] else: commands = f""" {op} EBX, EAX""" elif op in STACK_OPS: if op == "PUSH": register = "EBX" elif op == "POP": register = "EAX" commands = f""" {op} {register}""" Assembly.append(commands)
def __generate_assembly(self, value, st_id): Assembly.append(f""" MOV EBX, [{value}_{st_id}]""")
def __generate_assembly(self, var_name, st_id): Assembly.append(f""" {var_name}_{st_id} RESD 1""")
def __assembly_terminate(self): Assembly.append(INTERRUPT)
def __assembly_procs(self): Assembly.append(PRINT_PROC) Assembly.append(IF_WHILE_PROC) Assembly.append(START)
def __assembly_init(self): Assembly.append(CONSTANTS) Assembly.append(DATA_SEGMENT) Assembly.append(BSS_SEGMENT)
def __generate_assembly(self, value): Assembly.append(f""" MOV EBX, ${value}""")
def __generate_assembly(self): commands = [""" PUSH EBX""", """ CALL print"""] Assembly.append(commands)