def string_substr(self):
        self.params.append(ParamNode("self"))
        idx_arg = VariableInfo("idx_arg")
        self.register_param(idx_arg)
        length_arg = VariableInfo("length_arg")
        self.register_param(length_arg)

        ret_vinfo = self.define_internal_local()

        self.register_instruction(
            SubstringNode(ret_vinfo, "self", idx_arg.name, length_arg.name))
        self.register_instruction(ReturnNode(ret_vinfo))
    def string_concat(self):
        self.params.append(ParamNode("self"))
        other_arg = VariableInfo("other_arg")
        self.register_param(other_arg)

        ret_vinfo = self.define_internal_local()

        self.register_instruction(ConcatNode(ret_vinfo, "self",
                                             other_arg.name))
        self.register_instruction(ReturnNode(ret_vinfo))
 def object_type_name(self):
     self.params.append(ParamNode("self"))
     self.data.append(
         DataNode(f"type_name_{self.current_type.name}",
                  f"{self.current_type.name}"))
     type_name = self.define_internal_local()
     self.register_instruction(
         LoadNode(
             type_name,
             VariableInfo(
                 f"type_name_{self.current_type.name}",
                 None,
                 f"{self.current_type.name}",
             ),
         ))
     self.register_instruction(ReturnNode(type_name))
    def visit(self, node, return_var=None):
        self.current_method = self.current_type.get_method(node.id)

        # Add function to .CODE
        self.current_function = self.register_function(
            self.to_function_name(node.id, self.current_type.name))

        # Add params
        self.current_function.params.append(ParamNode("self"))
        for pname, _ in node.params:
            self.register_param(VariableInfo(pname))

        # Body
        value = self.define_internal_local()
        self.visit(node.body, value)

        # Return
        if isinstance(self.current_method.return_type, VoidType):
            value = None

        self.register_instruction(ReturnNode(value))

        self.current_method = None
        self.current_function = None
 def visit(self, node, return_var):
     idx = self.generate_next_string_id()
     self.data.append(DataNode(idx, node.lex))
     self.register_instruction(
         LoadNode(return_var, VariableInfo(idx, None, node.lex)))
 def io_outint(self):
     self.params.append(ParamNode("self"))
     int_arg = VariableInfo("int")
     self.register_param(int_arg)
     self.register_instruction(PrintIntNode(int_arg.name))
     self.register_instruction(ReturnNode("self"))
 def io_outstring(self):
     self.params.append(ParamNode("self"))
     str_arg = VariableInfo("str")
     self.register_param(str_arg)
     self.register_instruction(PrintStrNode(str_arg.name))
     self.register_instruction(ReturnNode("self"))
    def add_builtin_functions(self):
        # Object
        object_type = TypeNode("Object")
        object_type.attributes = []
        object_type.methods = [
            self.cil_predef_method("abort", "Object", self.object_abort),
            self.cil_predef_method("copy", "Object", self.object_copy),
            self.cil_predef_method("type_name", "Object",
                                   self.object_type_name)
        ]

        # "IO"
        functions = [
            self.cil_predef_method("abort", "IO", self.object_abort),
            self.cil_predef_method("copy", "IO", self.object_copy),
            self.cil_predef_method("type_name", "IO", self.object_type_name),
            self.cil_predef_method("out_string", "IO", self.io_outstring),
            self.cil_predef_method("out_int", "IO", self.io_outint),
            self.cil_predef_method("in_string", "IO", self.io_instring),
            self.cil_predef_method("in_int", "IO", self.io_inint),
        ]
        io_type = TypeNode("IO")
        io_type.attributes = []
        io_type.methods = functions

        # String
        self.attrs["String"] = {"length": (0, "Int"), "str_ref": (1, "String")}
        functions = [
            self.cil_predef_method("abort", "String", self.object_abort),
            self.cil_predef_method("copy", "String", self.object_copy),
            self.cil_predef_method("type_name", "String",
                                   self.object_type_name),
            self.cil_predef_method("length", "String", self.string_length),
            self.cil_predef_method("concat", "String", self.string_concat),
            self.cil_predef_method("substr", "String", self.string_substr),
        ]
        string_type = TypeNode("String")
        string_type.attributes = [
            VariableInfo("length").name,
            VariableInfo("str_ref").name,
        ]
        string_type.methods = functions

        # Int
        # self.attrs["Int"] = {"value": (0, "Int")}
        int_type = TypeNode("Int")
        int_type.attributes = [VariableInfo("value").name]
        int_type.methods = [
            self.cil_predef_method("abort", "Int", self.object_abort),
            self.cil_predef_method("copy", "Int", self.object_copy),
            self.cil_predef_method("type_name", "Int", self.object_type_name),
        ]

        # Bool
        # self.attrs["Bool"] = {"value": (0, "Int")}
        bool_type = TypeNode("Bool")
        bool_type.attributes = [VariableInfo("value").name]
        bool_type.methods = [
            self.cil_predef_method("abort", "Bool", self.object_abort),
            self.cil_predef_method("copy", "Bool", self.object_copy),
            self.cil_predef_method("type_name", "Bool", self.object_type_name),
        ]

        for typex in [object_type, io_type, string_type, int_type, bool_type]:
            self.types.append(typex)