def visit(self, node: COOL_AST.LetNode, scope): let_scope = scope.create_child() for var_name, var_type, var_expr in node.var_list: if var_expr is not None: var_expr_value = self.visit(var_expr, let_scope) else: instance = None if var_type in ['Int', 'Bool']: instance = self.define_internal_local(scope=let_scope, name="instance") self.register_instruction( CIL_AST.Allocate(var_type, self.context.get_type(var_type).tag, instance)) value = self.define_internal_local(scope=let_scope, name="value") self.register_instruction(CIL_AST.LoadInt(0, value)) result_init = self.define_internal_local(scope=let_scope, name="result_init") self.register_instruction( CIL_AST.Call(result_init, f'{var_type}_init', [CIL_AST.Arg(value), CIL_AST.Arg(instance)], var_type)) elif var_type == 'String': instance = self.define_internal_local(scope=let_scope, name="instance") self.register_instruction( CIL_AST.Allocate(var_type, self.context.get_type(var_type).tag, instance)) value = self.define_internal_local(scope=let_scope, name="value") self.register_instruction(CIL_AST.LoadStr('empty_str', value)) result_init = self.define_internal_local(scope=let_scope, name="result_init") self.register_instruction( CIL_AST.Call(result_init, f'{var_type}_init', [CIL_AST.Arg(value), CIL_AST.Arg(instance)], var_type)) var_expr_value = instance let_var = self.define_internal_local(scope=let_scope, name=var_name, cool_var_name=var_name) self.register_instruction(CIL_AST.Assign(let_var, var_expr_value)) body_value = self.visit(node.body, let_scope) result_local = self.define_internal_local(scope=scope, name="let_result") self.register_instruction(CIL_AST.Assign(result_local, body_value)) return result_local
def visit(self, node, scope): expr_local = self.visit(node.expr, scope) result_local = self.define_internal_local(scope=scope, name="result") cil_node_name = scope.find_cil_local(node.id) if self.is_defined_param(node.id): self.register_instruction(CIL_AST.Assign(node.id, expr_local)) elif self.current_type.has_attr(node.id): cil_type_name = 'self' self.register_instruction(CIL_AST.SetAttr(cil_type_name, node.id, expr_local, self.current_type.name)) else: self.register_instruction(CIL_AST.Assign(cil_node_name, expr_local)) return expr_local
def visit(self, node, scope): result_local = self.define_internal_local(scope=scope, name="result") cond_value = self.visit(node.if_expr, scope) if_then_label = self.get_label() self.register_instruction(CIL_AST.IfGoto(cond_value, if_then_label)) else_value = self.visit(node.else_expr, scope) self.register_instruction(CIL_AST.Assign(result_local, else_value)) end_if_label = self.get_label() self.register_instruction(CIL_AST.Goto(end_if_label)) self.register_instruction(CIL_AST.Label(if_then_label)) then_value = self.visit(node.then_expr, scope) self.register_instruction(CIL_AST.Assign(result_local, then_value)) self.register_instruction(CIL_AST.Label(end_if_label)) return result_local
def visit(self, node: COOL_AST.BooleanBinaryNode, scope): result_local = self.define_internal_local(scope=scope, name="result") op_local = self.define_internal_local(scope=scope, name="op") left_local = self.define_internal_local(scope=scope, name="left") right_local = self.define_internal_local(scope=scope, name="right") left_value = self.visit(node.left, scope) right_value = self.visit(node.right, scope) self.register_instruction(CIL_AST.GetAttr(left_local, left_value, "value", node.left.computed_type.name)) self.register_instruction(CIL_AST.GetAttr(right_local, right_value, "value", node.right.computed_type.name)) if isinstance(node, COOL_AST.LessNode): self.register_instruction(CIL_AST.BinaryOperator(op_local, left_local, right_local, "<")) elif isinstance(node, COOL_AST.LessNode): self.register_instruction(CIL_AST.BinaryOperator(op_local, left_local, right_local, "<=")) elif isinstance(node, COOL_AST.EqualNode): if node.left.computed_type.name == 'String': self.register_instruction( CIL_AST.Call(op_local, 'String_equals', [CIL_AST.Arg(right_value), CIL_AST.Arg(left_value)], 'String')) elif node.left.computed_type.name in ['Int', 'Bool']: self.register_instruction( CIL_AST.GetAttr(left_local, left_value, "value", node.left.computed_type.name)) self.register_instruction( CIL_AST.GetAttr(right_local, right_value, "value", node.right.computed_type.name)) else: self.register_instruction(CIL_AST.Assign(left_local, left_value)) self.register_instruction(CIL_AST.Assign(right_local, right_value)) self.register_instruction(CIL_AST.BinaryOperator(op_local, left_local, right_local, "=")) # Allocate Bool result self.register_instruction(CIL_AST.Allocate('Bool', self.context.get_type('Bool').tag, result_local)) result_init = self.define_internal_local(scope=scope, name="result_init") self.register_instruction( CIL_AST.Call(result_init, 'Bool_init', [CIL_AST.Arg(op_local), CIL_AST.Arg(result_local)], "Bool")) return result_local
def visit(self, node, scope): result_local = self.define_internal_local(scope=scope, name="result") case_expr = self.visit(node.expr, scope) exit_label = self.get_label() label = self.get_label() self.register_instruction(CIL_AST.Case(case_expr, label)) tag_lst = [] action_dict = {} for action in node.actions: tag = self.context.get_type(action.type).tag tag_lst.append(tag) action_dict[tag] = action tag_lst.sort() for t in reversed(tag_lst): action = action_dict[t] self.register_instruction(CIL_AST.Label(label)) label = self.get_label() action_Type = self.context.get_type(action.type) self.register_instruction(CIL_AST.Action(case_expr, action_Type.tag, action_Type.max_tag, label)) action_scope = scope.create_child() action_id = self.define_internal_local(scope=action_scope, name=action.id, cool_var_name=action.id) self.register_instruction(CIL_AST.Assign(action_id, case_expr)) expr_result = self.visit(action.action, action_scope) self.register_instruction(CIL_AST.Assign(result_local, expr_result)) self.register_instruction(CIL_AST.Goto(exit_label)) self.register_instruction(CIL_AST.Label(label)) self.register_instruction(CIL_AST.Goto('case_no_match_error')) self.register_instruction(CIL_AST.Label(exit_label)) return result_local