# Generated by tools/asdl_py.py
from rpython.tool.pairtype import extendabletype
from rpython.tool.sourcetools import func_with_new_name

from pypy.interpreter import typedef
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.gateway import interp2app


def raise_required_value(space, w_obj, name):
    raise oefmt(space.w_ValueError,
                "field %s is required for %T", name, w_obj)

def check_string(space, w_obj):
    if not (space.isinstance_w(w_obj, space.w_bytes) or
            space.isinstance_w(w_obj, space.w_unicode)):
        raise oefmt(space.w_TypeError,
                    "AST string must be of type str or unicode")
    return w_obj

def get_field(space, w_node, name, optional):
    w_obj = w_node.getdictvalue(space, name)
    if w_obj is None:
        if not optional:
            raise oefmt(space.w_TypeError,
                "required field \"%s\" missing from %T", name, w_node)
        w_obj = space.w_None
    return w_obj


class AST(object):
    __metaclass__ = extendabletype
    _attrs_ = ['lineno', 'col_offset']

    def walkabout(self, visitor):
        raise AssertionError("walkabout() implementation not provided")

    def mutate_over(self, visitor):
        raise AssertionError("mutate_over() implementation not provided")


class NodeVisitorNotImplemented(Exception):
    pass


class _FieldsWrapper(W_Root):
    "Hack around the fact we can't store tuples on a TypeDef."

    def __init__(self, fields):
        assert fields == []

    def spacebind(self, space):
        return space.newtuple([])


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 = space.getattr(w_type, space.newtext("_fields"))
        for w_name in space.fixedview(w_fields):
            try:
                space.setitem(w_dict, w_name,
                          space.getattr(self, w_name))
            except OperationError:
                pass
        w_attrs = space.findattr(w_type, space.newtext("_attributes"))
        if w_attrs:
            for w_name in space.fixedview(w_attrs):
                try:
                    space.setitem(w_dict, w_name,
                              space.getattr(self, w_name))
                except OperationError:
                    pass
        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 W_AST_new(space, w_type, __args__):
    node = space.allocate_instance(W_AST, w_type)
    return node

def W_AST_init(space, w_self, __args__):
    args_w, kwargs_w = __args__.unpack()
    fields_w = space.fixedview(space.getattr(space.type(w_self),
                               space.newtext("_fields")))
    num_fields = len(fields_w) if fields_w else 0
    if args_w and len(args_w) != num_fields:
        if num_fields == 0:
            raise oefmt(space.w_TypeError,
                "%T constructor takes 0 positional arguments", w_self)
        elif num_fields == 1:
            raise oefmt(space.w_TypeError,
                "%T constructor takes either 0 or %d positional argument", w_self, num_fields)
        else:
            raise oefmt(space.w_TypeError,
                "%T constructor takes either 0 or %d positional arguments", w_self, num_fields)
    if args_w:
        for i, w_field in enumerate(fields_w):
            space.setattr(w_self, w_field, args_w[i])
    for field, w_value in kwargs_w.iteritems():
        space.setattr(w_self, space.newtext(field), w_value)


W_AST.typedef = typedef.TypeDef("_ast.AST",
    _fields=_FieldsWrapper([]),
    _attributes=_FieldsWrapper([]),
    __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(W_AST_new),
    __init__=interp2app(W_AST_init),
)

class State:
    AST_TYPES = []

    @classmethod
    def ast_type(cls, name, base, fields, attributes=None):
        cls.AST_TYPES.append((name, base, fields, attributes))

    def __init__(self, space):
        self.w_AST = space.gettypeobject(W_AST.typedef)
        for (name, base, fields, attributes) in self.AST_TYPES:
            self.make_new_type(space, name, base, fields, attributes)

    def make_new_type(self, space, name, base, fields, attributes):
        w_base = getattr(self, 'w_%s' % base)
        w_dict = space.newdict()
        space.setitem_str(w_dict, '__module__', space.newtext('_ast'))
        if fields is not None:
            space.setitem_str(w_dict, "_fields",
                              space.newtuple([space.newtext(f) for f in fields]))
        if attributes is not None:
            space.setitem_str(w_dict, "_attributes",
                              space.newtuple([space.newtext(a) for a in attributes]))
        w_type = space.call_function(
            space.w_type,
            space.newtext(name), space.newtuple([w_base]), w_dict)
        setattr(self, 'w_%s' % name, w_type)

def get(space):
    return space.fromcache(State)

class mod(AST):
    @staticmethod
    def from_object(space, w_node):
        if space.is_w(w_node, space.w_None):
            return None
        if space.isinstance_w(w_node, get(space).w_Module):
            return Module.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Interactive):
            return Interactive.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Expression):
            return Expression.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Suite):
            return Suite.from_object(space, w_node)
        raise oefmt(space.w_TypeError,
                "Expected mod node, got %T", w_node)
State.ast_type('mod', 'AST', None, [])

class Module(mod):

    def __init__(self, body):
        self.body = body

    def walkabout(self, visitor):
        visitor.visit_Module(self)

    def mutate_over(self, visitor):
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        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.newtext('body'), w_body)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_body = get_field(space, w_node, 'body', False)
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        return Module(_body)

State.ast_type('Module', 'mod', ['body'])


class Interactive(mod):

    def __init__(self, body):
        self.body = body

    def walkabout(self, visitor):
        visitor.visit_Interactive(self)

    def mutate_over(self, visitor):
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        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.newtext('body'), w_body)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_body = get_field(space, w_node, 'body', False)
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        return Interactive(_body)

State.ast_type('Interactive', 'mod', ['body'])


class Expression(mod):

    def __init__(self, body):
        self.body = body

    def walkabout(self, visitor):
        visitor.visit_Expression(self)

    def mutate_over(self, visitor):
        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.newtext('body'), w_body)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_body = get_field(space, w_node, 'body', False)
        _body = expr.from_object(space, w_body)
        if _body is None:
            raise_required_value(space, w_node, 'body')
        return Expression(_body)

State.ast_type('Expression', 'mod', ['body'])


class Suite(mod):

    def __init__(self, body):
        self.body = body

    def walkabout(self, visitor):
        visitor.visit_Suite(self)

    def mutate_over(self, visitor):
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        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.newtext('body'), w_body)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_body = get_field(space, w_node, 'body', False)
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        return Suite(_body)

State.ast_type('Suite', 'mod', ['body'])


class stmt(AST):

    def __init__(self, lineno, col_offset):
        self.lineno = lineno
        self.col_offset = col_offset

    @staticmethod
    def from_object(space, w_node):
        if space.is_w(w_node, space.w_None):
            return None
        if space.isinstance_w(w_node, get(space).w_FunctionDef):
            return FunctionDef.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_ClassDef):
            return ClassDef.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Return):
            return Return.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Delete):
            return Delete.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Assign):
            return Assign.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_AugAssign):
            return AugAssign.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Print):
            return Print.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_For):
            return For.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_While):
            return While.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_If):
            return If.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_With):
            return With.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Raise):
            return Raise.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_TryExcept):
            return TryExcept.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_TryFinally):
            return TryFinally.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Assert):
            return Assert.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Import):
            return Import.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_ImportFrom):
            return ImportFrom.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Exec):
            return Exec.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Global):
            return Global.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Expr):
            return Expr.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Pass):
            return Pass.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Break):
            return Break.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Continue):
            return Continue.from_object(space, w_node)
        raise oefmt(space.w_TypeError,
                "Expected stmt node, got %T", w_node)
State.ast_type('stmt', 'AST', None, ['lineno', 'col_offset'])

class FunctionDef(stmt):

    def __init__(self, name, args, body, decorator_list, lineno, col_offset):
        self.name = name
        self.args = args
        self.body = body
        self.decorator_list = decorator_list
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_FunctionDef(self)

    def mutate_over(self, visitor):
        self.args = self.args.mutate_over(visitor)
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        if self.decorator_list:
            for i in range(len(self.decorator_list)):
                self.decorator_list[i] = self.decorator_list[i].mutate_over(visitor)
        return visitor.visit_FunctionDef(self)

    def to_object(self, space):
        w_node = space.call_function(get(space).w_FunctionDef)
        w_name = space.newtext(self.name)  # identifier
        space.setattr(w_node, space.newtext('name'), w_name)
        w_args = self.args.to_object(space)  # arguments
        space.setattr(w_node, space.newtext('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.newtext('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.newtext('decorator_list'), w_decorator_list)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_name = get_field(space, w_node, 'name', False)
        w_args = get_field(space, w_node, 'args', False)
        w_body = get_field(space, w_node, 'body', False)
        w_decorator_list = get_field(space, w_node, 'decorator_list', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _name = space.realtext_w(w_name)
        if _name is None:
            raise_required_value(space, w_node, 'name')
        _args = arguments.from_object(space, w_args)
        if _args is None:
            raise_required_value(space, w_node, 'args')
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        decorator_list_w = space.unpackiterable(w_decorator_list)
        _decorator_list = [expr.from_object(space, w_item) for w_item in decorator_list_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return FunctionDef(_name, _args, _body, _decorator_list, _lineno, _col_offset)

State.ast_type('FunctionDef', 'stmt', ['name', 'args', 'body', 'decorator_list'])


class ClassDef(stmt):

    def __init__(self, name, bases, body, decorator_list, lineno, col_offset):
        self.name = name
        self.bases = bases
        self.body = body
        self.decorator_list = decorator_list
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_ClassDef(self)

    def mutate_over(self, visitor):
        if self.bases:
            for i in range(len(self.bases)):
                self.bases[i] = self.bases[i].mutate_over(visitor)
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        if self.decorator_list:
            for i in range(len(self.decorator_list)):
                self.decorator_list[i] = self.decorator_list[i].mutate_over(visitor)
        return visitor.visit_ClassDef(self)

    def to_object(self, space):
        w_node = space.call_function(get(space).w_ClassDef)
        w_name = space.newtext(self.name)  # identifier
        space.setattr(w_node, space.newtext('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.newtext('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.newtext('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.newtext('decorator_list'), w_decorator_list)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_name = get_field(space, w_node, 'name', False)
        w_bases = get_field(space, w_node, 'bases', False)
        w_body = get_field(space, w_node, 'body', False)
        w_decorator_list = get_field(space, w_node, 'decorator_list', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _name = space.realtext_w(w_name)
        if _name is None:
            raise_required_value(space, w_node, 'name')
        bases_w = space.unpackiterable(w_bases)
        _bases = [expr.from_object(space, w_item) for w_item in bases_w]
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        decorator_list_w = space.unpackiterable(w_decorator_list)
        _decorator_list = [expr.from_object(space, w_item) for w_item in decorator_list_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return ClassDef(_name, _bases, _body, _decorator_list, _lineno, _col_offset)

State.ast_type('ClassDef', 'stmt', ['name', 'bases', 'body', 'decorator_list'])


class Return(stmt):

    def __init__(self, value, lineno, col_offset):
        self.value = value
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Return(self)

    def mutate_over(self, visitor):
        if self.value:
            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) if self.value is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('value'), w_value)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_value = get_field(space, w_node, 'value', True)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _value = expr.from_object(space, w_value)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Return(_value, _lineno, _col_offset)

State.ast_type('Return', 'stmt', ['value'])


class Delete(stmt):

    def __init__(self, targets, lineno, col_offset):
        self.targets = targets
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Delete(self)

    def mutate_over(self, visitor):
        if self.targets:
            for i in range(len(self.targets)):
                self.targets[i] = self.targets[i].mutate_over(visitor)
        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.newtext('targets'), w_targets)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_targets = get_field(space, w_node, 'targets', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        targets_w = space.unpackiterable(w_targets)
        _targets = [expr.from_object(space, w_item) for w_item in targets_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Delete(_targets, _lineno, _col_offset)

State.ast_type('Delete', 'stmt', ['targets'])


class Assign(stmt):

    def __init__(self, targets, value, lineno, col_offset):
        self.targets = targets
        self.value = value
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Assign(self)

    def mutate_over(self, visitor):
        if self.targets:
            for i in range(len(self.targets)):
                self.targets[i] = self.targets[i].mutate_over(visitor)
        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.newtext('targets'), w_targets)
        w_value = self.value.to_object(space)  # expr
        space.setattr(w_node, space.newtext('value'), w_value)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_targets = get_field(space, w_node, 'targets', False)
        w_value = get_field(space, w_node, 'value', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        targets_w = space.unpackiterable(w_targets)
        _targets = [expr.from_object(space, w_item) for w_item in targets_w]
        _value = expr.from_object(space, w_value)
        if _value is None:
            raise_required_value(space, w_node, 'value')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Assign(_targets, _value, _lineno, _col_offset)

State.ast_type('Assign', 'stmt', ['targets', 'value'])


class AugAssign(stmt):

    def __init__(self, target, op, value, lineno, col_offset):
        self.target = target
        self.op = op
        self.value = value
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_AugAssign(self)

    def mutate_over(self, visitor):
        self.target = self.target.mutate_over(visitor)
        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.newtext('target'), w_target)
        w_op = operator_to_class[self.op - 1]().to_object(space)  # operator
        space.setattr(w_node, space.newtext('op'), w_op)
        w_value = self.value.to_object(space)  # expr
        space.setattr(w_node, space.newtext('value'), w_value)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_target = get_field(space, w_node, 'target', False)
        w_op = get_field(space, w_node, 'op', False)
        w_value = get_field(space, w_node, 'value', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _target = expr.from_object(space, w_target)
        if _target is None:
            raise_required_value(space, w_node, 'target')
        _op = operator.from_object(space, w_op)
        if _op is None:
            raise_required_value(space, w_node, 'op')
        _value = expr.from_object(space, w_value)
        if _value is None:
            raise_required_value(space, w_node, 'value')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return AugAssign(_target, _op, _value, _lineno, _col_offset)

State.ast_type('AugAssign', 'stmt', ['target', 'op', 'value'])


class Print(stmt):

    def __init__(self, dest, values, nl, lineno, col_offset):
        self.dest = dest
        self.values = values
        self.nl = nl
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Print(self)

    def mutate_over(self, visitor):
        if self.dest:
            self.dest = self.dest.mutate_over(visitor)
        if self.values:
            for i in range(len(self.values)):
                self.values[i] = self.values[i].mutate_over(visitor)
        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) if self.dest is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('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.newtext('values'), w_values)
        w_nl = space.newbool(self.nl)  # bool
        space.setattr(w_node, space.newtext('nl'), w_nl)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_dest = get_field(space, w_node, 'dest', True)
        w_values = get_field(space, w_node, 'values', False)
        w_nl = get_field(space, w_node, 'nl', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _dest = expr.from_object(space, w_dest)
        values_w = space.unpackiterable(w_values)
        _values = [expr.from_object(space, w_item) for w_item in values_w]
        _nl = space.bool_w(w_nl)
        if _nl is None:
            raise_required_value(space, w_node, 'nl')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Print(_dest, _values, _nl, _lineno, _col_offset)

State.ast_type('Print', 'stmt', ['dest', 'values', 'nl'])


class For(stmt):

    def __init__(self, target, iter, body, orelse, lineno, col_offset):
        self.target = target
        self.iter = iter
        self.body = body
        self.orelse = orelse
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_For(self)

    def mutate_over(self, visitor):
        self.target = self.target.mutate_over(visitor)
        self.iter = self.iter.mutate_over(visitor)
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        if self.orelse:
            for i in range(len(self.orelse)):
                self.orelse[i] = self.orelse[i].mutate_over(visitor)
        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.newtext('target'), w_target)
        w_iter = self.iter.to_object(space)  # expr
        space.setattr(w_node, space.newtext('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.newtext('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.newtext('orelse'), w_orelse)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_target = get_field(space, w_node, 'target', False)
        w_iter = get_field(space, w_node, 'iter', False)
        w_body = get_field(space, w_node, 'body', False)
        w_orelse = get_field(space, w_node, 'orelse', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _target = expr.from_object(space, w_target)
        if _target is None:
            raise_required_value(space, w_node, 'target')
        _iter = expr.from_object(space, w_iter)
        if _iter is None:
            raise_required_value(space, w_node, 'iter')
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        orelse_w = space.unpackiterable(w_orelse)
        _orelse = [stmt.from_object(space, w_item) for w_item in orelse_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return For(_target, _iter, _body, _orelse, _lineno, _col_offset)

State.ast_type('For', 'stmt', ['target', 'iter', 'body', 'orelse'])


class While(stmt):

    def __init__(self, test, body, orelse, lineno, col_offset):
        self.test = test
        self.body = body
        self.orelse = orelse
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_While(self)

    def mutate_over(self, visitor):
        self.test = self.test.mutate_over(visitor)
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        if self.orelse:
            for i in range(len(self.orelse)):
                self.orelse[i] = self.orelse[i].mutate_over(visitor)
        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.newtext('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.newtext('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.newtext('orelse'), w_orelse)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_test = get_field(space, w_node, 'test', False)
        w_body = get_field(space, w_node, 'body', False)
        w_orelse = get_field(space, w_node, 'orelse', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _test = expr.from_object(space, w_test)
        if _test is None:
            raise_required_value(space, w_node, 'test')
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        orelse_w = space.unpackiterable(w_orelse)
        _orelse = [stmt.from_object(space, w_item) for w_item in orelse_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return While(_test, _body, _orelse, _lineno, _col_offset)

State.ast_type('While', 'stmt', ['test', 'body', 'orelse'])


class If(stmt):

    def __init__(self, test, body, orelse, lineno, col_offset):
        self.test = test
        self.body = body
        self.orelse = orelse
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_If(self)

    def mutate_over(self, visitor):
        self.test = self.test.mutate_over(visitor)
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        if self.orelse:
            for i in range(len(self.orelse)):
                self.orelse[i] = self.orelse[i].mutate_over(visitor)
        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.newtext('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.newtext('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.newtext('orelse'), w_orelse)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_test = get_field(space, w_node, 'test', False)
        w_body = get_field(space, w_node, 'body', False)
        w_orelse = get_field(space, w_node, 'orelse', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _test = expr.from_object(space, w_test)
        if _test is None:
            raise_required_value(space, w_node, 'test')
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        orelse_w = space.unpackiterable(w_orelse)
        _orelse = [stmt.from_object(space, w_item) for w_item in orelse_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return If(_test, _body, _orelse, _lineno, _col_offset)

State.ast_type('If', 'stmt', ['test', 'body', 'orelse'])


class With(stmt):

    def __init__(self, context_expr, optional_vars, body, lineno, col_offset):
        self.context_expr = context_expr
        self.optional_vars = optional_vars
        self.body = body
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_With(self)

    def mutate_over(self, visitor):
        self.context_expr = self.context_expr.mutate_over(visitor)
        if self.optional_vars:
            self.optional_vars = self.optional_vars.mutate_over(visitor)
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        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.newtext('context_expr'), w_context_expr)
        w_optional_vars = self.optional_vars.to_object(space) if self.optional_vars is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('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.newtext('body'), w_body)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_context_expr = get_field(space, w_node, 'context_expr', False)
        w_optional_vars = get_field(space, w_node, 'optional_vars', True)
        w_body = get_field(space, w_node, 'body', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _context_expr = expr.from_object(space, w_context_expr)
        if _context_expr is None:
            raise_required_value(space, w_node, 'context_expr')
        _optional_vars = expr.from_object(space, w_optional_vars)
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return With(_context_expr, _optional_vars, _body, _lineno, _col_offset)

State.ast_type('With', 'stmt', ['context_expr', 'optional_vars', 'body'])


class Raise(stmt):

    def __init__(self, type, inst, tback, lineno, col_offset):
        self.type = type
        self.inst = inst
        self.tback = tback
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Raise(self)

    def mutate_over(self, visitor):
        if self.type:
            self.type = self.type.mutate_over(visitor)
        if self.inst:
            self.inst = self.inst.mutate_over(visitor)
        if self.tback:
            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) if self.type is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('type'), w_type)
        w_inst = self.inst.to_object(space) if self.inst is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('inst'), w_inst)
        w_tback = self.tback.to_object(space) if self.tback is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('tback'), w_tback)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_type = get_field(space, w_node, 'type', True)
        w_inst = get_field(space, w_node, 'inst', True)
        w_tback = get_field(space, w_node, 'tback', True)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _type = expr.from_object(space, w_type)
        _inst = expr.from_object(space, w_inst)
        _tback = expr.from_object(space, w_tback)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Raise(_type, _inst, _tback, _lineno, _col_offset)

State.ast_type('Raise', 'stmt', ['type', 'inst', 'tback'])


class TryExcept(stmt):

    def __init__(self, body, handlers, orelse, lineno, col_offset):
        self.body = body
        self.handlers = handlers
        self.orelse = orelse
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_TryExcept(self)

    def mutate_over(self, visitor):
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        if self.handlers:
            for i in range(len(self.handlers)):
                self.handlers[i] = self.handlers[i].mutate_over(visitor)
        if self.orelse:
            for i in range(len(self.orelse)):
                self.orelse[i] = self.orelse[i].mutate_over(visitor)
        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.newtext('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.newtext('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.newtext('orelse'), w_orelse)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_body = get_field(space, w_node, 'body', False)
        w_handlers = get_field(space, w_node, 'handlers', False)
        w_orelse = get_field(space, w_node, 'orelse', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        handlers_w = space.unpackiterable(w_handlers)
        _handlers = [excepthandler.from_object(space, w_item) for w_item in handlers_w]
        orelse_w = space.unpackiterable(w_orelse)
        _orelse = [stmt.from_object(space, w_item) for w_item in orelse_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return TryExcept(_body, _handlers, _orelse, _lineno, _col_offset)

State.ast_type('TryExcept', 'stmt', ['body', 'handlers', 'orelse'])


class TryFinally(stmt):

    def __init__(self, body, finalbody, lineno, col_offset):
        self.body = body
        self.finalbody = finalbody
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_TryFinally(self)

    def mutate_over(self, visitor):
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        if self.finalbody:
            for i in range(len(self.finalbody)):
                self.finalbody[i] = self.finalbody[i].mutate_over(visitor)
        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.newtext('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.newtext('finalbody'), w_finalbody)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_body = get_field(space, w_node, 'body', False)
        w_finalbody = get_field(space, w_node, 'finalbody', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        finalbody_w = space.unpackiterable(w_finalbody)
        _finalbody = [stmt.from_object(space, w_item) for w_item in finalbody_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return TryFinally(_body, _finalbody, _lineno, _col_offset)

State.ast_type('TryFinally', 'stmt', ['body', 'finalbody'])


class Assert(stmt):

    def __init__(self, test, msg, lineno, col_offset):
        self.test = test
        self.msg = msg
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Assert(self)

    def mutate_over(self, visitor):
        self.test = self.test.mutate_over(visitor)
        if self.msg:
            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.newtext('test'), w_test)
        w_msg = self.msg.to_object(space) if self.msg is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('msg'), w_msg)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_test = get_field(space, w_node, 'test', False)
        w_msg = get_field(space, w_node, 'msg', True)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _test = expr.from_object(space, w_test)
        if _test is None:
            raise_required_value(space, w_node, 'test')
        _msg = expr.from_object(space, w_msg)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Assert(_test, _msg, _lineno, _col_offset)

State.ast_type('Assert', 'stmt', ['test', 'msg'])


class Import(stmt):

    def __init__(self, names, lineno, col_offset):
        self.names = names
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Import(self)

    def mutate_over(self, visitor):
        if self.names:
            for i in range(len(self.names)):
                self.names[i] = self.names[i].mutate_over(visitor)
        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.newtext('names'), w_names)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_names = get_field(space, w_node, 'names', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        names_w = space.unpackiterable(w_names)
        _names = [alias.from_object(space, w_item) for w_item in names_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Import(_names, _lineno, _col_offset)

State.ast_type('Import', 'stmt', ['names'])


class ImportFrom(stmt):

    def __init__(self, module, names, level, lineno, col_offset):
        self.module = module
        self.names = names
        self.level = level
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_ImportFrom(self)

    def mutate_over(self, visitor):
        if self.names:
            for i in range(len(self.names)):
                self.names[i] = self.names[i].mutate_over(visitor)
        return visitor.visit_ImportFrom(self)

    def to_object(self, space):
        w_node = space.call_function(get(space).w_ImportFrom)
        w_module = space.newtext_or_none(self.module)  # identifier
        space.setattr(w_node, space.newtext('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.newtext('names'), w_names)
        w_level = space.newint(self.level)  # int
        space.setattr(w_node, space.newtext('level'), w_level)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_module = get_field(space, w_node, 'module', True)
        w_names = get_field(space, w_node, 'names', False)
        w_level = get_field(space, w_node, 'level', True)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _module = space.realtext_w(w_module) if not space.is_none(w_module) else None
        names_w = space.unpackiterable(w_names)
        _names = [alias.from_object(space, w_item) for w_item in names_w]
        _level = space.int_w(w_level)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return ImportFrom(_module, _names, _level, _lineno, _col_offset)

State.ast_type('ImportFrom', 'stmt', ['module', 'names', 'level'])


class Exec(stmt):

    def __init__(self, body, globals, locals, lineno, col_offset):
        self.body = body
        self.globals = globals
        self.locals = locals
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Exec(self)

    def mutate_over(self, visitor):
        self.body = self.body.mutate_over(visitor)
        if self.globals:
            self.globals = self.globals.mutate_over(visitor)
        if self.locals:
            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.newtext('body'), w_body)
        w_globals = self.globals.to_object(space) if self.globals is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('globals'), w_globals)
        w_locals = self.locals.to_object(space) if self.locals is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('locals'), w_locals)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_body = get_field(space, w_node, 'body', False)
        w_globals = get_field(space, w_node, 'globals', True)
        w_locals = get_field(space, w_node, 'locals', True)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _body = expr.from_object(space, w_body)
        if _body is None:
            raise_required_value(space, w_node, 'body')
        _globals = expr.from_object(space, w_globals)
        _locals = expr.from_object(space, w_locals)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Exec(_body, _globals, _locals, _lineno, _col_offset)

State.ast_type('Exec', 'stmt', ['body', 'globals', 'locals'])


class Global(stmt):

    def __init__(self, names, lineno, col_offset):
        self.names = names
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Global(self)

    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 = [space.newtext(node) for node in self.names] # identifier
        w_names = space.newlist(names_w)
        space.setattr(w_node, space.newtext('names'), w_names)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_names = get_field(space, w_node, 'names', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        names_w = space.unpackiterable(w_names)
        _names = [space.realtext_w(w_item) for w_item in names_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Global(_names, _lineno, _col_offset)

State.ast_type('Global', 'stmt', ['names'])


class Expr(stmt):

    def __init__(self, value, lineno, col_offset):
        self.value = value
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Expr(self)

    def mutate_over(self, visitor):
        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.newtext('value'), w_value)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_value = get_field(space, w_node, 'value', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _value = expr.from_object(space, w_value)
        if _value is None:
            raise_required_value(space, w_node, 'value')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Expr(_value, _lineno, _col_offset)

State.ast_type('Expr', 'stmt', ['value'])


class Pass(stmt):

    def __init__(self, lineno, col_offset):
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Pass(self)

    def mutate_over(self, visitor):
        return visitor.visit_Pass(self)

    def to_object(self, space):
        w_node = space.call_function(get(space).w_Pass)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Pass(_lineno, _col_offset)

State.ast_type('Pass', 'stmt', [])


class Break(stmt):

    def __init__(self, lineno, col_offset):
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Break(self)

    def mutate_over(self, visitor):
        return visitor.visit_Break(self)

    def to_object(self, space):
        w_node = space.call_function(get(space).w_Break)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Break(_lineno, _col_offset)

State.ast_type('Break', 'stmt', [])


class Continue(stmt):

    def __init__(self, lineno, col_offset):
        stmt.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Continue(self)

    def mutate_over(self, visitor):
        return visitor.visit_Continue(self)

    def to_object(self, space):
        w_node = space.call_function(get(space).w_Continue)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Continue(_lineno, _col_offset)

State.ast_type('Continue', 'stmt', [])


class expr(AST):

    def __init__(self, lineno, col_offset):
        self.lineno = lineno
        self.col_offset = col_offset

    @staticmethod
    def from_object(space, w_node):
        if space.is_w(w_node, space.w_None):
            return None
        if space.isinstance_w(w_node, get(space).w_BoolOp):
            return BoolOp.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_BinOp):
            return BinOp.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_UnaryOp):
            return UnaryOp.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Lambda):
            return Lambda.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_IfExp):
            return IfExp.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Dict):
            return Dict.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Set):
            return Set.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_ListComp):
            return ListComp.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_SetComp):
            return SetComp.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_DictComp):
            return DictComp.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_GeneratorExp):
            return GeneratorExp.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Yield):
            return Yield.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Compare):
            return Compare.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Call):
            return Call.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Repr):
            return Repr.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Num):
            return Num.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Str):
            return Str.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_RevDBMetaVar):
            return RevDBMetaVar.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Attribute):
            return Attribute.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Subscript):
            return Subscript.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Name):
            return Name.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_List):
            return List.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Tuple):
            return Tuple.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Const):
            return Const.from_object(space, w_node)
        raise oefmt(space.w_TypeError,
                "Expected expr node, got %T", w_node)
State.ast_type('expr', 'AST', None, ['lineno', 'col_offset'])

class BoolOp(expr):

    def __init__(self, op, values, lineno, col_offset):
        self.op = op
        self.values = values
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_BoolOp(self)

    def mutate_over(self, visitor):
        if self.values:
            for i in range(len(self.values)):
                self.values[i] = self.values[i].mutate_over(visitor)
        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]().to_object(space)  # boolop
        space.setattr(w_node, space.newtext('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.newtext('values'), w_values)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_op = get_field(space, w_node, 'op', False)
        w_values = get_field(space, w_node, 'values', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _op = boolop.from_object(space, w_op)
        if _op is None:
            raise_required_value(space, w_node, 'op')
        values_w = space.unpackiterable(w_values)
        _values = [expr.from_object(space, w_item) for w_item in values_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return BoolOp(_op, _values, _lineno, _col_offset)

State.ast_type('BoolOp', 'expr', ['op', 'values'])


class BinOp(expr):

    def __init__(self, left, op, right, lineno, col_offset):
        self.left = left
        self.op = op
        self.right = right
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_BinOp(self)

    def mutate_over(self, visitor):
        self.left = self.left.mutate_over(visitor)
        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.newtext('left'), w_left)
        w_op = operator_to_class[self.op - 1]().to_object(space)  # operator
        space.setattr(w_node, space.newtext('op'), w_op)
        w_right = self.right.to_object(space)  # expr
        space.setattr(w_node, space.newtext('right'), w_right)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_left = get_field(space, w_node, 'left', False)
        w_op = get_field(space, w_node, 'op', False)
        w_right = get_field(space, w_node, 'right', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _left = expr.from_object(space, w_left)
        if _left is None:
            raise_required_value(space, w_node, 'left')
        _op = operator.from_object(space, w_op)
        if _op is None:
            raise_required_value(space, w_node, 'op')
        _right = expr.from_object(space, w_right)
        if _right is None:
            raise_required_value(space, w_node, 'right')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return BinOp(_left, _op, _right, _lineno, _col_offset)

State.ast_type('BinOp', 'expr', ['left', 'op', 'right'])


class UnaryOp(expr):

    def __init__(self, op, operand, lineno, col_offset):
        self.op = op
        self.operand = operand
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_UnaryOp(self)

    def mutate_over(self, visitor):
        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]().to_object(space)  # unaryop
        space.setattr(w_node, space.newtext('op'), w_op)
        w_operand = self.operand.to_object(space)  # expr
        space.setattr(w_node, space.newtext('operand'), w_operand)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_op = get_field(space, w_node, 'op', False)
        w_operand = get_field(space, w_node, 'operand', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _op = unaryop.from_object(space, w_op)
        if _op is None:
            raise_required_value(space, w_node, 'op')
        _operand = expr.from_object(space, w_operand)
        if _operand is None:
            raise_required_value(space, w_node, 'operand')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return UnaryOp(_op, _operand, _lineno, _col_offset)

State.ast_type('UnaryOp', 'expr', ['op', 'operand'])


class Lambda(expr):

    def __init__(self, args, body, lineno, col_offset):
        self.args = args
        self.body = body
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Lambda(self)

    def mutate_over(self, visitor):
        self.args = self.args.mutate_over(visitor)
        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.newtext('args'), w_args)
        w_body = self.body.to_object(space)  # expr
        space.setattr(w_node, space.newtext('body'), w_body)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_args = get_field(space, w_node, 'args', False)
        w_body = get_field(space, w_node, 'body', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _args = arguments.from_object(space, w_args)
        if _args is None:
            raise_required_value(space, w_node, 'args')
        _body = expr.from_object(space, w_body)
        if _body is None:
            raise_required_value(space, w_node, 'body')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Lambda(_args, _body, _lineno, _col_offset)

State.ast_type('Lambda', 'expr', ['args', 'body'])


class IfExp(expr):

    def __init__(self, test, body, orelse, lineno, col_offset):
        self.test = test
        self.body = body
        self.orelse = orelse
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_IfExp(self)

    def mutate_over(self, visitor):
        self.test = self.test.mutate_over(visitor)
        self.body = self.body.mutate_over(visitor)
        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.newtext('test'), w_test)
        w_body = self.body.to_object(space)  # expr
        space.setattr(w_node, space.newtext('body'), w_body)
        w_orelse = self.orelse.to_object(space)  # expr
        space.setattr(w_node, space.newtext('orelse'), w_orelse)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_test = get_field(space, w_node, 'test', False)
        w_body = get_field(space, w_node, 'body', False)
        w_orelse = get_field(space, w_node, 'orelse', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _test = expr.from_object(space, w_test)
        if _test is None:
            raise_required_value(space, w_node, 'test')
        _body = expr.from_object(space, w_body)
        if _body is None:
            raise_required_value(space, w_node, 'body')
        _orelse = expr.from_object(space, w_orelse)
        if _orelse is None:
            raise_required_value(space, w_node, 'orelse')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return IfExp(_test, _body, _orelse, _lineno, _col_offset)

State.ast_type('IfExp', 'expr', ['test', 'body', 'orelse'])


class Dict(expr):

    def __init__(self, keys, values, lineno, col_offset):
        self.keys = keys
        self.values = values
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Dict(self)

    def mutate_over(self, visitor):
        if self.keys:
            for i in range(len(self.keys)):
                self.keys[i] = self.keys[i].mutate_over(visitor)
        if self.values:
            for i in range(len(self.values)):
                self.values[i] = self.values[i].mutate_over(visitor)
        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.newtext('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.newtext('values'), w_values)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_keys = get_field(space, w_node, 'keys', False)
        w_values = get_field(space, w_node, 'values', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        keys_w = space.unpackiterable(w_keys)
        _keys = [expr.from_object(space, w_item) for w_item in keys_w]
        values_w = space.unpackiterable(w_values)
        _values = [expr.from_object(space, w_item) for w_item in values_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Dict(_keys, _values, _lineno, _col_offset)

State.ast_type('Dict', 'expr', ['keys', 'values'])


class Set(expr):

    def __init__(self, elts, lineno, col_offset):
        self.elts = elts
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Set(self)

    def mutate_over(self, visitor):
        if self.elts:
            for i in range(len(self.elts)):
                self.elts[i] = self.elts[i].mutate_over(visitor)
        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.newtext('elts'), w_elts)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_elts = get_field(space, w_node, 'elts', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        elts_w = space.unpackiterable(w_elts)
        _elts = [expr.from_object(space, w_item) for w_item in elts_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Set(_elts, _lineno, _col_offset)

State.ast_type('Set', 'expr', ['elts'])


class ListComp(expr):

    def __init__(self, elt, generators, lineno, col_offset):
        self.elt = elt
        self.generators = generators
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_ListComp(self)

    def mutate_over(self, visitor):
        self.elt = self.elt.mutate_over(visitor)
        if self.generators:
            for i in range(len(self.generators)):
                self.generators[i] = self.generators[i].mutate_over(visitor)
        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.newtext('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.newtext('generators'), w_generators)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_elt = get_field(space, w_node, 'elt', False)
        w_generators = get_field(space, w_node, 'generators', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _elt = expr.from_object(space, w_elt)
        if _elt is None:
            raise_required_value(space, w_node, 'elt')
        generators_w = space.unpackiterable(w_generators)
        _generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return ListComp(_elt, _generators, _lineno, _col_offset)

State.ast_type('ListComp', 'expr', ['elt', 'generators'])


class SetComp(expr):

    def __init__(self, elt, generators, lineno, col_offset):
        self.elt = elt
        self.generators = generators
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_SetComp(self)

    def mutate_over(self, visitor):
        self.elt = self.elt.mutate_over(visitor)
        if self.generators:
            for i in range(len(self.generators)):
                self.generators[i] = self.generators[i].mutate_over(visitor)
        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.newtext('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.newtext('generators'), w_generators)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_elt = get_field(space, w_node, 'elt', False)
        w_generators = get_field(space, w_node, 'generators', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _elt = expr.from_object(space, w_elt)
        if _elt is None:
            raise_required_value(space, w_node, 'elt')
        generators_w = space.unpackiterable(w_generators)
        _generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return SetComp(_elt, _generators, _lineno, _col_offset)

State.ast_type('SetComp', 'expr', ['elt', 'generators'])


class DictComp(expr):

    def __init__(self, key, value, generators, lineno, col_offset):
        self.key = key
        self.value = value
        self.generators = generators
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_DictComp(self)

    def mutate_over(self, visitor):
        self.key = self.key.mutate_over(visitor)
        self.value = self.value.mutate_over(visitor)
        if self.generators:
            for i in range(len(self.generators)):
                self.generators[i] = self.generators[i].mutate_over(visitor)
        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.newtext('key'), w_key)
        w_value = self.value.to_object(space)  # expr
        space.setattr(w_node, space.newtext('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.newtext('generators'), w_generators)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_key = get_field(space, w_node, 'key', False)
        w_value = get_field(space, w_node, 'value', False)
        w_generators = get_field(space, w_node, 'generators', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _key = expr.from_object(space, w_key)
        if _key is None:
            raise_required_value(space, w_node, 'key')
        _value = expr.from_object(space, w_value)
        if _value is None:
            raise_required_value(space, w_node, 'value')
        generators_w = space.unpackiterable(w_generators)
        _generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return DictComp(_key, _value, _generators, _lineno, _col_offset)

State.ast_type('DictComp', 'expr', ['key', 'value', 'generators'])


class GeneratorExp(expr):

    def __init__(self, elt, generators, lineno, col_offset):
        self.elt = elt
        self.generators = generators
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_GeneratorExp(self)

    def mutate_over(self, visitor):
        self.elt = self.elt.mutate_over(visitor)
        if self.generators:
            for i in range(len(self.generators)):
                self.generators[i] = self.generators[i].mutate_over(visitor)
        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.newtext('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.newtext('generators'), w_generators)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_elt = get_field(space, w_node, 'elt', False)
        w_generators = get_field(space, w_node, 'generators', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _elt = expr.from_object(space, w_elt)
        if _elt is None:
            raise_required_value(space, w_node, 'elt')
        generators_w = space.unpackiterable(w_generators)
        _generators = [comprehension.from_object(space, w_item) for w_item in generators_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return GeneratorExp(_elt, _generators, _lineno, _col_offset)

State.ast_type('GeneratorExp', 'expr', ['elt', 'generators'])


class Yield(expr):

    def __init__(self, value, lineno, col_offset):
        self.value = value
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Yield(self)

    def mutate_over(self, visitor):
        if self.value:
            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) if self.value is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('value'), w_value)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_value = get_field(space, w_node, 'value', True)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _value = expr.from_object(space, w_value)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Yield(_value, _lineno, _col_offset)

State.ast_type('Yield', 'expr', ['value'])


class Compare(expr):

    def __init__(self, left, ops, comparators, lineno, col_offset):
        self.left = left
        self.ops = ops
        self.comparators = comparators
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Compare(self)

    def mutate_over(self, visitor):
        self.left = self.left.mutate_over(visitor)
        if self.comparators:
            for i in range(len(self.comparators)):
                self.comparators[i] = self.comparators[i].mutate_over(visitor)
        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.newtext('left'), w_left)
        if self.ops is None:
            ops_w = []
        else:
            ops_w = [cmpop_to_class[node - 1]().to_object(space) for node in self.ops] # cmpop
        w_ops = space.newlist(ops_w)
        space.setattr(w_node, space.newtext('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.newtext('comparators'), w_comparators)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_left = get_field(space, w_node, 'left', False)
        w_ops = get_field(space, w_node, 'ops', False)
        w_comparators = get_field(space, w_node, 'comparators', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _left = expr.from_object(space, w_left)
        if _left is None:
            raise_required_value(space, w_node, 'left')
        ops_w = space.unpackiterable(w_ops)
        _ops = [cmpop.from_object(space, w_item) for w_item in ops_w]
        comparators_w = space.unpackiterable(w_comparators)
        _comparators = [expr.from_object(space, w_item) for w_item in comparators_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Compare(_left, _ops, _comparators, _lineno, _col_offset)

State.ast_type('Compare', 'expr', ['left', 'ops', 'comparators'])


class Call(expr):

    def __init__(self, func, args, keywords, starargs, kwargs, lineno, col_offset):
        self.func = func
        self.args = args
        self.keywords = keywords
        self.starargs = starargs
        self.kwargs = kwargs
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Call(self)

    def mutate_over(self, visitor):
        self.func = self.func.mutate_over(visitor)
        if self.args:
            for i in range(len(self.args)):
                self.args[i] = self.args[i].mutate_over(visitor)
        if self.keywords:
            for i in range(len(self.keywords)):
                self.keywords[i] = self.keywords[i].mutate_over(visitor)
        if self.starargs:
            self.starargs = self.starargs.mutate_over(visitor)
        if self.kwargs:
            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.newtext('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.newtext('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.newtext('keywords'), w_keywords)
        w_starargs = self.starargs.to_object(space) if self.starargs is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('starargs'), w_starargs)
        w_kwargs = self.kwargs.to_object(space) if self.kwargs is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('kwargs'), w_kwargs)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_func = get_field(space, w_node, 'func', False)
        w_args = get_field(space, w_node, 'args', False)
        w_keywords = get_field(space, w_node, 'keywords', False)
        w_starargs = get_field(space, w_node, 'starargs', True)
        w_kwargs = get_field(space, w_node, 'kwargs', True)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _func = expr.from_object(space, w_func)
        if _func is None:
            raise_required_value(space, w_node, 'func')
        args_w = space.unpackiterable(w_args)
        _args = [expr.from_object(space, w_item) for w_item in args_w]
        keywords_w = space.unpackiterable(w_keywords)
        _keywords = [keyword.from_object(space, w_item) for w_item in keywords_w]
        _starargs = expr.from_object(space, w_starargs)
        _kwargs = expr.from_object(space, w_kwargs)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Call(_func, _args, _keywords, _starargs, _kwargs, _lineno, _col_offset)

State.ast_type('Call', 'expr', ['func', 'args', 'keywords', 'starargs', 'kwargs'])


class Repr(expr):

    def __init__(self, value, lineno, col_offset):
        self.value = value
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Repr(self)

    def mutate_over(self, visitor):
        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.newtext('value'), w_value)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_value = get_field(space, w_node, 'value', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _value = expr.from_object(space, w_value)
        if _value is None:
            raise_required_value(space, w_node, 'value')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Repr(_value, _lineno, _col_offset)

State.ast_type('Repr', 'expr', ['value'])


class Num(expr):

    def __init__(self, n, lineno, col_offset):
        self.n = n
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Num(self)

    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  # object
        space.setattr(w_node, space.newtext('n'), w_n)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_n = get_field(space, w_node, 'n', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _n = w_n
        if _n is None:
            raise_required_value(space, w_node, 'n')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Num(_n, _lineno, _col_offset)

State.ast_type('Num', 'expr', ['n'])


class Str(expr):

    def __init__(self, s, lineno, col_offset):
        self.s = s
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Str(self)

    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  # string
        space.setattr(w_node, space.newtext('s'), w_s)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_s = get_field(space, w_node, 's', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _s = check_string(space, w_s)
        if _s is None:
            raise_required_value(space, w_node, 's')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Str(_s, _lineno, _col_offset)

State.ast_type('Str', 'expr', ['s'])


class RevDBMetaVar(expr):

    def __init__(self, metavar, lineno, col_offset):
        self.metavar = metavar
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_RevDBMetaVar(self)

    def mutate_over(self, visitor):
        return visitor.visit_RevDBMetaVar(self)

    def to_object(self, space):
        w_node = space.call_function(get(space).w_RevDBMetaVar)
        w_metavar = space.newint(self.metavar)  # int
        space.setattr(w_node, space.newtext('metavar'), w_metavar)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_metavar = get_field(space, w_node, 'metavar', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _metavar = space.int_w(w_metavar)
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return RevDBMetaVar(_metavar, _lineno, _col_offset)

State.ast_type('RevDBMetaVar', 'expr', ['metavar'])


class Attribute(expr):

    def __init__(self, value, attr, ctx, lineno, col_offset):
        self.value = value
        self.attr = attr
        self.ctx = ctx
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Attribute(self)

    def mutate_over(self, visitor):
        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.newtext('value'), w_value)
        w_attr = space.newtext(self.attr)  # identifier
        space.setattr(w_node, space.newtext('attr'), w_attr)
        w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
        space.setattr(w_node, space.newtext('ctx'), w_ctx)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_value = get_field(space, w_node, 'value', False)
        w_attr = get_field(space, w_node, 'attr', False)
        w_ctx = get_field(space, w_node, 'ctx', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _value = expr.from_object(space, w_value)
        if _value is None:
            raise_required_value(space, w_node, 'value')
        _attr = space.realtext_w(w_attr)
        if _attr is None:
            raise_required_value(space, w_node, 'attr')
        _ctx = expr_context.from_object(space, w_ctx)
        if _ctx is None:
            raise_required_value(space, w_node, 'ctx')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Attribute(_value, _attr, _ctx, _lineno, _col_offset)

State.ast_type('Attribute', 'expr', ['value', 'attr', 'ctx'])


class Subscript(expr):

    def __init__(self, value, slice, ctx, lineno, col_offset):
        self.value = value
        self.slice = slice
        self.ctx = ctx
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Subscript(self)

    def mutate_over(self, visitor):
        self.value = self.value.mutate_over(visitor)
        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.newtext('value'), w_value)
        w_slice = self.slice.to_object(space)  # slice
        space.setattr(w_node, space.newtext('slice'), w_slice)
        w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
        space.setattr(w_node, space.newtext('ctx'), w_ctx)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_value = get_field(space, w_node, 'value', False)
        w_slice = get_field(space, w_node, 'slice', False)
        w_ctx = get_field(space, w_node, 'ctx', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _value = expr.from_object(space, w_value)
        if _value is None:
            raise_required_value(space, w_node, 'value')
        _slice = slice.from_object(space, w_slice)
        if _slice is None:
            raise_required_value(space, w_node, 'slice')
        _ctx = expr_context.from_object(space, w_ctx)
        if _ctx is None:
            raise_required_value(space, w_node, 'ctx')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Subscript(_value, _slice, _ctx, _lineno, _col_offset)

State.ast_type('Subscript', 'expr', ['value', 'slice', 'ctx'])


class Name(expr):

    def __init__(self, id, ctx, lineno, col_offset):
        self.id = id
        self.ctx = ctx
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Name(self)

    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.newtext(self.id)  # identifier
        space.setattr(w_node, space.newtext('id'), w_id)
        w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
        space.setattr(w_node, space.newtext('ctx'), w_ctx)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_id = get_field(space, w_node, 'id', False)
        w_ctx = get_field(space, w_node, 'ctx', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _id = space.realtext_w(w_id)
        if _id is None:
            raise_required_value(space, w_node, 'id')
        _ctx = expr_context.from_object(space, w_ctx)
        if _ctx is None:
            raise_required_value(space, w_node, 'ctx')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Name(_id, _ctx, _lineno, _col_offset)

State.ast_type('Name', 'expr', ['id', 'ctx'])


class List(expr):

    def __init__(self, elts, ctx, lineno, col_offset):
        self.elts = elts
        self.ctx = ctx
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_List(self)

    def mutate_over(self, visitor):
        if self.elts:
            for i in range(len(self.elts)):
                self.elts[i] = self.elts[i].mutate_over(visitor)
        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.newtext('elts'), w_elts)
        w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
        space.setattr(w_node, space.newtext('ctx'), w_ctx)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_elts = get_field(space, w_node, 'elts', False)
        w_ctx = get_field(space, w_node, 'ctx', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        elts_w = space.unpackiterable(w_elts)
        _elts = [expr.from_object(space, w_item) for w_item in elts_w]
        _ctx = expr_context.from_object(space, w_ctx)
        if _ctx is None:
            raise_required_value(space, w_node, 'ctx')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return List(_elts, _ctx, _lineno, _col_offset)

State.ast_type('List', 'expr', ['elts', 'ctx'])


class Tuple(expr):

    def __init__(self, elts, ctx, lineno, col_offset):
        self.elts = elts
        self.ctx = ctx
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Tuple(self)

    def mutate_over(self, visitor):
        if self.elts:
            for i in range(len(self.elts)):
                self.elts[i] = self.elts[i].mutate_over(visitor)
        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.newtext('elts'), w_elts)
        w_ctx = expr_context_to_class[self.ctx - 1]().to_object(space)  # expr_context
        space.setattr(w_node, space.newtext('ctx'), w_ctx)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_elts = get_field(space, w_node, 'elts', False)
        w_ctx = get_field(space, w_node, 'ctx', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        elts_w = space.unpackiterable(w_elts)
        _elts = [expr.from_object(space, w_item) for w_item in elts_w]
        _ctx = expr_context.from_object(space, w_ctx)
        if _ctx is None:
            raise_required_value(space, w_node, 'ctx')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Tuple(_elts, _ctx, _lineno, _col_offset)

State.ast_type('Tuple', 'expr', ['elts', 'ctx'])


class Const(expr):

    def __init__(self, value, lineno, col_offset):
        self.value = value
        expr.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_Const(self)

    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  # object
        space.setattr(w_node, space.newtext('value'), w_value)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_value = get_field(space, w_node, 'value', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _value = w_value
        if _value is None:
            raise_required_value(space, w_node, 'value')
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return Const(_value, _lineno, _col_offset)

State.ast_type('Const', 'expr', ['value'])


class expr_context(AST):
    @staticmethod
    def from_object(space, w_node):
        if space.isinstance_w(w_node, get(space).w_Load):
            return 1
        if space.isinstance_w(w_node, get(space).w_Store):
            return 2
        if space.isinstance_w(w_node, get(space).w_Del):
            return 3
        if space.isinstance_w(w_node, get(space).w_AugLoad):
            return 4
        if space.isinstance_w(w_node, get(space).w_AugStore):
            return 5
        if space.isinstance_w(w_node, get(space).w_Param):
            return 6
        raise oefmt(space.w_TypeError,
                "Expected expr_context node, got %T", w_node)
State.ast_type('expr_context', 'AST', None)

class _Load(expr_context):
    def to_object(self, space):
        return space.call_function(get(space).w_Load)
State.ast_type('Load', 'expr_context', None)

class _Store(expr_context):
    def to_object(self, space):
        return space.call_function(get(space).w_Store)
State.ast_type('Store', 'expr_context', None)

class _Del(expr_context):
    def to_object(self, space):
        return space.call_function(get(space).w_Del)
State.ast_type('Del', 'expr_context', None)

class _AugLoad(expr_context):
    def to_object(self, space):
        return space.call_function(get(space).w_AugLoad)
State.ast_type('AugLoad', 'expr_context', None)

class _AugStore(expr_context):
    def to_object(self, space):
        return space.call_function(get(space).w_AugStore)
State.ast_type('AugStore', 'expr_context', None)

class _Param(expr_context):
    def to_object(self, space):
        return space.call_function(get(space).w_Param)
State.ast_type('Param', 'expr_context', None)

Load = 1
Store = 2
Del = 3
AugLoad = 4
AugStore = 5
Param = 6

expr_context_to_class = [
    _Load,
    _Store,
    _Del,
    _AugLoad,
    _AugStore,
    _Param,
]

class slice(AST):
    @staticmethod
    def from_object(space, w_node):
        if space.is_w(w_node, space.w_None):
            return None
        if space.isinstance_w(w_node, get(space).w_Ellipsis):
            return Ellipsis.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Slice):
            return Slice.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_ExtSlice):
            return ExtSlice.from_object(space, w_node)
        if space.isinstance_w(w_node, get(space).w_Index):
            return Index.from_object(space, w_node)
        raise oefmt(space.w_TypeError,
                "Expected slice node, got %T", w_node)
State.ast_type('slice', 'AST', None, [])

class Ellipsis(slice):


    def walkabout(self, visitor):
        visitor.visit_Ellipsis(self)

    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

    @staticmethod
    def from_object(space, w_node):
        return Ellipsis()

State.ast_type('Ellipsis', 'slice', [])


class Slice(slice):

    def __init__(self, lower, upper, step):
        self.lower = lower
        self.upper = upper
        self.step = step

    def walkabout(self, visitor):
        visitor.visit_Slice(self)

    def mutate_over(self, visitor):
        if self.lower:
            self.lower = self.lower.mutate_over(visitor)
        if self.upper:
            self.upper = self.upper.mutate_over(visitor)
        if self.step:
            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) if self.lower is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('lower'), w_lower)
        w_upper = self.upper.to_object(space) if self.upper is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('upper'), w_upper)
        w_step = self.step.to_object(space) if self.step is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('step'), w_step)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_lower = get_field(space, w_node, 'lower', True)
        w_upper = get_field(space, w_node, 'upper', True)
        w_step = get_field(space, w_node, 'step', True)
        _lower = expr.from_object(space, w_lower)
        _upper = expr.from_object(space, w_upper)
        _step = expr.from_object(space, w_step)
        return Slice(_lower, _upper, _step)

State.ast_type('Slice', 'slice', ['lower', 'upper', 'step'])


class ExtSlice(slice):

    def __init__(self, dims):
        self.dims = dims

    def walkabout(self, visitor):
        visitor.visit_ExtSlice(self)

    def mutate_over(self, visitor):
        if self.dims:
            for i in range(len(self.dims)):
                self.dims[i] = self.dims[i].mutate_over(visitor)
        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.newtext('dims'), w_dims)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_dims = get_field(space, w_node, 'dims', False)
        dims_w = space.unpackiterable(w_dims)
        _dims = [slice.from_object(space, w_item) for w_item in dims_w]
        return ExtSlice(_dims)

State.ast_type('ExtSlice', 'slice', ['dims'])


class Index(slice):

    def __init__(self, value):
        self.value = value

    def walkabout(self, visitor):
        visitor.visit_Index(self)

    def mutate_over(self, visitor):
        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.newtext('value'), w_value)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_value = get_field(space, w_node, 'value', False)
        _value = expr.from_object(space, w_value)
        if _value is None:
            raise_required_value(space, w_node, 'value')
        return Index(_value)

State.ast_type('Index', 'slice', ['value'])


class boolop(AST):
    @staticmethod
    def from_object(space, w_node):
        if space.isinstance_w(w_node, get(space).w_And):
            return 1
        if space.isinstance_w(w_node, get(space).w_Or):
            return 2
        raise oefmt(space.w_TypeError,
                "Expected boolop node, got %T", w_node)
State.ast_type('boolop', 'AST', None)

class _And(boolop):
    def to_object(self, space):
        return space.call_function(get(space).w_And)
State.ast_type('And', 'boolop', None)

class _Or(boolop):
    def to_object(self, space):
        return space.call_function(get(space).w_Or)
State.ast_type('Or', 'boolop', None)

And = 1
Or = 2

boolop_to_class = [
    _And,
    _Or,
]

class operator(AST):
    @staticmethod
    def from_object(space, w_node):
        if space.isinstance_w(w_node, get(space).w_Add):
            return 1
        if space.isinstance_w(w_node, get(space).w_Sub):
            return 2
        if space.isinstance_w(w_node, get(space).w_Mult):
            return 3
        if space.isinstance_w(w_node, get(space).w_Div):
            return 4
        if space.isinstance_w(w_node, get(space).w_Mod):
            return 5
        if space.isinstance_w(w_node, get(space).w_Pow):
            return 6
        if space.isinstance_w(w_node, get(space).w_LShift):
            return 7
        if space.isinstance_w(w_node, get(space).w_RShift):
            return 8
        if space.isinstance_w(w_node, get(space).w_BitOr):
            return 9
        if space.isinstance_w(w_node, get(space).w_BitXor):
            return 10
        if space.isinstance_w(w_node, get(space).w_BitAnd):
            return 11
        if space.isinstance_w(w_node, get(space).w_FloorDiv):
            return 12
        raise oefmt(space.w_TypeError,
                "Expected operator node, got %T", w_node)
State.ast_type('operator', 'AST', None)

class _Add(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_Add)
State.ast_type('Add', 'operator', None)

class _Sub(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_Sub)
State.ast_type('Sub', 'operator', None)

class _Mult(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_Mult)
State.ast_type('Mult', 'operator', None)

class _Div(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_Div)
State.ast_type('Div', 'operator', None)

class _Mod(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_Mod)
State.ast_type('Mod', 'operator', None)

class _Pow(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_Pow)
State.ast_type('Pow', 'operator', None)

class _LShift(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_LShift)
State.ast_type('LShift', 'operator', None)

class _RShift(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_RShift)
State.ast_type('RShift', 'operator', None)

class _BitOr(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_BitOr)
State.ast_type('BitOr', 'operator', None)

class _BitXor(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_BitXor)
State.ast_type('BitXor', 'operator', None)

class _BitAnd(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_BitAnd)
State.ast_type('BitAnd', 'operator', None)

class _FloorDiv(operator):
    def to_object(self, space):
        return space.call_function(get(space).w_FloorDiv)
State.ast_type('FloorDiv', 'operator', None)

Add = 1
Sub = 2
Mult = 3
Div = 4
Mod = 5
Pow = 6
LShift = 7
RShift = 8
BitOr = 9
BitXor = 10
BitAnd = 11
FloorDiv = 12

operator_to_class = [
    _Add,
    _Sub,
    _Mult,
    _Div,
    _Mod,
    _Pow,
    _LShift,
    _RShift,
    _BitOr,
    _BitXor,
    _BitAnd,
    _FloorDiv,
]

class unaryop(AST):
    @staticmethod
    def from_object(space, w_node):
        if space.isinstance_w(w_node, get(space).w_Invert):
            return 1
        if space.isinstance_w(w_node, get(space).w_Not):
            return 2
        if space.isinstance_w(w_node, get(space).w_UAdd):
            return 3
        if space.isinstance_w(w_node, get(space).w_USub):
            return 4
        raise oefmt(space.w_TypeError,
                "Expected unaryop node, got %T", w_node)
State.ast_type('unaryop', 'AST', None)

class _Invert(unaryop):
    def to_object(self, space):
        return space.call_function(get(space).w_Invert)
State.ast_type('Invert', 'unaryop', None)

class _Not(unaryop):
    def to_object(self, space):
        return space.call_function(get(space).w_Not)
State.ast_type('Not', 'unaryop', None)

class _UAdd(unaryop):
    def to_object(self, space):
        return space.call_function(get(space).w_UAdd)
State.ast_type('UAdd', 'unaryop', None)

class _USub(unaryop):
    def to_object(self, space):
        return space.call_function(get(space).w_USub)
State.ast_type('USub', 'unaryop', None)

Invert = 1
Not = 2
UAdd = 3
USub = 4

unaryop_to_class = [
    _Invert,
    _Not,
    _UAdd,
    _USub,
]

class cmpop(AST):
    @staticmethod
    def from_object(space, w_node):
        if space.isinstance_w(w_node, get(space).w_Eq):
            return 1
        if space.isinstance_w(w_node, get(space).w_NotEq):
            return 2
        if space.isinstance_w(w_node, get(space).w_Lt):
            return 3
        if space.isinstance_w(w_node, get(space).w_LtE):
            return 4
        if space.isinstance_w(w_node, get(space).w_Gt):
            return 5
        if space.isinstance_w(w_node, get(space).w_GtE):
            return 6
        if space.isinstance_w(w_node, get(space).w_Is):
            return 7
        if space.isinstance_w(w_node, get(space).w_IsNot):
            return 8
        if space.isinstance_w(w_node, get(space).w_In):
            return 9
        if space.isinstance_w(w_node, get(space).w_NotIn):
            return 10
        raise oefmt(space.w_TypeError,
                "Expected cmpop node, got %T", w_node)
State.ast_type('cmpop', 'AST', None)

class _Eq(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_Eq)
State.ast_type('Eq', 'cmpop', None)

class _NotEq(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_NotEq)
State.ast_type('NotEq', 'cmpop', None)

class _Lt(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_Lt)
State.ast_type('Lt', 'cmpop', None)

class _LtE(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_LtE)
State.ast_type('LtE', 'cmpop', None)

class _Gt(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_Gt)
State.ast_type('Gt', 'cmpop', None)

class _GtE(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_GtE)
State.ast_type('GtE', 'cmpop', None)

class _Is(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_Is)
State.ast_type('Is', 'cmpop', None)

class _IsNot(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_IsNot)
State.ast_type('IsNot', 'cmpop', None)

class _In(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_In)
State.ast_type('In', 'cmpop', None)

class _NotIn(cmpop):
    def to_object(self, space):
        return space.call_function(get(space).w_NotIn)
State.ast_type('NotIn', 'cmpop', None)

Eq = 1
NotEq = 2
Lt = 3
LtE = 4
Gt = 5
GtE = 6
Is = 7
IsNot = 8
In = 9
NotIn = 10

cmpop_to_class = [
    _Eq,
    _NotEq,
    _Lt,
    _LtE,
    _Gt,
    _GtE,
    _Is,
    _IsNot,
    _In,
    _NotIn,
]

class comprehension(AST):

    def __init__(self, target, iter, ifs):
        self.target = target
        self.iter = iter
        self.ifs = ifs

    def mutate_over(self, visitor):
        self.target = self.target.mutate_over(visitor)
        self.iter = self.iter.mutate_over(visitor)
        if self.ifs:
            for i in range(len(self.ifs)):
                self.ifs[i] = self.ifs[i].mutate_over(visitor)
        return visitor.visit_comprehension(self)

    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.newtext('target'), w_target)
        w_iter = self.iter.to_object(space)  # expr
        space.setattr(w_node, space.newtext('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.newtext('ifs'), w_ifs)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_target = get_field(space, w_node, 'target', False)
        w_iter = get_field(space, w_node, 'iter', False)
        w_ifs = get_field(space, w_node, 'ifs', False)
        _target = expr.from_object(space, w_target)
        if _target is None:
            raise_required_value(space, w_node, 'target')
        _iter = expr.from_object(space, w_iter)
        if _iter is None:
            raise_required_value(space, w_node, 'iter')
        ifs_w = space.unpackiterable(w_ifs)
        _ifs = [expr.from_object(space, w_item) for w_item in ifs_w]
        return comprehension(_target, _iter, _ifs)

State.ast_type('comprehension', 'AST', ['target', 'iter', 'ifs'])

class excepthandler(AST):

    def __init__(self, lineno, col_offset):
        self.lineno = lineno
        self.col_offset = col_offset

    @staticmethod
    def from_object(space, w_node):
        if space.is_w(w_node, space.w_None):
            return None
        if space.isinstance_w(w_node, get(space).w_ExceptHandler):
            return ExceptHandler.from_object(space, w_node)
        raise oefmt(space.w_TypeError,
                "Expected excepthandler node, got %T", w_node)
State.ast_type('excepthandler', 'AST', None, ['lineno', 'col_offset'])

class ExceptHandler(excepthandler):

    def __init__(self, type, name, body, lineno, col_offset):
        self.type = type
        self.name = name
        self.body = body
        excepthandler.__init__(self, lineno, col_offset)

    def walkabout(self, visitor):
        visitor.visit_ExceptHandler(self)

    def mutate_over(self, visitor):
        if self.type:
            self.type = self.type.mutate_over(visitor)
        if self.name:
            self.name = self.name.mutate_over(visitor)
        if self.body:
            for i in range(len(self.body)):
                self.body[i] = self.body[i].mutate_over(visitor)
        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) if self.type is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('type'), w_type)
        w_name = self.name.to_object(space) if self.name is not None else space.w_None  # expr
        space.setattr(w_node, space.newtext('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.newtext('body'), w_body)
        w_lineno = space.newint(self.lineno)  # int
        space.setattr(w_node, space.newtext('lineno'), w_lineno)
        w_col_offset = space.newint(self.col_offset)  # int
        space.setattr(w_node, space.newtext('col_offset'), w_col_offset)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_type = get_field(space, w_node, 'type', True)
        w_name = get_field(space, w_node, 'name', True)
        w_body = get_field(space, w_node, 'body', False)
        w_lineno = get_field(space, w_node, 'lineno', False)
        w_col_offset = get_field(space, w_node, 'col_offset', False)
        _type = expr.from_object(space, w_type)
        _name = expr.from_object(space, w_name)
        body_w = space.unpackiterable(w_body)
        _body = [stmt.from_object(space, w_item) for w_item in body_w]
        _lineno = space.int_w(w_lineno)
        _col_offset = space.int_w(w_col_offset)
        return ExceptHandler(_type, _name, _body, _lineno, _col_offset)

State.ast_type('ExceptHandler', 'excepthandler', ['type', 'name', 'body'])


class arguments(AST):

    def __init__(self, args, vararg, kwarg, defaults):
        self.args = args
        self.vararg = vararg
        self.kwarg = kwarg
        self.defaults = defaults

    def mutate_over(self, visitor):
        if self.args:
            for i in range(len(self.args)):
                self.args[i] = self.args[i].mutate_over(visitor)
        if self.defaults:
            for i in range(len(self.defaults)):
                self.defaults[i] = self.defaults[i].mutate_over(visitor)
        return visitor.visit_arguments(self)

    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.newtext('args'), w_args)
        w_vararg = space.newtext_or_none(self.vararg)  # identifier
        space.setattr(w_node, space.newtext('vararg'), w_vararg)
        w_kwarg = space.newtext_or_none(self.kwarg)  # identifier
        space.setattr(w_node, space.newtext('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.newtext('defaults'), w_defaults)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_args = get_field(space, w_node, 'args', False)
        w_vararg = get_field(space, w_node, 'vararg', True)
        w_kwarg = get_field(space, w_node, 'kwarg', True)
        w_defaults = get_field(space, w_node, 'defaults', False)
        args_w = space.unpackiterable(w_args)
        _args = [expr.from_object(space, w_item) for w_item in args_w]
        _vararg = space.realtext_w(w_vararg) if not space.is_none(w_vararg) else None
        _kwarg = space.realtext_w(w_kwarg) if not space.is_none(w_kwarg) else None
        defaults_w = space.unpackiterable(w_defaults)
        _defaults = [expr.from_object(space, w_item) for w_item in defaults_w]
        return arguments(_args, _vararg, _kwarg, _defaults)

State.ast_type('arguments', 'AST', ['args', 'vararg', 'kwarg', 'defaults'])

class keyword(AST):

    def __init__(self, arg, value):
        self.arg = arg
        self.value = value

    def mutate_over(self, visitor):
        self.value = self.value.mutate_over(visitor)
        return visitor.visit_keyword(self)

    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.newtext(self.arg)  # identifier
        space.setattr(w_node, space.newtext('arg'), w_arg)
        w_value = self.value.to_object(space)  # expr
        space.setattr(w_node, space.newtext('value'), w_value)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_arg = get_field(space, w_node, 'arg', False)
        w_value = get_field(space, w_node, 'value', False)
        _arg = space.realtext_w(w_arg)
        if _arg is None:
            raise_required_value(space, w_node, 'arg')
        _value = expr.from_object(space, w_value)
        if _value is None:
            raise_required_value(space, w_node, 'value')
        return keyword(_arg, _value)

State.ast_type('keyword', 'AST', ['arg', 'value'])

class alias(AST):

    def __init__(self, name, asname):
        self.name = name
        self.asname = asname

    def mutate_over(self, visitor):
        return visitor.visit_alias(self)

    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.newtext(self.name)  # identifier
        space.setattr(w_node, space.newtext('name'), w_name)
        w_asname = space.newtext_or_none(self.asname)  # identifier
        space.setattr(w_node, space.newtext('asname'), w_asname)
        return w_node

    @staticmethod
    def from_object(space, w_node):
        w_name = get_field(space, w_node, 'name', False)
        w_asname = get_field(space, w_node, 'asname', True)
        _name = space.realtext_w(w_name)
        if _name is None:
            raise_required_value(space, w_node, 'name')
        _asname = space.realtext_w(w_asname) if not space.is_none(w_asname) else None
        return alias(_name, _asname)

State.ast_type('alias', 'AST', ['name', 'asname'])

class ASTVisitor(object):

    def visit_sequence(self, seq):
        if seq is not None:
            for node in seq:
                node.walkabout(self)

    def default_visitor(self, node):
        raise NodeVisitorNotImplemented

    def visit_Module(self, node):
        return self.default_visitor(node)
    def visit_Interactive(self, node):
        return self.default_visitor(node)
    def visit_Expression(self, node):
        return self.default_visitor(node)
    def visit_Suite(self, node):
        return self.default_visitor(node)
    def visit_FunctionDef(self, node):
        return self.default_visitor(node)
    def visit_ClassDef(self, node):
        return self.default_visitor(node)
    def visit_Return(self, node):
        return self.default_visitor(node)
    def visit_Delete(self, node):
        return self.default_visitor(node)
    def visit_Assign(self, node):
        return self.default_visitor(node)
    def visit_AugAssign(self, node):
        return self.default_visitor(node)
    def visit_Print(self, node):
        return self.default_visitor(node)
    def visit_For(self, node):
        return self.default_visitor(node)
    def visit_While(self, node):
        return self.default_visitor(node)
    def visit_If(self, node):
        return self.default_visitor(node)
    def visit_With(self, node):
        return self.default_visitor(node)
    def visit_Raise(self, node):
        return self.default_visitor(node)
    def visit_TryExcept(self, node):
        return self.default_visitor(node)
    def visit_TryFinally(self, node):
        return self.default_visitor(node)
    def visit_Assert(self, node):
        return self.default_visitor(node)
    def visit_Import(self, node):
        return self.default_visitor(node)
    def visit_ImportFrom(self, node):
        return self.default_visitor(node)
    def visit_Exec(self, node):
        return self.default_visitor(node)
    def visit_Global(self, node):
        return self.default_visitor(node)
    def visit_Expr(self, node):
        return self.default_visitor(node)
    def visit_Pass(self, node):
        return self.default_visitor(node)
    def visit_Break(self, node):
        return self.default_visitor(node)
    def visit_Continue(self, node):
        return self.default_visitor(node)
    def visit_BoolOp(self, node):
        return self.default_visitor(node)
    def visit_BinOp(self, node):
        return self.default_visitor(node)
    def visit_UnaryOp(self, node):
        return self.default_visitor(node)
    def visit_Lambda(self, node):
        return self.default_visitor(node)
    def visit_IfExp(self, node):
        return self.default_visitor(node)
    def visit_Dict(self, node):
        return self.default_visitor(node)
    def visit_Set(self, node):
        return self.default_visitor(node)
    def visit_ListComp(self, node):
        return self.default_visitor(node)
    def visit_SetComp(self, node):
        return self.default_visitor(node)
    def visit_DictComp(self, node):
        return self.default_visitor(node)
    def visit_GeneratorExp(self, node):
        return self.default_visitor(node)
    def visit_Yield(self, node):
        return self.default_visitor(node)
    def visit_Compare(self, node):
        return self.default_visitor(node)
    def visit_Call(self, node):
        return self.default_visitor(node)
    def visit_Repr(self, node):
        return self.default_visitor(node)
    def visit_Num(self, node):
        return self.default_visitor(node)
    def visit_Str(self, node):
        return self.default_visitor(node)
    def visit_RevDBMetaVar(self, node):
        return self.default_visitor(node)
    def visit_Attribute(self, node):
        return self.default_visitor(node)
    def visit_Subscript(self, node):
        return self.default_visitor(node)
    def visit_Name(self, node):
        return self.default_visitor(node)
    def visit_List(self, node):
        return self.default_visitor(node)
    def visit_Tuple(self, node):
        return self.default_visitor(node)
    def visit_Const(self, node):
        return self.default_visitor(node)
    def visit_Ellipsis(self, node):
        return self.default_visitor(node)
    def visit_Slice(self, node):
        return self.default_visitor(node)
    def visit_ExtSlice(self, node):
        return self.default_visitor(node)
    def visit_Index(self, node):
        return self.default_visitor(node)
    def visit_comprehension(self, node):
        return self.default_visitor(node)
    def visit_ExceptHandler(self, node):
        return self.default_visitor(node)
    def visit_arguments(self, node):
        return self.default_visitor(node)
    def visit_keyword(self, node):
        return self.default_visitor(node)
    def visit_alias(self, node):
        return self.default_visitor(node)

class GenericASTVisitor(ASTVisitor):

    def visit_Module(self, node):
        self.visit_sequence(node.body)

    def visit_Interactive(self, node):
        self.visit_sequence(node.body)

    def visit_Expression(self, node):
        node.body.walkabout(self)

    def visit_Suite(self, node):
        self.visit_sequence(node.body)

    def visit_FunctionDef(self, node):
        node.args.walkabout(self)
        self.visit_sequence(node.body)
        self.visit_sequence(node.decorator_list)

    def visit_ClassDef(self, node):
        self.visit_sequence(node.bases)
        self.visit_sequence(node.body)
        self.visit_sequence(node.decorator_list)

    def visit_Return(self, node):
        if node.value:
            node.value.walkabout(self)

    def visit_Delete(self, node):
        self.visit_sequence(node.targets)

    def visit_Assign(self, node):
        self.visit_sequence(node.targets)
        node.value.walkabout(self)

    def visit_AugAssign(self, node):
        node.target.walkabout(self)
        node.value.walkabout(self)

    def visit_Print(self, node):
        if node.dest:
            node.dest.walkabout(self)
        self.visit_sequence(node.values)

    def visit_For(self, node):
        node.target.walkabout(self)
        node.iter.walkabout(self)
        self.visit_sequence(node.body)
        self.visit_sequence(node.orelse)

    def visit_While(self, node):
        node.test.walkabout(self)
        self.visit_sequence(node.body)
        self.visit_sequence(node.orelse)

    def visit_If(self, node):
        node.test.walkabout(self)
        self.visit_sequence(node.body)
        self.visit_sequence(node.orelse)

    def visit_With(self, node):
        node.context_expr.walkabout(self)
        if node.optional_vars:
            node.optional_vars.walkabout(self)
        self.visit_sequence(node.body)

    def visit_Raise(self, node):
        if node.type:
            node.type.walkabout(self)
        if node.inst:
            node.inst.walkabout(self)
        if node.tback:
            node.tback.walkabout(self)

    def visit_TryExcept(self, node):
        self.visit_sequence(node.body)
        self.visit_sequence(node.handlers)
        self.visit_sequence(node.orelse)

    def visit_TryFinally(self, node):
        self.visit_sequence(node.body)
        self.visit_sequence(node.finalbody)

    def visit_Assert(self, node):
        node.test.walkabout(self)
        if node.msg:
            node.msg.walkabout(self)

    def visit_Import(self, node):
        self.visit_sequence(node.names)

    def visit_ImportFrom(self, node):
        self.visit_sequence(node.names)

    def visit_Exec(self, node):
        node.body.walkabout(self)
        if node.globals:
            node.globals.walkabout(self)
        if node.locals:
            node.locals.walkabout(self)

    def visit_Global(self, node):
        pass

    def visit_Expr(self, node):
        node.value.walkabout(self)

    def visit_Pass(self, node):
        pass

    def visit_Break(self, node):
        pass

    def visit_Continue(self, node):
        pass

    def visit_BoolOp(self, node):
        self.visit_sequence(node.values)

    def visit_BinOp(self, node):
        node.left.walkabout(self)
        node.right.walkabout(self)

    def visit_UnaryOp(self, node):
        node.operand.walkabout(self)

    def visit_Lambda(self, node):
        node.args.walkabout(self)
        node.body.walkabout(self)

    def visit_IfExp(self, node):
        node.test.walkabout(self)
        node.body.walkabout(self)
        node.orelse.walkabout(self)

    def visit_Dict(self, node):
        self.visit_sequence(node.keys)
        self.visit_sequence(node.values)

    def visit_Set(self, node):
        self.visit_sequence(node.elts)

    def visit_ListComp(self, node):
        node.elt.walkabout(self)
        self.visit_sequence(node.generators)

    def visit_SetComp(self, node):
        node.elt.walkabout(self)
        self.visit_sequence(node.generators)

    def visit_DictComp(self, node):
        node.key.walkabout(self)
        node.value.walkabout(self)
        self.visit_sequence(node.generators)

    def visit_GeneratorExp(self, node):
        node.elt.walkabout(self)
        self.visit_sequence(node.generators)

    def visit_Yield(self, node):
        if node.value:
            node.value.walkabout(self)

    def visit_Compare(self, node):
        node.left.walkabout(self)
        self.visit_sequence(node.comparators)

    def visit_Call(self, node):
        node.func.walkabout(self)
        self.visit_sequence(node.args)
        self.visit_sequence(node.keywords)
        if node.starargs:
            node.starargs.walkabout(self)
        if node.kwargs:
            node.kwargs.walkabout(self)

    def visit_Repr(self, node):
        node.value.walkabout(self)

    def visit_Num(self, node):
        pass

    def visit_Str(self, node):
        pass

    def visit_RevDBMetaVar(self, node):
        pass

    def visit_Attribute(self, node):
        node.value.walkabout(self)

    def visit_Subscript(self, node):
        node.value.walkabout(self)
        node.slice.walkabout(self)

    def visit_Name(self, node):
        pass

    def visit_List(self, node):
        self.visit_sequence(node.elts)

    def visit_Tuple(self, node):
        self.visit_sequence(node.elts)

    def visit_Const(self, node):
        pass

    def visit_Ellipsis(self, node):
        pass

    def visit_Slice(self, node):
        if node.lower:
            node.lower.walkabout(self)
        if node.upper:
            node.upper.walkabout(self)
        if node.step:
            node.step.walkabout(self)

    def visit_ExtSlice(self, node):
        self.visit_sequence(node.dims)

    def visit_Index(self, node):
        node.value.walkabout(self)

    def visit_comprehension(self, node):
        node.target.walkabout(self)
        node.iter.walkabout(self)
        self.visit_sequence(node.ifs)

    def visit_ExceptHandler(self, node):
        if node.type:
            node.type.walkabout(self)
        if node.name:
            node.name.walkabout(self)
        self.visit_sequence(node.body)

    def visit_arguments(self, node):
        self.visit_sequence(node.args)
        self.visit_sequence(node.defaults)

    def visit_keyword(self, node):
        node.value.walkabout(self)

    def visit_alias(self, node):
        pass


