def codegen(self, c): mainclass, *classes = self.children c.setLine(1) #codegen classes for cls in classes: cls.codegen(c) #make main function main = CodeGen(c.filename, 'main') main.setFlags(Flags.NEWLOCALS | Flags.OPTIMIZED) mainclass.codegen(main) c.LOAD_CONST(main) c.MAKE_FUNCTION() c.STORE_NAME('main') #ifmain c.LOAD_NAME('__name__') c.LOAD_CONST('__main__') c.COMPARE_OP(CmpOp.EQUAL) dest = c.POP_JUMP_IF_FALSE() c.LOAD_NAME('main') c.CALL_FUNCTION() c.POP_TOP() #module return dest() c.LOAD_CONST(None) c.RETURN_VALUE()
def genMethod(method, methodname): func = CodeGen(cls.filename, methodname) func.setFlags(Flags.NEWLOCALS | Flags.OPTIMIZED) func.argcount = len(method.formallist) + 1 func.varnames = ['self'] + list(map(lambda formal: formal.ID, method.formallist)) method.codegen(func) cls.LOAD_CONST(func) cls.MAKE_FUNCTION() cls.STORE_NAME(methodname)
def codegen(self, c): for method in self.children: methodname = '{0}__{1}'.format(self.name, method.ID) func = CodeGen(c.filename, methodname) func.setFlags(Flags.NEWLOCALS | Flags.OPTIMIZED) func.argcount = len(method.formallist)+1 func.varnames = ['self'] + list(map(lambda formal: formal.ID, method.formallist)) method.codegen(func) c.LOAD_CONST(func) c.MAKE_FUNCTION() c.STORE_NAME(methodname)
def codegen(path, tree, dumpbin=False): module = CodeGen(path, "<module>") tree.codegen(module) co = module.code() with open(path, "wb") as fout: # magic header fout.write(imp.get_magic()) # timestamp fout.write(struct.pack("I", int(time.time()))) # code object marshal.dump(co, fout) if dumpbin: dump(co)
def codegen(self, c): c.LOAD_BUILD_CLASS() cls = CodeGen(c.filename, self.name) cls.setFlags(Flags.NEWLOCALS) cls.argcount = 1 cls.setLine(1) cls.LOAD_FAST('__locals__') cls.STORE_LOCALS() cls.LOAD_NAME('__name__') cls.STORE_NAME('__module__') #define constructor to initialize class variables init = CodeGen(cls.filename, '__init__') init.setFlags(Flags.NEWLOCALS | Flags.OPTIMIZED) init.argcount = 1 init.varnames = ['self'] if self.parent: init.LOAD_GLOBAL(self.parent) init.LOAD_ATTR('__init__') init.LOAD_FAST('self') init.CALL_FUNCTION(1) init.POP_TOP() for var in self.classvars: vartype = var.typename if vartype == ast.IntType: init.LOAD_CONST(0) elif vartype == ast.BoolType: init.LOAD_CONST(False) else: init.LOAD_CONST(None) init.LOAD_FAST('self') init.STORE_ATTR('_' + var.ID) init.LOAD_CONST(None) init.RETURN_VALUE() cls.LOAD_CONST(init) cls.MAKE_FUNCTION() cls.STORE_NAME('__init__') #generate methods def genMethod(method, methodname): func = CodeGen(cls.filename, methodname) func.setFlags(Flags.NEWLOCALS | Flags.OPTIMIZED) func.argcount = len(method.formallist) + 1 func.varnames = ['self'] + list(map(lambda formal: formal.ID, method.formallist)) method.codegen(func) cls.LOAD_CONST(func) cls.MAKE_FUNCTION() cls.STORE_NAME(methodname) for method in self.children: genMethod(method, method.ID) if method.ID == 'toString': genMethod(method, '__str__') cls.LOAD_CONST(None) cls.RETURN_VALUE() c.LOAD_CONST(cls) c.MAKE_FUNCTION() c.LOAD_CONST(self.name) if self.parent: c.LOAD_GLOBAL(self.parent) c.CALL_FUNCTION(3) else: c.CALL_FUNCTION(2) c.STORE_NAME(self.name)