[pypy-commit] pypy split-ast-classes: in-progress: conversion of internal trees to Python-visible AST.
amauryfa
noreply at buildbot.pypy.org
Wed Jun 26 23:22:05 CEST 2013
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: split-ast-classes
Changeset: r65014:e1dff3384dde
Date: 2013-06-23 13:57 +0200
http://bitbucket.org/pypy/pypy/changeset/e1dff3384dde/
Log: in-progress: conversion of internal trees to Python-visible AST.
diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -1,6 +1,10 @@
# Generated by tools/asdl_py.py
from pypy.interpreter.error import OperationError
from rpython.tool.pairtype import extendabletype
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter import typedef
+from pypy.interpreter.gateway import interp2app
+from rpython.tool.sourcetools import func_with_new_name
class AST(object):
@@ -16,8 +20,101 @@
class NodeVisitorNotImplemented(Exception):
pass
+
+class _FieldsWrapper(W_Root):
+ "Hack around the fact we can't store tuples on a TypeDef."
+
+ def __init__(self, fields):
+ self.fields = fields
+
+ def __spacebind__(self, space):
+ return space.newtuple([space.wrap(field) for field in self.fields])
+
+
+class W_AST(W_Root):
+ w_dict = None
+
+ def getdict(self, space):
+ if self.w_dict is None:
+ self.w_dict = space.newdict(instance=True)
+ return self.w_dict
+
+ def reduce_w(self, space):
+ w_dict = self.w_dict
+ if w_dict is None:
+ w_dict = space.newdict()
+ w_type = space.type(self)
+ w_fields = w_type.getdictvalue(space, "_fields")
+ for w_name in space.fixedview(w_fields):
+ space.setitem(w_dict, w_name,
+ space.getattr(self, w_name))
+ w_attrs = space.findattr(w_type, space.wrap("_attributes"))
+ if w_attrs:
+ for w_name in space.fixedview(w_attrs):
+ space.setitem(w_dict, w_name,
+ space.getattr(self, w_name))
+ return space.newtuple([space.type(self),
+ space.newtuple([]),
+ w_dict])
+
+ def setstate_w(self, space, w_state):
+ for w_name in space.unpackiterable(w_state):
+ space.setattr(self, w_name,
+ space.getitem(w_state, w_name))
+
+def get_W_AST_new(node_class):
+ def generic_W_AST_new(space, w_type, __args__):
+ node = space.allocate_instance(node_class, w_type)
+ return space.wrap(node)
+ return func_with_new_name(generic_W_AST_new, "new_%s" % node_class.__name__)
+
+
+def W_AST_init(space, w_self, __args__):
+ args_w, kwargs_w = __args__.unpack()
+ if args_w and len(args_w) != 0:
+ w_err = space.wrap("_ast.AST constructor takes 0 positional arguments")
+ raise OperationError(space.w_TypeError, w_err)
+ for field, w_value in kwargs_w.iteritems():
+ space.setattr(w_self, space.wrap(field), w_value)
+
+
+W_AST.typedef = typedef.TypeDef("AST",
+ _fields=_FieldsWrapper([]),
+ _attributes=_FieldsWrapper([]),
+ __module__='_ast',
+ __reduce__=interp2app(W_AST.reduce_w),
+ __setstate__=interp2app(W_AST.setstate_w),
+ __dict__ = typedef.GetSetProperty(typedef.descr_get_dict,
+ typedef.descr_set_dict, cls=W_AST),
+ __new__=interp2app(get_W_AST_new(W_AST)),
+ __init__=interp2app(W_AST_init),
+)
+
+class State:
+ AST_TYPES = []
+
+ @classmethod
+ def ast_type(cls, name, base):
+ cls.AST_TYPES.append((name, base))
+
+ def __init__(self, space):
+ self.w_AST = space.gettypeobject(W_AST.typedef)
+ for (name, base) in self.AST_TYPES:
+ self.make_new_type(space, name, base)
+
+ def make_new_type(self, space, name, base):
+ w_base = getattr(self, 'w_%s' % base)
+ w_type = space.call_function(
+ space.w_type,
+ space.wrap(name), space.newtuple([w_base]), space.newdict())
+ setattr(self, 'w_%s' % name, w_type)
+
+def get(space):
+ return space.fromcache(State)
+
class mod(AST):
pass
+State.ast_type('mod', 'AST')
class Module(mod):
@@ -32,6 +129,17 @@
visitor._mutate_sequence(self.body)
return visitor.visit_Module(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Module)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ return w_node
+State.ast_type('Module', 'mod')
+
class Interactive(mod):
@@ -46,6 +154,17 @@
visitor._mutate_sequence(self.body)
return visitor.visit_Interactive(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Interactive)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ return w_node
+State.ast_type('Interactive', 'mod')
+
class Expression(mod):
@@ -59,6 +178,13 @@
self.body = self.body.mutate_over(visitor)
return visitor.visit_Expression(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Expression)
+ w_body = self.body.to_object(space) # expr
+ space.setattr(w_node, space.wrap('body'), w_body)
+ return w_node
+State.ast_type('Expression', 'mod')
+
class Suite(mod):
@@ -73,12 +199,24 @@
visitor._mutate_sequence(self.body)
return visitor.visit_Suite(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Suite)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ return w_node
+State.ast_type('Suite', 'mod')
+
class stmt(AST):
def __init__(self, lineno, col_offset):
self.lineno = lineno
self.col_offset = col_offset
+State.ast_type('stmt', 'AST')
class FunctionDef(stmt):
@@ -100,6 +238,27 @@
visitor._mutate_sequence(self.decorator_list)
return visitor.visit_FunctionDef(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_FunctionDef)
+ w_name = space.wrap(self.name)
+ space.setattr(w_node, space.wrap('name'), w_name)
+ w_args = self.args.to_object(space) # arguments
+ space.setattr(w_node, space.wrap('args'), w_args)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ if self.decorator_list is None:
+ decorator_list_w = []
+ else:
+ decorator_list_w = [node.to_object(space) for node in self.decorator_list] # expr
+ w_decorator_list = space.newlist(decorator_list_w)
+ space.setattr(w_node, space.wrap('decorator_list'), w_decorator_list)
+ return w_node
+State.ast_type('FunctionDef', 'stmt')
+
class ClassDef(stmt):
@@ -122,6 +281,31 @@
visitor._mutate_sequence(self.decorator_list)
return visitor.visit_ClassDef(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_ClassDef)
+ w_name = space.wrap(self.name)
+ space.setattr(w_node, space.wrap('name'), w_name)
+ if self.bases is None:
+ bases_w = []
+ else:
+ bases_w = [node.to_object(space) for node in self.bases] # expr
+ w_bases = space.newlist(bases_w)
+ space.setattr(w_node, space.wrap('bases'), w_bases)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ if self.decorator_list is None:
+ decorator_list_w = []
+ else:
+ decorator_list_w = [node.to_object(space) for node in self.decorator_list] # expr
+ w_decorator_list = space.newlist(decorator_list_w)
+ space.setattr(w_node, space.wrap('decorator_list'), w_decorator_list)
+ return w_node
+State.ast_type('ClassDef', 'stmt')
+
class Return(stmt):
@@ -137,6 +321,13 @@
self.value = self.value.mutate_over(visitor)
return visitor.visit_Return(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Return)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ return w_node
+State.ast_type('Return', 'stmt')
+
class Delete(stmt):
@@ -152,6 +343,17 @@
visitor._mutate_sequence(self.targets)
return visitor.visit_Delete(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Delete)
+ if self.targets is None:
+ targets_w = []
+ else:
+ targets_w = [node.to_object(space) for node in self.targets] # expr
+ w_targets = space.newlist(targets_w)
+ space.setattr(w_node, space.wrap('targets'), w_targets)
+ return w_node
+State.ast_type('Delete', 'stmt')
+
class Assign(stmt):
@@ -169,6 +371,19 @@
self.value = self.value.mutate_over(visitor)
return visitor.visit_Assign(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Assign)
+ if self.targets is None:
+ targets_w = []
+ else:
+ targets_w = [node.to_object(space) for node in self.targets] # expr
+ w_targets = space.newlist(targets_w)
+ space.setattr(w_node, space.wrap('targets'), w_targets)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ return w_node
+State.ast_type('Assign', 'stmt')
+
class AugAssign(stmt):
@@ -186,6 +401,17 @@
self.value = self.value.mutate_over(visitor)
return visitor.visit_AugAssign(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_AugAssign)
+ w_target = self.target.to_object(space) # expr
+ space.setattr(w_node, space.wrap('target'), w_target)
+ w_op = operator_to_class[self.op - 1]()
+ space.setattr(w_node, space.wrap('op'), w_op)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ return w_node
+State.ast_type('AugAssign', 'stmt')
+
class Print(stmt):
@@ -205,6 +431,21 @@
visitor._mutate_sequence(self.values)
return visitor.visit_Print(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Print)
+ w_dest = self.dest.to_object(space) # expr
+ space.setattr(w_node, space.wrap('dest'), w_dest)
+ if self.values is None:
+ values_w = []
+ else:
+ values_w = [node.to_object(space) for node in self.values] # expr
+ w_values = space.newlist(values_w)
+ space.setattr(w_node, space.wrap('values'), w_values)
+ w_nl = self.nl.to_object(space) # bool
+ space.setattr(w_node, space.wrap('nl'), w_nl)
+ return w_node
+State.ast_type('Print', 'stmt')
+
class For(stmt):
@@ -227,6 +468,27 @@
visitor._mutate_sequence(self.orelse)
return visitor.visit_For(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_For)
+ w_target = self.target.to_object(space) # expr
+ space.setattr(w_node, space.wrap('target'), w_target)
+ w_iter = self.iter.to_object(space) # expr
+ space.setattr(w_node, space.wrap('iter'), w_iter)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ if self.orelse is None:
+ orelse_w = []
+ else:
+ orelse_w = [node.to_object(space) for node in self.orelse] # stmt
+ w_orelse = space.newlist(orelse_w)
+ space.setattr(w_node, space.wrap('orelse'), w_orelse)
+ return w_node
+State.ast_type('For', 'stmt')
+
class While(stmt):
@@ -247,6 +509,25 @@
visitor._mutate_sequence(self.orelse)
return visitor.visit_While(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_While)
+ w_test = self.test.to_object(space) # expr
+ space.setattr(w_node, space.wrap('test'), w_test)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ if self.orelse is None:
+ orelse_w = []
+ else:
+ orelse_w = [node.to_object(space) for node in self.orelse] # stmt
+ w_orelse = space.newlist(orelse_w)
+ space.setattr(w_node, space.wrap('orelse'), w_orelse)
+ return w_node
+State.ast_type('While', 'stmt')
+
class If(stmt):
@@ -267,6 +548,25 @@
visitor._mutate_sequence(self.orelse)
return visitor.visit_If(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_If)
+ w_test = self.test.to_object(space) # expr
+ space.setattr(w_node, space.wrap('test'), w_test)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ if self.orelse is None:
+ orelse_w = []
+ else:
+ orelse_w = [node.to_object(space) for node in self.orelse] # stmt
+ w_orelse = space.newlist(orelse_w)
+ space.setattr(w_node, space.wrap('orelse'), w_orelse)
+ return w_node
+State.ast_type('If', 'stmt')
+
class With(stmt):
@@ -287,6 +587,21 @@
visitor._mutate_sequence(self.body)
return visitor.visit_With(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_With)
+ w_context_expr = self.context_expr.to_object(space) # expr
+ space.setattr(w_node, space.wrap('context_expr'), w_context_expr)
+ w_optional_vars = self.optional_vars.to_object(space) # expr
+ space.setattr(w_node, space.wrap('optional_vars'), w_optional_vars)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ return w_node
+State.ast_type('With', 'stmt')
+
class Raise(stmt):
@@ -308,6 +623,17 @@
self.tback = self.tback.mutate_over(visitor)
return visitor.visit_Raise(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Raise)
+ w_type = self.type.to_object(space) # expr
+ space.setattr(w_node, space.wrap('type'), w_type)
+ w_inst = self.inst.to_object(space) # expr
+ space.setattr(w_node, space.wrap('inst'), w_inst)
+ w_tback = self.tback.to_object(space) # expr
+ space.setattr(w_node, space.wrap('tback'), w_tback)
+ return w_node
+State.ast_type('Raise', 'stmt')
+
class TryExcept(stmt):
@@ -329,6 +655,29 @@
visitor._mutate_sequence(self.orelse)
return visitor.visit_TryExcept(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_TryExcept)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ if self.handlers is None:
+ handlers_w = []
+ else:
+ handlers_w = [node.to_object(space) for node in self.handlers] # excepthandler
+ w_handlers = space.newlist(handlers_w)
+ space.setattr(w_node, space.wrap('handlers'), w_handlers)
+ if self.orelse is None:
+ orelse_w = []
+ else:
+ orelse_w = [node.to_object(space) for node in self.orelse] # stmt
+ w_orelse = space.newlist(orelse_w)
+ space.setattr(w_node, space.wrap('orelse'), w_orelse)
+ return w_node
+State.ast_type('TryExcept', 'stmt')
+
class TryFinally(stmt):
@@ -347,6 +696,23 @@
visitor._mutate_sequence(self.finalbody)
return visitor.visit_TryFinally(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_TryFinally)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ if self.finalbody is None:
+ finalbody_w = []
+ else:
+ finalbody_w = [node.to_object(space) for node in self.finalbody] # stmt
+ w_finalbody = space.newlist(finalbody_w)
+ space.setattr(w_node, space.wrap('finalbody'), w_finalbody)
+ return w_node
+State.ast_type('TryFinally', 'stmt')
+
class Assert(stmt):
@@ -364,6 +730,15 @@
self.msg = self.msg.mutate_over(visitor)
return visitor.visit_Assert(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Assert)
+ w_test = self.test.to_object(space) # expr
+ space.setattr(w_node, space.wrap('test'), w_test)
+ w_msg = self.msg.to_object(space) # expr
+ space.setattr(w_node, space.wrap('msg'), w_msg)
+ return w_node
+State.ast_type('Assert', 'stmt')
+
class Import(stmt):
@@ -379,6 +754,17 @@
visitor._mutate_sequence(self.names)
return visitor.visit_Import(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Import)
+ if self.names is None:
+ names_w = []
+ else:
+ names_w = [node.to_object(space) for node in self.names] # alias
+ w_names = space.newlist(names_w)
+ space.setattr(w_node, space.wrap('names'), w_names)
+ return w_node
+State.ast_type('Import', 'stmt')
+
class ImportFrom(stmt):
@@ -396,6 +782,21 @@
visitor._mutate_sequence(self.names)
return visitor.visit_ImportFrom(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_ImportFrom)
+ w_module = space.wrap(self.module)
+ space.setattr(w_node, space.wrap('module'), w_module)
+ if self.names is None:
+ names_w = []
+ else:
+ names_w = [node.to_object(space) for node in self.names] # alias
+ w_names = space.newlist(names_w)
+ space.setattr(w_node, space.wrap('names'), w_names)
+ w_level = self.level.to_object(space) # int
+ space.setattr(w_node, space.wrap('level'), w_level)
+ return w_node
+State.ast_type('ImportFrom', 'stmt')
+
class Exec(stmt):
@@ -416,6 +817,17 @@
self.locals = self.locals.mutate_over(visitor)
return visitor.visit_Exec(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Exec)
+ w_body = self.body.to_object(space) # expr
+ space.setattr(w_node, space.wrap('body'), w_body)
+ w_globals = self.globals.to_object(space) # expr
+ space.setattr(w_node, space.wrap('globals'), w_globals)
+ w_locals = self.locals.to_object(space) # expr
+ space.setattr(w_node, space.wrap('locals'), w_locals)
+ return w_node
+State.ast_type('Exec', 'stmt')
+
class Global(stmt):
@@ -429,6 +841,17 @@
def mutate_over(self, visitor):
return visitor.visit_Global(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Global)
+ if self.names is None:
+ names_w = []
+ else:
+ names_w = [node.to_object(space) for node in self.names] # identifier
+ w_names = space.newlist(names_w)
+ space.setattr(w_node, space.wrap('names'), w_names)
+ return w_node
+State.ast_type('Global', 'stmt')
+
class Expr(stmt):
@@ -443,6 +866,13 @@
self.value = self.value.mutate_over(visitor)
return visitor.visit_Expr(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Expr)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ return w_node
+State.ast_type('Expr', 'stmt')
+
class Pass(stmt):
@@ -455,6 +885,11 @@
def mutate_over(self, visitor):
return visitor.visit_Pass(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Pass)
+ return w_node
+State.ast_type('Pass', 'stmt')
+
class Break(stmt):
@@ -467,6 +902,11 @@
def mutate_over(self, visitor):
return visitor.visit_Break(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Break)
+ return w_node
+State.ast_type('Break', 'stmt')
+
class Continue(stmt):
@@ -479,12 +919,18 @@
def mutate_over(self, visitor):
return visitor.visit_Continue(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Continue)
+ return w_node
+State.ast_type('Continue', 'stmt')
+
class expr(AST):
def __init__(self, lineno, col_offset):
self.lineno = lineno
self.col_offset = col_offset
+State.ast_type('expr', 'AST')
class BoolOp(expr):
@@ -501,6 +947,19 @@
visitor._mutate_sequence(self.values)
return visitor.visit_BoolOp(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_BoolOp)
+ w_op = boolop_to_class[self.op - 1]()
+ space.setattr(w_node, space.wrap('op'), w_op)
+ if self.values is None:
+ values_w = []
+ else:
+ values_w = [node.to_object(space) for node in self.values] # expr
+ w_values = space.newlist(values_w)
+ space.setattr(w_node, space.wrap('values'), w_values)
+ return w_node
+State.ast_type('BoolOp', 'expr')
+
class BinOp(expr):
@@ -518,6 +977,17 @@
self.right = self.right.mutate_over(visitor)
return visitor.visit_BinOp(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_BinOp)
+ w_left = self.left.to_object(space) # expr
+ space.setattr(w_node, space.wrap('left'), w_left)
+ w_op = operator_to_class[self.op - 1]()
+ space.setattr(w_node, space.wrap('op'), w_op)
+ w_right = self.right.to_object(space) # expr
+ space.setattr(w_node, space.wrap('right'), w_right)
+ return w_node
+State.ast_type('BinOp', 'expr')
+
class UnaryOp(expr):
@@ -533,6 +1003,15 @@
self.operand = self.operand.mutate_over(visitor)
return visitor.visit_UnaryOp(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_UnaryOp)
+ w_op = unaryop_to_class[self.op - 1]()
+ space.setattr(w_node, space.wrap('op'), w_op)
+ w_operand = self.operand.to_object(space) # expr
+ space.setattr(w_node, space.wrap('operand'), w_operand)
+ return w_node
+State.ast_type('UnaryOp', 'expr')
+
class Lambda(expr):
@@ -549,6 +1028,15 @@
self.body = self.body.mutate_over(visitor)
return visitor.visit_Lambda(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Lambda)
+ w_args = self.args.to_object(space) # arguments
+ space.setattr(w_node, space.wrap('args'), w_args)
+ w_body = self.body.to_object(space) # expr
+ space.setattr(w_node, space.wrap('body'), w_body)
+ return w_node
+State.ast_type('Lambda', 'expr')
+
class IfExp(expr):
@@ -567,6 +1055,17 @@
self.orelse = self.orelse.mutate_over(visitor)
return visitor.visit_IfExp(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_IfExp)
+ w_test = self.test.to_object(space) # expr
+ space.setattr(w_node, space.wrap('test'), w_test)
+ w_body = self.body.to_object(space) # expr
+ space.setattr(w_node, space.wrap('body'), w_body)
+ w_orelse = self.orelse.to_object(space) # expr
+ space.setattr(w_node, space.wrap('orelse'), w_orelse)
+ return w_node
+State.ast_type('IfExp', 'expr')
+
class Dict(expr):
@@ -585,6 +1084,23 @@
visitor._mutate_sequence(self.values)
return visitor.visit_Dict(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Dict)
+ if self.keys is None:
+ keys_w = []
+ else:
+ keys_w = [node.to_object(space) for node in self.keys] # expr
+ w_keys = space.newlist(keys_w)
+ space.setattr(w_node, space.wrap('keys'), w_keys)
+ if self.values is None:
+ values_w = []
+ else:
+ values_w = [node.to_object(space) for node in self.values] # expr
+ w_values = space.newlist(values_w)
+ space.setattr(w_node, space.wrap('values'), w_values)
+ return w_node
+State.ast_type('Dict', 'expr')
+
class Set(expr):
@@ -600,6 +1116,17 @@
visitor._mutate_sequence(self.elts)
return visitor.visit_Set(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Set)
+ if self.elts is None:
+ elts_w = []
+ else:
+ elts_w = [node.to_object(space) for node in self.elts] # expr
+ w_elts = space.newlist(elts_w)
+ space.setattr(w_node, space.wrap('elts'), w_elts)
+ return w_node
+State.ast_type('Set', 'expr')
+
class ListComp(expr):
@@ -617,6 +1144,19 @@
visitor._mutate_sequence(self.generators)
return visitor.visit_ListComp(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_ListComp)
+ w_elt = self.elt.to_object(space) # expr
+ space.setattr(w_node, space.wrap('elt'), w_elt)
+ if self.generators is None:
+ generators_w = []
+ else:
+ generators_w = [node.to_object(space) for node in self.generators] # comprehension
+ w_generators = space.newlist(generators_w)
+ space.setattr(w_node, space.wrap('generators'), w_generators)
+ return w_node
+State.ast_type('ListComp', 'expr')
+
class SetComp(expr):
@@ -634,6 +1174,19 @@
visitor._mutate_sequence(self.generators)
return visitor.visit_SetComp(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_SetComp)
+ w_elt = self.elt.to_object(space) # expr
+ space.setattr(w_node, space.wrap('elt'), w_elt)
+ if self.generators is None:
+ generators_w = []
+ else:
+ generators_w = [node.to_object(space) for node in self.generators] # comprehension
+ w_generators = space.newlist(generators_w)
+ space.setattr(w_node, space.wrap('generators'), w_generators)
+ return w_node
+State.ast_type('SetComp', 'expr')
+
class DictComp(expr):
@@ -653,6 +1206,21 @@
visitor._mutate_sequence(self.generators)
return visitor.visit_DictComp(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_DictComp)
+ w_key = self.key.to_object(space) # expr
+ space.setattr(w_node, space.wrap('key'), w_key)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ if self.generators is None:
+ generators_w = []
+ else:
+ generators_w = [node.to_object(space) for node in self.generators] # comprehension
+ w_generators = space.newlist(generators_w)
+ space.setattr(w_node, space.wrap('generators'), w_generators)
+ return w_node
+State.ast_type('DictComp', 'expr')
+
class GeneratorExp(expr):
@@ -670,6 +1238,19 @@
visitor._mutate_sequence(self.generators)
return visitor.visit_GeneratorExp(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_GeneratorExp)
+ w_elt = self.elt.to_object(space) # expr
+ space.setattr(w_node, space.wrap('elt'), w_elt)
+ if self.generators is None:
+ generators_w = []
+ else:
+ generators_w = [node.to_object(space) for node in self.generators] # comprehension
+ w_generators = space.newlist(generators_w)
+ space.setattr(w_node, space.wrap('generators'), w_generators)
+ return w_node
+State.ast_type('GeneratorExp', 'expr')
+
class Yield(expr):
@@ -685,6 +1266,13 @@
self.value = self.value.mutate_over(visitor)
return visitor.visit_Yield(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Yield)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ return w_node
+State.ast_type('Yield', 'expr')
+
class Compare(expr):
@@ -703,6 +1291,25 @@
visitor._mutate_sequence(self.comparators)
return visitor.visit_Compare(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Compare)
+ w_left = self.left.to_object(space) # expr
+ space.setattr(w_node, space.wrap('left'), w_left)
+ if self.ops is None:
+ ops_w = []
+ else:
+ ops_w = [cmpop_to_class[node - 1]() for node in self.ops] # cmpop
+ w_ops = space.newlist(ops_w)
+ space.setattr(w_node, space.wrap('ops'), w_ops)
+ if self.comparators is None:
+ comparators_w = []
+ else:
+ comparators_w = [node.to_object(space) for node in self.comparators] # expr
+ w_comparators = space.newlist(comparators_w)
+ space.setattr(w_node, space.wrap('comparators'), w_comparators)
+ return w_node
+State.ast_type('Compare', 'expr')
+
class Call(expr):
@@ -729,6 +1336,29 @@
self.kwargs = self.kwargs.mutate_over(visitor)
return visitor.visit_Call(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Call)
+ w_func = self.func.to_object(space) # expr
+ space.setattr(w_node, space.wrap('func'), w_func)
+ if self.args is None:
+ args_w = []
+ else:
+ args_w = [node.to_object(space) for node in self.args] # expr
+ w_args = space.newlist(args_w)
+ space.setattr(w_node, space.wrap('args'), w_args)
+ if self.keywords is None:
+ keywords_w = []
+ else:
+ keywords_w = [node.to_object(space) for node in self.keywords] # keyword
+ w_keywords = space.newlist(keywords_w)
+ space.setattr(w_node, space.wrap('keywords'), w_keywords)
+ w_starargs = self.starargs.to_object(space) # expr
+ space.setattr(w_node, space.wrap('starargs'), w_starargs)
+ w_kwargs = self.kwargs.to_object(space) # expr
+ space.setattr(w_node, space.wrap('kwargs'), w_kwargs)
+ return w_node
+State.ast_type('Call', 'expr')
+
class Repr(expr):
@@ -743,6 +1373,13 @@
self.value = self.value.mutate_over(visitor)
return visitor.visit_Repr(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Repr)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ return w_node
+State.ast_type('Repr', 'expr')
+
class Num(expr):
@@ -756,6 +1393,13 @@
def mutate_over(self, visitor):
return visitor.visit_Num(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Num)
+ w_n = self.n
+ space.setattr(w_node, space.wrap('n'), w_n)
+ return w_node
+State.ast_type('Num', 'expr')
+
class Str(expr):
@@ -769,6 +1413,13 @@
def mutate_over(self, visitor):
return visitor.visit_Str(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Str)
+ w_s = self.s
+ space.setattr(w_node, space.wrap('s'), w_s)
+ return w_node
+State.ast_type('Str', 'expr')
+
class Attribute(expr):
@@ -785,6 +1436,17 @@
self.value = self.value.mutate_over(visitor)
return visitor.visit_Attribute(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Attribute)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ w_attr = space.wrap(self.attr)
+ space.setattr(w_node, space.wrap('attr'), w_attr)
+ w_ctx = expr_context_to_class[self.ctx - 1]()
+ space.setattr(w_node, space.wrap('ctx'), w_ctx)
+ return w_node
+State.ast_type('Attribute', 'expr')
+
class Subscript(expr):
@@ -802,6 +1464,17 @@
self.slice = self.slice.mutate_over(visitor)
return visitor.visit_Subscript(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Subscript)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ w_slice = self.slice.to_object(space) # slice
+ space.setattr(w_node, space.wrap('slice'), w_slice)
+ w_ctx = expr_context_to_class[self.ctx - 1]()
+ space.setattr(w_node, space.wrap('ctx'), w_ctx)
+ return w_node
+State.ast_type('Subscript', 'expr')
+
class Name(expr):
@@ -816,6 +1489,15 @@
def mutate_over(self, visitor):
return visitor.visit_Name(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Name)
+ w_id = space.wrap(self.id)
+ space.setattr(w_node, space.wrap('id'), w_id)
+ w_ctx = expr_context_to_class[self.ctx - 1]()
+ space.setattr(w_node, space.wrap('ctx'), w_ctx)
+ return w_node
+State.ast_type('Name', 'expr')
+
class List(expr):
@@ -832,6 +1514,19 @@
visitor._mutate_sequence(self.elts)
return visitor.visit_List(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_List)
+ if self.elts is None:
+ elts_w = []
+ else:
+ elts_w = [node.to_object(space) for node in self.elts] # expr
+ w_elts = space.newlist(elts_w)
+ space.setattr(w_node, space.wrap('elts'), w_elts)
+ w_ctx = expr_context_to_class[self.ctx - 1]()
+ space.setattr(w_node, space.wrap('ctx'), w_ctx)
+ return w_node
+State.ast_type('List', 'expr')
+
class Tuple(expr):
@@ -848,6 +1543,19 @@
visitor._mutate_sequence(self.elts)
return visitor.visit_Tuple(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Tuple)
+ if self.elts is None:
+ elts_w = []
+ else:
+ elts_w = [node.to_object(space) for node in self.elts] # expr
+ w_elts = space.newlist(elts_w)
+ space.setattr(w_node, space.wrap('elts'), w_elts)
+ w_ctx = expr_context_to_class[self.ctx - 1]()
+ space.setattr(w_node, space.wrap('ctx'), w_ctx)
+ return w_node
+State.ast_type('Tuple', 'expr')
+
class Const(expr):
@@ -861,42 +1569,56 @@
def mutate_over(self, visitor):
return visitor.visit_Const(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Const)
+ w_value = self.value
+ space.setattr(w_node, space.wrap('value'), w_value)
+ return w_node
+State.ast_type('Const', 'expr')
+
class expr_context(AST):
def to_simple_int(self, space):
w_msg = space.wrap("not a valid expr_context")
raise OperationError(space.w_TypeError, w_msg)
+State.ast_type('expr_context', 'AST')
class _Load(expr_context):
def to_simple_int(self, space):
return 1
+State.ast_type('Load', 'expr_context')
class _Store(expr_context):
def to_simple_int(self, space):
return 2
+State.ast_type('Store', 'expr_context')
class _Del(expr_context):
def to_simple_int(self, space):
return 3
+State.ast_type('Del', 'expr_context')
class _AugLoad(expr_context):
def to_simple_int(self, space):
return 4
+State.ast_type('AugLoad', 'expr_context')
class _AugStore(expr_context):
def to_simple_int(self, space):
return 5
+State.ast_type('AugStore', 'expr_context')
class _Param(expr_context):
def to_simple_int(self, space):
return 6
+State.ast_type('Param', 'expr_context')
Load = 1
Store = 2
@@ -916,6 +1638,7 @@
class slice(AST):
pass
+State.ast_type('slice', 'AST')
class Ellipsis(slice):
@@ -926,6 +1649,11 @@
def mutate_over(self, visitor):
return visitor.visit_Ellipsis(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Ellipsis)
+ return w_node
+State.ast_type('Ellipsis', 'slice')
+
class Slice(slice):
@@ -946,6 +1674,17 @@
self.step = self.step.mutate_over(visitor)
return visitor.visit_Slice(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Slice)
+ w_lower = self.lower.to_object(space) # expr
+ space.setattr(w_node, space.wrap('lower'), w_lower)
+ w_upper = self.upper.to_object(space) # expr
+ space.setattr(w_node, space.wrap('upper'), w_upper)
+ w_step = self.step.to_object(space) # expr
+ space.setattr(w_node, space.wrap('step'), w_step)
+ return w_node
+State.ast_type('Slice', 'slice')
+
class ExtSlice(slice):
@@ -960,6 +1699,17 @@
visitor._mutate_sequence(self.dims)
return visitor.visit_ExtSlice(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_ExtSlice)
+ if self.dims is None:
+ dims_w = []
+ else:
+ dims_w = [node.to_object(space) for node in self.dims] # slice
+ w_dims = space.newlist(dims_w)
+ space.setattr(w_node, space.wrap('dims'), w_dims)
+ return w_node
+State.ast_type('ExtSlice', 'slice')
+
class Index(slice):
@@ -973,22 +1723,32 @@
self.value = self.value.mutate_over(visitor)
return visitor.visit_Index(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_Index)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ return w_node
+State.ast_type('Index', 'slice')
+
class boolop(AST):
def to_simple_int(self, space):
w_msg = space.wrap("not a valid boolop")
raise OperationError(space.w_TypeError, w_msg)
+State.ast_type('boolop', 'AST')
class _And(boolop):
def to_simple_int(self, space):
return 1
+State.ast_type('And', 'boolop')
class _Or(boolop):
def to_simple_int(self, space):
return 2
+State.ast_type('Or', 'boolop')
And = 1
Or = 2
@@ -1003,66 +1763,79 @@
def to_simple_int(self, space):
w_msg = space.wrap("not a valid operator")
raise OperationError(space.w_TypeError, w_msg)
+State.ast_type('operator', 'AST')
class _Add(operator):
def to_simple_int(self, space):
return 1
+State.ast_type('Add', 'operator')
class _Sub(operator):
def to_simple_int(self, space):
return 2
+State.ast_type('Sub', 'operator')
class _Mult(operator):
def to_simple_int(self, space):
return 3
+State.ast_type('Mult', 'operator')
class _Div(operator):
def to_simple_int(self, space):
return 4
+State.ast_type('Div', 'operator')
class _Mod(operator):
def to_simple_int(self, space):
return 5
+State.ast_type('Mod', 'operator')
class _Pow(operator):
def to_simple_int(self, space):
return 6
+State.ast_type('Pow', 'operator')
class _LShift(operator):
def to_simple_int(self, space):
return 7
+State.ast_type('LShift', 'operator')
class _RShift(operator):
def to_simple_int(self, space):
return 8
+State.ast_type('RShift', 'operator')
class _BitOr(operator):
def to_simple_int(self, space):
return 9
+State.ast_type('BitOr', 'operator')
class _BitXor(operator):
def to_simple_int(self, space):
return 10
+State.ast_type('BitXor', 'operator')
class _BitAnd(operator):
def to_simple_int(self, space):
return 11
+State.ast_type('BitAnd', 'operator')
class _FloorDiv(operator):
def to_simple_int(self, space):
return 12
+State.ast_type('FloorDiv', 'operator')
Add = 1
Sub = 2
@@ -1097,26 +1870,31 @@
def to_simple_int(self, space):
w_msg = space.wrap("not a valid unaryop")
raise OperationError(space.w_TypeError, w_msg)
+State.ast_type('unaryop', 'AST')
class _Invert(unaryop):
def to_simple_int(self, space):
return 1
+State.ast_type('Invert', 'unaryop')
class _Not(unaryop):
def to_simple_int(self, space):
return 2
+State.ast_type('Not', 'unaryop')
class _UAdd(unaryop):
def to_simple_int(self, space):
return 3
+State.ast_type('UAdd', 'unaryop')
class _USub(unaryop):
def to_simple_int(self, space):
return 4
+State.ast_type('USub', 'unaryop')
Invert = 1
Not = 2
@@ -1135,56 +1913,67 @@
def to_simple_int(self, space):
w_msg = space.wrap("not a valid cmpop")
raise OperationError(space.w_TypeError, w_msg)
+State.ast_type('cmpop', 'AST')
class _Eq(cmpop):
def to_simple_int(self, space):
return 1
+State.ast_type('Eq', 'cmpop')
class _NotEq(cmpop):
def to_simple_int(self, space):
return 2
+State.ast_type('NotEq', 'cmpop')
class _Lt(cmpop):
def to_simple_int(self, space):
return 3
+State.ast_type('Lt', 'cmpop')
class _LtE(cmpop):
def to_simple_int(self, space):
return 4
+State.ast_type('LtE', 'cmpop')
class _Gt(cmpop):
def to_simple_int(self, space):
return 5
+State.ast_type('Gt', 'cmpop')
class _GtE(cmpop):
def to_simple_int(self, space):
return 6
+State.ast_type('GtE', 'cmpop')
class _Is(cmpop):
def to_simple_int(self, space):
return 7
+State.ast_type('Is', 'cmpop')
class _IsNot(cmpop):
def to_simple_int(self, space):
return 8
+State.ast_type('IsNot', 'cmpop')
class _In(cmpop):
def to_simple_int(self, space):
return 9
+State.ast_type('In', 'cmpop')
class _NotIn(cmpop):
def to_simple_int(self, space):
return 10
+State.ast_type('NotIn', 'cmpop')
Eq = 1
NotEq = 2
@@ -1227,11 +2016,27 @@
def walkabout(self, visitor):
visitor.visit_comprehension(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_comprehension)
+ w_target = self.target.to_object(space) # expr
+ space.setattr(w_node, space.wrap('target'), w_target)
+ w_iter = self.iter.to_object(space) # expr
+ space.setattr(w_node, space.wrap('iter'), w_iter)
+ if self.ifs is None:
+ ifs_w = []
+ else:
+ ifs_w = [node.to_object(space) for node in self.ifs] # expr
+ w_ifs = space.newlist(ifs_w)
+ space.setattr(w_node, space.wrap('ifs'), w_ifs)
+ return w_node
+State.ast_type('comprehension', 'AST')
+
class excepthandler(AST):
def __init__(self, lineno, col_offset):
self.lineno = lineno
self.col_offset = col_offset
+State.ast_type('excepthandler', 'AST')
class ExceptHandler(excepthandler):
@@ -1253,6 +2058,21 @@
visitor._mutate_sequence(self.body)
return visitor.visit_ExceptHandler(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_ExceptHandler)
+ w_type = self.type.to_object(space) # expr
+ space.setattr(w_node, space.wrap('type'), w_type)
+ w_name = self.name.to_object(space) # expr
+ space.setattr(w_node, space.wrap('name'), w_name)
+ if self.body is None:
+ body_w = []
+ else:
+ body_w = [node.to_object(space) for node in self.body] # stmt
+ w_body = space.newlist(body_w)
+ space.setattr(w_node, space.wrap('body'), w_body)
+ return w_node
+State.ast_type('ExceptHandler', 'excepthandler')
+
class arguments(AST):
@@ -1272,6 +2092,27 @@
def walkabout(self, visitor):
visitor.visit_arguments(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_arguments)
+ if self.args is None:
+ args_w = []
+ else:
+ args_w = [node.to_object(space) for node in self.args] # expr
+ w_args = space.newlist(args_w)
+ space.setattr(w_node, space.wrap('args'), w_args)
+ w_vararg = space.wrap(self.vararg)
+ space.setattr(w_node, space.wrap('vararg'), w_vararg)
+ w_kwarg = space.wrap(self.kwarg)
+ space.setattr(w_node, space.wrap('kwarg'), w_kwarg)
+ if self.defaults is None:
+ defaults_w = []
+ else:
+ defaults_w = [node.to_object(space) for node in self.defaults] # expr
+ w_defaults = space.newlist(defaults_w)
+ space.setattr(w_node, space.wrap('defaults'), w_defaults)
+ return w_node
+State.ast_type('arguments', 'AST')
+
class keyword(AST):
def __init__(self, arg, value):
@@ -1285,6 +2126,15 @@
def walkabout(self, visitor):
visitor.visit_keyword(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_keyword)
+ w_arg = space.wrap(self.arg)
+ space.setattr(w_node, space.wrap('arg'), w_arg)
+ w_value = self.value.to_object(space) # expr
+ space.setattr(w_node, space.wrap('value'), w_value)
+ return w_node
+State.ast_type('keyword', 'AST')
+
class alias(AST):
def __init__(self, name, asname):
@@ -1297,6 +2147,15 @@
def walkabout(self, visitor):
visitor.visit_alias(self)
+ def to_object(self, space):
+ w_node = space.call_function(get(space).w_alias)
+ w_name = space.wrap(self.name)
+ space.setattr(w_node, space.wrap('name'), w_name)
+ w_asname = space.wrap(self.asname)
+ space.setattr(w_node, space.wrap('asname'), w_asname)
+ return w_node
+State.ast_type('alias', 'AST')
+
class ASTVisitor(object):
def visit_sequence(self, seq):
diff --git a/pypy/interpreter/astcompiler/test/test_ast.py b/pypy/interpreter/astcompiler/test/test_ast.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/astcompiler/test/test_ast.py
@@ -0,0 +1,30 @@
+from pypy.interpreter.astcompiler import ast
+class TestAstToObject:
+ def test_types(self, space):
+ assert space.is_true(space.issubtype(
+ ast.get(space).w_Module, ast.get(space).w_mod))
+
+ def test_num(self, space):
+ value = space.wrap(42)
+ node = ast.Num(value, lineno=1, col_offset=1)
+ w_node = node.to_object(space)
+ assert space.getattr(w_node, space.wrap("n")) is value
+
+ def test_expr(self, space):
+ value = space.wrap(42)
+ node = ast.Num(value, lineno=1, col_offset=1)
+ expr = ast.Expr(node, lineno=1, col_offset=1)
+ w_node = expr.to_object(space)
+ # node.value.n
+ assert space.getattr(space.getattr(w_node, space.wrap("value")),
+ space.wrap("n")) is value
+
+ def test_operation(self, space):
+ val1 = ast.Num(space.wrap(1), lineno=1, col_offset=1)
+ val2 = ast.Num(space.wrap(2), lineno=1, col_offset=1)
+ node = ast.BinOp(left=val1, right=val2, op=ast.Add,
+ lineno=1, col_offset=1)
+ w_node = node.to_object(space)
+ w_op = space.getattr(w_node, space.wrap("op"))
+ assert space.is_true(space.issubtype(
+ ast.get(space).w_operator, w_op))
diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py
--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
+++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
@@ -61,12 +61,14 @@
self.emit("def to_simple_int(self, space):", 1)
self.emit("w_msg = space.wrap(\"not a valid %s\")" % (base,), 2)
self.emit("raise OperationError(space.w_TypeError, w_msg)", 2)
+ self.emit("State.ast_type('%s', 'AST')" % (base,))
self.emit("")
for i, cons in enumerate(sum.types):
self.emit("class _%s(%s):" % (cons.name, base))
self.emit("")
self.emit("def to_simple_int(self, space):", 1)
self.emit("return %i" % (i + 1,), 2)
+ self.emit("State.ast_type('%s', '%s')" % (cons.name, base))
self.emit("")
for i, cons in enumerate(sum.types):
self.emit("%s = %i" % (cons.name, i + 1))
@@ -84,10 +86,10 @@
self.emit("def __init__(self, %s):" % (args,), 1)
for attr in sum.attributes:
self.visit(attr)
- self.emit("")
else:
self.emit("pass", 1)
- self.emit("")
+ self.emit("State.ast_type('%r', 'AST')" % (base,))
+ self.emit("")
for cons in sum.types:
self.visit(cons, base, sum.attributes)
self.emit("")
@@ -101,6 +103,47 @@
self.emit("def walkabout(self, visitor):", 1)
self.emit("visitor.visit_%s(self)" % (name,), 2)
self.emit("")
+ self.make_converters(product.fields, name)
+ self.emit("State.ast_type('%r', 'AST')" % (name,))
+ self.emit("")
+
+ def get_field_converter(self, field):
+ if field.seq:
+ lines = []
+ lines.append("if self.%s is None:" % field.name)
+ lines.append(" %s_w = []" % field.name)
+ lines.append("else:")
+ if field.type.value in self.data.simple_types:
+ wrapper = "%s_to_class[node - 1]()" % (field.type,)
+ elif field.type.value in ("object", "string"):
+ wrapper = "node"
+ else:
+ wrapper = "node.to_object(space)"
+ lines.append(" %s_w = [%s for node in self.%s] # %s" %
+ (field.name, wrapper, field.name, field.type))
+ lines.append("w_%s = space.newlist(%s_w)" % (field.name, field.name))
+ return lines
+ elif field.type.value in self.data.simple_types:
+ return ["w_%s = %s_to_class[self.%s - 1]()" %
+ (field.name, field.type, field.name)]
+ elif field.type.value in ("object", "string"):
+ return ["w_%s = self.%s" % (field.name, field.name)]
+ elif field.type.value in ("identifier",):
+ return ["w_%s = space.wrap(self.%s)" % (field.name, field.name)]
+ else:
+ return ["w_%s = self.%s.to_object(space) # %s" %
+ (field.name, field.name, field.type)]
+
+ def make_converters(self, fields, name):
+ self.emit("def to_object(self, space):", 1)
+ self.emit("w_node = space.call_function(get(space).w_%s)" % name, 2)
+ for field in fields:
+ wrapping_code = self.get_field_converter(field)
+ for line in wrapping_code:
+ self.emit(line, 2)
+ self.emit("space.setattr(w_node, space.wrap(%r), w_%s)" % (
+ str(field.name), field.name), 2)
+ self.emit("return w_node", 2)
def make_constructor(self, fields, node, extras=None, base=None):
if fields or extras:
@@ -142,6 +185,9 @@
self.emit("visitor.visit_%s(self)" % (cons.name,), 2)
self.emit("")
self.make_mutate_over(cons, cons.name)
+ self.make_converters(cons.fields, cons.name)
+ self.emit("State.ast_type('%r', '%s')" % (cons.name, base))
+ self.emit("")
def visitField(self, field):
self.emit("self.%s = %s" % (field.name, field.name), 2)
@@ -212,8 +258,8 @@
self.emit("")
def visitField(self, field):
- if field.type.value not in asdl.builtin_types and \
- field.type.value not in self.data.simple_types:
+ if (field.type.value not in asdl.builtin_types and
+ field.type.value not in self.data.simple_types):
level = 2
template = "node.%s.walkabout(self)"
if field.seq:
@@ -276,6 +322,10 @@
HEAD = """# Generated by tools/asdl_py.py
from pypy.interpreter.error import OperationError
from rpython.tool.pairtype import extendabletype
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter import typedef
+from pypy.interpreter.gateway import interp2app
+from rpython.tool.sourcetools import func_with_new_name
class AST(object):
@@ -291,6 +341,98 @@
class NodeVisitorNotImplemented(Exception):
pass
+
+class _FieldsWrapper(W_Root):
+ "Hack around the fact we can't store tuples on a TypeDef."
+
+ def __init__(self, fields):
+ self.fields = fields
+
+ def __spacebind__(self, space):
+ return space.newtuple([space.wrap(field) for field in self.fields])
+
+
+class W_AST(W_Root):
+ w_dict = None
+
+ def getdict(self, space):
+ if self.w_dict is None:
+ self.w_dict = space.newdict(instance=True)
+ return self.w_dict
+
+ def reduce_w(self, space):
+ w_dict = self.w_dict
+ if w_dict is None:
+ w_dict = space.newdict()
+ w_type = space.type(self)
+ w_fields = w_type.getdictvalue(space, "_fields")
+ for w_name in space.fixedview(w_fields):
+ space.setitem(w_dict, w_name,
+ space.getattr(self, w_name))
+ w_attrs = space.findattr(w_type, space.wrap("_attributes"))
+ if w_attrs:
+ for w_name in space.fixedview(w_attrs):
+ space.setitem(w_dict, w_name,
+ space.getattr(self, w_name))
+ return space.newtuple([space.type(self),
+ space.newtuple([]),
+ w_dict])
+
+ def setstate_w(self, space, w_state):
+ for w_name in space.unpackiterable(w_state):
+ space.setattr(self, w_name,
+ space.getitem(w_state, w_name))
+
+def get_W_AST_new(node_class):
+ def generic_W_AST_new(space, w_type, __args__):
+ node = space.allocate_instance(node_class, w_type)
+ return space.wrap(node)
+ return func_with_new_name(generic_W_AST_new, "new_%s" % node_class.__name__)
+
+
+def W_AST_init(space, w_self, __args__):
+ args_w, kwargs_w = __args__.unpack()
+ if args_w and len(args_w) != 0:
+ w_err = space.wrap("_ast.AST constructor takes 0 positional arguments")
+ raise OperationError(space.w_TypeError, w_err)
+ for field, w_value in kwargs_w.iteritems():
+ space.setattr(w_self, space.wrap(field), w_value)
+
+
+W_AST.typedef = typedef.TypeDef("AST",
+ _fields=_FieldsWrapper([]),
+ _attributes=_FieldsWrapper([]),
+ __module__='_ast',
+ __reduce__=interp2app(W_AST.reduce_w),
+ __setstate__=interp2app(W_AST.setstate_w),
+ __dict__ = typedef.GetSetProperty(typedef.descr_get_dict,
+ typedef.descr_set_dict, cls=W_AST),
+ __new__=interp2app(get_W_AST_new(W_AST)),
+ __init__=interp2app(W_AST_init),
+)
+
+class State:
+ AST_TYPES = []
+
+ @classmethod
+ def ast_type(cls, name, base):
+ cls.AST_TYPES.append((name, base))
+
+ def __init__(self, space):
+ self.w_AST = space.gettypeobject(W_AST.typedef)
+ for (name, base) in self.AST_TYPES:
+ self.make_new_type(space, name, base)
+
+ def make_new_type(self, space, name, base):
+ w_base = getattr(self, 'w_%s' % base)
+ w_type = space.call_function(
+ space.w_type,
+ space.wrap(name), space.newtuple([w_base]), space.newdict())
+ setattr(self, 'w_%s' % name, w_type)
+
+def get(space):
+ return space.fromcache(State)
+
"""
visitors = [ASTNodeVisitor, ASTVisitorVisitor, GenericASTVisitorVisitor]
diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py
--- a/pypy/module/__builtin__/compiling.py
+++ b/pypy/module/__builtin__/compiling.py
@@ -25,7 +25,7 @@
"""
ast_node = None
- w_ast_type = space.gettypeobject(interp_ast.W_AST.typedef)
+ w_ast_type = space.gettypeobject(ast.W_AST.typedef)
str_ = None
if space.isinstance_w(w_source, w_ast_type):
ast_node = space.interp_w(ast.mod, w_source)
@@ -57,7 +57,8 @@
if ast_node is None:
if flags & consts.PyCF_ONLY_AST:
mod = ec.compiler.compile_to_ast(str_, filename, mode, flags)
- return space.wrap(mod)
+ w_mod = mod.to_object(space)
+ return w_mod
else:
code = ec.compiler.compile(str_, filename, mode, flags)
else:
diff --git a/pypy/module/_ast/__init__.py b/pypy/module/_ast/__init__.py
--- a/pypy/module/_ast/__init__.py
+++ b/pypy/module/_ast/__init__.py
@@ -7,14 +7,12 @@
interpleveldefs = {
"PyCF_ONLY_AST" : "space.wrap(%s)" % consts.PyCF_ONLY_AST,
"__version__" : "space.wrap('82160')", # from CPython's svn.
- "AST": "interp_ast.W_AST",
}
appleveldefs = {}
def _setup():
defs = Module.interpleveldefs
- for name, cls in ast.__dict__.iteritems():
- if isinstance(cls, type) and issubclass(cls, ast.AST):
- defs[name.lstrip("_")] = cls.__module__ + "." + name
+ for (name, base) in ast.State.AST_TYPES:
+ defs[name] = "pypy.interpreter.astcompiler.ast.get(space).w_" + name
_setup()
More information about the pypy-commit
mailing list