from copy import copy class Node(object): def __init__(self, *args): if len(args) > len(self._items_): raise TypeError, 'too many arguments' for name, arg in zip(self._items_, args): setattr(self, name, arg) for name in self._items_[len(args):]: if not hasattr(self, name): raise TypeError, 'too few arguments' setattr(self, name, copy(getattr(self, name))) def __repr__(self): items = self._items_[:] while items and (hasattr(self.__class__, items[-1]) and getattr(self.__class__, items[-1]) == getattr(self, items[-1])): del items[-1] args = [repr(getattr(self, name)) for name in items] return '%s(%s)' % (self.__class__.__name__, ', '.join(args)) # ____________________________________________________________ class Module(Node): _items_ = ['doc', 'node'] class Expression(Node): _items_ = ['node'] # ____________________________________________________________ class ExprNode(Node): pass class Const(ExprNode): _items_ = ['value'] class Name(ExprNode): _items_ = ['name'] class List(ExprNode): _items_ = ['nodes'] class Dict(ExprNode): _items_ = ['items'] class Function(Node): _items_ = ['name', 'parameters', 'suite'] class Lambda(Function, ExprNode): _items_ = ['parameters', 'expr'] name = '' def __init__(self, parameters, expr): self.parameters = parameters self.expr = expr self.suite = [Return(expr)] class Parameters(Node): _items_ = ['args', 'vararg', 'kwarg'] args = [] vararg = None kwarg = None def add(self, name, value): if value is None and self.args and self.args[-1][1] is not None: raise SyntaxError, "positional arguments must precede '=' arguments" self.args.append((name, value)) class Tuple(ExprNode): _items_ = ['nodes'] class Discard(Node): _items_ = ['expr'] class Assign(Node): _items_ = ['lefts', 'right'] class InPlaceAssign(Node): _items_ = ['left', 'op', 'right'] class Print(Node): _items_ = ['nodes', 'dest'] nodes = [] newline = False dest = None class Printnl(Print): newline = True class Del(Node): _items_ = ['expr'] class Pass(Node): _items_ = [] class Break(Node): _items_ = [] class Continue(Node): _items_ = [] class Return(Node): _items_ = ['expr'] expr = None class Yield(Node): _items_ = ['expr'] expr = None class Raise(Node): _items_ = ['expr1', 'expr2', 'expr3'] expr1 = None expr2 = None expr3 = None class Import(Node): _items_ = ['names'] class From(Node): _items_ = ['modname', 'names'] class Global(Node): _items_ = ['names'] class Exec(Node): _items_ = ['code', 'global', 'local'] class Assert(Node): _items_ = ['test', 'value'] class If(Node): _items_ = ['test', 'then', 'else_'] else_ = None class While(Node): _items_ = ['test', 'body', 'else_'] else_ = None class For(Node): _items_ = ['assign', 'list', 'body', 'else_'] else_ = None class TryFinally(Node): _items_ = ['body', 'finally_'] class TryExcept(Node): _items_ = ['body', 'handlers', 'else_'] else_ = None class Or(ExprNode): _items_ = ['nodes'] class And(ExprNode): _items_ = ['left', 'right'] class UnaryOp(ExprNode): _items_ = ['expr'] class Invert(UnaryOp): op = '~' class UnaryAdd(UnaryOp): op = '+' UNARY_OPS = { '~': Invert, '+': UnaryAdd, } class BinaryOp(ExprNode): _items_ = ['left', 'right'] class Mul(BinaryOp): op = '*' class RightShift(BinaryOp): op = '>>' BINARY_OPS = { '*' : Mul, '>>': RightShift, } class Compare(ExprNode): _items_ = ['ops'] class ListComp(ExprNode): _items_ = ['stmt'] class ListCompAppend(Node): _items_ = ['expr'] class Call(ExprNode): _items_ = ['obj', 'parameters'] class Subscript(ExprNode): _items_ = ['obj', 'subscript'] class Ellipsis(ExprNode): _items_ = [] class Getattr(ExprNode): _items_ = ['expr', 'attrname'] class Slice(ExprNode): _items_ = ['start', 'stop', 'step'] start = stop = step = None class Class(Node): _items_ = ['name', 'bases', 'body']