Index: peak/rules/codegen.py =================================================================== --- peak/rules/codegen.py (revision 2704) +++ peak/rules/codegen.py (working copy) @@ -2,6 +2,7 @@ from peak.util.symbols import Symbol from peak.rules.core import gen_arg, clone_function from ast_builder import build, parse_expr +from types import ModuleType import sys try: set @@ -31,14 +32,13 @@ return code.SLICE_0() +def module_to_ns(ns): + if isinstance(ns, ModuleType): + return ns.__dict__ + return ns - - - - - nodetype(fmt="%s:%s:%s") def BuildSlice(start=Pass, stop=Pass, stride=Pass, code=None): if code is None: @@ -174,7 +174,7 @@ self.code = code = CSECode.from_function(func) #, copy_lineno=True) self.actions = {} self.func = func - loop_top, exit, bad_action, fake = Label(), Label(), Label(), Label() + first_action, loop_top, exit, bad_action, fake = Label(), Label(), Label(), Label(), Label() args, star, dstar, defaults = inspect.getargspec(func) actions, self.actions_const = self.make_const({}) start_node, self.startnode_const = self.make_const(object()) @@ -188,8 +188,8 @@ bad_action.JUMP_IF_FALSE_OR_POP, Code.ROT_TWO, # argument, action self.SET_ARG, # action - fake.SETUP_LOOP, self.WHY_CONTINUE, Code.END_FINALLY, - Code.POP_BLOCK, fake, Return(Pass), # <- all dead code, never runs + first_action.JUMP_FORWARD, #fake.SETUP_LOOP, self.WHY_CONTINUE, Code.END_FINALLY, + #Code.POP_BLOCK, fake, Return(Pass), # <- all dead code, never runs exit, Code.POP_TOP, # drop action, leaving argument Return( @@ -197,7 +197,8 @@ ), bad_action, Code.POP_TOP, - Return(Call(Const(self.bad_action),(Code.ROT_THREE, Code.ROT_TWO))) + Return(Call(Const(self.bad_action),(Code.ROT_THREE, Code.ROT_TWO))), + first_action, ) self.NEXT_STATE = loop_top.JUMP_ABSOLUTE self.maybe_cache = code.maybe_cache @@ -221,10 +222,17 @@ return self.actions[expression] except KeyError: action = self.actions[expression] = self.code.here() - self.code.stack_size = 0 - self.code(expression) + self.code.stack_size = 1 + next_action = Label() + self.code( + Compare(Code.DUP_TOP, (('==', action),)), + next_action.JUMP_IF_FALSE_OR_POP, + Code.POP_TOP, expression, + ) + #self.code(expression) if self.code.stack_size is not None: self.code(self.NEXT_STATE) + self.code(next_action, Code.POP_TOP) return action def bad_action(self, action, argument): @@ -238,12 +246,6 @@ - - - - - - CACHE = Local('$CSECache') SET_CACHE = lambda code: code.STORE_FAST(CACHE.name) @@ -324,14 +326,12 @@ else: scall(ob) - - class ExprBuilder: """Expression builder returning bytecode-able AST nodes""" def __init__(self,arguments,*namespaces): self.bindings = [ - dict([(k,self.Const(v)) for k,v in ns.iteritems()]) for ns in namespaces + dict([(k,self.Const(v)) for k,v in module_to_ns(ns).iteritems()]) for ns in namespaces ] self.push(arguments); self.push()