Beispiel #1
0
    def visit(self, node: CaseNode, scope):
        expr, typex = self.visit(node.expr, scope)

        result = self.define_internal_local()
        end_label = cil.LabelNode(f'end__{self.idx}')
        error_label = cil.LabelNode(f'error__{self.idx}')

        isvoid = self.check_void(expr)
        self.add_instruction(cil.GotoIfNode(isvoid, error_label.label))

        try:
            new_scope = scope.expr_dict[node]
        except:
            new_scope = scope
        sorted_case_list = self.sort_nodes(node.case_list)
        for i, case in enumerate(sorted_case_list):
            next_label = cil.LabelNode(f'next__{self.idx}_{i}')
            expr_i = self.visit(case, new_scope.create_child(), expr,
                                next_label, typex)
            self.add_instruction(cil.AssignNode(result, expr_i))
            self.add_instruction(cil.GotoNode(end_label.label))
            self.add_instruction(next_label)
        self.add_instruction(cil.ErrorNode('case_error'))
        self.add_instruction(error_label)
        self.add_instruction(cil.ErrorNode('case_void_error'))
        self.add_instruction(end_label)
        return result, typex
Beispiel #2
0
 def visit(self, node: BlockNode, scope):
     value = None
     for exp in node.expr_list:
         value, typex = self.visit(exp, scope)
     result = self.define_internal_local()
     self.add_instruction(cil.AssignNode(result, value))
     return result, typex
Beispiel #3
0
 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
Beispiel #4
0
    def visit(self, node: ConditionalNode, scope):
        cond, _ = self.visit(node.cond, scope)

        true_label = cil.LabelNode(f"true__{self.idx}")
        end_label = cil.LabelNode(f"end__{self.idx}")

        result = self.define_internal_local()
        self.add_instruction(cil.GotoIfNode(cond, true_label.label))

        false_expr, ftypex = self.visit(node.else_stm, scope)
        self.add_instruction(cil.AssignNode(result, false_expr))
        self.add_instruction(cil.GotoNode(end_label.label))
        self.add_instruction(true_label)

        true_expr, ttypex = self.visit(node.stm, scope)
        self.add_instruction(cil.AssignNode(result, true_expr))
        self.add_instruction(end_label)
        return result, get_common_basetype([ttypex, ftypex])
Beispiel #5
0
    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
Beispiel #6
0
    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
Beispiel #7
0
    def visit(self, node: WhileNode, scope):
        start_label = cil.LabelNode(f'start__{self.idx}')
        end_label = cil.LabelNode(f'end__{self.idx}')

        result = self.define_internal_local()
        self.add_instruction(cil.VoidConstantNode(result))
        self.add_instruction(start_label)

        cond, _ = self.visit(node.cond, scope)
        self.add_instruction(cil.GotoIfFalseNode(cond, end_label.label))
        expr, typex = self.visit(node.expr, scope)
        self.add_instruction(cil.AssignNode(result, expr))
        self.add_instruction(cil.GotoNode(start_label.label))
        self.add_instruction(end_label)

        return result, ObjectType()
Beispiel #8
0
    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
Beispiel #9
0
    def create_built_in(self):

        f1_params = [cil.ParamNode("self", 'Object')]
        f1_localVars = [cil.LocalNode("local_abort_Object_self_0")]
        f1_intructions = [
            cil.AssignNode(f1_localVars[0].name, f1_params[0].name,
                           self.index),
            cil.ExitNode(f1_params[0].name, idx=self.index)
        ]
        f1 = cil.FunctionNode("function_abort_Object", f1_params, f1_localVars,
                              f1_intructions)

        f2_params = [cil.ParamNode("self", 'Object')]
        f2_localVars = [cil.LocalNode("local_type_name_Object_result_0")]
        f2_intructions = [
            cil.TypeOfNode(f2_params[0].name, f2_localVars[0].name,
                           self.index),
            cil.ReturnNode(f2_localVars[0].name, self.index)
        ]
        f2 = cil.FunctionNode("function_type_name_Object", f2_params,
                              f2_localVars, f2_intructions)

        f3_params = [cil.ParamNode("self", 'Object')]
        f3_localVars = [cil.LocalNode("local_copy_Object_result_0")]
        f3_intructions = [
            cil.CopyNode(f3_localVars[0].name, f3_params[0].name, self.index),
            cil.ReturnNode(f3_localVars[0].name, self.index)
        ]
        f3 = cil.FunctionNode("function_copy_Object", f3_params, f3_localVars,
                              f3_intructions)

        f4_params = [
            cil.ParamNode("self", 'IO'),
            cil.ParamNode("word", 'String')
        ]
        f4_localVars = [cil.LocalNode("local_out_string_String_self_0")]
        f4_intructions = [
            cil.AssignNode(f4_localVars[0].name, f4_params[0].name,
                           self.index),
            cil.OutStringNode(f4_params[1].name, self.index),
            cil.ReturnNode(f4_localVars[0].name, self.index)
        ]
        f4 = cil.FunctionNode("function_out_string_IO", f4_params,
                              f4_localVars, f4_intructions)

        f5_params = [
            cil.ParamNode("self", 'IO'),
            cil.ParamNode("number", 'Int')
        ]
        f5_localVars = [cil.LocalNode("local_out_int_IO_self_0")]
        f5_intructions = [
            cil.AssignNode(f5_localVars[0].name, f5_params[0].name,
                           self.index),
            cil.OutIntNode(f5_params[1].name, self.index),
            cil.ReturnNode(f5_localVars[0].name, self.index)
        ]
        f5 = cil.FunctionNode("function_out_int_IO", f5_params, f5_localVars,
                              f5_intructions)

        f6_params = [cil.ParamNode("self", 'IO')]
        f6_localVars = [cil.LocalNode("local_in_int_IO_result_0")]
        f6_intructions = [
            cil.ReadIntNode(f6_localVars[0].name, self.index),
            cil.ReturnNode(f6_localVars[0].name, self.index)
        ]
        f6 = cil.FunctionNode("function_in_int_IO", f6_params, f6_localVars,
                              f6_intructions)

        f7_params = [cil.ParamNode("self", 'IO')]
        f7_localVars = [cil.LocalNode("local_in_string_IO_result_0")]
        f7_intructions = [
            cil.ReadStringNode(f7_localVars[0].name, self.index),
            cil.ReturnNode(f7_localVars[0].name, self.index)
        ]
        f7 = cil.FunctionNode("function_in_string_IO", f7_params, f7_localVars,
                              f7_intructions)

        f8_params = [cil.ParamNode("self", 'String')]
        f8_localVars = [cil.LocalNode("local_length_String_result_0")]
        f8_intructions = [
            cil.LengthNode(f8_localVars[0].name, f8_params[0].name,
                           self.index),
            cil.ReturnNode(f8_localVars[0].name, self.index)
        ]
        f8 = cil.FunctionNode("function_length_String", f8_params,
                              f8_localVars, f8_intructions)

        f9_params = [
            cil.ParamNode("self", 'String'),
            cil.ParamNode("word", 'String')
        ]
        f9_localVars = [cil.LocalNode("local_concat_String_result_0")]
        f9_intructions = [
            cil.ConcatNode(f9_localVars[0].name, f9_params[0].name,
                           f9_params[1].name, self.index),
            cil.ReturnNode(f9_localVars[0].name, self.index)
        ]
        f9 = cil.FunctionNode("function_concat_String", f9_params,
                              f9_localVars, f9_intructions)

        f10_params = [
            cil.ParamNode("self", 'String'),
            cil.ParamNode("begin", 'Int'),
            cil.ParamNode("end", 'Int')
        ]
        f10_localVars = [cil.LocalNode("local_substr_String_result_0")]
        f10_intructions = [
            cil.SubstringNode(f10_localVars[0].name, f10_params[0].name,
                              f10_params[1].name, f10_params[2].name,
                              self.index),
            cil.ReturnNode(f10_localVars[0].name, self.index)
        ]
        f10 = cil.FunctionNode("function_substr_String", f10_params,
                               f10_localVars, f10_intructions)

        f11_params = [cil.ParamNode("self", 'String')]
        f11_localVars = [cil.LocalNode("local_type_name_String_result_0")]
        f11_intructions = [
            cil.LoadNode(f11_localVars[0].name, 'type_String', self.index),
            cil.ReturnNode(f11_localVars[0].name, self.index)
        ]
        f11 = cil.FunctionNode("function_type_name_String", f11_params,
                               f11_localVars, f11_intructions)

        f12_params = [cil.ParamNode("self", 'String')]
        f12_localVars = [cil.LocalNode("local_copy_String_result_0")]
        f12_intructions = [
            cil.ConcatNode(f12_localVars[0].name, f12_params[0].name, None,
                           self.index),
            cil.ReturnNode(f12_localVars[0].name, self.index)
        ]
        f12 = cil.FunctionNode("function_copy_String", f12_params,
                               f12_localVars, f12_intructions)

        f17_params = [cil.ParamNode("self", 'String')]
        f17_localVars = [cil.LocalNode('local_abort_String_msg_0')]
        f17_intructions = [
            cil.LoadNode(f17_params[0].name, 'string_abort'),
            cil.OutStringNode(f17_params[0].name, self.index),
            cil.ExitNode(f17_params[0].name, idx=self.index)
        ]
        f17 = cil.FunctionNode("function_abort_String", f17_params,
                               f17_localVars, f17_intructions)

        f13_params = [cil.ParamNode("self", 'Int')]
        f13_localVars = [cil.LocalNode("local_type_name_Int_result_0")]
        f13_intructions = [
            cil.LoadNode(f13_localVars[0].name, 'type_Int', self.index),
            cil.ReturnNode(f13_localVars[0].name, self.index)
        ]
        f13 = cil.FunctionNode("function_type_name_Int", f13_params,
                               f13_localVars, f13_intructions)

        f14_params = [cil.ParamNode("self", 'Int')]
        f14_localVars = [cil.LocalNode("local_copy_Int_result_0")]
        f14_intructions = [
            cil.AssignNode(f14_localVars[0].name, f14_params[0].name),
            cil.ReturnNode(f14_localVars[0].name, self.index)
        ]
        f14 = cil.FunctionNode("function_copy_Int", f14_params, f14_localVars,
                               f14_intructions)

        f18_params = [cil.ParamNode("self", 'Int')]
        f18_localVars = [cil.LocalNode('local_abort_Int_msg_0')]
        f18_intructions = [
            cil.LoadNode(f18_params[0].name, 'int_abort'),
            cil.OutStringNode(f18_params[0].name, self.index),
            cil.ExitNode(f18_params[0].name, idx=self.index)
        ]
        f18 = cil.FunctionNode("function_abort_Int", f18_params, f18_localVars,
                               f18_intructions)

        f15_params = [cil.ParamNode("self", 'Bool')]
        f15_localVars = [cil.LocalNode("local_type_name_Bool_result_0")]
        f15_intructions = [
            cil.LoadNode(f15_localVars[0].name, 'type_Bool', self.index),
            cil.ReturnNode(f15_localVars[0].name, self.index)
        ]
        f15 = cil.FunctionNode("function_type_name_Bool", f15_params,
                               f15_localVars, f15_intructions)

        f16_params = [cil.ParamNode("self", 'Bool')]
        f16_localVars = [cil.LocalNode("local_copy_result_Bool_0")]
        f16_intructions = [
            cil.AssignNode(f16_localVars[0].name, f16_params[0].name),
            cil.ReturnNode(f16_localVars[0].name, self.index)
        ]
        f16 = cil.FunctionNode("function_copy_Bool", f16_params, f16_localVars,
                               f16_intructions)

        f19_params = [cil.ParamNode("self", 'Bool')]
        f19_localVars = [cil.LocalNode('local_abort_Bool_msg_0')]
        f19_intructions = [
            cil.LoadNode(f19_params[0].name, 'bool_abort'),
            cil.OutStringNode(f19_params[0].name, self.index),
            cil.ExitNode(f19_params[0].name, idx=self.index)
        ]
        f19 = cil.FunctionNode("function_abort_Bool", f19_params,
                               f19_localVars, f19_intructions)

        self.dotcode += [
            f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
            f16, f17, f18, f19
        ]
        object_methods = [('abort', f1.name), ('type_name', f2.name),
                          ('copy', f3.name)]
        string_methods = [('length', f8.name), ('concat', f9.name),
                          ('substr', f10.name), ('abort', f17.name),
                          ('type_name', f11.name), ('copy', f12.name)]
        io_methods = [('out_string', f4.name), ('out_int', f5.name),
                      ('in_int', f6.name), ('in_string', f7.name)]
        int_methods = [('abort', f18.name), ('type_name', f13.name),
                       ('copy', f14.name)]
        bool_methods = [('abort', f19.name), ('type_name', f15.name),
                        ('copy', f16.name)]

        self.dottypes += [
            cil.TypeNode("Object", [], object_methods),
            cil.TypeNode("IO", [], object_methods + io_methods),
            cil.TypeNode("String", [], string_methods),
            cil.TypeNode('Int', [], int_methods),
            cil.TypeNode('Bool', [], bool_methods)
        ]