Пример #1
0
    def visit_Function(self, obj: Function):
        body = []

        for i in range(obj.temp_count):
            body.append(cgen.Declare(AIZE_OBJECT_REF, f"AT{i}", None))

        if obj.unique != 'main':
            body.append(
                cgen.ExprStmt(cgen.Call(cgen.GetVar("aize_mem_enter"), [])))
            self.in_main_main = False
        else:
            body.append(
                cgen.ExprStmt(cgen.Call(cgen.GetVar("aize_mem_init"), [])))
            self.in_main_main = True

        for stmt in obj.body:
            ret = self.visit(stmt)
            if self.debug:
                body.append(cgen.Comment(f"{stmt}"))
                body.append(cgen.printf(str(stmt)))
            if isinstance(ret, (list, tuple)):
                body.extend(ret)
            elif ret is not None:
                body.append(ret)

        if len(obj.body) == 0 or not isinstance(obj.body[-1], Return):
            body.append(
                cgen.ExprStmt(cgen.Call(cgen.GetVar("aize_mem_exit"), [])))

        return cgen.Function(
            obj.unique,
            {param.unique: self.visit(param.type)
             for param in obj.args}, self.visit(obj.type.ret), body)
Пример #2
0
    def visit_Class(self, obj: Class):
        cls_ptr = self.visit(obj.type)
        attrs = {'ATBASE': AIZE_BASE}
        attrs.update({
            attr.unique: self.visit(attr.type)
            for attr in obj.attrs.values()
        })
        cls_struct = cgen.Struct(obj.unique, attrs)

        implementers = {}
        owned_methods = []
        methods = {}
        for n, meth_proto in enumerate(obj.methods.values()):
            meth = obj.type.get_method(meth_proto.name)
            if meth.owner is obj.type:
                methods[str(len(owned_methods))] = cgen.Ref(
                    cgen.GetVar(meth.unique))
                owned_methods.append(meth_proto)
        implementers[obj.type.unique.upper()] = cgen.ArrayInit(methods)
        ttable = cgen.GlobalArray(
            obj.type.ttable, cgen.void_ptr(),
            (len(self.program.classes), len(owned_methods)),
            cgen.ArrayInit(implementers))

        new_unique = obj.type.cls_namespace.get_name("new").unique
        new_attrs = {
            attr.unique: self.visit(attr.type)
            for attr in obj.attrs.values()
        }

        def set_attr(attr):
            return cgen.ExprStmt(
                cgen.SetArrow(self.get_cls_ptr(cgen.GetVar('mem'), obj.type),
                              attr.unique, cgen.GetVar(attr.unique)))

        new_func = cgen.Function(new_unique, new_attrs, cls_ptr, [
            cgen.ExprStmt(cgen.Call(cgen.GetVar("aize_mem_enter"), [])),
            cgen.Declare(
                cls_ptr, "mem",
                cgen.StructInit([
                    cgen.Call(cgen.GetVar("aize_mem_malloc"),
                              [cgen.SizeOf(cls_struct.struct_type)]),
                    cgen.GetVar(cls_struct.name.upper())
                ])),
            *(set_attr(attr) for attr in obj.attrs.values()),
            cgen.ExprStmt(
                cgen.SetArrow(cgen.GetAttr(cgen.GetVar('mem'), 'obj'),
                              "ref_count", cgen.Constant(0))),
            cgen.Return(
                cgen.Call(cgen.GetVar('aize_mem_ret'), [cgen.GetVar("mem")])),
        ])

        methods = []
        for meth in obj.methods.values():
            methods.append(self.visit(meth))

        return [cls_struct, new_func, *methods, ttable]
Пример #3
0
 def visit_Return(self, obj: Return):
     if self.in_main_main:
         return cgen.Return(self.visit(obj.val))
     val = self.visit(obj.val)
     if isinstance(obj.val.ret, ClassType):
         ret = cgen.Call(cgen.GetVar("aize_mem_ret"), [val])
         return cgen.Return(ret)
     else:
         ret = cgen.Declare(self.visit(obj.val.ret), 'ATR', val)
         exit_call = cgen.ExprStmt(
             cgen.Call(cgen.GetVar("aize_mem_exit"), []))
         return [ret, exit_call, cgen.Return(cgen.GetVar('ATR'))]
Пример #4
0
 def visit_Call(self, obj: Call):
     if obj.method_data is not None:
         args = obj.args
         obj = obj.method_data
         ttable = obj.pointed.owner.ttable
         left = cgen.StrExpr(
             f"{ttable}[(AT{obj.depth} = {self.visit(obj.obj)}).typeid][{obj.index}]"
         )
         left = cgen.Cast(left, self.visit(obj.pointed.type))
         left = cgen.Call(left, [cgen.GetVar(f"AT{obj.depth}")] +
                          [self.visit(arg) for arg in args])
         return left
     return cgen.Call(self.visit(obj.left),
                      [self.visit(arg) for arg in obj.args])