[pypy-svn] r16450 - in pypy/dist/pypy: interpreter interpreter/astcompiler interpreter/pyparser interpreter/pyparser/test translator/goal
ludal at codespeak.net
ludal at codespeak.net
Thu Aug 25 11:25:47 CEST 2005
Author: ludal
Date: Thu Aug 25 11:25:42 2005
New Revision: 16450
Modified:
pypy/dist/pypy/interpreter/astcompiler/ast.py
pypy/dist/pypy/interpreter/astcompiler/astgen.py
pypy/dist/pypy/interpreter/astcompiler/future.py
pypy/dist/pypy/interpreter/astcompiler/pyassem.py
pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
pypy/dist/pypy/interpreter/astcompiler/symbols.py
pypy/dist/pypy/interpreter/pycompiler.py
pypy/dist/pypy/interpreter/pyparser/astbuilder.py
pypy/dist/pypy/interpreter/pyparser/pythonutil.py
pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py
pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py
pypy/dist/pypy/translator/goal/targetcompiler.py
Log:
- more refactoring of the astcompiler to make it rpython
- removed multiple inheritance which was actually only single inheritance with tricks with init functions
so that multiple inheritance behaved like single inheritance (yes...)
- splitted emit methods into several methods with a different type of object
- fixed some bug from previous refactoring (scope in symbols.py, visitors not inheriting from ASTVisitor)
- removed the class members NameFinder, FunctionGen, ClassGen whose type we exactly know at the time we build the class
- setlineno returning
- use a stack for genexpr and listcomp fallback block instead of passing it as *arg to the visitor
- removed the recently introduced visit*Const since our const now contains wrapped objects
- use two visitors for augmented assignement instead of wrapping node objects into delegator nodes
- introduce the space object all over the compiler
- we now build wrapped objects directly into the consts tuple of code objects
- we can use functions from strutil that need the space object to convert string to long objects for example
- astgen.py should understand parent relationship in ast tree
- this is needed to make sure that for example And.nodes and Or.nodes share the same base attribute nodes
Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/ast.py (original)
+++ pypy/dist/pypy/interpreter/astcompiler/ast.py Thu Aug 25 11:25:42 2005
@@ -35,8 +35,8 @@
return self.getChildren()
def getChildNodes(self):
return [] # implemented by subclasses
- def accept(self, visitor, *args):
- return visitor.visitNode(self, *args)
+ def accept(self, visitor):
+ return visitor.visitNode(self)
def flatten(self):
res = []
nodes = self.getChildNodes()
@@ -48,8 +48,8 @@
return res
class EmptyNode(Node):
- def accept(self, visitor, *args):
- return visitor.visitEmptyNode(self, *args)
+ def accept(self, visitor):
+ return visitor.visitEmptyNode(self)
class Expression(Node):
# Expression is an artificial node class to support "eval"
@@ -67,8 +67,8 @@
def __repr__(self):
return "Expression(%s)" % (repr(self.node))
- def accept(self, visitor, *args):
- return visitor.visitExpression(self, *args)
+ def accept(self, visitor):
+ return visitor.visitExpression(self)
class Add(Node):
def __init__(self, (left, right), lineno=None):
@@ -85,8 +85,8 @@
def __repr__(self):
return "Add((%s, %s))" % (repr(self.left), repr(self.right))
- def accept(self, visitor, *args):
- return visitor.visitAdd(self, *args)
+ def accept(self, visitor):
+ return visitor.visitAdd(self)
class And(Node):
def __init__(self, nodes, lineno=None):
@@ -104,8 +104,8 @@
def __repr__(self):
return "And(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitAnd(self, *args)
+ def accept(self, visitor):
+ return visitor.visitAnd(self)
class AssAttr(Node):
def __init__(self, expr, attrname, flags, lineno=None):
@@ -123,8 +123,8 @@
def __repr__(self):
return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags))
- def accept(self, visitor, *args):
- return visitor.visitAssAttr(self, *args)
+ def accept(self, visitor):
+ return visitor.visitAssAttr(self)
class AssList(Node):
def __init__(self, nodes, lineno=None):
@@ -142,8 +142,8 @@
def __repr__(self):
return "AssList(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitAssList(self, *args)
+ def accept(self, visitor):
+ return visitor.visitAssList(self)
class AssName(Node):
def __init__(self, name, flags, lineno=None):
@@ -160,8 +160,8 @@
def __repr__(self):
return "AssName(%s, %s)" % (repr(self.name), repr(self.flags))
- def accept(self, visitor, *args):
- return visitor.visitAssName(self, *args)
+ def accept(self, visitor):
+ return visitor.visitAssName(self)
class AssTuple(Node):
def __init__(self, nodes, lineno=None):
@@ -179,8 +179,8 @@
def __repr__(self):
return "AssTuple(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitAssTuple(self, *args)
+ def accept(self, visitor):
+ return visitor.visitAssTuple(self)
class Assert(Node):
def __init__(self, test, fail, lineno=None):
@@ -204,8 +204,8 @@
def __repr__(self):
return "Assert(%s, %s)" % (repr(self.test), repr(self.fail))
- def accept(self, visitor, *args):
- return visitor.visitAssert(self, *args)
+ def accept(self, visitor):
+ return visitor.visitAssert(self)
class Assign(Node):
def __init__(self, nodes, expr, lineno=None):
@@ -228,8 +228,8 @@
def __repr__(self):
return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr))
- def accept(self, visitor, *args):
- return visitor.visitAssign(self, *args)
+ def accept(self, visitor):
+ return visitor.visitAssign(self)
class AugAssign(Node):
def __init__(self, node, op, expr, lineno=None):
@@ -247,8 +247,8 @@
def __repr__(self):
return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr))
- def accept(self, visitor, *args):
- return visitor.visitAugAssign(self, *args)
+ def accept(self, visitor):
+ return visitor.visitAugAssign(self)
class Backquote(Node):
def __init__(self, expr, lineno=None):
@@ -264,8 +264,8 @@
def __repr__(self):
return "Backquote(%s)" % (repr(self.expr),)
- def accept(self, visitor, *args):
- return visitor.visitBackquote(self, *args)
+ def accept(self, visitor):
+ return visitor.visitBackquote(self)
class Bitand(Node):
def __init__(self, nodes, lineno=None):
@@ -283,8 +283,8 @@
def __repr__(self):
return "Bitand(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitBitand(self, *args)
+ def accept(self, visitor):
+ return visitor.visitBitand(self)
class Bitor(Node):
def __init__(self, nodes, lineno=None):
@@ -302,8 +302,8 @@
def __repr__(self):
return "Bitor(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitBitor(self, *args)
+ def accept(self, visitor):
+ return visitor.visitBitor(self)
class Bitxor(Node):
def __init__(self, nodes, lineno=None):
@@ -321,8 +321,8 @@
def __repr__(self):
return "Bitxor(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitBitxor(self, *args)
+ def accept(self, visitor):
+ return visitor.visitBitxor(self)
class Break(Node):
def __init__(self, lineno=None):
@@ -337,8 +337,8 @@
def __repr__(self):
return "Break()"
- def accept(self, visitor, *args):
- return visitor.visitBreak(self, *args)
+ def accept(self, visitor):
+ return visitor.visitBreak(self)
class CallFunc(Node):
def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None):
@@ -369,8 +369,8 @@
def __repr__(self):
return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args))
- def accept(self, visitor, *args):
- return visitor.visitCallFunc(self, *args)
+ def accept(self, visitor):
+ return visitor.visitCallFunc(self)
class Class(Node):
def __init__(self, name, bases, doc, code, lineno=None):
@@ -397,8 +397,8 @@
def __repr__(self):
return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code))
- def accept(self, visitor, *args):
- return visitor.visitClass(self, *args)
+ def accept(self, visitor):
+ return visitor.visitClass(self)
class Compare(Node):
def __init__(self, expr, ops, lineno=None):
@@ -421,8 +421,8 @@
def __repr__(self):
return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops))
- def accept(self, visitor, *args):
- return visitor.visitCompare(self, *args)
+ def accept(self, visitor):
+ return visitor.visitCompare(self)
class Const(Node):
def __init__(self, value, lineno=None):
@@ -438,8 +438,8 @@
def __repr__(self):
return "Const(%s)" % (repr(self.value),)
- def accept(self, visitor, *args):
- return visitor.visitConst(self, *args)
+ def accept(self, visitor):
+ return visitor.visitConst(self)
class Continue(Node):
def __init__(self, lineno=None):
@@ -454,8 +454,8 @@
def __repr__(self):
return "Continue()"
- def accept(self, visitor, *args):
- return visitor.visitContinue(self, *args)
+ def accept(self, visitor):
+ return visitor.visitContinue(self)
class Decorators(Node):
def __init__(self, nodes, lineno=None):
@@ -473,8 +473,8 @@
def __repr__(self):
return "Decorators(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitDecorators(self, *args)
+ def accept(self, visitor):
+ return visitor.visitDecorators(self)
class Dict(Node):
def __init__(self, items, lineno=None):
@@ -492,8 +492,8 @@
def __repr__(self):
return "Dict(%s)" % (repr(self.items),)
- def accept(self, visitor, *args):
- return visitor.visitDict(self, *args)
+ def accept(self, visitor):
+ return visitor.visitDict(self)
class Discard(Node):
def __init__(self, expr, lineno=None):
@@ -509,8 +509,8 @@
def __repr__(self):
return "Discard(%s)" % (repr(self.expr),)
- def accept(self, visitor, *args):
- return visitor.visitDiscard(self, *args)
+ def accept(self, visitor):
+ return visitor.visitDiscard(self)
class Div(Node):
def __init__(self, (left, right), lineno=None):
@@ -527,8 +527,8 @@
def __repr__(self):
return "Div((%s, %s))" % (repr(self.left), repr(self.right))
- def accept(self, visitor, *args):
- return visitor.visitDiv(self, *args)
+ def accept(self, visitor):
+ return visitor.visitDiv(self)
class Ellipsis(Node):
def __init__(self, lineno=None):
@@ -543,8 +543,8 @@
def __repr__(self):
return "Ellipsis()"
- def accept(self, visitor, *args):
- return visitor.visitEllipsis(self, *args)
+ def accept(self, visitor):
+ return visitor.visitEllipsis(self)
class Exec(Node):
def __init__(self, expr, locals, globals, lineno=None):
@@ -572,8 +572,8 @@
def __repr__(self):
return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals))
- def accept(self, visitor, *args):
- return visitor.visitExec(self, *args)
+ def accept(self, visitor):
+ return visitor.visitExec(self)
class FloorDiv(Node):
def __init__(self, (left, right), lineno=None):
@@ -590,8 +590,8 @@
def __repr__(self):
return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right))
- def accept(self, visitor, *args):
- return visitor.visitFloorDiv(self, *args)
+ def accept(self, visitor):
+ return visitor.visitFloorDiv(self)
class For(Node):
def __init__(self, assign, list, body, else_, lineno=None):
@@ -621,8 +621,8 @@
def __repr__(self):
return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_))
- def accept(self, visitor, *args):
- return visitor.visitFor(self, *args)
+ def accept(self, visitor):
+ return visitor.visitFor(self)
class From(Node):
def __init__(self, modname, names, lineno=None):
@@ -639,8 +639,8 @@
def __repr__(self):
return "From(%s, %s)" % (repr(self.modname), repr(self.names))
- def accept(self, visitor, *args):
- return visitor.visitFrom(self, *args)
+ def accept(self, visitor):
+ return visitor.visitFrom(self)
class Function(Node):
def __init__(self, decorators, name, argnames, defaults, flags, doc, code, lineno=None):
@@ -682,8 +682,8 @@
def __repr__(self):
return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code))
- def accept(self, visitor, *args):
- return visitor.visitFunction(self, *args)
+ def accept(self, visitor):
+ return visitor.visitFunction(self)
class GenExpr(Node):
def __init__(self, code, lineno=None):
@@ -703,8 +703,8 @@
def __repr__(self):
return "GenExpr(%s)" % (repr(self.code),)
- def accept(self, visitor, *args):
- return visitor.visitGenExpr(self, *args)
+ def accept(self, visitor):
+ return visitor.visitGenExpr(self)
class GenExprFor(Node):
def __init__(self, assign, iter, ifs, lineno=None):
@@ -732,8 +732,8 @@
def __repr__(self):
return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs))
- def accept(self, visitor, *args):
- return visitor.visitGenExprFor(self, *args)
+ def accept(self, visitor):
+ return visitor.visitGenExprFor(self)
class GenExprIf(Node):
def __init__(self, test, lineno=None):
@@ -749,8 +749,8 @@
def __repr__(self):
return "GenExprIf(%s)" % (repr(self.test),)
- def accept(self, visitor, *args):
- return visitor.visitGenExprIf(self, *args)
+ def accept(self, visitor):
+ return visitor.visitGenExprIf(self)
class GenExprInner(Node):
def __init__(self, expr, quals, lineno=None):
@@ -773,8 +773,8 @@
def __repr__(self):
return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals))
- def accept(self, visitor, *args):
- return visitor.visitGenExprInner(self, *args)
+ def accept(self, visitor):
+ return visitor.visitGenExprInner(self)
class Getattr(Node):
def __init__(self, expr, attrname, lineno=None):
@@ -791,8 +791,8 @@
def __repr__(self):
return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname))
- def accept(self, visitor, *args):
- return visitor.visitGetattr(self, *args)
+ def accept(self, visitor):
+ return visitor.visitGetattr(self)
class Global(Node):
def __init__(self, names, lineno=None):
@@ -808,8 +808,8 @@
def __repr__(self):
return "Global(%s)" % (repr(self.names),)
- def accept(self, visitor, *args):
- return visitor.visitGlobal(self, *args)
+ def accept(self, visitor):
+ return visitor.visitGlobal(self)
class If(Node):
def __init__(self, tests, else_, lineno=None):
@@ -833,8 +833,8 @@
def __repr__(self):
return "If(%s, %s)" % (repr(self.tests), repr(self.else_))
- def accept(self, visitor, *args):
- return visitor.visitIf(self, *args)
+ def accept(self, visitor):
+ return visitor.visitIf(self)
class Import(Node):
def __init__(self, names, lineno=None):
@@ -850,8 +850,8 @@
def __repr__(self):
return "Import(%s)" % (repr(self.names),)
- def accept(self, visitor, *args):
- return visitor.visitImport(self, *args)
+ def accept(self, visitor):
+ return visitor.visitImport(self)
class Invert(Node):
def __init__(self, expr, lineno=None):
@@ -867,8 +867,8 @@
def __repr__(self):
return "Invert(%s)" % (repr(self.expr),)
- def accept(self, visitor, *args):
- return visitor.visitInvert(self, *args)
+ def accept(self, visitor):
+ return visitor.visitInvert(self)
class Keyword(Node):
def __init__(self, name, expr, lineno=None):
@@ -885,8 +885,8 @@
def __repr__(self):
return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr))
- def accept(self, visitor, *args):
- return visitor.visitKeyword(self, *args)
+ def accept(self, visitor):
+ return visitor.visitKeyword(self)
class Lambda(Node):
def __init__(self, argnames, defaults, flags, code, lineno=None):
@@ -920,8 +920,8 @@
def __repr__(self):
return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code))
- def accept(self, visitor, *args):
- return visitor.visitLambda(self, *args)
+ def accept(self, visitor):
+ return visitor.visitLambda(self)
class LeftShift(Node):
def __init__(self, (left, right), lineno=None):
@@ -938,8 +938,8 @@
def __repr__(self):
return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right))
- def accept(self, visitor, *args):
- return visitor.visitLeftShift(self, *args)
+ def accept(self, visitor):
+ return visitor.visitLeftShift(self)
class List(Node):
def __init__(self, nodes, lineno=None):
@@ -957,8 +957,8 @@
def __repr__(self):
return "List(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitList(self, *args)
+ def accept(self, visitor):
+ return visitor.visitList(self)
class ListComp(Node):
def __init__(self, expr, quals, lineno=None):
@@ -981,8 +981,8 @@
def __repr__(self):
return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals))
- def accept(self, visitor, *args):
- return visitor.visitListComp(self, *args)
+ def accept(self, visitor):
+ return visitor.visitListComp(self)
class ListCompFor(Node):
def __init__(self, assign, list, ifs, lineno=None):
@@ -1008,8 +1008,8 @@
def __repr__(self):
return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs))
- def accept(self, visitor, *args):
- return visitor.visitListCompFor(self, *args)
+ def accept(self, visitor):
+ return visitor.visitListCompFor(self)
class ListCompIf(Node):
def __init__(self, test, lineno=None):
@@ -1025,8 +1025,8 @@
def __repr__(self):
return "ListCompIf(%s)" % (repr(self.test),)
- def accept(self, visitor, *args):
- return visitor.visitListCompIf(self, *args)
+ def accept(self, visitor):
+ return visitor.visitListCompIf(self)
class Mod(Node):
def __init__(self, (left, right), lineno=None):
@@ -1043,8 +1043,8 @@
def __repr__(self):
return "Mod((%s, %s))" % (repr(self.left), repr(self.right))
- def accept(self, visitor, *args):
- return visitor.visitMod(self, *args)
+ def accept(self, visitor):
+ return visitor.visitMod(self)
class Module(Node):
def __init__(self, doc, node, lineno=None):
@@ -1061,8 +1061,8 @@
def __repr__(self):
return "Module(%s, %s)" % (repr(self.doc), repr(self.node))
- def accept(self, visitor, *args):
- return visitor.visitModule(self, *args)
+ def accept(self, visitor):
+ return visitor.visitModule(self)
class Mul(Node):
def __init__(self, (left, right), lineno=None):
@@ -1079,8 +1079,8 @@
def __repr__(self):
return "Mul((%s, %s))" % (repr(self.left), repr(self.right))
- def accept(self, visitor, *args):
- return visitor.visitMul(self, *args)
+ def accept(self, visitor):
+ return visitor.visitMul(self)
class Name(Node):
def __init__(self, varname, lineno=None):
@@ -1096,8 +1096,8 @@
def __repr__(self):
return "Name(%s)" % (repr(self.varname),)
- def accept(self, visitor, *args):
- return visitor.visitName(self, *args)
+ def accept(self, visitor):
+ return visitor.visitName(self)
class NoneConst(Node):
def __init__(self, lineno=None):
@@ -1112,8 +1112,8 @@
def __repr__(self):
return "NoneConst()"
- def accept(self, visitor, *args):
- return visitor.visitNoneConst(self, *args)
+ def accept(self, visitor):
+ return visitor.visitNoneConst(self)
class Not(Node):
def __init__(self, expr, lineno=None):
@@ -1129,8 +1129,8 @@
def __repr__(self):
return "Not(%s)" % (repr(self.expr),)
- def accept(self, visitor, *args):
- return visitor.visitNot(self, *args)
+ def accept(self, visitor):
+ return visitor.visitNot(self)
class NumberConst(Node):
def __init__(self, number_value, lineno=None):
@@ -1146,8 +1146,8 @@
def __repr__(self):
return "NumberConst(%s)" % (repr(self.number_value),)
- def accept(self, visitor, *args):
- return visitor.visitNumberConst(self, *args)
+ def accept(self, visitor):
+ return visitor.visitNumberConst(self)
class Or(Node):
def __init__(self, nodes, lineno=None):
@@ -1165,8 +1165,8 @@
def __repr__(self):
return "Or(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitOr(self, *args)
+ def accept(self, visitor):
+ return visitor.visitOr(self)
class Pass(Node):
def __init__(self, lineno=None):
@@ -1181,8 +1181,8 @@
def __repr__(self):
return "Pass()"
- def accept(self, visitor, *args):
- return visitor.visitPass(self, *args)
+ def accept(self, visitor):
+ return visitor.visitPass(self)
class Power(Node):
def __init__(self, (left, right), lineno=None):
@@ -1199,8 +1199,8 @@
def __repr__(self):
return "Power((%s, %s))" % (repr(self.left), repr(self.right))
- def accept(self, visitor, *args):
- return visitor.visitPower(self, *args)
+ def accept(self, visitor):
+ return visitor.visitPower(self)
class Print(Node):
def __init__(self, nodes, dest, lineno=None):
@@ -1224,8 +1224,8 @@
def __repr__(self):
return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest))
- def accept(self, visitor, *args):
- return visitor.visitPrint(self, *args)
+ def accept(self, visitor):
+ return visitor.visitPrint(self)
class Printnl(Node):
def __init__(self, nodes, dest, lineno=None):
@@ -1249,8 +1249,8 @@
def __repr__(self):
return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest))
- def accept(self, visitor, *args):
- return visitor.visitPrintnl(self, *args)
+ def accept(self, visitor):
+ return visitor.visitPrintnl(self)
class Raise(Node):
def __init__(self, expr1, expr2, expr3, lineno=None):
@@ -1279,8 +1279,8 @@
def __repr__(self):
return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3))
- def accept(self, visitor, *args):
- return visitor.visitRaise(self, *args)
+ def accept(self, visitor):
+ return visitor.visitRaise(self)
class Return(Node):
def __init__(self, value, lineno=None):
@@ -1296,8 +1296,8 @@
def __repr__(self):
return "Return(%s)" % (repr(self.value),)
- def accept(self, visitor, *args):
- return visitor.visitReturn(self, *args)
+ def accept(self, visitor):
+ return visitor.visitReturn(self)
class RightShift(Node):
def __init__(self, (left, right), lineno=None):
@@ -1314,8 +1314,8 @@
def __repr__(self):
return "RightShift((%s, %s))" % (repr(self.left), repr(self.right))
- def accept(self, visitor, *args):
- return visitor.visitRightShift(self, *args)
+ def accept(self, visitor):
+ return visitor.visitRightShift(self)
class Slice(Node):
def __init__(self, expr, flags, lower, upper, lineno=None):
@@ -1345,8 +1345,8 @@
def __repr__(self):
return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper))
- def accept(self, visitor, *args):
- return visitor.visitSlice(self, *args)
+ def accept(self, visitor):
+ return visitor.visitSlice(self)
class Sliceobj(Node):
def __init__(self, nodes, lineno=None):
@@ -1364,8 +1364,8 @@
def __repr__(self):
return "Sliceobj(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitSliceobj(self, *args)
+ def accept(self, visitor):
+ return visitor.visitSliceobj(self)
class Stmt(Node):
def __init__(self, nodes, lineno=None):
@@ -1383,8 +1383,8 @@
def __repr__(self):
return "Stmt(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitStmt(self, *args)
+ def accept(self, visitor):
+ return visitor.visitStmt(self)
class StringConst(Node):
def __init__(self, string_value, lineno=None):
@@ -1400,8 +1400,8 @@
def __repr__(self):
return "StringConst(%s)" % (repr(self.string_value),)
- def accept(self, visitor, *args):
- return visitor.visitStringConst(self, *args)
+ def accept(self, visitor):
+ return visitor.visitStringConst(self)
class Sub(Node):
def __init__(self, (left, right), lineno=None):
@@ -1418,8 +1418,8 @@
def __repr__(self):
return "Sub((%s, %s))" % (repr(self.left), repr(self.right))
- def accept(self, visitor, *args):
- return visitor.visitSub(self, *args)
+ def accept(self, visitor):
+ return visitor.visitSub(self)
class Subscript(Node):
def __init__(self, expr, flags, subs, lineno=None):
@@ -1444,8 +1444,8 @@
def __repr__(self):
return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs))
- def accept(self, visitor, *args):
- return visitor.visitSubscript(self, *args)
+ def accept(self, visitor):
+ return visitor.visitSubscript(self)
class TryExcept(Node):
def __init__(self, body, handlers, else_, lineno=None):
@@ -1472,8 +1472,8 @@
def __repr__(self):
return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_))
- def accept(self, visitor, *args):
- return visitor.visitTryExcept(self, *args)
+ def accept(self, visitor):
+ return visitor.visitTryExcept(self)
class TryFinally(Node):
def __init__(self, body, final, lineno=None):
@@ -1490,8 +1490,8 @@
def __repr__(self):
return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final))
- def accept(self, visitor, *args):
- return visitor.visitTryFinally(self, *args)
+ def accept(self, visitor):
+ return visitor.visitTryFinally(self)
class Tuple(Node):
def __init__(self, nodes, lineno=None):
@@ -1509,8 +1509,8 @@
def __repr__(self):
return "Tuple(%s)" % (repr(self.nodes),)
- def accept(self, visitor, *args):
- return visitor.visitTuple(self, *args)
+ def accept(self, visitor):
+ return visitor.visitTuple(self)
class UnaryAdd(Node):
def __init__(self, expr, lineno=None):
@@ -1526,8 +1526,8 @@
def __repr__(self):
return "UnaryAdd(%s)" % (repr(self.expr),)
- def accept(self, visitor, *args):
- return visitor.visitUnaryAdd(self, *args)
+ def accept(self, visitor):
+ return visitor.visitUnaryAdd(self)
class UnarySub(Node):
def __init__(self, expr, lineno=None):
@@ -1543,8 +1543,8 @@
def __repr__(self):
return "UnarySub(%s)" % (repr(self.expr),)
- def accept(self, visitor, *args):
- return visitor.visitUnarySub(self, *args)
+ def accept(self, visitor):
+ return visitor.visitUnarySub(self)
class While(Node):
def __init__(self, test, body, else_, lineno=None):
@@ -1571,8 +1571,8 @@
def __repr__(self):
return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_))
- def accept(self, visitor, *args):
- return visitor.visitWhile(self, *args)
+ def accept(self, visitor):
+ return visitor.visitWhile(self)
class Yield(Node):
def __init__(self, value, lineno=None):
@@ -1588,8 +1588,8 @@
def __repr__(self):
return "Yield(%s)" % (repr(self.value),)
- def accept(self, visitor, *args):
- return visitor.visitYield(self, *args)
+ def accept(self, visitor):
+ return visitor.visitYield(self)
class ASTVisitor(object):
@@ -1598,157 +1598,157 @@
It could also use to identify base type for visit arguments of AST nodes
"""
- def default(self, node, *args):
+ def default(self, node):
for child in node.getChildNodes():
- child.accept(self, *args)
+ child.accept(self)
- def visitAdd(self, node, *args):
- return self.default( node, *args )
- def visitAnd(self, node, *args):
- return self.default( node, *args )
- def visitAssAttr(self, node, *args):
- return self.default( node, *args )
- def visitAssList(self, node, *args):
- return self.default( node, *args )
- def visitAssName(self, node, *args):
- return self.default( node, *args )
- def visitAssTuple(self, node, *args):
- return self.default( node, *args )
- def visitAssert(self, node, *args):
- return self.default( node, *args )
- def visitAssign(self, node, *args):
- return self.default( node, *args )
- def visitAugAssign(self, node, *args):
- return self.default( node, *args )
- def visitBackquote(self, node, *args):
- return self.default( node, *args )
- def visitBitand(self, node, *args):
- return self.default( node, *args )
- def visitBitor(self, node, *args):
- return self.default( node, *args )
- def visitBitxor(self, node, *args):
- return self.default( node, *args )
- def visitBreak(self, node, *args):
- return self.default( node, *args )
- def visitCallFunc(self, node, *args):
- return self.default( node, *args )
- def visitClass(self, node, *args):
- return self.default( node, *args )
- def visitCompare(self, node, *args):
- return self.default( node, *args )
- def visitConst(self, node, *args):
- return self.default( node, *args )
- def visitContinue(self, node, *args):
- return self.default( node, *args )
- def visitDecorators(self, node, *args):
- return self.default( node, *args )
- def visitDict(self, node, *args):
- return self.default( node, *args )
- def visitDiscard(self, node, *args):
- return self.default( node, *args )
- def visitDiv(self, node, *args):
- return self.default( node, *args )
- def visitEllipsis(self, node, *args):
- return self.default( node, *args )
- def visitExec(self, node, *args):
- return self.default( node, *args )
- def visitFloorDiv(self, node, *args):
- return self.default( node, *args )
- def visitFor(self, node, *args):
- return self.default( node, *args )
- def visitFrom(self, node, *args):
- return self.default( node, *args )
- def visitFunction(self, node, *args):
- return self.default( node, *args )
- def visitGenExpr(self, node, *args):
- return self.default( node, *args )
- def visitGenExprFor(self, node, *args):
- return self.default( node, *args )
- def visitGenExprIf(self, node, *args):
- return self.default( node, *args )
- def visitGenExprInner(self, node, *args):
- return self.default( node, *args )
- def visitGetattr(self, node, *args):
- return self.default( node, *args )
- def visitGlobal(self, node, *args):
- return self.default( node, *args )
- def visitIf(self, node, *args):
- return self.default( node, *args )
- def visitImport(self, node, *args):
- return self.default( node, *args )
- def visitInvert(self, node, *args):
- return self.default( node, *args )
- def visitKeyword(self, node, *args):
- return self.default( node, *args )
- def visitLambda(self, node, *args):
- return self.default( node, *args )
- def visitLeftShift(self, node, *args):
- return self.default( node, *args )
- def visitList(self, node, *args):
- return self.default( node, *args )
- def visitListComp(self, node, *args):
- return self.default( node, *args )
- def visitListCompFor(self, node, *args):
- return self.default( node, *args )
- def visitListCompIf(self, node, *args):
- return self.default( node, *args )
- def visitMod(self, node, *args):
- return self.default( node, *args )
- def visitModule(self, node, *args):
- return self.default( node, *args )
- def visitMul(self, node, *args):
- return self.default( node, *args )
- def visitName(self, node, *args):
- return self.default( node, *args )
- def visitNoneConst(self, node, *args):
- return self.default( node, *args )
- def visitNot(self, node, *args):
- return self.default( node, *args )
- def visitNumberConst(self, node, *args):
- return self.default( node, *args )
- def visitOr(self, node, *args):
- return self.default( node, *args )
- def visitPass(self, node, *args):
- return self.default( node, *args )
- def visitPower(self, node, *args):
- return self.default( node, *args )
- def visitPrint(self, node, *args):
- return self.default( node, *args )
- def visitPrintnl(self, node, *args):
- return self.default( node, *args )
- def visitRaise(self, node, *args):
- return self.default( node, *args )
- def visitReturn(self, node, *args):
- return self.default( node, *args )
- def visitRightShift(self, node, *args):
- return self.default( node, *args )
- def visitSlice(self, node, *args):
- return self.default( node, *args )
- def visitSliceobj(self, node, *args):
- return self.default( node, *args )
- def visitStmt(self, node, *args):
- return self.default( node, *args )
- def visitStringConst(self, node, *args):
- return self.default( node, *args )
- def visitSub(self, node, *args):
- return self.default( node, *args )
- def visitSubscript(self, node, *args):
- return self.default( node, *args )
- def visitTryExcept(self, node, *args):
- return self.default( node, *args )
- def visitTryFinally(self, node, *args):
- return self.default( node, *args )
- def visitTuple(self, node, *args):
- return self.default( node, *args )
- def visitUnaryAdd(self, node, *args):
- return self.default( node, *args )
- def visitUnarySub(self, node, *args):
- return self.default( node, *args )
- def visitWhile(self, node, *args):
- return self.default( node, *args )
- def visitYield(self, node, *args):
- return self.default( node, *args )
+ def visitAdd(self, node):
+ return self.default( node )
+ def visitAnd(self, node):
+ return self.default( node )
+ def visitAssAttr(self, node):
+ return self.default( node )
+ def visitAssList(self, node):
+ return self.default( node )
+ def visitAssName(self, node):
+ return self.default( node )
+ def visitAssTuple(self, node):
+ return self.default( node )
+ def visitAssert(self, node):
+ return self.default( node )
+ def visitAssign(self, node):
+ return self.default( node )
+ def visitAugAssign(self, node):
+ return self.default( node )
+ def visitBackquote(self, node):
+ return self.default( node )
+ def visitBitand(self, node):
+ return self.default( node )
+ def visitBitor(self, node):
+ return self.default( node )
+ def visitBitxor(self, node):
+ return self.default( node )
+ def visitBreak(self, node):
+ return self.default( node )
+ def visitCallFunc(self, node):
+ return self.default( node )
+ def visitClass(self, node):
+ return self.default( node )
+ def visitCompare(self, node):
+ return self.default( node )
+ def visitConst(self, node):
+ return self.default( node )
+ def visitContinue(self, node):
+ return self.default( node )
+ def visitDecorators(self, node):
+ return self.default( node )
+ def visitDict(self, node):
+ return self.default( node )
+ def visitDiscard(self, node):
+ return self.default( node )
+ def visitDiv(self, node):
+ return self.default( node )
+ def visitEllipsis(self, node):
+ return self.default( node )
+ def visitExec(self, node):
+ return self.default( node )
+ def visitFloorDiv(self, node):
+ return self.default( node )
+ def visitFor(self, node):
+ return self.default( node )
+ def visitFrom(self, node):
+ return self.default( node )
+ def visitFunction(self, node):
+ return self.default( node )
+ def visitGenExpr(self, node):
+ return self.default( node )
+ def visitGenExprFor(self, node):
+ return self.default( node )
+ def visitGenExprIf(self, node):
+ return self.default( node )
+ def visitGenExprInner(self, node):
+ return self.default( node )
+ def visitGetattr(self, node):
+ return self.default( node )
+ def visitGlobal(self, node):
+ return self.default( node )
+ def visitIf(self, node):
+ return self.default( node )
+ def visitImport(self, node):
+ return self.default( node )
+ def visitInvert(self, node):
+ return self.default( node )
+ def visitKeyword(self, node):
+ return self.default( node )
+ def visitLambda(self, node):
+ return self.default( node )
+ def visitLeftShift(self, node):
+ return self.default( node )
+ def visitList(self, node):
+ return self.default( node )
+ def visitListComp(self, node):
+ return self.default( node )
+ def visitListCompFor(self, node):
+ return self.default( node )
+ def visitListCompIf(self, node):
+ return self.default( node )
+ def visitMod(self, node):
+ return self.default( node )
+ def visitModule(self, node):
+ return self.default( node )
+ def visitMul(self, node):
+ return self.default( node )
+ def visitName(self, node):
+ return self.default( node )
+ def visitNoneConst(self, node):
+ return self.default( node )
+ def visitNot(self, node):
+ return self.default( node )
+ def visitNumberConst(self, node):
+ return self.default( node )
+ def visitOr(self, node):
+ return self.default( node )
+ def visitPass(self, node):
+ return self.default( node )
+ def visitPower(self, node):
+ return self.default( node )
+ def visitPrint(self, node):
+ return self.default( node )
+ def visitPrintnl(self, node):
+ return self.default( node )
+ def visitRaise(self, node):
+ return self.default( node )
+ def visitReturn(self, node):
+ return self.default( node )
+ def visitRightShift(self, node):
+ return self.default( node )
+ def visitSlice(self, node):
+ return self.default( node )
+ def visitSliceobj(self, node):
+ return self.default( node )
+ def visitStmt(self, node):
+ return self.default( node )
+ def visitStringConst(self, node):
+ return self.default( node )
+ def visitSub(self, node):
+ return self.default( node )
+ def visitSubscript(self, node):
+ return self.default( node )
+ def visitTryExcept(self, node):
+ return self.default( node )
+ def visitTryFinally(self, node):
+ return self.default( node )
+ def visitTuple(self, node):
+ return self.default( node )
+ def visitUnaryAdd(self, node):
+ return self.default( node )
+ def visitUnarySub(self, node):
+ return self.default( node )
+ def visitWhile(self, node):
+ return self.default( node )
+ def visitYield(self, node):
+ return self.default( node )
for name, obj in globals().items():
if isinstance(obj, type) and issubclass(obj, Node):
Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original)
+++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Thu Aug 25 11:25:42 2005
@@ -43,13 +43,20 @@
class NodeInfo:
"""Each instance describes a specific AST node"""
- def __init__(self, name, args):
+ def __init__(self, name, args, parent=None):
self.name = name
self.args = args.strip()
self.argnames = self.get_argnames()
self.argprops = self.get_argprops()
self.nargs = len(self.argnames)
self.init = []
+ self.parent = parent
+
+ def setup_parent(self, classes):
+ if self.parent:
+ self.parent = classes[self.parent]
+ else:
+ self.parent = NodeInfo("Node","")
def get_argnames(self):
if '(' in self.args:
@@ -95,7 +102,7 @@
def gen_source(self):
buf = StringIO()
- print >> buf, "class %s(Node):" % self.name
+ print >> buf, "class %s(%s):" % (self.name, self.parent.name)
self._gen_init(buf)
print >> buf
self._gen_getChildren(buf)
@@ -109,11 +116,18 @@
return buf.read()
def _gen_init(self, buf):
- if self.args:
- print >> buf, " def __init__(self, %s, lineno=None):" % self.args
+ if self.parent.args and self.args:
+ args = self.parent.args +","+ self.args
+ else:
+ args = self.parent.args or self.args
+ if args:
+ print >> buf, " def __init__(self, %s, lineno=None):" % args
else:
print >> buf, " def __init__(self, lineno=None):"
- print >> buf, " Node.__init__(self, lineno)"
+ if self.parent.args:
+ print >> buf, " %s.__init__(self, %s, lineno)" % self.parent.args
+ else:
+ print >> buf, " Node.__init__(self, lineno)"
if self.argnames:
for name in self.argnames:
print >> buf, " self.%s = %s" % (name, name)
@@ -192,12 +206,12 @@
print >> buf, ' return "%s()"' % self.name
def _gen_visit(self, buf):
- print >> buf, " def accept(self, visitor, *args):"
- print >> buf, " return visitor.visit%s(self, *args)" % self.name
+ print >> buf, " def accept(self, visitor):"
+ print >> buf, " return visitor.visit%s(self)" % self.name
def gen_base_visit(self, buf):
- print >> buf, " def visit%s(self, node, *args):" % self.name
- print >> buf, " return self.default( node, *args )"
+ print >> buf, " def visit%s(self, node):" % self.name
+ print >> buf, " return self.default( node )"
rx_init = re.compile('init\((.*)\):')
@@ -215,7 +229,12 @@
name, args = line.split(':')
except ValueError:
continue
- classes[name] = NodeInfo(name, args)
+ if "(" in name:
+ name, parent = name.split("(")
+ parent = parent[:-1]
+ else:
+ parent = None
+ classes[name] = NodeInfo(name, args, parent)
cur = None
else:
# some code for the __init__ method
@@ -224,6 +243,8 @@
# some extra code for a Node's __init__ method
name = mo.group(1)
cur = classes[name]
+ for node in classes.values():
+ node.setup_parent(classes)
return sorted(classes.values(), key=lambda n: n.name)
ASTVISITORCLASS='''
@@ -233,9 +254,9 @@
It could also use to identify base type for visit arguments of AST nodes
"""
- def default(self, node, *args):
+ def default(self, node):
for child in node.getChildNodes():
- child.accept(self, *args)
+ child.accept(self)
'''
@@ -266,6 +287,7 @@
This file is automatically generated by Tools/compiler/astgen.py
"""
from consts import CO_VARARGS, CO_VARKEYWORDS, OP_ASSIGN
+from pypy.interpreter.baseobjspace import Wrappable
def flatten(list):
l = []
@@ -283,7 +305,7 @@
nodes = {}
-class Node:
+class Node(Wrappable):
"""Abstract base class for ast nodes."""
def __init__(self, lineno = None):
self.lineno = lineno
@@ -298,8 +320,8 @@
return self.getChildren()
def getChildNodes(self):
return [] # implemented by subclasses
- def accept(self, visitor, *args):
- return visitor.visitNode(self, *args)
+ def accept(self, visitor):
+ return visitor.visitNode(self)
def flatten(self):
res = []
nodes = self.getChildNodes()
@@ -310,9 +332,10 @@
res.append( self )
return res
+
class EmptyNode(Node):
- def accept(self, visitor, *args):
- return visitor.visitEmptyNode(self, *args)
+ def accept(self, visitor):
+ return visitor.visitEmptyNode(self)
class Expression(Node):
# Expression is an artificial node class to support "eval"
@@ -330,8 +353,8 @@
def __repr__(self):
return "Expression(%s)" % (repr(self.node))
- def accept(self, visitor, *args):
- return visitor.visitExpression(self, *args)
+ def accept(self, visitor):
+ return visitor.visitExpression(self)
### EPILOGUE
for name, obj in globals().items():
Modified: pypy/dist/pypy/interpreter/astcompiler/future.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/future.py (original)
+++ pypy/dist/pypy/interpreter/astcompiler/future.py Thu Aug 25 11:25:42 2005
@@ -13,7 +13,7 @@
else:
return 0
-class FutureParser:
+class FutureParser(ast.ASTVisitor):
features = ("nested_scopes", "generators", "division")
@@ -42,7 +42,7 @@
"""Return list of features enabled by future statements"""
return self.found.keys()
-class BadFutureParser:
+class BadFutureParser(ast.ASTVisitor):
"""Check for invalid future statements"""
def visitFrom(self, node):
Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original)
+++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Thu Aug 25 11:25:42 2005
@@ -1,19 +1,20 @@
"""A flow graph representation for Python bytecode"""
import dis
-import new
import sys
import types
-from pypy.interpreter.pycode import PyCode
from pypy.interpreter.astcompiler import misc, ast
from pypy.interpreter.astcompiler.consts \
import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS
+from pypy.interpreter.pycode import PyCode
+from pypy.interpreter.baseobjspace import W_Root
class FlowGraph:
- def __init__(self):
- self.current = self.entry = Block()
- self.exit = Block("exit")
+ def __init__(self, space):
+ self.space = space
+ self.current = self.entry = Block(space)
+ self.exit = Block(space,"exit")
self.blocks = misc.Set()
self.blocks.add(self.entry)
self.blocks.add(self.exit)
@@ -54,7 +55,7 @@
self.startBlock(block)
def newBlock(self):
- b = Block()
+ b = Block(self.space)
self.blocks.add(b)
return b
@@ -69,14 +70,41 @@
def _disable_debug(self):
self._debug = 0
- def emit(self, *inst):
+ def emit(self, inst):
if self._debug:
print "\t", inst
- if inst[0] in ['RETURN_VALUE', 'YIELD_VALUE']:
+ if inst in ['RETURN_VALUE', 'YIELD_VALUE']:
self.current.addOutEdge(self.exit)
- if len(inst) == 2 and isinstance(inst[1], Block):
- self.current.addOutEdge(inst[1])
- self.current.emit(inst)
+ self.current.emit( (inst,) )
+
+ def emitop(self, inst, arg ):
+ if self._debug:
+ print "\t", inst, arg
+ self.current.emit( (inst,arg) )
+
+ def emitop_obj(self, inst, obj ):
+ if self._debug:
+ print "\t", inst, repr(obj)
+ self.current.emit( (inst,obj) )
+
+ def emitop_int(self, inst, intval ):
+ if self._debug:
+ print "\t", inst, intval
+ assert type(intval)==int
+ self.current.emit( (inst,intval) )
+
+ def emitop_block(self, inst, block):
+ if self._debug:
+ print "\t", inst, block
+ assert isinstance(block, Block)
+ self.current.addOutEdge( block )
+ self.current.emit( (inst,block) )
+
+ def emitop_name(self, inst, name ):
+ if self._debug:
+ print "\t", inst, name
+ assert type(name)==str
+ self.current.emit( (inst,name) )
def getBlocksInOrder(self):
"""Return the blocks in reverse postorder
@@ -235,13 +263,14 @@
class Block:
_count = BlockCounter()
- def __init__(self, label=''):
+ def __init__(self, space, label=''):
self.insts = []
self.inEdges = misc.Set()
self.outEdges = misc.Set()
self.label = label
self.bid = Block._count.value()
self.next = []
+ self.space = space
Block._count.inc()
def __repr__(self):
@@ -259,6 +288,8 @@
op = inst[0]
if op[:4] == 'JUMP':
self.outEdges.add(inst[1])
+## if op=="LOAD_CONST":
+## assert isinstance( inst[1], W_Root ) or hasattr( inst[1], 'getCode')
self.insts.append( list(inst) )
def getInstructions(self):
@@ -327,13 +358,12 @@
DONE = "DONE"
class PyFlowGraph(FlowGraph):
- super_init = FlowGraph.__init__
- def __init__(self, name, filename, args=(), optimized=0, klass=None):
- self.super_init()
+ def __init__(self, space, name, filename, args=(), optimized=0, klass=None):
+ FlowGraph.__init__(self, space)
self.name = name
self.filename = filename
- self.docstring = None
+ self.docstring = space.w_None
self.args = args # XXX
self.argcount = getArgCount(args)
self.klass = klass
@@ -569,6 +599,7 @@
def _convert_LOAD_CONST(self, arg):
if hasattr(arg, 'getCode'):
arg = arg.getCode()
+## assert arg is not None
return self._lookupName(arg, self.consts)
def _convert_LOAD_FAST(self, arg):
@@ -662,12 +693,13 @@
argcount = argcount - 1
# was return new.code, now we just return the parameters and let
# the caller create the code object
- return (argcount, nlocals, self.stacksize, self.flags,
- self.lnotab.getCode(), self.getConsts(),
- tuple(self.names), tuple(self.varnames),
- self.filename, self.name, self.lnotab.firstline,
- self.lnotab.getTable(), tuple(self.freevars),
- tuple(self.cellvars))
+ return PyCode(self.space)._code_new_w( argcount, nlocals,
+ self.stacksize, self.flags,
+ self.lnotab.getCode(), self.getConsts(),
+ tuple(self.names), tuple(self.varnames),
+ self.filename, self.name, self.lnotab.firstline,
+ self.lnotab.getTable(), tuple(self.freevars),
+ tuple(self.cellvars))
def getConsts(self):
"""Return a tuple for the const slot of the code object
Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original)
+++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Thu Aug 25 11:25:42 2005
@@ -13,6 +13,7 @@
from pypy.interpreter.astcompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \
CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION
from pypy.interpreter.astcompiler.pyassem import TupleArg
+from pypy.interpreter.pyparser.error import SyntaxError
# drop VERSION dependency since it the ast transformer for 2.4 doesn't work with 2.3 anyway
VERSION = 2
@@ -188,12 +189,14 @@
__initialized = None
class_name = None # provide default for instance variable
- def __init__(self):
+ def __init__(self, space):
+ self.space = space
self.checkClass()
self.locals = misc.Stack()
self.setups = misc.Stack()
self.last_lineno = None
self._div_op = "BINARY_DIVIDE"
+ self.genexpr_cont_stack = []
# XXX set flags based on future features
futures = self.get_module().futures
@@ -208,16 +211,26 @@
"""Verify that class is constructed correctly"""
try:
assert hasattr(self, 'graph')
- assert getattr(self, 'NameFinder')
- assert getattr(self, 'FunctionGen')
- assert getattr(self, 'ClassGen')
except AssertionError, msg:
intro = "Bad class construction for %s" % self.__class__.__name__
raise AssertionError, intro
- def emit(self, *inst ):
- return self.graph.emit( *inst )
+ def emit(self, inst ):
+ return self.graph.emit( inst )
+
+ def emitop(self, inst, op):
+ return self.graph.emitop_name( inst, op )
+
+ def emitop_obj(self, inst, obj):
+ return self.graph.emitop_obj( inst, obj )
+
+ def emitop_int(self, inst, op):
+ assert type(op) == int
+ return self.graph.emitop_int( inst, op )
+
+ def emitop_block(self, inst, block):
+ return self.graph.emitop_block( inst, block )
def nextBlock(self, block=None ):
"""graph delegation"""
@@ -272,18 +285,18 @@
scope = self.scope.check_name(name)
if scope == SC_LOCAL:
if not self.optimized:
- self.emit(prefix + '_NAME', name)
+ self.emitop(prefix + '_NAME', name)
else:
- self.emit(prefix + '_FAST', name)
+ self.emitop(prefix + '_FAST', name)
elif scope == SC_GLOBAL:
if not self.optimized:
- self.emit(prefix + '_NAME', name)
+ self.emitop(prefix + '_NAME', name)
else:
- self.emit(prefix + '_GLOBAL', name)
+ self.emitop(prefix + '_GLOBAL', name)
elif scope == SC_FREE or scope == SC_CELL:
- self.emit(prefix + '_DEREF', name)
+ self.emitop(prefix + '_DEREF', name)
elif scope == SC_REALLY_GLOBAL:
- self.emit(prefix + '_GLOBAL', name)
+ self.emitop(prefix + '_GLOBAL', name)
else:
raise RuntimeError, "unsupported scope for var %s: %d" % \
(name, scope)
@@ -296,9 +309,9 @@
they aren't present in the program text.
"""
if self.optimized:
- self.emit(prefix + '_FAST', name)
+ self.emitop(prefix + '_FAST', name)
else:
- self.emit(prefix + '_NAME', name)
+ self.emitop(prefix + '_NAME', name)
# The set_lineno() function and the explicit emit() calls for
# SET_LINENO below are only used to generate the line number table.
@@ -319,10 +332,12 @@
and a consistent policy implemented and documented. Until
then, this method works around missing line numbers.
"""
+ if node is None:
+ return False
lineno = node.lineno
if lineno is not None and (lineno != self.last_lineno
or force):
- self.emit('SET_LINENO', lineno)
+ self.emitop_int('SET_LINENO', lineno)
self.last_lineno = lineno
return True
return False
@@ -331,21 +346,19 @@
# code objects. They use class attributes to determine what
# specialized code generators to use.
- NameFinder = LocalNameFinder
- FunctionGen = None
- ClassGen = None
def visitModule(self, node):
self.scopes = self.parseSymbols(node)
self.scope = self.scopes[node]
- self.emit('SET_LINENO', 0)
+ self.emitop_int('SET_LINENO', 0)
if node.doc:
- self.emit('LOAD_CONST', node.doc)
+ self.emitop_obj('LOAD_CONST', node.doc)
self.storeName('__doc__')
- lnf = walk(node.node, self.NameFinder(), verbose=0)
+ lnf = LocalNameFinder()
+ node.node.accept(lnf)
self.locals.push(lnf.getLocals())
node.node.accept( self )
- self.emit('LOAD_CONST', None)
+ self.emitop_obj('LOAD_CONST', self.space.w_None )
self.emit('RETURN_VALUE')
def visitExpression(self, node):
@@ -372,7 +385,7 @@
else:
ndecorators = 0
- gen = self.FunctionGen(node, self.scopes, isLambda,
+ gen = FunctionCodeGenerator(self.space, node, self.scopes, isLambda,
self.class_name, self.get_module())
walk(node.code, gen)
gen.finish()
@@ -382,35 +395,35 @@
frees = gen.scope.get_free_vars()
if frees:
for name in frees:
- self.emit('LOAD_CLOSURE', name)
- self.emit('LOAD_CONST', gen)
- self.emit('MAKE_CLOSURE', len(node.defaults))
+ self.emitop('LOAD_CLOSURE', name)
+ self.emitop_obj('LOAD_CONST', gen)
+ self.emitop_int('MAKE_CLOSURE', len(node.defaults))
else:
- self.emit('LOAD_CONST', gen)
- self.emit('MAKE_FUNCTION', len(node.defaults))
+ self.emitop_obj('LOAD_CONST', gen)
+ self.emitop_int('MAKE_FUNCTION', len(node.defaults))
for i in range(ndecorators):
- self.emit('CALL_FUNCTION', 1)
+ self.emitop_int('CALL_FUNCTION', 1)
def visitClass(self, node):
- gen = self.ClassGen(node, self.scopes,
- self.get_module())
+ gen = ClassCodeGenerator(self.space, node, self.scopes,
+ self.get_module())
walk(node.code, gen)
gen.finish()
self.set_lineno(node)
- self.emit('LOAD_CONST', node.name)
+ self.emitop_obj('LOAD_CONST', self.space.wrap(node.name) )
for base in node.bases:
base.accept( self )
- self.emit('BUILD_TUPLE', len(node.bases))
+ self.emitop_int('BUILD_TUPLE', len(node.bases))
frees = gen.scope.get_free_vars()
for name in frees:
- self.emit('LOAD_CLOSURE', name)
- self.emit('LOAD_CONST', gen)
+ self.emitop('LOAD_CLOSURE', name)
+ self.emitop_obj('LOAD_CONST', gen)
if frees:
- self.emit('MAKE_CLOSURE', 0)
+ self.emitop_int('MAKE_CLOSURE', 0)
else:
- self.emit('MAKE_FUNCTION', 0)
- self.emit('CALL_FUNCTION', 0)
+ self.emitop_int('MAKE_FUNCTION', 0)
+ self.emitop_int('CALL_FUNCTION', 0)
self.emit('BUILD_CLASS')
self.storeName(node.name)
@@ -420,20 +433,18 @@
def visitIf(self, node):
end = self.newBlock()
- numtests = len(node.tests)
- for i in range(numtests):
- test, suite = node.tests[i]
+ for test, suite in node.tests:
if is_constant_false(test):
# XXX will need to check generator stuff here
continue
self.set_lineno(test)
test.accept( self )
nextTest = self.newBlock()
- self.emit('JUMP_IF_FALSE', nextTest)
+ self.emitop_block('JUMP_IF_FALSE', nextTest)
self.nextBlock()
self.emit('POP_TOP')
suite.accept( self )
- self.emit('JUMP_FORWARD', end)
+ self.emitop_block('JUMP_FORWARD', end)
self.startBlock(nextTest)
self.emit('POP_TOP')
if node.else_:
@@ -447,19 +458,19 @@
else_ = self.newBlock()
after = self.newBlock()
- self.emit('SETUP_LOOP', after)
+ self.emitop_block('SETUP_LOOP', after)
self.nextBlock(loop)
self.setups.push((LOOP, loop))
self.set_lineno(node, force=True)
node.test.accept( self )
- self.emit('JUMP_IF_FALSE', else_ or after)
+ self.emitop_block('JUMP_IF_FALSE', else_ or after)
self.nextBlock()
self.emit('POP_TOP')
node.body.accept( self )
- self.emit('JUMP_ABSOLUTE', loop)
+ self.emitop_block('JUMP_ABSOLUTE', loop)
self.startBlock(else_) # or just the POPs if not else clause
self.emit('POP_TOP')
@@ -476,16 +487,16 @@
self.setups.push((LOOP, start))
self.set_lineno(node)
- self.emit('SETUP_LOOP', after)
+ self.emitop_block('SETUP_LOOP', after)
node.list.accept( self )
self.emit('GET_ITER')
self.nextBlock(start)
self.set_lineno(node, force=1)
- self.emit('FOR_ITER', anchor)
+ self.emitop_block('FOR_ITER', anchor)
node.assign.accept( self )
node.body.accept( self )
- self.emit('JUMP_ABSOLUTE', start)
+ self.emitop_block('JUMP_ABSOLUTE', start)
self.nextBlock(anchor)
self.emit('POP_BLOCK')
self.setups.pop()
@@ -495,51 +506,56 @@
def visitBreak(self, node):
if not self.setups:
- raise SyntaxError, "'break' outside loop (%s, %d)" % \
- (node.filename, node.lineno)
+ raise SyntaxError( "'break' outside loop (%s, %d)" %
+ (node.filename, node.lineno) )
self.set_lineno(node)
self.emit('BREAK_LOOP')
def visitContinue(self, node):
if not self.setups:
- raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno)
+ raise SyntaxError( "'continue' not properly in loop"
+ # (%s, %d)" % (node.filename, node.lineno)
+ )
kind, block = self.setups.top()
if kind == LOOP:
self.set_lineno(node)
- self.emit('JUMP_ABSOLUTE', block)
+ self.emitop_block('JUMP_ABSOLUTE', block)
self.nextBlock()
elif kind == EXCEPT or kind == TRY_FINALLY:
self.set_lineno(node)
# find the block that starts the loop
top = len(self.setups)
+ loop_block = None
while top > 0:
top = top - 1
kind, loop_block = self.setups[top]
if kind == LOOP:
break
if kind != LOOP:
- raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno)
- self.emit('CONTINUE_LOOP', loop_block)
+ raise SyntaxError( "'continue' not properly in loop"
+ # (%s, %d)" % (node.filename, node.lineno)
+ )
+ self.emitop_block('CONTINUE_LOOP', loop_block)
self.nextBlock()
elif kind == END_FINALLY:
msg = "'continue' not supported inside 'finally' clause" # " (%s, %d)"
- raise SyntaxError, msg # % (node.filename, node.lineno)
+ raise SyntaxError( msg ) # % (node.filename, node.lineno)
- def visitTest(self, node, jump):
+ def _visitTest(self, node, jump):
end = self.newBlock()
for child in node.nodes[:-1]:
child.accept( self )
- self.emit(jump, end)
+ self.emitop_block(jump, end)
self.nextBlock()
self.emit('POP_TOP')
node.nodes[-1].accept( self )
self.nextBlock(end)
def visitAnd(self, node):
- self.visitTest(node, 'JUMP_IF_FALSE')
+ self._visitTest(node, 'JUMP_IF_FALSE')
def visitOr(self, node):
- self.visitTest(node, 'JUMP_IF_TRUE')
+ self._visitTest(node, 'JUMP_IF_TRUE')
def visitCompare(self, node):
node.expr.accept( self )
@@ -548,18 +564,18 @@
code.accept( self )
self.emit('DUP_TOP')
self.emit('ROT_THREE')
- self.emit('COMPARE_OP', op)
- self.emit('JUMP_IF_FALSE', cleanup)
+ self.emitop('COMPARE_OP', op)
+ self.emitop_block('JUMP_IF_FALSE', cleanup)
self.nextBlock()
self.emit('POP_TOP')
# now do the last comparison
if node.ops:
op, code = node.ops[-1]
code.accept( self )
- self.emit('COMPARE_OP', op)
+ self.emitop('COMPARE_OP', op)
if len(node.ops) > 1:
end = self.newBlock()
- self.emit('JUMP_FORWARD', end)
+ self.emitop_block('JUMP_FORWARD', end)
self.startBlock(cleanup)
self.emit('ROT_TWO')
self.emit('POP_TOP')
@@ -573,34 +589,36 @@
# setup list
append = "$append%d" % self.__list_count
self.__list_count = self.__list_count + 1
- self.emit('BUILD_LIST', 0)
+ self.emitop_int('BUILD_LIST', 0)
self.emit('DUP_TOP')
- self.emit('LOAD_ATTR', 'append')
+ self.emitop('LOAD_ATTR', 'append')
self._implicitNameOp('STORE', append)
+
stack = []
for i, for_ in zip(range(len(node.quals)), node.quals):
start, anchor = for_.accept( self )
- cont = None
+ self.genexpr_cont_stack.append( None )
for if_ in for_.ifs:
- if cont is None:
- cont = self.newBlock()
- if_.accept( self, cont)
- stack.insert(0, (start, cont, anchor))
+ if self.genexpr_cont_stack[-1] is None:
+ self.genexpr_cont_stack[-1] = self.newBlock()
+ if_.accept( self )
+ stack.insert(0, (start, self.genexpr_cont_stack[-1], anchor))
+ self.genexpr_cont_stack.pop()
self._implicitNameOp('LOAD', append)
node.expr.accept( self )
- self.emit('CALL_FUNCTION', 1)
+ self.emitop_int('CALL_FUNCTION', 1)
self.emit('POP_TOP')
for start, cont, anchor in stack:
if cont:
skip_one = self.newBlock()
- self.emit('JUMP_FORWARD', skip_one)
+ self.emitop_block('JUMP_FORWARD', skip_one)
self.startBlock(cont)
self.emit('POP_TOP')
self.nextBlock(skip_one)
- self.emit('JUMP_ABSOLUTE', start)
+ self.emitop_block('JUMP_ABSOLUTE', start)
self.startBlock(anchor)
self._implicitNameOp('DELETE', append)
@@ -614,20 +632,21 @@
self.emit('GET_ITER')
self.nextBlock(start)
self.set_lineno(node, force=True)
- self.emit('FOR_ITER', anchor)
+ self.emitop_block('FOR_ITER', anchor)
self.nextBlock()
node.assign.accept( self )
return start, anchor
- def visitListCompIf(self, node, branch):
+ def visitListCompIf(self, node):
+ branch = self.genexpr_cont_stack[-1]
self.set_lineno(node, force=True)
node.test.accept( self )
- self.emit('JUMP_IF_FALSE', branch)
+ self.emitop_block('JUMP_IF_FALSE', branch)
self.newBlock()
self.emit('POP_TOP')
def visitGenExpr(self, node):
- gen = GenExprCodeGenerator(node, self.scopes, self.class_name,
+ gen = GenExprCodeGenerator(self.space, node, self.scopes, self.class_name,
self.get_module())
walk(node.code, gen)
gen.finish()
@@ -635,17 +654,17 @@
frees = gen.scope.get_free_vars()
if frees:
for name in frees:
- self.emit('LOAD_CLOSURE', name)
- self.emit('LOAD_CONST', gen)
- self.emit('MAKE_CLOSURE', 0)
+ self.emitop('LOAD_CLOSURE', name)
+ self.emitop_obj('LOAD_CONST', gen)
+ self.emitop_int('MAKE_CLOSURE', 0)
else:
- self.emit('LOAD_CONST', gen)
- self.emit('MAKE_FUNCTION', 0)
+ self.emitop_obj('LOAD_CONST', gen)
+ self.emitop_int('MAKE_FUNCTION', 0)
# precomputation of outmost iterable
node.code.quals[0].iter.accept( self )
self.emit('GET_ITER')
- self.emit('CALL_FUNCTION', 1)
+ self.emitop_int('CALL_FUNCTION', 1)
def visitGenExprInner(self, node):
self.set_lineno(node)
@@ -654,12 +673,13 @@
stack = []
for i, for_ in zip(range(len(node.quals)), node.quals):
start, anchor = for_.accept( self )
- cont = None
+ self.genexpr_cont_stack.append( None )
for if_ in for_.ifs:
- if cont is None:
- cont = self.newBlock()
- if_.accept( self, cont)
- stack.insert(0, (start, cont, anchor))
+ if self.genexpr_cont_stack[-1] is None:
+ self.genexpr_cont_stack[-1] = self.newBlock()
+ if_.accept( self )
+ stack.insert(0, (start, self.genexpr_cont_stack[-1], anchor))
+ self.genexpr_cont_stack.pop()
node.expr.accept( self )
self.emit('YIELD_VALUE')
@@ -667,13 +687,13 @@
for start, cont, anchor in stack:
if cont:
skip_one = self.newBlock()
- self.emit('JUMP_FORWARD', skip_one)
+ self.emitop_block('JUMP_FORWARD', skip_one)
self.startBlock(cont)
self.emit('POP_TOP')
self.nextBlock(skip_one)
- self.emit('JUMP_ABSOLUTE', start)
+ self.emitop_block('JUMP_ABSOLUTE', start)
self.startBlock(anchor)
- self.emit('LOAD_CONST', None)
+ self.emitop_obj('LOAD_CONST', self.space.w_None)
def visitGenExprFor(self, node):
start = self.newBlock()
@@ -687,15 +707,16 @@
self.nextBlock(start)
self.set_lineno(node, force=True)
- self.emit('FOR_ITER', anchor)
+ self.emitop_block('FOR_ITER', anchor)
self.nextBlock()
node.assign.accept( self )
return start, anchor
- def visitGenExprIf(self, node, branch):
+ def visitGenExprIf(self, node ):
+ branch = self.genexpr_cont_stack[-1]
self.set_lineno(node, force=True)
node.test.accept( self )
- self.emit('JUMP_IF_FALSE', branch)
+ self.emitop_block('JUMP_IF_FALSE', branch)
self.newBlock()
self.emit('POP_TOP')
@@ -712,15 +733,15 @@
# is a sort of renaming op.
self.nextBlock()
node.test.accept( self )
- self.emit('JUMP_IF_TRUE', end)
+ self.emitop_block('JUMP_IF_TRUE', end)
self.nextBlock()
self.emit('POP_TOP')
- self.emit('LOAD_GLOBAL', 'AssertionError')
+ self.emitop('LOAD_GLOBAL', 'AssertionError')
if node.fail:
node.fail.accept( self )
- self.emit('RAISE_VARARGS', 2)
+ self.emitop_int('RAISE_VARARGS', 2)
else:
- self.emit('RAISE_VARARGS', 1)
+ self.emitop_int('RAISE_VARARGS', 1)
self.nextBlock(end)
self.emit('POP_TOP')
@@ -736,7 +757,7 @@
if node.expr3:
node.expr3.accept( self )
n = n + 1
- self.emit('RAISE_VARARGS', n)
+ self.emitop_int('RAISE_VARARGS', n)
def visitTryExcept(self, node):
body = self.newBlock()
@@ -747,27 +768,29 @@
else:
lElse = end
self.set_lineno(node)
- self.emit('SETUP_EXCEPT', handlers)
+ self.emitop_block('SETUP_EXCEPT', handlers)
self.nextBlock(body)
self.setups.push((EXCEPT, body))
node.body.accept( self )
self.emit('POP_BLOCK')
self.setups.pop()
- self.emit('JUMP_FORWARD', lElse)
+ self.emitop_block('JUMP_FORWARD', lElse)
self.startBlock(handlers)
last = len(node.handlers) - 1
- for i in range(len(node.handlers)):
- expr, target, body = node.handlers[i]
- self.set_lineno(expr)
+ next = None
+ for expr, target, body in node.handlers:
if expr:
+ self.set_lineno(expr)
self.emit('DUP_TOP')
expr.accept( self )
- self.emit('COMPARE_OP', 'exception match')
+ self.emitop('COMPARE_OP', 'exception match')
next = self.newBlock()
- self.emit('JUMP_IF_FALSE', next)
+ self.emitop_block('JUMP_IF_FALSE', next)
self.nextBlock()
self.emit('POP_TOP')
+ else:
+ next = None
self.emit('POP_TOP')
if target:
target.accept( self )
@@ -775,11 +798,8 @@
self.emit('POP_TOP')
self.emit('POP_TOP')
body.accept( self )
- self.emit('JUMP_FORWARD', end)
- if expr:
- self.nextBlock(next)
- else:
- self.nextBlock()
+ self.emitop_block('JUMP_FORWARD', end)
+ self.nextBlock(next)
if expr: # XXX
self.emit('POP_TOP')
self.emit('END_FINALLY')
@@ -792,13 +812,13 @@
body = self.newBlock()
final = self.newBlock()
self.set_lineno(node)
- self.emit('SETUP_FINALLY', final)
+ self.emitop_block('SETUP_FINALLY', final)
self.nextBlock(body)
self.setups.push((TRY_FINALLY, body))
node.body.accept( self )
self.emit('POP_BLOCK')
self.setups.pop()
- self.emit('LOAD_CONST', None)
+ self.emitop_obj('LOAD_CONST', self.space.w_None)
self.nextBlock(final)
self.setups.push((END_FINALLY, final))
node.final.accept( self )
@@ -813,19 +833,10 @@
self.emit('POP_TOP')
def visitConst(self, node):
- self.emit('LOAD_CONST', node.value)
-
- def visitNoneConst(self, node):
- self.emit('LOAD_CONST', None)
-
- def visitNumberConst(self, node):
- self.emit('LOAD_CONST', node.number_value)
-
- def visitStringConst(self, node):
- self.emit('LOAD_CONST', node.string_value)
+ self.emitop_obj('LOAD_CONST', node.value)
def visitKeyword(self, node):
- self.emit('LOAD_CONST', node.name)
+ self.emitop_obj('LOAD_CONST', self.space.wrap(node.name) )
node.expr.accept( self )
def visitGlobal(self, node):
@@ -842,8 +853,8 @@
def visitImport(self, node):
self.set_lineno(node)
for name, alias in node.names:
- self.emit('LOAD_CONST', None)
- self.emit('IMPORT_NAME', name)
+ self.emitop_obj('LOAD_CONST', self.space.w_None)
+ self.emitop('IMPORT_NAME', name)
mod = name.split(".")[0]
if alias:
self._resolveDots(name)
@@ -853,9 +864,9 @@
def visitFrom(self, node):
self.set_lineno(node)
- fromlist = map(lambda (name, alias): name, node.names)
- self.emit('LOAD_CONST', tuple(fromlist))
- self.emit('IMPORT_NAME', node.modname)
+ fromlist = [ self.space.wrap(name) for name,alias in node.names ]
+ self.emitop_obj('LOAD_CONST', self.space.newtuple(fromlist))
+ self.emitop('IMPORT_NAME', node.modname)
for name, alias in node.names:
if name == '*':
self.namespace = 0
@@ -864,7 +875,7 @@
assert len(node.names) == 1
return
else:
- self.emit('IMPORT_FROM', name)
+ self.emitop('IMPORT_FROM', name)
self._resolveDots(name)
self.storeName(alias or name)
self.emit('POP_TOP')
@@ -874,11 +885,11 @@
if len(elts) == 1:
return
for elt in elts[1:]:
- self.emit('LOAD_ATTR', elt)
+ self.emitop('LOAD_ATTR', elt)
def visitGetattr(self, node):
node.expr.accept( self )
- self.emit('LOAD_ATTR', self.mangle(node.attrname))
+ self.emitop('LOAD_ATTR', self.mangle(node.attrname))
# next five implement assignments
@@ -905,38 +916,30 @@
def visitAssAttr(self, node):
node.expr.accept( self )
if node.flags == 'OP_ASSIGN':
- self.emit('STORE_ATTR', self.mangle(node.attrname))
+ self.emitop('STORE_ATTR', self.mangle(node.attrname))
elif node.flags == 'OP_DELETE':
- self.emit('DELETE_ATTR', self.mangle(node.attrname))
+ self.emitop('DELETE_ATTR', self.mangle(node.attrname))
else:
print "warning: unexpected flags:", node.flags
print node
def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'):
if findOp(node) != 'OP_DELETE':
- self.emit(op, len(node.nodes))
+ self.emitop_int(op, len(node.nodes))
for child in node.nodes:
child.accept( self )
- if VERSION > 1:
- visitAssTuple = _visitAssSequence
- visitAssList = _visitAssSequence
- else:
- def visitAssTuple(self, node):
- self._visitAssSequence(node, 'UNPACK_TUPLE')
-
- def visitAssList(self, node):
- self._visitAssSequence(node, 'UNPACK_LIST')
+ visitAssTuple = _visitAssSequence
+ visitAssList = _visitAssSequence
# augmented assignment
def visitAugAssign(self, node):
self.set_lineno(node)
- aug_node = wrap_aug(node.node)
- aug_node.accept( self, "load")
+ node.node.accept( AugLoadVisitor(self) )
node.expr.accept( self )
self.emit(self._augmented_opcode[node.op])
- aug_node.accept( self, "store")
+ node.node.accept( AugStoreVisitor(self) )
_augmented_opcode = {
'+=' : 'INPLACE_ADD',
@@ -953,51 +956,10 @@
'|=' : 'INPLACE_OR',
}
- def visitAugName(self, node, mode):
- if mode == "load":
- self.loadName(node.name)
- elif mode == "store":
- self.storeName(node.name)
-
- def visitAugGetattr(self, node, mode):
- if mode == "load":
- node.expr.accept( self )
- self.emit('DUP_TOP')
- self.emit('LOAD_ATTR', self.mangle(node.attrname))
- elif mode == "store":
- self.emit('ROT_TWO')
- self.emit('STORE_ATTR', self.mangle(node.attrname))
-
- def visitAugSlice(self, node, mode):
- if mode == "load":
- self.visitSlice(node, 1)
- elif mode == "store":
- slice = 0
- if node.lower:
- slice = slice | 1
- if node.upper:
- slice = slice | 2
- if slice == 0:
- self.emit('ROT_TWO')
- elif slice == 3:
- self.emit('ROT_FOUR')
- else:
- self.emit('ROT_THREE')
- self.emit('STORE_SLICE+%d' % slice)
-
- def visitAugSubscript(self, node, mode):
- if len(node.subs) > 1:
- raise SyntaxError, "augmented assignment to tuple is not possible"
- if mode == "load":
- self.visitSubscript(node, 1)
- elif mode == "store":
- self.emit('ROT_THREE')
- self.emit('STORE_SUBSCR')
-
def visitExec(self, node):
node.expr.accept( self )
if node.locals is None:
- self.emit('LOAD_CONST', None)
+ self.emitop_obj('LOAD_CONST', self.space.w_None)
else:
node.locals.accept( self )
if node.globals is None:
@@ -1024,7 +986,7 @@
have_star = node.star_args is not None
have_dstar = node.dstar_args is not None
opcode = callfunc_opcode_info[have_star, have_dstar]
- self.emit(opcode, kw << 8 | pos)
+ self.emitop_int(opcode, kw << 8 | pos)
def visitPrint(self, node, newline=0):
self.set_lineno(node)
@@ -1075,9 +1037,9 @@
if slice == 0:
self.emit('DUP_TOP')
elif slice == 3:
- self.emit('DUP_TOPX', 3)
+ self.emitop_int('DUP_TOPX', 3)
else:
- self.emit('DUP_TOPX', 2)
+ self.emitop_int('DUP_TOPX', 2)
if node.flags == 'OP_APPLY':
self.emit('SLICE+%d' % slice)
elif node.flags == 'OP_ASSIGN':
@@ -1093,9 +1055,9 @@
for sub in node.subs:
sub.accept( self )
if aug_flag:
- self.emit('DUP_TOPX', 2)
+ self.emitop_int('DUP_TOPX', 2)
if len(node.subs) > 1:
- self.emit('BUILD_TUPLE', len(node.subs))
+ self.emitop_int('BUILD_TUPLE', len(node.subs))
if node.flags == 'OP_APPLY':
self.emit('BINARY_SUBSCR')
elif node.flags == 'OP_ASSIGN':
@@ -1181,28 +1143,28 @@
# object constructors
def visitEllipsis(self, node):
- self.emit('LOAD_CONST', Ellipsis)
+ self.emitop_obj('LOAD_CONST', self.space.wrap(Ellipsis) )
def visitTuple(self, node):
self.set_lineno(node)
for elt in node.nodes:
elt.accept( self )
- self.emit('BUILD_TUPLE', len(node.nodes))
+ self.emitop_int('BUILD_TUPLE', len(node.nodes))
def visitList(self, node):
self.set_lineno(node)
for elt in node.nodes:
elt.accept( self )
- self.emit('BUILD_LIST', len(node.nodes))
+ self.emitop_int('BUILD_LIST', len(node.nodes))
def visitSliceobj(self, node):
for child in node.nodes:
child.accept( self )
- self.emit('BUILD_SLICE', len(node.nodes))
+ self.emitop_int('BUILD_SLICE', len(node.nodes))
def visitDict(self, node):
self.set_lineno(node)
- self.emit('BUILD_MAP', 0)
+ self.emitop_int('BUILD_MAP', 0)
for k, v in node.items:
self.emit('DUP_TOP')
k.accept( self )
@@ -1212,43 +1174,42 @@
class ModuleCodeGenerator(CodeGenerator):
- __super_init = CodeGenerator.__init__
-
scopes = None
- def __init__(self, tree):
- self.graph = pyassem.PyFlowGraph("<module>", tree.filename)
+ def __init__(self, space, tree, futures = []):
+ self.graph = pyassem.PyFlowGraph(space, "<module>", tree.filename)
self.futures = future.find_futures(tree)
- self.__super_init()
+ for f in futures:
+ if f not in self.futures:
+ self.futures.append(f)
+ CodeGenerator.__init__(self, space)
walk(tree, self)
def get_module(self):
return self
class ExpressionCodeGenerator(CodeGenerator):
- __super_init = CodeGenerator.__init__
-
scopes = None
- futures = ()
- def __init__(self, tree):
- self.graph = pyassem.PyFlowGraph("<expression>", tree.filename)
- self.__super_init()
+ def __init__(self, space, tree, futures=[]):
+ self.graph = pyassem.PyFlowGraph(space, "<expression>", tree.filename)
+ self.futures = futures[:]
+ CodeGenerator.__init__(self, space)
walk(tree, self)
def get_module(self):
return self
class InteractiveCodeGenerator(CodeGenerator):
-
- __super_init = CodeGenerator.__init__
-
scopes = None
- futures = ()
- def __init__(self, tree):
- self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename)
- self.__super_init()
+ def __init__(self, space, tree, futures=[]):
+ self.graph = pyassem.PyFlowGraph(space, "<interactive>", tree.filename)
+ self.futures = future.find_futures(tree)
+ for f in futures:
+ if f not in self.futures:
+ self.futures.append(f)
+ CodeGenerator.__init__(self, space)
self.set_lineno(tree)
walk(tree, self)
self.emit('RETURN_VALUE')
@@ -1262,11 +1223,11 @@
node.expr.accept( self )
self.emit('PRINT_EXPR')
-class AbstractFunctionCode:
+class AbstractFunctionCode(CodeGenerator):
optimized = 1
lambdaCount = 0
- def __init__(self, func, scopes, isLambda, class_name, mod):
+ def __init__(self, space, func, scopes, isLambda, class_name, mod):
self.class_name = class_name
self.module = mod
if isLambda:
@@ -1277,15 +1238,16 @@
name = func.name
args, hasTupleArg = generateArgList(func.argnames)
- self.graph = pyassem.PyFlowGraph(name, func.filename, args,
+ self.graph = pyassem.PyFlowGraph(space, name, func.filename, args,
optimized=1)
self.isLambda = isLambda
- self.super_init()
+ CodeGenerator.__init__(self, space)
if not isLambda and func.doc:
self.setDocstring(func.doc)
- lnf = walk(func.code, self.NameFinder(args), verbose=0)
+ lnf = LocalNameFinder(args)
+ func.code.accept(lnf)
self.locals.push(lnf.getLocals())
if func.varargs:
self.graph.setFlag(CO_VARARGS)
@@ -1301,21 +1263,21 @@
def finish(self):
self.graph.startExitBlock()
if not self.isLambda:
- self.emit('LOAD_CONST', None)
+ self.emitop_obj('LOAD_CONST', self.space.w_None)
self.emit('RETURN_VALUE')
def generateArgUnpack(self, args):
for i in range(len(args)):
arg = args[i]
if isinstance(arg, ast.AssTuple):
- self.emit('LOAD_FAST', '.%d' % (i * 2))
+ self.emitop('LOAD_FAST', '.%d' % (i * 2))
self.unpackSequence(arg)
def unpackSequence(self, tup):
if VERSION > 1:
- self.emit('UNPACK_SEQUENCE', len(tup.nodes))
+ self.emitop_int('UNPACK_SEQUENCE', len(tup.nodes))
else:
- self.emit('UNPACK_TUPLE', len(tup.nodes))
+ self.emitop_int('UNPACK_TUPLE', len(tup.nodes))
for elt in tup.nodes:
if isinstance(elt, ast.AssName):
@@ -1327,46 +1289,39 @@
unpackTuple = unpackSequence
-class FunctionCodeGenerator(AbstractFunctionCode,
- CodeGenerator):
- super_init = CodeGenerator.__init__ # call be other init
+class FunctionCodeGenerator(AbstractFunctionCode):
scopes = None
- __super_init = AbstractFunctionCode.__init__
-
- def __init__(self, func, scopes, isLambda, class_name, mod):
+ def __init__(self, space, func, scopes, isLambda, class_name, mod):
self.scopes = scopes
self.scope = scopes[func]
- self.__super_init(func, scopes, isLambda, class_name, mod)
+ AbstractFunctionCode.__init__(self, space, func, scopes, isLambda, class_name, mod)
self.graph.setFreeVars(self.scope.get_free_vars())
self.graph.setCellVars(self.scope.get_cell_vars())
if self.scope.generator is not None:
self.graph.setFlag(CO_GENERATOR)
-class GenExprCodeGenerator(AbstractFunctionCode,
- CodeGenerator):
- super_init = CodeGenerator.__init__ # call be other init
+class GenExprCodeGenerator(AbstractFunctionCode):
scopes = None
- __super_init = AbstractFunctionCode.__init__
-
- def __init__(self, gexp, scopes, class_name, mod):
+ def __init__(self, space, gexp, scopes, class_name, mod):
self.scopes = scopes
self.scope = scopes[gexp]
- self.__super_init(gexp, scopes, 1, class_name, mod)
+ AbstractFunctionCode.__init__(self, space, gexp, scopes, 1, class_name, mod)
self.graph.setFreeVars(self.scope.get_free_vars())
self.graph.setCellVars(self.scope.get_cell_vars())
self.graph.setFlag(CO_GENERATOR)
-class AbstractClassCode:
+class AbstractClassCode(CodeGenerator):
- def __init__(self, klass, scopes, module):
+ def __init__(self, space, klass, scopes, module):
self.class_name = klass.name
self.module = module
- self.graph = pyassem.PyFlowGraph(klass.name, klass.filename,
+ self.graph = pyassem.PyFlowGraph( space, klass.name, klass.filename,
optimized=0, klass=1)
- self.super_init()
- lnf = walk(klass.code, self.NameFinder(), verbose=0)
+ CodeGenerator.__init__(self, space)
+ lnf = LocalNameFinder()
+ klass.code.accept(lnf)
self.locals.push(lnf.getLocals())
self.graph.setFlag(CO_NEWLOCALS)
if klass.doc:
@@ -1380,23 +1335,20 @@
self.emit('LOAD_LOCALS')
self.emit('RETURN_VALUE')
-class ClassCodeGenerator(AbstractClassCode, CodeGenerator):
- super_init = CodeGenerator.__init__
+class ClassCodeGenerator(AbstractClassCode):
scopes = None
- __super_init = AbstractClassCode.__init__
-
- def __init__(self, klass, scopes, module):
+ def __init__(self, space, klass, scopes, module):
self.scopes = scopes
self.scope = scopes[klass]
- self.__super_init(klass, scopes, module)
+ AbstractClassCode.__init__(self, space, klass, scopes, module)
self.graph.setFreeVars(self.scope.get_free_vars())
self.graph.setCellVars(self.scope.get_cell_vars())
self.set_lineno(klass)
- self.emit("LOAD_GLOBAL", "__name__")
+ self.emitop("LOAD_GLOBAL", "__name__")
self.storeName("__module__")
if klass.doc:
- self.emit("LOAD_CONST", klass.doc)
+ self.emitop_obj("LOAD_CONST", klass.doc)
self.storeName('__doc__')
def generateArgList(arglist):
@@ -1433,53 +1385,65 @@
visitAssAttr = visitAssName
visitSubscript = visitAssName
-class Delegator:
- """Base class to support delegation for augmented assignment nodes
- To generator code for augmented assignments, we use the following
- wrapper classes. In visitAugAssign, the left-hand expression node
- is visited twice. The first time the visit uses the normal method
- for that node . The second time the visit uses a different method
- that generates the appropriate code to perform the assignment.
- These delegator classes wrap the original AST nodes in order to
- support the variant visit methods.
- """
- def __init__(self, obj):
- self.obj = obj
- def __getattr__(self, attr):
- return getattr(self.obj, attr)
+class AugLoadVisitor(ast.ASTVisitor):
+ def __init__(self, main_visitor):
+ self.main = main_visitor
-class AugGetattr(Delegator):
- pass
-
-class AugName(Delegator):
- pass
+ def default(self, node):
+ raise RuntimeError("shouldn't arrive here!")
+
+ def visitName(self, node ):
+ self.main.loadName(node.varname)
-class AugSlice(Delegator):
- pass
+ def visitGetattr(self, node):
+ node.expr.accept( self )
+ self.main.emit('DUP_TOP')
+ self.main.emitop('LOAD_ATTR', self.main.mangle(node.attrname))
-class AugSubscript(Delegator):
- pass
+ def visitSlice(self, node):
+ self.main.visitSlice(node, 1)
-wrapper = {
- ast.Getattr: AugGetattr,
- ast.Name: AugName,
- ast.Slice: AugSlice,
- ast.Subscript: AugSubscript,
- }
+ def visitSubscript(self, node):
+ if len(node.subs) > 1:
+ raise SyntaxError( "augmented assignment to tuple is not possible" )
+ self.main.visitSubscript(node, 1)
-def wrap_aug(node):
- return wrapper[node.__class__](node)
+class AugStoreVisitor(ast.ASTVisitor):
+ def __init__(self, main_visitor):
+ self.main = main_visitor
+
+ def default(self, node):
+ raise RuntimeError("shouldn't arrive here!")
+
+ def visitName(self, node):
+ self.main.storeName(node.varname)
-for klass in (ModuleCodeGenerator, ExpressionCodeGenerator, InteractiveCodeGenerator,
- FunctionCodeGenerator, GenExprCodeGenerator, ClassCodeGenerator):
- klass.NameFinder = LocalNameFinder
- klass.FunctionGen = FunctionCodeGenerator
- klass.ClassGen = ClassCodeGenerator
+ def visitGetattr(self, node):
+ self.main.emit('ROT_TWO')
+ self.main.emitop('STORE_ATTR', self.main.mangle(node.attrname))
+ def visitSlice(self, node):
+ slice = 0
+ if node.lower:
+ slice = slice | 1
+ if node.upper:
+ slice = slice | 2
+ if slice == 0:
+ self.main.emit('ROT_TWO')
+ elif slice == 3:
+ self.main.emit('ROT_FOUR')
+ else:
+ self.main.emit('ROT_THREE')
+ self.main.emit('STORE_SLICE+%d' % slice)
+ def visitSubscript(self, node):
+ if len(node.subs) > 1:
+ raise SyntaxError( "augmented assignment to tuple is not possible" )
+ self.main.emit('ROT_THREE')
+ self.main.emit('STORE_SUBSCR')
if __name__ == "__main__":
for file in sys.argv[1:]:
Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original)
+++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Thu Aug 25 11:25:42 2005
@@ -4,6 +4,7 @@
from pypy.interpreter.astcompiler.consts import SC_LOCAL, SC_GLOBAL, \
SC_FREE, SC_CELL, SC_UNKNOWN, SC_REALLY_GLOBAL
from pypy.interpreter.astcompiler.misc import mangle
+from pypy.interpreter.pyparser.error import SyntaxError
import types
@@ -471,6 +472,7 @@
# a yield statement signals a generator
def visitYield(self, node ):
+ scope = self.cur_scope()
scope.generator = 1
node.value.accept( self )
Modified: pypy/dist/pypy/interpreter/pycompiler.py
==============================================================================
--- pypy/dist/pypy/interpreter/pycompiler.py (original)
+++ pypy/dist/pypy/interpreter/pycompiler.py Thu Aug 25 11:25:42 2005
@@ -323,12 +323,15 @@
"""
def compile(self, source, filename, mode, flags):
from pyparser.error import ParseError
- from pyparser.pythonutil import internal_pypy_parse_to_ast
+ from pyparser.pythonutil import AstBuilder, PYTHON_PARSER, TARGET_DICT
flags |= __future__.generators.compiler_flag # always on (2.2 compat)
- # XXX use 'flags'
space = self.space
try:
- encoding, ast_tree = internal_pypy_parse_to_ast(source, mode, True, flags)
+ builder = AstBuilder(space=space)
+ target_rule = TARGET_DICT[mode]
+ PYTHON_PARSER.parse_source(source, target_rule, builder, flags)
+ ast_tree = builder.rule_stack[-1]
+ encoding = builder.source_encoding
except ParseError, e:
raise OperationError(space.w_SyntaxError,
e.wrap_info(space, filename))
@@ -339,6 +342,7 @@
# __________
# XXX this uses the non-annotatable astcompiler at interp-level
from pypy.interpreter import astcompiler
+ from pyparser.error import SyntaxError
from pypy.interpreter.astcompiler.pycodegen import ModuleCodeGenerator
from pypy.interpreter.astcompiler.pycodegen import InteractiveCodeGenerator
from pypy.interpreter.astcompiler.pycodegen import ExpressionCodeGenerator
@@ -347,11 +351,11 @@
astcompiler.misc.set_filename(filename, ast_tree)
flag_names = get_flag_names( flags )
if mode == 'exec':
- codegenerator = ModuleCodeGenerator(ast_tree, flag_names)
+ codegenerator = ModuleCodeGenerator(space, ast_tree, flag_names)
elif mode == 'single':
- codegenerator = InteractiveCodeGenerator(ast_tree, flag_names)
+ codegenerator = InteractiveCodeGenerator(space, ast_tree, flag_names)
else: # mode == 'eval':
- codegenerator = ExpressionCodeGenerator(ast_tree, flag_names)
+ codegenerator = ExpressionCodeGenerator(space, ast_tree, flag_names)
c = codegenerator.getCode()
except SyntaxError, e:
w_synerr = space.newtuple([space.wrap(e.msg),
@@ -367,8 +371,8 @@
raise OperationError(space.w_TypeError,space.wrap(str(e)))
# __________ end of XXX above
from pypy.interpreter.pycode import PyCode
- code = PyCode(space)._from_code(c)
- return code
+ assert isinstance(c,PyCode)
+ return c
#compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler'
Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Thu Aug 25 11:25:42 2005
@@ -265,7 +265,7 @@
return genexpr_fors
-def get_docstring(stmt):
+def get_docstring(builder,stmt):
"""parses a Stmt node.
If a docstring if found, the Discard node is **removed**
@@ -276,15 +276,15 @@
"""
if not isinstance(stmt, ast.Stmt):
return None
- doc = None
+ doc = builder.wrap_none()
if len(stmt.nodes):
first_child = stmt.nodes[0]
if isinstance(first_child, ast.Discard):
expr = first_child.expr
- if isinstance(expr, ast.StringConst):
+ if builder.is_string_const(expr):
# This *is* a docstring, remove it from stmt list
del stmt.nodes[0]
- doc = expr.string_value
+ doc = expr.value
return doc
@@ -341,21 +341,6 @@
atoms.reverse()
return atoms
-def eval_number(value):
- """temporary implementation
- eval_number intends to replace number = eval(value) ; return number
- """
- from pypy.objspace.std.strutil import string_to_int, string_to_float
- from pypy.objspace.std.strutil import string_to_long
- from pypy.objspace.std.strutil import ParseStringError
- if value.endswith('l') or value.endswith('L'):
- value = value[:-1]
- # ???
- try:
- return string_to_int(value)
- except ParseStringError:
- return string_to_float(value)
-
def eval_string(value):
"""temporary implementation
@@ -385,6 +370,7 @@
result = result.replace(escaped, value)
return result
+
## misc utilities, especially for power: rule
def reduce_callfunc(obj, arglist):
"""generic factory for CallFunc nodes"""
@@ -495,14 +481,14 @@
elif top.name == tok.NAME:
builder.push( ast.Name(top.get_value()) )
elif top.name == tok.NUMBER:
- builder.push(ast.NumberConst(eval_number(top.get_value())))
+ builder.push(ast.Const(builder.eval_number(top.get_value())))
elif top.name == tok.STRING:
# need to concatenate strings in atoms
s = ''
for token in atoms:
assert isinstance(token, TokenObject)
s += eval_string(token.get_value())
- builder.push(ast.StringConst(s))
+ builder.push(ast.Const(builder.wrap_string(s)))
elif top.name == tok.BACKQUOTE:
builder.push(ast.Backquote(atoms[1]))
else:
@@ -707,7 +693,7 @@
for n in range(0,l,2):
node = atoms[n]
if isinstance(node, TokenObject) and node.name == tok.NEWLINE:
- nodes.append(ast.Discard(ast.NoneConst()))
+ nodes.append(ast.Discard(ast.Const(builder.wrap_none())))
else:
nodes.append(node)
builder.push(ast.Stmt(nodes))
@@ -717,12 +703,11 @@
if len(atoms) > 2:
assert False, "return several stmts not implemented"
elif len(atoms) == 1:
- builder.push(ast.Return(ast.NoneConst(), None)) # XXX lineno
+ builder.push(ast.Return(ast.Const(builder.wrap_none()), None)) # XXX lineno
else:
builder.push(ast.Return(atoms[1], None)) # XXX lineno
def build_file_input(builder, nb):
- doc = None
stmts = []
atoms = get_atoms(builder, nb)
for node in atoms:
@@ -736,13 +721,20 @@
else:
stmts.append(node)
main_stmt = ast.Stmt(stmts)
- doc = get_docstring(main_stmt)
+ doc = get_docstring(builder,main_stmt)
return builder.push(ast.Module(doc, main_stmt))
+def build_eval_input(builder, nb):
+ doc = builder.wrap_none()
+ stmts = []
+ atoms = get_atoms(builder, nb)
+ assert len(atoms)>=1
+ return builder.push(ast.Expression(atoms[0]))
+
def build_single_input( builder, nb ):
atoms = get_atoms( builder, nb )
l = len(atoms)
- if l >= 1:
+ if l == 1 or l==2:
builder.push(ast.Module(None, atoms[0]))
else:
assert False, "Forbidden path"
@@ -851,7 +843,7 @@
sliceobj_infos = []
for value in sliceinfos:
if value is None:
- sliceobj_infos.append(ast.NoneConst())
+ sliceobj_infos.append(ast.Const(builder.wrap_none()))
else:
sliceobj_infos.append(value)
builder.push(SlicelistObject('sliceobj', sliceobj_infos, None))
@@ -929,7 +921,7 @@
funcname = funcname_token.get_value()
arglist = atoms[2]
code = atoms[-1]
- doc = get_docstring(code)
+ doc = get_docstring(builder, code)
builder.push(ast.Function(decorator_node, funcname, names, default, flags, doc, code))
@@ -953,7 +945,7 @@
basenames.append(node)
else:
basenames.append(base)
- doc = get_docstring(body)
+ doc = get_docstring(builder,body)
builder.push(ast.Class(classname, basenames, doc, body))
def build_suite(builder, nb):
@@ -1303,6 +1295,7 @@
sym.try_stmt : build_try_stmt,
sym.exprlist : build_exprlist,
sym.decorator : build_decorator,
+ sym.eval_input : build_eval_input,
}
## Stack elements definitions ###################################
@@ -1447,9 +1440,10 @@
class AstBuilder(BaseGrammarBuilder):
"""A builder that directly produce the AST"""
- def __init__(self, rules=None, debug=0):
+ def __init__(self, rules=None, debug=0, space=None):
BaseGrammarBuilder.__init__(self, rules, debug)
self.rule_stack = []
+ self.space = space
def context(self):
return AstBuilderContext(self.rule_stack)
@@ -1530,6 +1524,47 @@
self.push_tok(name, value, source)
return True
+ def eval_number(self, value):
+ """temporary implementation
+ eval_number intends to replace number = eval(value) ; return number
+ """
+ from pypy.objspace.std.strutil import string_to_int, string_to_float
+ from pypy.objspace.std.strutil import string_to_w_long, interp_string_to_float
+ from pypy.objspace.std.strutil import ParseStringError
+ space = self.space
+ base = 10
+ if value.startswith("0x") or value.startswith("0X"):
+ base = 16
+ elif value.startswith("0"):
+ base = 8
+ if value.endswith('l') or value.endswith('L'):
+ value = value[:-1]
+ return string_to_w_long( space, value, base=base )
+ try:
+ value = string_to_int(value, base=base)
+ return space.wrap(value)
+ except ParseStringError:
+ return space.wrap(interp_string_to_float(space,value))
+
+ def is_string_const(self, expr):
+ if not isinstance(expr,ast.Const):
+ return False
+ space = self.space
+ return space.is_true(space.isinstance(expr.value,space.w_str))
+
+ def wrap_string(self, obj):
+ if self.space:
+ return self.space.wrap(obj)
+ else:
+ return obj
+
+ def wrap_none(self):
+ if self.space:
+ return self.space.w_None
+ else:
+ return None
+
+
def show_stack(before, after):
"""debugging helper function"""
size1 = len(before)
Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/pythonutil.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/pythonutil.py Thu Aug 25 11:25:42 2005
@@ -115,6 +115,17 @@
code1 = codegenerator.getCode()
return code1
+def target_ast_compile(space, input, mode):
+ from pypy.interpreter.astcompiler import ast, misc, pycodegen
+ builder = AstBuilder(rules=None, debug=0, space=space)
+ target = TARGET_DICT[mode]
+ PYTHON_PARSER.parse_source(input, target, builder)
+ ast_tree = builder.rule_stack[-1]
+ misc.set_filename("<?>", ast_tree)
+ codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree)
+ code1 = codegenerator.getCode()
+ return code1
+
def internal_pypy_parse_to_ast(source, mode='exec', lineno=False, flags=0):
builder = AstBuilder()
Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Thu Aug 25 11:25:42 2005
@@ -55,7 +55,9 @@
if not arglist_equal(left_args, right_args):
return False
elif isinstance(left,stable_ast.Const):
- if isinstance(right,ast_ast.NoneConst):
+ if isinstance(right,ast_ast.Const):
+ return left.value == right.value
+ elif isinstance(right,ast_ast.NoneConst):
return left.value == None
elif isinstance(right, ast_ast.NumberConst):
return left.value == right.number_value
@@ -159,6 +161,10 @@
"l = (i for j in k for i in j)",
"l = (i for j in k for i in j if j%2==0)",
"l = (i for j in k if j%2 == 0 if j*2 < 20 for i in j if i%2==0)",
+ "l = (i for i in [ j*2 for j in range(10) ] )",
+ "l = [i for i in ( j*2 for j in range(10) ) ]",
+ "l = (i for i in [ j*2 for j in ( k*3 for k in range(10) ) ] )",
+ "l = [i for j in ( j*2 for j in [ k*3 for k in range(10) ] ) ]",
]
@@ -413,8 +419,63 @@
'return (a,b,c,d)',
]
+augassigns = [
+ 'a=1;a+=2',
+ 'a=1;a-=2',
+ 'a=1;a*=2',
+ 'a=1;a/=2',
+ 'a=1;a//=2',
+ 'a=1;a%=2',
+ 'a=1;a**=2',
+ 'a=1;a>>=2',
+ 'a=1;a<<=2',
+ 'a=1;a&=2',
+ 'a=1;a^=2',
+ 'a=1;a|=2',
+
+ 'a=A();a.x+=2',
+ 'a=A();a.x-=2',
+ 'a=A();a.x*=2',
+ 'a=A();a.x/=2',
+ 'a=A();a.x//=2',
+ 'a=A();a.x%=2',
+ 'a=A();a.x**=2',
+ 'a=A();a.x>>=2',
+ 'a=A();a.x<<=2',
+ 'a=A();a.x&=2',
+ 'a=A();a.x^=2',
+ 'a=A();a.x|=2',
+
+ 'a=A();a[0]+=2',
+ 'a=A();a[0]-=2',
+ 'a=A();a[0]*=2',
+ 'a=A();a[0]/=2',
+ 'a=A();a[0]//=2',
+ 'a=A();a[0]%=2',
+ 'a=A();a[0]**=2',
+ 'a=A();a[0]>>=2',
+ 'a=A();a[0]<<=2',
+ 'a=A();a[0]&=2',
+ 'a=A();a[0]^=2',
+ 'a=A();a[0]|=2',
+
+ 'a=A();a[0:2]+=2',
+ 'a=A();a[0:2]-=2',
+ 'a=A();a[0:2]*=2',
+ 'a=A();a[0:2]/=2',
+ 'a=A();a[0:2]//=2',
+ 'a=A();a[0:2]%=2',
+ 'a=A();a[0:2]**=2',
+ 'a=A();a[0:2]>>=2',
+ 'a=A();a[0:2]<<=2',
+ 'a=A();a[0:2]&=2',
+ 'a=A();a[0:2]^=2',
+ 'a=A();a[0:2]|=2',
+ ]
+
TESTS = [
expressions,
+ augassigns,
comparisons,
funccalls,
backtrackings,
@@ -448,9 +509,27 @@
'eval' : 'eval_input',
}
+
+class FakeSpace:
+ w_None = None
+ w_str = str
+ w_int = int
+
+ def wrap(self,obj):
+ return obj
+
+ def isinstance(self, obj, wtype ):
+ return isinstance(obj,wtype)
+
+ def is_true(self, obj):
+ return obj
+
+ def newtuple(self, lst):
+ return tuple(lst)
+
def ast_parse_expr(expr, target='single'):
target = TARGET_DICT[target]
- builder = AstBuilder()
+ builder = AstBuilder(space=FakeSpace())
PYTHON_PARSER.parse_source(expr, target, builder)
return builder
Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Thu Aug 25 11:25:42 2005
@@ -1,19 +1,20 @@
from pypy.interpreter.pyparser.pythonparse import PYTHON_PARSER
from pypy.interpreter.pyparser.astbuilder import AstBuilder
-
-
-from pypy.interpreter.pyparser.pythonutil import ast_from_input
+from pypy.interpreter.pycode import PyCode
import py.test
from pypy.interpreter.astcompiler import ast, misc, pycodegen
from test_astbuilder import expressions, comparisons, funccalls, backtrackings,\
listmakers, genexps, dictmakers, multiexpr, attraccess, slices, imports,\
- asserts, execs, prints, globs, raises, imports_newstyle
+ asserts, execs, prints, globs, raises, imports_newstyle, augassigns
+
+from test_astbuilder import FakeSpace
TESTS = [
expressions,
+ augassigns,
comparisons,
funccalls,
backtrackings,
@@ -42,18 +43,18 @@
'eval' : 'eval_input',
}
-def ast_parse_expr(expr, target='single'):
+def ast_parse_expr(expr, target='single', space=FakeSpace()):
target = TARGET_DICT[target]
- builder = AstBuilder()
+ builder = AstBuilder(space=space)
PYTHON_PARSER.parse_source(expr, target, builder)
return builder.rule_stack[-1]
### Note: builtin compile and compiler.compile behave differently
-def compile_expr( expr, target="single" ):
+def compile_expr( expr, target="exec" ):
return compile( expr, "<?>", target )
-def ast_compile( expr, target="single" ):
+def ast_compile( expr, target="exec" ):
from compiler import compile
return compile( expr, "<?>", target )
@@ -71,15 +72,42 @@
dis.dis(code2)
assert code1.co_code == code2.co_code
assert code1.co_varnames == code2.co_varnames
+
+ assert len(code1.co_consts) == len(code2.co_consts)
+ for c1, c2 in zip( code1.co_consts, code2.co_consts ):
+ if type(c1)==PyCode:
+ c1 = to_code(c1)
+ return compare_code( c1, c2 )
+ else:
+ assert c1 == c2
-def check_compile( expr ):
+def to_code( rcode ):
import new
- ast_tree = ast_parse_expr( expr )
+ code = new.code( rcode.co_argcount,
+ rcode.co_nlocals,
+ rcode.co_stacksize,
+ rcode.co_flags,
+ rcode.co_code,
+ rcode.co_consts_w,
+ tuple(rcode.co_names),
+ tuple(rcode.co_varnames),
+ rcode.co_filename,
+ rcode.co_name,
+ rcode.co_firstlineno,
+ rcode.co_lnotab,
+ tuple(rcode.co_freevars),
+ tuple(rcode.co_cellvars) )
+ return code
+
+def check_compile( expr ):
+ space = FakeSpace()
+ ast_tree = ast_parse_expr( expr, target='exec', space=space )
misc.set_filename("<?>", ast_tree)
print "Compiling:", expr
- #print ast_tree
- codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree)
- code1 = new.code(*codegenerator.getCode())
+ print ast_tree
+ codegenerator = pycodegen.ModuleCodeGenerator(space,ast_tree)
+ rcode = codegenerator.getCode()
+ code1 = to_code( rcode )
code2 = ast_compile( expr )
compare_code(code1,code2)
Modified: pypy/dist/pypy/translator/goal/targetcompiler.py
==============================================================================
--- pypy/dist/pypy/translator/goal/targetcompiler.py (original)
+++ pypy/dist/pypy/translator/goal/targetcompiler.py Thu Aug 25 11:25:42 2005
@@ -12,11 +12,26 @@
# __________ Entry point __________
# entry_point = annotateme
-from pypy.interpreter.pyparser.pythonutil import ast_compile
-entry_point = ast_compile
+from pypy.interpreter.pyparser.pythonutil import target_ast_compile
+from pypy.objspace.std.objspace import StdObjSpace
+
+def entry_point( s1, s2 ):
+ global space
+ return target_ast_compile( space, s1, s2 )
# _____ Define and setup target ___
def target():
+ global space, w_entry_point
+ # disable translation of the whole of classobjinterp.py
+ StdObjSpace.setup_old_style_classes = lambda self: None
+ # disable geninterp for now -- we have faaar toooo much interp-level code
+ # for the poor translator already
+ # XXX why can't I enable this? crashes the annotator!
+ space = StdObjSpace(nofaking=True,
+ compiler="astparser",
+ translating=True,
+ #usemodules=['marhsal', '_sre'],
+ geninterp=False)
return entry_point, [str, str]
# _____ Run translated _____
More information about the Pypy-commit
mailing list