def compileToC(self, codegen):
        self.typ.toCType()

        #if self.typ.package == "_global" and type(self.typ) in [Types.Struct, Types.Enum]:
        #    codegen.append("NULL")
        #    return

        package = self.typ.package if self.typ.package != "" else "_global"
        fullName = SimplifyAst.toUniqueID(package, self.typ.normalName, self.typ.remainingGen)

        if not type(self.typ) in [Types.Interface, Types.Pointer, Types.Alias, Types.Null]:
            if type(self.typ) is Types.T:
                typeof_none = Typeof(self, Types.Null())
                Tree.castFrom(typeof_none.type, Parser.IType, typeof_none, "", codegen)
            else:
                codegen.append(f"{fullName}_get_type(NULL," + codegen.getContext() + ")")
        else:
            if type(self.typ) is Types.Pointer:
                codegen.append("_global_boxPointerType(_global_PointerTypeInit(")
                tmp = Typeof(self, self.typ.pType)
                Cast.castFrom(tmp.type, Parser.IType, tmp, "", codegen)
                codegen.append(",0)," + codegen.getContext() + ")")
            elif type(self.typ) is Types.Null:
                codegen.append(f"&None_Type")
            else:
                codegen.append(f"&{fullName}_Type")
Exemple #2
0
 def replaceT(self, structT, newName):
     self.package = structT.package
     self.normalName = newName
     self.const = structT.const
     self.onlyGenericName = SimplifyAst.toUniqueID("", "",
                                                   structT.remainingGen)[1:]
     self.generic = structT.remainingGen
     self.replaced = True
     self.realNormalName = structT.normalName
     self.type = structT
Exemple #3
0
 def getFieldOfInterface(iType, pointer=False):
     n = SimplifyAst.sanitize(iType.name)
     codegen.append(f"*{n}_{self.field}")
     if pointer:
         codegen.append("(")
     else:
         codegen.append("ByValue(")
     self.nodes[0].compileToC(codegen)
     if pointer:
         codegen.append(")")
     codegen.append(")")
def funcBody(parser, name, names, types, brace, returnType, do):
    body = Tree.FuncBody(parser)
    body.name = name
    body.returnType = returnType
    body.package = parser.package
    body.do = do
    body.types = types

    brace.body = body

    parser.currentNode.addNode(body)
    parser.currentNode = body

    if not parser.sc and not SimplifyAst.isGenericFunc(brace):
        body.sc = False

        if parser.nextToken().token == "\n":
            Parser.callToken(parser)
        while not Parser.isEnd(parser):
            if parser.nextToken().token == "\n":
                Parser.callToken(parser)
        parser.currentNode = body.owner
        Scope.decrScope(parser)
        #print("should not compile", name)
        return body

    for i in range(len(names)):
        n = Tree.InitArg(names[i], parser)
        n.package = parser.package
        n.varType = types[i]
        n.imutable = not Scope.isMutable(parser, parser.package, names[i])
        body.addNode(n)

    parser.nextToken()
    Parser.callToken(parser)  #incase next case is newline

    while not Parser.isEnd(parser):
        parser.nextToken()
        t = parser.thisToken().token
        Parser.callToken(parser)

    ExprParser.endExpr(parser)

    parser.currentNode = body.owner

    Scope.decrScope(parser)
    return body
Exemple #5
0
        def compile(target, sources, filenames, former=None):
            global global_parser

            global_parser = cache

            #print(cache.usedModules)

            lexed = Lexer.lex(target, sources, filenames, files, cache, {},
                              tags)

            print("Lexed and parsed : " + str(Lexer.linesOfCode))

            declarations = Parser.Parser(lexed, filenames)
            declarations.hotswap = False
            declarations.shouldCompile = {}
            declarations.atoms = 0
            declarations.atomTyp = False
            declarations.outputFile = outputFile
            declarations.usedModules = {}
            declarations.path = os.path.abspath("")
            declarations.compilingRuntime = compileRuntime

            global_parser = declarations

            if cache:
                declarations.scope = cache.scope
                declarations.interfaces = cache.interfaces
                declarations.structs = cache.structs
                declarations.hotswap = hotswap
                declarations.allImports = cache.allImports
                declarations.atomTyp = cache.atomTyp
                declarations.hotswap = True
                declarations.usedModules = cache.usedModules
                declarations.specifications = cache.specifications
                declarations.includes = cache.includes

                Types.genericTypes = cache.generatedGenericTypes
                Types.inProjectTypes = {
                    name: None
                    for name in Types.genericTypes
                }
                from TopCompiler import Tree
                Tree.casted = cache.casted

                declarations.contextFields = cache.contextFields
                declarations.contextType = {}
                for package in declarations.contextFields:
                    declarations.contextType.update(
                        declarations.contextFields[package])

            if former:
                #print("inserting", target)
                ResolveSymbols.insert(former,
                                      declarations,
                                      only=True,
                                      copy=False)
                #print(declarations.scope["_global"])

            declarations.files = files
            declarations.lexed = lexed
            declarations.filenames = filenames
            declarations.opt = opt
            declarations.compiled = coll.OrderedDict()
            declarations.externFuncs = {"main": []}
            declarations.filenames_sources = filenames_sources
            declarations.global_target = target
            declarations.output_target = target
            declarations.didCompile = False
            declarations.linkWith = linkWith

            if (dev and run):
                clearMain(declarations)

            #print("declarations")

            #print(declarations.shouldCompile)

            declarations.setGlobalData(compileRuntime)
            ResolveSymbols.resolve(declarations)

            if opt == 3 or doc or ImportParser.shouldCompile(
                    False, "main", declarations):
                print("Recompiling")

                parser = Parser.Parser(lexed["main"], filenames["main"])
                parser.package = "main"
                ResolveSymbols.insert(declarations, parser, only=True)

                parser.files = files
                parser.global_target = target
                parser.output_target = target
                parser.lexed = lexed
                parser.filenames = filenames
                parser.compiled = declarations.compiled
                parser.compiled["main"] = None
                parser.contextFields["main"] = {}
                parser.dev = dev
                parser.sc = True

                parsed = parser.parse()

                parser.compiled["main"] = (True, (parsed, []))

                global_parser = parser

                import AST as Tree
                allCode = Tree.Root()
                """
                if opt > 0:
                    for d in parser.compiled:
                        allCode.addNode(parser.compiled[d][1][0])
                    optimize(allCode, opt)
                """

                #print("parsing")

                if doc:
                    return parser

                canStartWith = ['']

                order_of_modules = []

                compiled = parser.order_of_modules  # order_of_modules #parser.compiled

                typesInContext = []

                for i in parser.compiled:
                    parser.package = i
                    sc = parser.compiled[i][0]
                    if sc or not cache:
                        SimplifyAst.resolveGeneric(parser,
                                                   parser.compiled[i][1][0])

                #generatedTypes = Types.genericTypes
                #Types.genericTypes = {}
                contextCCode = CodeGen.buildContext(parser)
                """ 
                for i in parser.compiled:
                    parser.package = i
                    sc = parser.compiled[i][0]
                    if not parser.compiled[i][0]:
                        if cache and i in cache.generatedTypesPerPackage:
                            parser.generatedTypesPerPackage[i] = cache.generatedTypesPerPackage[i]
                            for typ in cache.generatedTypesPerPackage[i]:
                                Types.genericTypes[typ] = None
                                Types.inProjectTypes[typ] = None
                """

                #print(Types.genericTypes)
                #generatedTypes.update(Types.genericTypes)
                #Types.genericTypes = generatedTypes

                #if not compileRuntime:
                #    addTypes(removedTypes)
                #    contextCCode = CodeGen.buildContext(parser.contextType)

                includes = []

                for i in compiled:
                    tmp = os.path.dirname(parser.filenames[i][0][0])

                    dir = tmp[tmp.find("packages") + len("packages") +
                              1:tmp.rfind("src") - 1]
                    canStartWith.append(dir)

                    sc = parser.compiled[i][0]

                    if sc or not cache:
                        inc = CodeGen.CodeGen(parser,
                                              order_of_modules,
                                              i,
                                              parser.compiled[i][1][0],
                                              parser.compiled[i][1][1],
                                              target,
                                              opt,
                                              debug=debug).compile(opt=opt)
                        includes.extend(inc)
                        parser.includes[i] = inc
                    else:
                        includes.extend(parser.includes[i])

                order_of_modules.append("main")

                for i in parser.lexed:
                    parser.usedModules[i] = datetime.datetime.now()

                _linkWith = [i for (d, i) in linkWith if d in canStartWith]
                _headerIncludePath = [
                    i for (d, i) in headerIncludePath if d in canStartWith
                ]

                parser.generatedGenericTypes = Types.genericTypes
                if compileRuntime:  #not dev and not _raise:
                    deleteQue = []
                    for c in parser.generatedGenericTypes:
                        parser.generatedGenericTypes[c] = None
                        if c in ["_global_Allocator", "_global_Type"]:
                            deleteQue.append(c)

                    for c in deleteQue:
                        del parser.generatedGenericTypes[c]

                timeForCodeAnalysis = time() - beforeLoad

                print("Code Analysis : " + str(timeForCodeAnalysis))

                if False:  #not compileRuntime:
                    c = []

                    for i in compiled:
                        sc = parser.compiled[i][0]
                        if sc:
                            c.append(i)
                        else:
                            header = "lib/" + i + ".h"
                            header = os.path.abspath(header)
                            includes.append('#include "' + header + '"\n')

                    print(includes)

                    prelink = CodeGen.link(
                        c,
                        "recompiled_" + outputFile,
                        to_obj=True,
                        opt=opt,
                        dev=dev,
                        hotswap=hotswap,
                        debug=debug,
                        includes=includes,
                        linkWith=[],
                        headerIncludePath=_headerIncludePath,
                        target=target,
                        context=contextCCode,
                        runtimeBuild=compileRuntime)

                    l = CodeGen.link([],
                                     outputFile,
                                     to_obj=True,
                                     opt=opt,
                                     dev=dev,
                                     hotswap=hotswap,
                                     debug=debug,
                                     includes=includes,
                                     linkWith=[],
                                     headerIncludePath=_headerIncludePath,
                                     target=target,
                                     context=contextCCode,
                                     runtimeBuild=compileRuntime)

                    if not to_obj:
                        l = CodeGen.link([],
                                         outputFile,
                                         to_obj=to_obj,
                                         opt=opt,
                                         dev=dev,
                                         hotswap=hotswap,
                                         debug=debug,
                                         includes=includes,
                                         linkWith=_linkWith + [
                                             outputFile + ".o",
                                             "recompiled_" + outputFile + ".o"
                                         ],
                                         headerIncludePath=_headerIncludePath,
                                         target=target,
                                         context=contextCCode,
                                         runtimeBuild=compileRuntime)
                else:
                    l = CodeGen.link(compiled,
                                     outputFile,
                                     to_obj=to_obj,
                                     opt=opt,
                                     dev=dev,
                                     hotswap=hotswap,
                                     debug=debug,
                                     includes=includes,
                                     linkWith=_linkWith,
                                     headerIncludePath=_headerIncludePath,
                                     target=target,
                                     context=contextCCode,
                                     runtimeBuild=compileRuntime)
                if compileRuntime:
                    saveParser.save(parser, compileRuntime)

                print("\n======== recompiling =========")
                print("Compilation took : " + str(time() - time1))
                print("")

                if run:
                    if to_obj:
                        Error.error("Cannot run .obj")
                    CodeGen.exec(outputFile)

                didCompile = True

                parser.didCompile = True
                return parser
            elif run:
                CodeGen.exec(outputFile)

            return declarations
Exemple #6
0
def castFrom(originalType, newType, node, realName, codegen):
    key_cast = (originalType.name, newType.name)

    if originalType == newType:
        node.compileToC(codegen)
        return

    if originalType.isType(Types.FuncPointer):
        return node.compileToC(codegen)
    #elif type(newType) is Types.I32:
    #    return node.compileToC(codegen)
    elif type(newType) is Types.Interface:
        n = SimplifyAst.sanitize(newType.name if newType.package != "_global" else "_global_" + newType.name)

        if not key_cast in casted:
            from TopCompiler import topc

            tmp = SimplifyAst.sanitize(originalType.name + "_VTABLE_FOR_" + newType.name)  #CodeGen.genGlobalTmp(codegen.filename)

            codegen.inFunction()
            codegen.append("struct " + n + "_VTABLE " + tmp + ";")
            codegen.outFunction()
        else:
            tmp = casted[key_cast]

        if not type(originalType) is Types.Pointer:
            node.error("Can only convert to interface from pointer")

        originalType = originalType.pType
        codegen.append(n + "FromStruct(")
        node.compileToC(codegen)
        codegen.append(",")

        codegen.append("&" + tmp)
        codegen.append(",")

        if not key_cast in casted:
            get_type = BasicTypes.Typeof(node, originalType)
            casted[key_cast] = tmp
            castFrom(get_type.type, Parser.IType, get_type, "", codegen)
        else:
            codegen.append(tmp + ".type")


        for field in newType.types: #@cleanup handle recursive cast
            codegen.append(f", offsetof({originalType.toCType()},{field})")
        for field in newType.methods:
            if field in realName:
                name = realName[field]
            else:
                pack = "_global" if originalType.package == "" else originalType.package
                name = f"{pack}_{originalType.normalName}_{field}"

            codegen.append(f", &{name}")
        codegen.append(")")

        return
    elif type(newType) is Types.Array:
        if type(originalType) is Types.Alias:
            node.compileToC(codegen)
            return

        if newType.both and originalType.isType(Types.Pointer) and originalType.pType.static:
            if key_cast in casted:
                funcName = casted[key_cast]
            else:
                funcName = CodeGen.genGlobalTmp(codegen.filename)
                codegen.inGenerateFunction()

                inputT = codegen.getName()
                typNewC = newType.toCType()

                initCall = typNewC.replace("struct ", "") + "Init"

                codegen.append(f"{typNewC} {funcName}({originalType.toCType()} {inputT}) {{\n")
                codegen.append(f"return {initCall}({inputT}->data, {originalType.pType.numElements});")
                codegen.append("};\n")
                codegen.outFunction()
                casted[key_cast] = funcName

            codegen.append(f"{funcName}(")
            node.compileToC(codegen)
            codegen.append(")")

            return
        elif newType.both and originalType.empty:
            initCall = newType.toCType().replace("struct ", "") + "Init"
            codegen.append(initCall + "(NULL, 0)")
            return
        elif newType.both and not originalType.both and not originalType.static:
            if not type(node) in [Tree.ReadVar, Tree.Field]:
                node.error("not handled yet")

            typNewC = newType.toCType()
            initCall = typNewC.replace("struct ", "") + "Init"

            codegen.append(f"{initCall}(")
            node.compileToC(codegen)
            codegen.append(".data, ")
            node.compileToC(codegen)
            codegen.append(".length)")
            return

        elif originalType.empty:
            structName = newType.toCType()[len("struct "):]
            codegen.append(structName + "Init(0, 0, NULL, NULL)")

            """ 
            print(structName)
            if key_cast in casted:
                funcName = casted[key_cast]
            else:
                funcName = CodeGen.genGlobalTmp(codegen.filename)
                codegen.inGenerateFunction()

                inputT = codegen.getName()
                typNewC = newType.toCType()

                codegen.append(f"{typNewC} {funcName}({originalType.toCType()} {inputT}) {{\n")
                codegen.append(f"return *(({typNewC}*) &{inputT});")
                codegen.append("};\n")
                codegen.outFunction()

                casted[key_cast] = funcName

            codegen.append(f"{funcName}(")
            node.compileToC(codegen)
            codegen.append(")")
            """
            return

        print(newType.name)
        print(originalType.name)
        node.error("not handled yet")
    elif type(newType) in [Types.Enum, Types.Struct] and notSpecified(originalType):
        if Types.isMaybe(newType):
            codegen.append("NULL")
            return


        funcName = CodeGen.genGlobalTmp(codegen.filename)
        tmp = codegen.getName()
        inputT = codegen.getName()

        codegen.inGenerateFunction()

        typNewC = newType.toCType()

        codegen.append(f"static inline {typNewC} {funcName}({originalType.toCType()} {inputT}) {{\n")
        codegen.append(f"{typNewC} {tmp};")

        if type(newType) is Types.Enum: #@cleanup maybe optimization will cause this not to be valid
            codegen.append(f"{tmp}.tag = {inputT}.tag;")
            unionTyp = typNewC.replace("struct", "union", 1) + "_cases"
            codegen.append(f"{tmp}.cases = *({unionTyp}*) &({inputT}.cases);")
        else:
            for field in newType.types: #change this when using comes out
                codegen.append(f"{tmp}.{field} = {inputT}.{field};")

        codegen.append(f"return {tmp};\n}}\n")

        codegen.outFunction()

        codegen.append(funcName + "(")
        node.compileToC(codegen)
        codegen.append(")")
        return

    codegen.append("(" + newType.toCType() + ")")
    node.compileToC(codegen)
    def compileToC(self, codegen):
        codegen.inFunction()

        iType = self.iType
        context = codegen.getName()
        methods = {}

        pNone = Types.Pointer(Types.Null(), True)

        for methName in iType.methods:
            meth = iType.methods[methName]
            f = Types.FuncPointer([pNone] + meth.args, meth.returnType,
                                  meth.generic, meth.do)
            methods[methName] = f

        #interface as c struct
        vtable_name = self.name + "_VTABLE"

        codegen.append("struct " + self.name + " {\n")
        codegen.append(f"struct {vtable_name}* vtable;\n")
        codegen.append("void* data;\n")
        codegen.append("};")

        type_interface = "struct _global_Type"

        def gen_func(meth, field):
            s = meth.returnType.toCType()
            s += f"(*{field})("

            for (iter, i) in enumerate(meth.args):
                s += i.toCType() + ","
            s += "struct _global_Context*"
            s += ")"
            return s

        codegen.append(f"struct {vtable_name} {{")
        codegen.append(f"{type_interface} type;")
        for field in methods:
            meth = methods[field]
            meth_name = "method_" + field
            codegen.append(f"{gen_func(meth, meth_name)};\n")
        #codegen.append(f"{methods[field].toCType()} method_{field};\n")
        codegen.append("};")

        type_interface = Parser.IType.toCType()

        #for field in iType.types:
        #    codegen.append(f"unsigned short field_{field};\n") #just store offset, should be long enough let's see

        #helper function from struct to interface

        #if self.iType.package == "" or self.iType.package == "_global":
        #    front = self.normalName
        #else:
        front = SimplifyAst.sanitize(self.iType.fullName)

        if self.iType.package == "" or self.iType.package == "_global":
            front = "_global_" + front

        if len(self.iType.remainingGen) > 0:
            back = "_" + SimplifyAst.sanitize(self.iType.name)
        else:
            back = ""

        codegen.append(
            f"static inline struct {self.name} {self.name}FromStruct(void* data, struct {vtable_name}* vtable, {type_interface} typ"
        )
        method_names = []

        for field in methods:
            n = codegen.getName()
            codegen.append(f", {gen_func(methods[field], n)}")
            method_names.append(n)

        codegen.append("){ \n")

        tmp = codegen.getName()

        codegen.append(f"struct {self.name} {tmp};\n")

        codegen.append(f"{tmp}.data = data;")
        codegen.append(f"{tmp}.vtable = vtable;")
        for (name, field) in zip(method_names, methods):
            codegen.append(f"{tmp}.vtable->method_{field} = {name};\n")
        codegen.append(f"{tmp}.vtable->type = typ;\n")
        codegen.append(f"return {tmp}; \n}}")

        codegen.append(
            f"void* {self.name}_get_pointer_to_data(struct {self.name}* self, struct _global_Context* context) {{ return self->data; }}"
        )

        #print()

        #helper function to call methods
        for field in methods:
            typ = methods[field]
            #print(f"{front}_{field}{back}")
            codegen.append(
                f"static inline {typ.returnType.toCType()} {front}_{field}{back}(struct {self.name}* {tmp}"
            )
            names = []
            for i in typ.args[1:]:
                n = codegen.getName()
                names.append(n)
                codegen.append(f",{i.toCType()} {n}")
            codegen.append(f",struct _global_Context* {context}")

            codegen.append(f"){{\n")
            codegen.append(f"return {tmp}->vtable->method_{field}({tmp}->data")
            for i in names:
                codegen.append(f",{i}")
            codegen.append(f",{context}")
            codegen.append(");")
            codegen.append("\n};")

            codegen.append(
                f"static inline {typ.returnType.toCType()} {front}_{field}{back}ByValue(struct {self.name} {tmp}"
            )
            for (iter, i) in enumerate(typ.args[1:]):
                codegen.append(f",{i.toCType()} {names[iter]}")
            codegen.append(f",struct _global_Context* {context}")
            codegen.append(f"){{\n")
            data = codegen.getName()
            codegen.append(f"return {tmp}.vtable->method_{field}({tmp}.data")
            for i in names:
                codegen.append(f",{i}")
            codegen.append(f",{context}")
            codegen.append(");")
            codegen.append("\n};")

        codegen.append(
            f"{type_interface} {self.name}_get_type(struct {self.name}* {tmp}, struct _global_Context* context)"
        )
        codegen.append("{ return " + tmp + "->vtable->type; }")

        codegen.append(
            f"{type_interface} {self.name}_get_typeByValue(struct {self.name} {tmp}, struct _global_Context* context)"
        )
        codegen.append("{ return " + tmp + ".vtable->type; }\n")

        interface_type = Parser.InterfaceType.toCType()

        if self.name.endswith("_"):
            typ_name = self.name + "Type"
        else:
            typ_name = f"{self.name}_Type"

        codegen.append(f"{interface_type} {typ_name};")

        codegen.outFunction()

        def as_string(s):
            return f'_global_StringInit({len(s)}, "{s}")'

        codegen.append(f"{typ_name}.name = " + as_string(iType.normalName))
        codegen.append(f";{typ_name}.package = " + as_string(iType.package) +
                       ";")
        """
        struct Animal Animal_FromString(void* data, size_t offset)
            struct Animal a;
            a.data = data;
            a.type = type;
            a.offset = offset;
        };
        
        
        """

        if self.name in Types.compiledTypes and not self.name == "_global_Type":
            del Types.compiledTypes[self.name]