Exemple #1
0
    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
Exemple #2
0
    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
Exemple #3
0
    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
Exemple #4
0
    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
Exemple #5
0
    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