Index: BaseEvaluator.py =================================================================== RCS file: /cvsroot/jython/jython/Tools/jythonc/BaseEvaluator.py,v retrieving revision 2.9 diff -u -5 -r2.9 BaseEvaluator.py --- BaseEvaluator.py 2000/11/10 15:06:56 2.9 +++ BaseEvaluator.py 2001/05/20 16:15:27 @@ -86,11 +86,11 @@ return self.visit(obj).delattr(name) def set(self, node, value): if node.id == JJTNAME: return self.set_name(node.getInfo(), value) - elif node.id == JJTLIST or node.id == JJTTUPLE: + elif node.id == JJTLIST or node.id == JJTFPLIST or node.id == JJTTUPLE: return self.set_list(nodeToList(node), value) elif node.id == JJTINDEX_OP: return self.set_item(node.getChild(0), node.getChild(1), value) elif node.id == JJTDOT_OP: Index: ObjectFactory.py =================================================================== RCS file: /cvsroot/jython/jython/Tools/jythonc/ObjectFactory.py,v retrieving revision 2.7 diff -u -5 -r2.7 ObjectFactory.py --- ObjectFactory.py 2001/03/22 20:07:08 2.7 +++ ObjectFactory.py 2001/05/20 16:15:27 @@ -28,16 +28,16 @@ def importName(self, name): ns = PyNamespace(self.parent, name) return Object(ns.getNew(), ns) - def makeFunction(self, name, args, body, doc=None): - func = PyFunction(self.parent, self, name, args, body, doc) + def makeFunction(self, name, def_compiler, scope, body, doc=None): + func = PyFunction(self, name, def_compiler, scope, body, doc) return Object(func.getNew(), func) - def makeClass(self, name, bases, body, doc=None): - cls = PyClass(self.parent, self, name, bases, body, doc) + def makeClass(self, name, bases, def_compiler, scope, body, doc=None): + cls = PyClass(self, name, bases, def_compiler, scope, body, doc) # Yuck! We can't call getNew() before all modules have been analyzed. class DelayGen: def __init__(self, cls): self.cls = cls self.cls.makeCode() @@ -102,21 +102,17 @@ def makeSlice(self, items): code = jast.New("PySlice", [items[0].asAny(), items[1].asAny(), items[2].asAny()]) return Object(code, Generic) - def makeFunctionFrame(self): - return SimpleCompiler.LocalFrame(self.parent) + def getCompiler(self, parent_compiler, frameCtr, scope): + return SimpleCompiler.SimpleCompiler(self.parent.module, self, + parent = parent_compiler, + frameCtr = frameCtr, + scope = scope, + options = self.parent.options) - def makeClassFrame(self): - return SimpleCompiler.LocalFrame(self.parent, - SimpleCompiler.DynamicStringReference) - - def getCompiler(self, frame): - return SimpleCompiler.SimpleCompiler(self.parent.module, self, frame, - self.parent.options) - class FixedObject(PyObject): pass @@ -129,51 +125,57 @@ return jast.Comment(str(self.value)) class PyFunction(FixedObject): - def __init__(self, parent, factory, name, args, body, doc=None): + def __init__(self, factory, name, def_compiler,scope, body, doc=None): self.name = name self.factory = factory - self.parent = parent - self.args = args + self.def_compiler = def_compiler + self.scope = scope self.body = body self.doc = doc def getNew(self): - globals = jast.GetInstanceAttribute(self.parent.frame.frame, + globals = jast.GetInstanceAttribute(self.def_compiler.frame.frame, "f_globals") pycode = self.makeCode() - return jast.New("PyFunction", - [globals, PyObjectArray(self.args.defaults), pycode]) + defaults = [ d.visit(self.def_compiler.visitor) for d in self.scope.ac.defaults ] + clos = self.def_compiler.frame.makeClosure(self.scope) + ctrargs = [globals, PyObjectArray(defaults), pycode] + if clos: + ctrargs.append(PyObjectArray(clos)) + return jast.New("PyFunction", ctrargs) - def makeCode(self): - # Don't handle a,b style args yet - init_code = [] - frame = self.parent.frame + def makeCode(self): # now handles a,b style args too # Add args to funcframe - funcframe = self.factory.makeFunctionFrame() - for argname in self.args.names: - funcframe.setname(argname, self.factory.makePyObject(None)) - #funcframe.addlocal(argname) + ac = self.scope.ac # Parse the body - comp = self.factory.getCompiler(funcframe) - code = jast.Block([comp.parse(self.body)]) + comp = self.factory.getCompiler(self.def_compiler,SimpleCompiler.FunctionFrame,self.scope) + for argname in ac.names: + comp.frame.setname(argname, self.factory.makePyObject(None)) + + tree = self.body + if ac.init_code.numChildren > 0: + ac.init_code.jjtAddChild(tree, ac.init_code.numChildren) + tree = ac.init_code + code = jast.Block([comp.parse(tree)]) # Set up a code object - self.pycode = self.parent.module.getCodeConstant( - self.name, self.args, funcframe.getlocals(), code) - self.frame = funcframe + self.pycode = self.def_compiler.top_compiler.module.getCodeConstant( + self.name, code, comp.frame) + self.frame = comp.frame return self.pycode class PyClass(FixedObject): - def __init__(self, parent, factory, name, bases, body, doc=None): + def __init__(self, factory, name, bases, def_compiler, scope, body, doc=None): self.name = name - self.parent = parent self.factory = factory self.bases = bases + self.def_compiler = def_compiler + self.scope = scope self.body = body self.doc = doc def getNew(self): args = [jast.StringConstant(self.name), @@ -181,10 +183,14 @@ jast.Null] if self.isSuperclassJava(): args.append(jast.Identifier("%s.class" % self.proxyname)) + clos = self.def_compiler.frame.makeClosure(self.scope) + if clos: + args.append(PyObjectArray(clos)) + return jast.InvokeStatic("Py", "makeClass", args) def isSuperclassJava(self): if hasattr(self, 'javaclasses'): return len(self.javaclasses) @@ -238,19 +244,18 @@ self.proxyname = self.name return self.supername != None def makeCode(self): - classframe = self.factory.makeClassFrame() - comp = self.factory.getCompiler(classframe) + comp = self.factory.getCompiler(self.def_compiler, + SimpleCompiler.ClassFrame, self.scope) code = jast.Block([comp.parse(self.body), - jast.Return(jast.Invoke(classframe.frame, + jast.Return(jast.Invoke(comp.frame.frame, "getf_locals", []))]) - self.frame = classframe - self.pycode = self.parent.module.getCodeConstant( - self.name, None, - classframe.getlocals(), code) + self.frame = comp.frame + self.pycode = self.def_compiler.top_compiler.module.getCodeConstant( + self.name, code, comp.frame) return self.pycode class PyNamespace(FixedObject): def __init__(self, parent, name): self.name = name Index: PythonModule.py =================================================================== RCS file: /cvsroot/jython/jython/Tools/jythonc/PythonModule.py,v retrieving revision 2.13 diff -u -5 -r2.13 PythonModule.py --- PythonModule.py 2000/11/20 21:55:49 2.13 +++ PythonModule.py 2001/05/20 16:15:28 @@ -2,15 +2,16 @@ import os import jast import java, org -from PythonVisitor import Arguments EMPTYSTRING = '' +from org.python.core.PyTableCode import CO_OPTIMIZED,CO_NESTED + """ class foo class py -- what gets imported by jpython holds all py constants @@ -41,10 +42,17 @@ else: return EMPTYSTRING.join(letters) + +def StringArrayOrNull(strs): + if strs: + return jast.StringArray(strs) + else: + return jast.Null + class PythonInner: def __init__(self, parent): self.constantValues = {} self.constants = [] self.codes = [] @@ -92,16 +100,14 @@ def getStringConstant(self, value): code = jast.InvokeStatic("Py", "newString", [jast.StringConstant(value)]) return self.getConstant(value, code, "s") - def getCodeConstant(self, name, args, locals, code): - if args is None: - args = Arguments([]) + def getCodeConstant(self, name, code, frame): label = "c$%d_%s" % (len(self.codes), legalJavaName(name)) ret = jast.Identifier(label) - self.codes.append( (label, name, args, locals, code) ) + self.codes.append( (label, name, code, frame) ) return ret def dumpConstants(self): self.dumpCodes() stmts = [] @@ -116,30 +122,39 @@ return decls def dumpCodes(self): self.constants.append(["PyFunctionTable", self.getFunctionTable(), jast.New(self.name, [])]) + + for label, name, code, frame in self.codes: + code = frame.toCellPrepend(code) - for label, name, args, locals, code in self.codes: funcid = self.addFunctionCode(name, code) arglist = keyworddict = jast.False - if args.arglist: + if frame.args_arglist(): arglist = jast.True - if args.keyworddict: + if frame.args_keyworddict(): keyworddict = jast.True - names = jast.StringArray(locals) + names = jast.StringArray(frame.getnames()) + cellnames = StringArrayOrNull(frame.getcellnames()) + freenames = StringArrayOrNull(frame.getfreenames()) + npurecell = frame.get_npurecell() - cargs = [jast.IntegerConstant(len(args.names)), + cargs = [jast.IntegerConstant(frame.args_count()), names, jast.StringConstant(self.filename), jast.StringConstant(name), arglist, keyworddict, self.getFunctionTable(), - jast.IntegerConstant(funcid)] + jast.IntegerConstant(funcid), + cellnames, + freenames, + jast.IntegerConstant(npurecell), + jast.IntegerConstant((frame.opt_globals and CO_OPTIMIZED) | (frame.scope.nested_scopes and CO_NESTED))] newcode = jast.InvokeStatic("Py", "newCode", cargs) self.constants.append(("PyCode", jast.Identifier(label), newcode)) def uniquename(self, name): self.uniquenames.append(name) @@ -181,12 +196,11 @@ def addFunctionCode(self, name, code): self.funccodes.append((legalJavaName(name), len(self.funccodes), code)) return len(self.funccodes)-1 def addMain(self, code, cc): - self.mainCode = self.getCodeConstant("main", Arguments([]), - cc.frame.getlocals(), code) + self.mainCode = self.getCodeConstant("main", code, cc.frame) def dumpMain(self): if not hasattr(self, 'mainCode'): return [] meths = [] @@ -299,12 +313,12 @@ return self.pyinner.getFloatConstant(value) def getStringConstant(self, value): return self.pyinner.getStringConstant(value) - def getCodeConstant(self, name, args, locals, code): - return self.pyinner.getCodeConstant(name, args, locals, code) + def getCodeConstant(self, name, code, frame): + return self.pyinner.getCodeConstant(name, code, frame) def addFunctionCode(self, name, code): return self.pyinner.addFunctionCode(name, code) def addMain(self, code, cc): Index: PythonVisitor.py =================================================================== RCS file: /cvsroot/jython/jython/Tools/jythonc/PythonVisitor.py,v retrieving revision 2.7 diff -u -5 -r2.7 PythonVisitor.py --- PythonVisitor.py 2000/11/10 15:08:48 2.7 +++ PythonVisitor.py 2001/05/20 16:15:28 @@ -2,10 +2,12 @@ from org.python.parser import Visitor, SimpleNode from org.python.parser.PythonGrammarTreeConstants import * from org.python.parser import SimpleNode +from org.python.compiler import Future + comp_ops = {JJTLESS_CMP : 'lt', JJTEQUAL_CMP : 'eq', JJTGREATER_CMP : 'gt', JJTGREATER_EQUAL_CMP: 'ge', @@ -31,49 +33,10 @@ names.append(node.getChild(i).getInfo()) return names -class Arguments(Visitor): - def __init__(self, parent, argslist=None): - self.arglist = 0 - self.keyworddict = 0 - self.names = [] - self.defaults = [] - - self.parent = parent - - if argslist is not None: - argslist.visit(self) - - def varargslist(self, node): - for i in range(node.numChildren): - node.getChild(i).visit(self) - - def ExtraArgList(self, node): - self.arglist = 1 - self.names.append(node.getChild(0).visit(self)) - - def ExtraKeywordList(self, node): - self.keyworddict = 1 - self.names.append(node.getChild(0).visit(self)) - - def defaultarg(self, node): - name = node.getChild(0).visit(self) - self.names.append(name) - if node.numChildren > 1: - self.defaults.append(node.getChild(1).visit(self.parent)) - - def fplist(self, node): - return 'ugh' - pass # ??? - - def Name(self, node): - return node.getInfo() - - - def getDocString(suite): if suite.numChildren > 0: n = suite.getChild(0) if n.id == JJTEXPR_STMT and n.getChild(0).id == JJTSTRING: return n.getChild(0).getInfo() @@ -162,10 +125,11 @@ self.startnode(node) names = self.import_as_name(node, 0) return self.walker.import_stmt(names) def ImportFrom(self, node): + Future.checkFromFuture(node) # future stmt support self.startnode(node) if node.numChildren > 1: names = self.import_as_name(node, 1) return self.walker.importfrom_stmt(node.getChild(0).visit(self), names) @@ -517,29 +481,20 @@ funcname = node.getChild(0).getInfo() Body = node.getChild(node.numChildren-1) doc = getDocString(Body) - if node.numChildren > 2: - args = Arguments(self, node.getChild(1)) - else: - args = Arguments(self) - return self.walker.funcdef(funcname, args, Body, doc) + return self.walker.funcdef(funcname, node.scope, Body, doc) def lambdef(self, node): Body = node.getChild(node.numChildren-1) - if node.numChildren > 1: - args = Arguments(self, node.getChild(0)) - else: - args = Arguments(self) - retBody = SimpleNode(JJTRETURN_STMT) retBody.jjtAddChild(Body, 0) - return self.walker.lambdef(args, retBody) + return self.walker.lambdef(node.scope, retBody) def classdef(self, node): self.startnode(node) name = node.getChild(0).getInfo() @@ -548,6 +503,6 @@ doc = getDocString(suite) bases = [] for i in range(1, n-1): bases.append(node.getChild(i).visit(self)) - return self.walker.classdef(name, bases, suite, doc) + return self.walker.classdef(name, bases, node.scope, suite, doc) Index: SimpleCompiler.py =================================================================== RCS file: /cvsroot/jython/jython/Tools/jythonc/SimpleCompiler.py,v retrieving revision 2.13 diff -u -5 -r2.13 SimpleCompiler.py --- SimpleCompiler.py 2001/02/25 15:37:21 2.13 +++ SimpleCompiler.py 2001/05/20 16:15:28 @@ -1,130 +1,84 @@ # Copyright © Corporation for National Research Initiatives from BaseEvaluator import BaseEvaluator -from PythonVisitor import Arguments import jast import ImportName COMMASPACE = ', ' +from org.python.compiler import ScopesCompiler, Future, CompilationContext +from org.python.compiler.ScopeConstants import * - -class Reference: - def __init__(self, frame, name): - self.iframe = frame.frame - self.frame = frame - self.locals = frame.locals - self.name = name - self.value = None - self.init() - - def init(self): pass - - def noValue(self): - raise NameError, 'try to get %s before set' % repr(self.name) - - def getValue(self): - if self.value is None: - return self.noValue() - return self.value - - def setValue(self, value): - if self.value is None: - self.value = value.makeReference(self.getCode()) - else: - # Might want to try and merge types here... - self.value = self.value.mergeWith(value) - self.value.code = self.getCode() - #PyObject(self.getCode(), None) - return self.setCode(value) - - def delValue(self): - #self.value = None - return self.delCode() - +import warnings +from org.python.parser import ParseException -class DynamicIntReference(Reference): - def init(self): - self.ivalue = jast.IntegerConstant(len(self.locals)) - - def getCode(self): - return jast.Invoke(self.iframe, "getlocal", (self.ivalue,)) - - def setCode(self, value): - return jast.Invoke(self.iframe, "setlocal", - (self.ivalue, value.asAny())) +class LocalFrame: + def __init__(self, compiler, scope=None): + + self.frame = jast.Identifier("frame") - def delCode(self): - return jast.Invoke(self.iframe, "dellocal", (self.ivalue,)) + self.compiler = compiler + self.names = {} - -class DynamicStringReference(Reference): - def init(self): - self.ivalue = jast.StringConstant(self.name) - - def getCode(self): - return jast.Invoke(self.iframe, "getname", (self.ivalue,)) - - def delCode(self): - return jast.Invoke(self.iframe, "delname", (self.ivalue,)) - - def setCode(self, value): - return jast.Invoke(self.iframe, "setlocal", - (self.ivalue, value.asAny())) - -class DynamicStringReference2(DynamicStringReference): - def setCode(self, value): - return jast.Invoke(self.iframe, "setglobal", - (self.ivalue, value.asAny())) - - def noValue(self): - # Reference to builtin - return self.frame.parent.factory.makePyObject(self.getCode()) + self.temporaries = {} - -class DynamicGlobalStringReference(Reference): - def init(self): - self.ivalue = jast.StringConstant(self.name) - - def getCode(self): - return jast.Invoke(self.iframe, "getglobal", (self.ivalue,)) - - def delCode(self): - return jast.Invoke(self.iframe, "delglobal", (self.ivalue,)) - - def setCode(self, value): - return jast.Invoke(self.iframe, "setglobal", - (self.ivalue, value.asAny())) - - def noValue(self): - # Reference to builtin - return self.frame.parent.factory.makePyObject(self.getCode()) + self.scope = scope + self.fast_locals = 0 + self.opt_globals = 0 - -class LocalFrame: - def __init__(self, parent, newReference=DynamicIntReference): - self.frame = jast.Identifier("frame") - - # This should only use SlowGlobals if the function uses - # ImportAll or ExecStmt. If not it should use - # parent.globalNamespace. - - #self.globalNamespace = SlowGlobals(parent) - self.globalNamespace = parent.globalNamespace - - self.parent = parent - self.newReference = newReference - - self.names = {} - self.globals = {} - self.locals = [] + def setupClosure(self,nested_scope): + nested_scope.setup_closure(self.scope) - self.temporaries = {} + def makeClosure(self,nested_scope): + freenames = nested_scope.freevars + if len(freenames) == 0: return None + clos = [] + factory = self.compiler.factory + for free in freenames: + i = self.scope.tbl.get(free).env_index + code = jast.Invoke(self.frame, "getclosure", [jast.IntegerConstant(i)]) + clos.append(factory.makePyObject(code)) + return clos + + def getnames(self): + return self.scope.names + + def args_count(self): + if self.scope.ac: + return len(self.scope.ac.names) + return 0 + + def args_arglist(self): + return self.scope.ac and self.scope.ac.arglist + + def args_keyworddict(self): + return self.scope.ac and self.scope.ac.keywordlist + + def getfreenames(self): + return self.scope.freevars + + def getcellnames(self): + return self.scope.cellvars + + def get_npurecell(self): + return self.scope.jy_npurecell + + def toCellPrepend(self,code): + scope = self.scope + pre = [] + for parmcell in scope.jy_paramcells: + syminf = scope.tbl.get(parmcell) + args = [jast.IntegerConstant(syminf.locals_index), + jast.IntegerConstant(syminf.env_index)] + pre.append(jast.Invoke(self.frame, "to_cell", args)) + if not pre: return code + pre.append(jast.BlankLine()) + return jast.Block(jast.flatten([pre,code])) def gettemps(self, type): try: temps = self.temporaries[type] except KeyError: @@ -159,45 +113,94 @@ if temps[index] is None: raise ValueError, 'temp already freed' temps[index] = None - def getname(self, name): - if not self.names.has_key(name): - return self.globalNamespace.getname(self, name) - ref = self.getReference(name) - return ref.getValue() + def get_local_value(self,name): + if self.names.has_key(name): return self.names[name] + return None # ?? better to fail? when? + + def get_closure_value(self,name,up=0): + if not up: + syminf = self.scope.tbl.get(name) + if syminf and syminf.flags&CELL: return self.get_local_value(name) + return self.compiler.parent_compiler.frame.get_closure_value(name) + + def get_global_value(self,name): + return self.compiler.top_compiler.frame.get_local_value(name) + + def get_name_value(self,name): + if self.names.has_key(name): return self.names[name] + return self.get_global_value(name) - def delname(self, name): - if self.globals.has_key(name): - return self.globalNamespace.delname(self, name) - ref = self.getReference(name) - return ref.delValue() + def set_global_value(self,name,value): + self.compiler.top_compiler.frame.set_value(name,value) - def setname(self, name, value): - if self.globals.has_key(name): - return self.globalNamespace.setname(self, name, value) - ref = self.getReference(name) - return ref.setValue(value) - - def addglobal(self, name): - self.globals[name] = 1 + def set_value(self,name,value): + if self.names.has_key(name): + self.names[name] = self.names[name].mergeWith(value) + return + self.names[name] = value + + def delCode(self,method,ref): + if type(ref) is type(""): + ref = (jast.StringConstant(ref),) + else: + ref = (jast.IntegerConstant(ref),) + return jast.Invoke(self.frame,method,ref) + + def getReference(self,value,method,ref): + code = self.delCode(method,ref) + if value: return value.makeReference(code) + return self.compiler.factory.makePyObject(code) + + def setCode(self,method,ref,value): + if type(ref) is type(""): + args = (jast.StringConstant(ref),value.asAny()) + else: + args = (jast.IntegerConstant(ref),value.asAny()) + return jast.Invoke(self.frame,method,args) - def addlocal(self, name): - self.getReference(name) + def getglobal(self,name): + return self.getReference(self.get_global_value(name),'getglobal',name) - def getlocals(self): - return self.locals + def getname(self, name): + syminf = self.scope.tbl.get(name) + if syminf: + flags = syminf.flags + if not self.scope.nested_scopes: flags &= ~FREE + if flags&GLOBAL or self.opt_globals and not (flags&(BOUND|CELL|FREE)): + return self.getglobal(name) + if self.fast_locals: + if flags&CELL: return self.getReference( + self.get_closure_value(name),'getderef',syminf.env_index) + if flags&BOUND: return self.getReference( + self.get_local_value(name),'getlocal',syminf.locals_index) + if flags&FREE and not flags&BOUND: return self.getReference( + self.get_closure_value(name,up=1),'getderef',syminf.env_index) + return self.getReference(self.get_name_value(name),'getname',name) + - def getReference(self, name): - if self.names.has_key(name): - return self.names[name] - ret = self.newReference(self, name) - self.names[name] = ret - self.locals.append(name) - return ret + def delname(self, name): + syminf = self.scope.tbl.get(name) + if syminf and syminf.flags&GLOBAL: return self.delCode('delglobal',name) + if not self.fast_locals: return self.delCode('dellocal',name) + if syminf.flags&CELL: raise NameError,"can not delete variable '%s' referenced in nested scope" % name + return self.delCode('dellocal',syminf.locals_index) + def setname(self, name, value): + syminf = self.scope.tbl.get(name) + if syminf and syminf.flags&GLOBAL: + self.set_global_value(name,value) + return self.setCode('setglobal',name,value) + + self.set_value(name,value) + + if not self.fast_locals: return self.setCode('setlocal',name,value) + if syminf and syminf.flags&CELL: return self.setCode('setderef',syminf.env_index,value) + return self.setCode('setlocal',syminf.locals_index,value) + def getDeclarations(self): if len(self.temporaries) == 0: return [] decs = [jast.SimpleComment("Temporary Variables")] @@ -211,58 +214,40 @@ return decs class GlobalFrame(LocalFrame): - def __init__(self, parent): - LocalFrame.__init__(self, parent) - self.globalNamespace = parent.globalNamespace + def __init__(self, compiler): + LocalFrame.__init__(self, compiler) - def getReference(self, name): - return self.globalNamespace.getReference(self, name) + def setScope(self,scope): self.scope = scope - - -class BasicGlobals: - def __init__(self, parent, newReference=DynamicGlobalStringReference): - self.names = {} - self.newReference = newReference - self.parent = parent - - def delname(self, frame, name): - ref = self.getReference(frame, name) - return ref.delValue() - - def getname(self, frame, name): - ref = self.getReference(frame, name) - return ref.getValue() - - def setname(self, frame, name, value): - ref = self.getReference(frame, name) - return ref.setValue(value) - - def getReference(self, frame, name): - if self.names.has_key(name): - return self.names[name] - ret = self.newReference(frame, name) - self.names[name] = ret - return ret - -class SlowGlobals(BasicGlobals): - def __init__(self, parent, newReference=DynamicStringReference2): - self.names = {} - self.newReference = newReference - self.parent = parent +class ClassFrame(LocalFrame): + def getnames(self): + return [] +class FunctionFrame(LocalFrame): + def __init__(self,compiler,scope): + LocalFrame.__init__(self,compiler,scope=scope) + self.fast_locals = 1 + self.opt_globals = not scope.exec and not scope.from_import_star -class SimpleCompiler(BaseEvaluator): - def __init__(self, module, factory, frame=None, options=None): +class SimpleCompiler(BaseEvaluator, CompilationContext): + def __init__(self, module, factory, parent=None, frameCtr=None, scope=None, + options=None): BaseEvaluator.__init__(self) - self.globalNamespace = BasicGlobals(self) - if frame is None: + + if parent is None: frame = GlobalFrame(self) + self.parent_compiler = None + self.top_compiler = self + else: + frame = frameCtr(self, scope=scope) + self.parent_compiler = parent + self.top_compiler = parent.top_compiler + self.frame = frame self.module = module self.nthrowables = 0 self.factory = factory self.options = options @@ -271,11 +256,31 @@ def isAlwaysFalse(self, name): if self.options is None: return 0 return name in self.options.falsenames + def getFutures(self): + return self._futures + + def getFilename(self): + return self.module.filename + + def error(self,msg,err,node): + if not err: + try: + warnings.warn_explicit(msg,SyntaxWarning,self.getFilename(),node.beginLine) + return + except Exception,e: + if not isinstance(e,SyntaxWarning): raise e + raise ParseException(msg,node) + def parse(self, node): + if isinstance(self.frame,GlobalFrame): + futures = self._futures = Future() + futures.preprocessFutures(node,None) + ScopesCompiler(self).parse(node) + self.frame.setScope(node.scope) ret = BaseEvaluator.parse(self, node) #print 'parse', ret decs = self.frame.getDeclarations() if len(decs) != 0: return [decs, jast.SimpleComment('Code'), ret] @@ -386,12 +391,10 @@ def name_const(self, name): return self.frame.getname(name) def global_stmt(self, names): - for name in names: - self.frame.addglobal(name) return jast.SimpleComment('global ' + COMMASPACE.join(names)) def get_module(self, names, topmost=0): ret = self.factory.importName(names[0]) top = ret @@ -565,11 +568,11 @@ args = [test.asAny()] if message is not None: args.append(message.asAny()) - return jast.If(self.name_const("__debug__").nonzero(), + return jast.If(self.frame.getglobal("__debug__").nonzero(), jast.InvokeStatic("Py", "assert", args)) def return_stmt(self, value=None): if value is None: return jast.Return(jast.GetStaticAttribute("Py", "None")) @@ -712,20 +715,23 @@ self.frame.freetemp(wtmp) return ret else: return [init, jast.While(test, suite)] - def funcdef(self, name, args, body, doc=None): - func = self.factory.makeFunction(name, args, body, doc) + def funcdef(self, name, scope, body, doc=None): + self.frame.setupClosure(scope) + func = self.factory.makeFunction(name, self, scope, body, doc) return self.set_name(name, func) - def lambdef(self, args, body): - func = self.factory.makeFunction("", args, body) + def lambdef(self, scope, body): + self.frame.setupClosure(scope) + func = self.factory.makeFunction("", self, scope, body) return func - def classdef(self, name, bases, body, doc=None): - c = self.factory.makeClass(name, bases, body, doc) + def classdef(self, name, bases, scope, body, doc=None): + self.frame.setupClosure(scope) + c = self.factory.makeClass(name, bases, self, scope, body, doc) self.module.classes[name] = c return self.set_name(name, c) def addModule(self, mod, value=1): #print 'add module', mod Index: compile.py =================================================================== RCS file: /cvsroot/jython/jython/Tools/jythonc/compile.py,v retrieving revision 2.17 diff -u -5 -r2.17 compile.py --- compile.py 2001/03/22 20:07:08 2.17 +++ compile.py 2001/05/20 16:15:28 @@ -133,14 +133,14 @@ def makeJavaProxy(module, pyc): frame = pyc.frame methods = [] for name, func in frame.names.items(): - v = func.value.value + v = func.value args = None - if hasattr(v, 'args'): - args = v.args + if hasattr(v, 'frame'): + args = v.frame.scope.ac sig = None if hasattr(v, 'doc'): if name == "__init__": sig = getsig(v.doc, args, constructor=1) else: @@ -218,17 +218,23 @@ def compile(self, data, filename, name): if self.javapackage is not None: name = self.javapackage+'.'+name - data = "__file__=%s\n" % repr(filename) + data + '\n\n' - + data = data + '\n\n' + mod = PythonModule(name, filename, frozen=self.deep) fact = ObjectFactory() pi = SimpleCompiler(mod, fact, options=self.options) fact.parent = pi - code = jast.Block(pi.execstring(data)) + code = pi.execstring(data) + # __file__ + code.insert(0,jast.Invoke(jast.Identifier('frame'),"setglobal", + [jast.StringConstant('__file__'), + mod.getStringConstant(filename)])) + code.insert(1,jast.BlankLine()) + code = jast.Block(code) mod.addMain(code, pi) self.addDependencies(mod) return mod def addJavaClass(self, name, parent):