def visit_id(self, obj: Id): var_access: IAccess = self.current_frame.find_local_or_formal(obj.name) if var_access is not None: var_exp = var_access.get_exp( Temp( fp_name, None, None, obj.position ), obj.position ) else: assert self.table.get_scoped_class() is not None var_exp = self.table.get_scoped_class().class_struct.get_field_from( obj.name, self.current_frame.find_local_or_formal(THIS_NAME).get_exp( Temp( fp_name, None, None, obj.position ), obj.position ), obj.position ) self.type_stack_visitor.visit(obj) self.main_subtree = ExpWrapper(var_exp)
def visit_random_access_expr(self, obj: RandomAccessExpr): obj.object.accept(self) array_base = self.main_subtree.to_exp() obj.position_in_arr.accept(self) element_number = self.main_subtree.to_exp() self.main_subtree = ExpWrapper(array_struct.get_element(array_base, element_number, obj.position)) self.type_stack_visitor.visit(obj)
def visit_this_expr(self, obj: ThisExpr): self.main_subtree = ExpWrapper( Mem( self.current_frame.find_local_or_formal(THIS_NAME).get_exp( Temp(fp_name, None, None, obj.position), obj.position ), obj.position ) ) self.type_stack_visitor.visit(obj)
def visit_print_line_statement(self, obj: PrintLineStatement): obj.obj.accept(self) self.type_stack_visitor.pop_type_from_stack() self.main_subtree = ExpWrapper( Call( Name( println_name, obj.position ), ExpList(self.main_subtree.to_exp(), None, obj.position), obj.position ) )
def visit_new_int_array_expr(self, obj: NewIntArrExpr): obj.size.accept(self) self.type_stack_visitor.pop_type_from_stack() number_of_elements = self.main_subtree.to_exp() args = ExpList( Binop( BinopEnum.MUL, number_of_elements, Const( self.current_frame.type_size(TypeEnum.INT), obj.position ), obj.position ) ) self.main_subtree = ExpWrapper(Call(Name(MALLOC_NAME, obj.position), args, obj.position)) self.type_stack_visitor.visit(obj)
def visit_call_method_expr(self, obj: CallMethodExpr): obj.expr.accept(self) base_address = Temp(None, 0, None, obj.position) base_exp = Eseq( Move( base_address, self.main_subtree.to_exp(), obj.position ), Mem( Temp( None, None, base_address, obj.position ), obj.position ) ) info: TypeInfo = self.type_stack_visitor.get_type_from_stack() assert info is not None assert info.type_enum == TypeEnum.USER_CLASS type_switcher = TypeScopeSwitcher(info, None, self.table, obj.position) arguments = ExpList(base_exp, None, obj.position) for expr in obj.expr_list: expr.accept(self) arguments = ExpList( self.main_subtree.to_exp(), arguments, obj.position ) self.type_stack_visitor.pop_type_from_stack() class_info = self.table.get_class(info.user_class_name) method_address = class_info.class_struct.get_virtual_method_address( obj.id.name, Temp(None, None, base_address), obj.position, ) self.main_subtree = ExpWrapper(Call(method_address, arguments, obj.position)) self.type_stack_visitor.visit(obj) type_switcher.destroy()
def visit_length_expr(self, obj: LengthExpr): obj.obj.accept(self) array_base = self.main_subtree.to_exp() self.main_subtree = ExpWrapper(array_struct.get_length(array_base, obj.position)) self.type_stack_visitor.visit(obj)
def visit_new_object_expr(self, obj: NewObjectExpr): class_info = self.table.get_class(obj.id.name) alloc_actions = class_info.class_struct.allocate_new(obj.position) self.main_subtree = ExpWrapper(alloc_actions) self.type_stack_visitor.visit(obj)
def visit_not_expr(self, obj: NotExpr): obj.right.accept(self) self.type_stack_visitor.pop_type_from_stack() self.main_subtree = ExpWrapper(UnaryOp(UnaryOpEnum.NOT, self.main_subtree.to_exp(), obj.position)) self.type_stack_visitor.visit(obj)
def visit_value_expr(self, obj: ValueExpr): self.main_subtree = ExpWrapper(Const(obj.value, obj.position)) self.type_stack_visitor.visit(obj)
def visit_binary_expr(self, obj: BinaryExpr): obj.left.accept(self) left = self.main_subtree.to_exp() self.type_stack_visitor.pop_type_from_stack() obj.right.accept(self) right = self.main_subtree.to_exp() self.type_stack_visitor.pop_type_from_stack() if obj.binary_enum == BinaryEnum.MINUS: result = Binop(BinopEnum.MINUS, left, right, obj.position) elif obj.binary_enum == BinaryEnum.MULT: result = Binop(BinopEnum.MUL, left, right, obj.position) elif obj.binary_enum == BinaryEnum.PLUS: result = Binop(BinopEnum.PLUS, left, right, obj.position) elif obj.binary_enum == BinaryEnum.MOD: result = Binop(BinopEnum.MOD, left, right, obj.position) elif obj.binary_enum == BinaryEnum.LESS: true_label = Label.get_next_enumerated_label() false_label = Label.get_next_enumerated_label() return_label = Label.get_next_enumerated_label() condition = JumpC(JumpTypeEnum.LT, left, right, true_label, obj.position) exp_value = Temp('exp_value', None, None, obj.position) true_branch = Seq( Seq( LabelStm( true_label, obj.position ), Move( exp_value, Const( 1, obj.position ), obj.position ), obj.position ), Jump( return_label, obj.position ), obj.position ) false_branch = Seq( Seq( LabelStm( false_label, obj.position ), Move( Temp(None, None, exp_value), Const( 0, obj.position ), obj.position ), obj.position ), Jump( return_label, obj.position ), obj.position ) result = Eseq( Seq( Seq( Seq( condition, false_branch, obj.position ), true_branch, obj.position ), LabelStm( return_label, obj.position ), obj.position ), Mem( Temp(None, None, exp_value), obj.position ), obj.position ) elif obj.binary_enum == BinaryEnum.AND: true_label = Label.get_next_enumerated_label() false_label = Label.get_next_enumerated_label() return_label = Label.get_next_enumerated_label() exp_value = Temp('exp_value', None, None, obj.position) condition = JumpC(JumpTypeEnum.NEQ, left, Const(1, obj.position), false_label, obj.position) true_branch = Seq( JumpC(JumpTypeEnum.NEQ, right, Const(1, obj.position), false_label, obj.position), Seq( Move(exp_value, Const(1, obj.position), obj.position), Jump(return_label, obj.position), obj.position ), obj.position ) false_branch = Seq( LabelStm(false_label, obj.position), Seq( Move(Temp(None, None, exp_value), Const(0, obj.position), obj.position), Jump(return_label, obj.position), obj.position ), obj.position ) result = Eseq( Seq( Seq( Seq( condition, true_branch, obj.position ), false_branch, obj.position ), LabelStm(return_label, obj.position), obj.position ), Mem(Temp(None, None, exp_value), obj.position), obj.position ) elif obj.binary_enum == BinaryEnum.OR: true_label = Label.get_next_enumerated_label() false_label = Label.get_next_enumerated_label() return_label = Label.get_next_enumerated_label() exp_value = Temp('exp_value', None, None, obj.position) condition = JumpC(JumpTypeEnum.EQ, left, Const(1, obj.position), true_label, obj.position) true_branch = Seq( JumpC(JumpTypeEnum.NEQ, right, Const(1, obj.position), false_label, obj.position), Seq( LabelStm(true_label, obj.position), Seq( Move(exp_value, Const(1, obj.position), obj.position), Jump(return_label, obj.position), obj.position ), obj.position ), obj.position ) false_branch = Seq( LabelStm(false_label, obj.position), Seq( Move(Temp(None, None, exp_value), Const(0, obj.position), obj.position), Jump(return_label, obj.position), obj.position ), obj.position ) result = Eseq( Seq( Seq( Seq( condition, true_branch, obj.position ), false_branch, obj.position ), LabelStm(return_label, obj.position), obj.position ), Mem(Temp(None, None, exp_value), obj.position), obj.position ) else: raise Exception('Hello there! - General Kenobi!') self.main_subtree = ExpWrapper(result) self.type_stack_visitor.visit(obj)
def visit_exp_wrapper(self, obj: ExpWrapper): stm = obj.to_stm() stm.accept(self)