def visit(self, node: AssignNode, scope): var_info = scope.find_local(node.id) value, typex = self.visit(node.expr, scope) if var_info is None: var_info = scope.find_attribute(node.id) attributes = [ attr.name for attr, a_type in self.current_type.all_attributes() ] if var_info.type.name == 'Object' and typex.name in [ 'String', 'Bool', 'Int' ]: value = self.define_internal_local() self.add_instruction(cil.BoxingNode(value, typex.name)) self.add_instruction( cil.SetAttribNode('self', var_info.name, self.current_type.name, value)) else: local_name = self.to_var_name(var_info.name) if var_info.type.name == 'Object' and typex.name in [ 'String', 'Bool', 'Int' ]: self.add_instruction(cil.BoxingNode(local_name, typex.name)) else: self.add_instruction(cil.AssignNode(local_name, value)) return value, typex
def visit(self, node: VarDeclarationNode, scope): var_info = scope.find_variable(node.id) vtype = get_type(var_info.type, self.current_type) local_var = self.register_local(var_info.name) value, typex = self.visit(node.expr, scope) if vtype.name == 'Object' and typex.name in ['String', 'Int', 'Bool']: self.add_instruction(cil.BoxingNode(local_var, typex.name)) else: self.add_instruction(cil.AssignNode(local_var, value)) return local_var, vtype
def handle_arguments(self, args, scope, param_types): args_node = [] args = [self.visit(arg, scope) for arg in args] for (arg, typex), param_type in zip(args, param_types): if typex.name in ['String', 'Int', 'Bool' ] and param_type.name == 'Object': auxiliar = self.define_internal_local() self.add_instruction(cil.BoxingNode(auxiliar, typex.name)) else: auxiliar = arg args_node.append(cil.ArgNode(auxiliar, self.index)) return args_node
def visit(self, node: OptionNode, scope, expr, next_label, type_e): aux = self.define_internal_local() self.add_instruction(cil.ConformsNode(aux, expr, node.typex)) self.add_instruction(cil.GotoIfFalseNode(aux, next_label.label)) local_var = self.register_local(node.id) typex = self.context.get_type(node.typex, node.type_pos) scope.define_variable(node.id, typex) if typex.name == 'Object' and type_e.name in ['String', 'Int', 'Bool']: self.add_instruction(cil.BoxingNode(local_var, type_e.name)) else: self.add_instruction(cil.AssignNode(local_var, expr)) expr_i, type_expr = self.visit(node.expr, scope) return expr_i
def visit(self, node: FuncDeclarationNode, scope): self.current_method = self.current_type.get_method(node.id, node.pos) name = self.to_function_name(node.id, self.current_type.name) self.current_function = self.add_function(name) self.register_param('self', self.current_type.name) for p_name, p_type in node.params: self.register_param(p_name, p_type.value) value, typex = self.visit(node.body, scope) if not isinstance(value, str): result = self.define_internal_local() self.add_instruction(cil.AssignNode(result, value)) else: result = value if (typex.name == 'Int' or typex.name == 'String' or typex.name == 'Bool' ) and self.current_method.return_type.name == 'Object': self.add_instruction(cil.BoxingNode(result, typex.name)) self.add_instruction(cil.ReturnNode(result)) self.current_method = None