def produce(self, or_expression: LogicalOr, factories: Dict[type, TemplateFactory], bundle: Dict) -> str: valid = get_unique_id() invalid = get_unique_id() assembly = self.add_verbose(bundle) assembly += ( f"{factories[type(or_expression.left)].produce(or_expression.left, factories, bundle)}" f"{factories[type(or_expression.right)].produce(or_expression.right, factories, bundle)}" "pop eax\n" "pop ecx\n" "xor ebx, ebx\n" "test eax, eax\n" f"jnz loc_{valid}\n" "test ecx, ecx\n" f"jnz loc_{valid}\n" f"jmp loc_{invalid}\n" f"loc_{valid}:\n" "mov ebx, 1\n" f"loc_{invalid}:\n" "push ebx\n") return assembly
def produce(self, while_expression: While, factories: Dict[type, TemplateFactory], bundle: Dict) -> str: loop_start = get_unique_id() loop_end = get_unique_id() body_assembly = "" prev_scope = bundle["scope"] bundle["scope"] = while_expression.scope for expression in while_expression.body: if not isinstance(expression, VariableDeclaration): body_assembly += factories[type(expression)].produce( expression, factories, bundle) assembly = ( f"{self.add_verbose(bundle)}" f"loc_{loop_start}:\n" f"{factories[type(while_expression.condition)].produce(while_expression.condition, factories, bundle)}" "pop eax\n" "test eax, eax\n" f"jz loc_{loop_end}\n" f"{body_assembly}" f"jmp loc_{loop_start}\n" f"loc_{loop_end}:\n") bundle["scope"] = prev_scope return assembly
def produce(self, equal_expression: Equal, factories: Dict[type, TemplateFactory], bundle: Dict) -> str: not_equal = get_unique_id() assembly = self.add_verbose(bundle) assembly += ( f"{factories[type(equal_expression.left)].produce(equal_expression.left, factories, bundle)}" f"{factories[type(equal_expression.right)].produce(equal_expression.right, factories, bundle)}" "xor ecx, ecx\n" "pop eax\n" "pop ebx\n" "cmp eax, ebx\n" f"jne loc_{not_equal}\n" "mov ecx, 1\n" f"loc_{not_equal}:\n" "push ecx\n") return assembly
def produce(self, greater_expression: LogicalGreater, factories: Dict[type, TemplateFactory], bundle: Dict) -> str: not_greater = get_unique_id() assembly = self.add_verbose(bundle) assembly += ( f"{factories[type(greater_expression.left)].produce(greater_expression.left, factories, bundle)}" f"{factories[type(greater_expression.right)].produce(greater_expression.right, factories, bundle)}" "pop ebx\n" "pop eax\n" "xor ecx, ecx\n" "cmp eax, ebx\n" f"jbe loc_{not_greater}\n" "mov ecx, 1\n" f"loc_{not_greater}:\n" "push ecx\n") return assembly
def produce(self, and_expression: LogicalAnd, factories: Dict[type, TemplateFactory], bundle: Dict) -> str: end = get_unique_id() assembly = self.add_verbose(bundle) assembly += ( f"{factories[type(and_expression.left)].produce(and_expression.left, factories, bundle)}" f"{factories[type(and_expression.right)].produce(and_expression.right, factories, bundle)}" "pop eax\n" "xor ebx, ebx\n" f"test eax, eax\n" f"jz loc_{end}\n" "pop eax\n" "test eax, eax\n" f"jz loc_{end}\n" "mov ebx, 1\n" f"loc_{end}:\n" "push ebx\n") return assembly
def produce(self, if_expression: If, factories: Dict[type, TemplateFactory], bundle: Dict) -> str: skip_if_id = get_unique_id() body_assembly = "" prev_scope = bundle["scope"] bundle["scope"] = if_expression.scope for expression in if_expression.body: if not isinstance(expression, VariableDeclaration): body_assembly += factories[type(expression)].produce( expression, factories, bundle) assembly = self.add_verbose(bundle) assembly += ( f"{factories[type(if_expression.condition)].produce(if_expression.condition, factories, bundle)}" "pop eax\n" "test eax, eax\n" f"jz loc_{skip_if_id}\n" f"{body_assembly}" f"loc_{skip_if_id}:\n") bundle["scope"] = prev_scope return assembly
def produce(self, indexer_expression: ArrayIndexer, factories: Dict[type, TemplateFactory], bundle: Dict) -> str: passed_boundary_check = get_unique_id() assembly = self.add_verbose(bundle) assembly += ( f"{factories[type(indexer_expression.right)].produce(indexer_expression.right, factories, bundle)}\n" f"{factories[type(indexer_expression.left)].produce(indexer_expression.left, factories, bundle)}\n" "pop edi\n" "pop eax\n" "mov ebx, [edi]\n" "cmp eax, ebx\n" # Check if index is off bounds f"jb loc_{passed_boundary_check}\n" "mov eax, 0\n" "mov ebx, 0\n" "int 0x80\n" f"loc_{passed_boundary_check}:\n" "mov ecx, [edi + 4]\n" "xor edx, edx\n" "mul ecx\n" "add edi, 8\n" "add edi, eax\n" "push edi\n") return assembly