# This file describes the nodes of the AST in ast.py.  The module is
# generated by astgen.py.
# The descriptions use the following special notation to describe
# properties of the children:

#    *   this child is not a node

#    *int   this child is not a node
#    *str   this child is not a node
#    *[int]   this child is not a node
#    *[str]   this child is not a node

#    %   this child is a wrapped object
#    !   this child is a sequence that contains nodes in it
#    &   this child may be set to None
#    (type) where type is int, str
#    [type]
#  = ... a default value for the node constructor (optional args)
Module: w_doc%, node
Stmt: nodes!
Decorators: nodes!
AbstractFunction:
Function(AbstractFunction): decorators&, name*str, argnames!, defaults!, flags*int, w_doc%, code
Lambda(AbstractFunction): argnames!, defaults!, flags*int, code
Class: name*str, bases!, w_doc%, code
Pass:
Break:
Continue:
For: assign, list, body, else_&
With: expr, body, var&
While: test, body, else_&
If: tests!, else_&
Exec: expr, locals&, globals&
From: modname*str, names*
Import: names*
Raise: expr1&, expr2&, expr3&
TryFinally: body, final
TryExcept: body, handlers!, else_&
Return: value&
Yield: value
Const: value%
NoneConst:
#StringConst: string_value*
#NumberConst: number_value*
Print: nodes!, dest&
Printnl: nodes!, dest&
Discard: expr
AugAssign: node, op*str, expr
Assign: nodes!, expr
AssSeq:
AssTuple(AssSeq): nodes!
AssList(AssSeq): nodes!
AssName: name*str, flags*int
AssAttr: expr, attrname*str, flags*int
ListComp: expr, quals!
ListCompFor: assign, list, ifs!
ListCompIf: test
GenExpr(AbstractFunction): code
GenExprInner: expr, quals!
GenExprFor: assign, iter, ifs!
GenExprIf: test
List: nodes!
Dict: items!
UnaryOp:
Not(UnaryOp): expr
Compare: expr, ops!
Name: varname*str
Global: names*[str]
Backquote(UnaryOp): expr
Getattr: expr, attrname*str
CallFunc: node, args!, star_args& = None, dstar_args& = None
Keyword: name*str, expr
Subscript: expr, flags*int, sub
Ellipsis: 
Sliceobj: nodes!
Slice: expr, flags*int, lower&, upper&
Assert: test, fail&
Tuple: nodes!
AbstractTest:
Or(AbstractTest): nodes!
And(AbstractTest): nodes!
CondExpr: test, true_expr, false_expr
BitOp:
Bitor(BitOp): nodes!
Bitxor(BitOp): nodes!
Bitand(BitOp): nodes!
BinaryOp:
LeftShift(BinaryOp): left, right
RightShift(BinaryOp): left, right
Add(BinaryOp): left, right
Sub(BinaryOp): left, right
Mul(BinaryOp): left, right
Div(BinaryOp): left, right
Mod(BinaryOp): left, right
Power(BinaryOp): left, right
FloorDiv(BinaryOp): left, right
UnaryAdd(UnaryOp): expr
UnarySub(UnaryOp): expr
Invert(UnaryOp): expr

== OVERRIDES ==

init(Function):
    self.varargs = self.kwargs = 0
    if flags & CO_VARARGS:
        self.varargs = 1
    if flags & CO_VARKEYWORDS:
        self.kwargs = 1

init(Lambda):
    self.varargs = self.kwargs = 0
    if flags & CO_VARARGS:
        self.varargs = 1
    if flags & CO_VARKEYWORDS:
        self.kwargs = 1

init(GenExpr):
    self.argnames = [AssName('[outmost-iterable]', OP_ASSIGN)]
    self.varargs = self.kwargs = 0

init(GenExprFor):
    self.is_outmost = False

flatten_nodes(Compare.ops):
    # ops is a list of couples (op_name, node)
    for op_name, node in self.ops:
        nodelist.append(node)

mutate(Compare.ops):
    for i in range(len(self.ops)):
        op_name, node = self.ops[i]
        self.ops[i] = op_name, node.mutate(visitor)

flatten_nodes(TryExcept.handlers):
    # handlers is a list of triplets (expr1, expr2, body)
    for expr1, expr2, body in self.handlers:
        if expr1 is not None:
            nodelist.append(expr1)
        if expr2 is not None:
            nodelist.append(expr2)
        if body is not None:
            nodelist.append(body)

mutate(TryExcept.handlers):
    for i in range(len(self.handlers)):
        expr1, expr2, body = self.handlers[i]
        if expr1 is not None:
            expr1 = expr1.mutate(visitor)
        if expr2 is not None:
            expr2 = expr2.mutate(visitor)
        if body is not None:
            body = body.mutate(visitor)
        self.handlers[i] = expr1, expr2, body

flatten_nodes(Dict.items):
    # items is a list of couples (node (key), node (value))
    for key, value in self.items:
        nodelist.append(key)
        nodelist.append(value)

mutate(Dict.items):
    for i in range(len(self.items)):
        n, o = self.items[i]
        self.items[i] = n.mutate(visitor), o.mutate(visitor)

flatten_nodes(If.tests):
    # tests is a list of couples (node (test), node (suite))
    for test, suite in self.tests:
        nodelist.append(test)
        nodelist.append(suite)

mutate(If.tests):
    for i in range(len(self.tests)):
        n, o = self.tests[i]
        self.tests[i] = n.mutate(visitor), o.mutate(visitor)

AssTuple.getArgNames(self):
    argnames = []
    for node in self.nodes:
        if isinstance(node, AssTuple):
            argnames.extend(node.getArgNames())
        elif isinstance(node, AssName):
            name = node.name
            assert isinstance(name, str)
            argnames.append(name)
        else:
            assert False, "should only have AssName and AssTuple as children"
    return argnames

Compare.fget_ops( space, self ):
    lst = []
    for op_name, node in self.ops:
        lst.append( space.newtuple( [ space.wrap(op_name), space.wrap(node) ] ) )
    return space.newlist( lst )

Compare.fset_ops( space, self, w_arg ):
    del self.ops[:]
    for w_obj in space.unpackiterable( w_arg ):
        w_opname = space.getitem( w_obj, space.wrap(0) )
        w_node = space.getitem( w_obj, space.wrap(1) )
        ops = space.str_w(w_opname)
        node = space.interp_w(Node, w_node)
        self.ops.append( (ops,node) )

Dict.fget_items(space, self):
    return space.newlist( [ space.newtuple( [ space.wrap(key), space.wrap(value) ] )
                            for key, value in self.items ] )

Dict.fset_items( space, self, w_arg ):
    del self.items[:]
    for w_tup in space.unpackiterable( w_arg ):
        w_key = space.getitem( w_tup, space.wrap(0) )
        w_value = space.getitem( w_tup, space.wrap(1) )
        key = space.interp_w(Node, w_key)
        value = space.interp_w(Node, w_value)
        self.items.append( (key,value) )


If.fget_tests( space, self ):
    return space.newlist( [ space.newtuple( [ space.wrap(test),
                                              space.wrap(suite) ] )
                            for test, suite in self.tests ] )

If.fset_tests( space, self, w_arg ):
    del self.tests[:]
    for w_tup in space.unpackiterable( w_arg ):
        w_test = space.getitem( w_tup, space.wrap(0) )
        w_suite = space.getitem( w_tup, space.wrap(1) )
        test = space.interp_w(Node, w_test)
        suite = space.interp_w(Node, w_suite)
        self.tests.append( (test,suite) )


TryExcept.fget_handlers( space, self ):
    return space.newlist( [ space.newtuple( [ space.wrap(expr1),
                                              space.wrap(expr2),
                                              space.wrap(body) ] )
                            for expr1, expr2, body in self.handlers ] )

TryExcept.fset_handlers( space, self, w_arg ):
    del self.handlers[:]
    for w_tup in space.unpackiterable( w_arg ):
        w_expr1 = space.getitem( w_tup, space.wrap(0) )
        w_expr2 = space.getitem( w_tup, space.wrap(1) )
        w_body = space.getitem( w_tup, space.wrap(2) )
        expr1 = space.interp_w(Node,  w_expr1, can_be_None=True)
        expr2 = space.interp_w(Node,  w_expr2, can_be_None=True)
        body = space.interp_w(Node,  w_body, can_be_None=False)
        self.handlers.append( (expr1,expr2,body) )

Import.fget_names( space, self ):
    return space.newlist( [ space.newtuple( [ space.wrap(name), space.wrap(as_name) ] )
                            for name, as_name in self.names ] )

Import.fset_names( space, self, w_arg ):
    del self.names[:]
    for w_tup in space.unpackiterable( w_arg ):
        w_name = space.getitem( w_tup, space.wrap(0) )
        w_as_name = space.getitem( w_tup, space.wrap(1) )
        name = space.str_w( w_name )
        as_name = None
        if not space.is_w( w_as_name, space.w_None ):
            as_name = space.str_w( w_as_name )
        self.names.append( (name, as_name) )

From.fget_names( space, self ):
    return space.newlist( [ space.newtuple( [ space.wrap(name), space.wrap(as_name) ] )
                            for name, as_name in self.names ] )

From.fset_names( space, self, w_arg ):
    del self.names[:]
    for w_tup in space.unpackiterable( w_arg ):
        w_name = space.getitem( w_tup, space.wrap(0) )
        w_as_name = space.getitem( w_tup, space.wrap(1) )
        name = space.str_w( w_name )
        as_name = None
        if not space.is_w( w_as_name, space.w_None ):
            as_name = space.str_w( w_as_name )
        self.names.append( (name, as_name) )

def descr_From_new(space, w_subtype, w_modname, w_names, lineno=-1):
    self = space.allocate_instance(From, w_subtype)
    modname = space.str_w(w_modname)
    self.modname = modname
    names = []
    for w_tuple in space.unpackiterable(w_names):
        w_name = space.getitem(w_tuple, space.wrap(0))
        w_as_name = space.getitem(w_tuple, space.wrap(1))
        name = space.str_w(w_name)
        as_name = None
        if not space.is_w(w_as_name, space.w_None):
            as_name = space.str_w(w_as_name)
        names.append((name, as_name))
    self.names = names
    self.lineno = lineno
    return space.wrap(self)


def descr_Lambda_new(space, w_subtype, w_argnames, w_defaults, w_flags, w_code, lineno=-1):
    self = space.allocate_instance(Lambda, w_subtype)
    argnames = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_argnames)]
    self.argnames = argnames
    defaults = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_defaults)]
    self.defaults = defaults
    flags = space.int_w(w_flags)
    self.flags = flags
    code = space.interp_w(Node, w_code, can_be_None=False)
    self.code = code
    self.lineno = lineno
    self.varargs = 0
    self.kwargs = 0
    if flags & CO_VARARGS:
        self.varargs = 1
    if flags & CO_VARKEYWORDS:
        self.kwargs = 1
    return space.wrap(self)

def descr_Function_new(space, w_subtype, w_decorators, w_name, w_argnames, w_defaults, w_flags, w_doc, w_code, lineno=-1):
    self = space.allocate_instance(Function, w_subtype)
    decorators = space.interp_w(Node, w_decorators, can_be_None=True)
    self.decorators = decorators
    name = space.str_w(w_name)
    self.name = name
    argnames = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_argnames)]
    self.argnames = argnames
    defaults = [space.interp_w(Node, w_node) for w_node in space.unpackiterable(w_defaults)]
    self.defaults = defaults
    flags = space.int_w(w_flags)
    self.flags = flags    
    self.w_doc = w_doc
    code = space.interp_w(Node, w_code, can_be_None=False)
    self.code = code
    self.lineno = lineno

    self.varargs = 0
    self.kwargs = 0
    if flags & CO_VARARGS:
        self.varargs = 1
    if flags & CO_VARKEYWORDS:
        self.kwargs = 1
    return space.wrap(self)

def descr_Import_new(space, w_subtype, w_names, lineno=-1):
    self = space.allocate_instance(Import, w_subtype)
    names = []
    for w_tuple in space.unpackiterable(w_names):
        w_name = space.getitem(w_tuple, space.wrap(0))
        w_as_name = space.getitem(w_tuple, space.wrap(1))
        name = space.str_w(w_name)
        as_name = None
        if not space.is_w(w_as_name, space.w_None):
            as_name = space.str_w(w_as_name)
        names.append((name, as_name))
    self.names = names
    self.lineno = lineno
    return space.wrap(self)

def descr_Compare_new(space, w_subtype, w_expr, w_ops, lineno=-1):
    self = space.allocate_instance(Compare, w_subtype)
    self.expr = space.interp_w(Node, w_expr)
    ops = []
    for w_tuple in space.unpackiterable(w_ops):
        w_opname = space.getitem(w_tuple, space.wrap(0))
        w_node = space.getitem(w_tuple, space.wrap(1))
        opname = space.str_w(w_opname)
        node = space.interp_w(Node, w_node)
        ops.append((opname, node))
    self.ops = ops
    self.lineno = lineno
    return space.wrap(self)

def descr_Compare_mutate(space, w_self, w_visitor): 
    w_expr = space.getattr(w_self, space.wrap("expr"))
    w_new_expr = space.call_method(w_expr, "mutate", w_visitor)
    space.setattr(w_self, space.wrap("expr"), w_new_expr)

    w_list = space.getattr(w_self, space.wrap("ops"))
    list_w = space.unpackiterable(w_list)
    newlist_w = []
    for w_item in list_w:
        w_opname, w_node = space.unpackiterable(w_item, 2)
        
        w_newnode = space.call_method(w_node, "mutate", w_visitor)
        
        newlist_w.append(space.newtuple([w_opname, w_newnode]))
    w_newlist = space.newlist(newlist_w)
    space.setattr(w_self, space.wrap("ops"), w_newlist)
    return space.call_method(w_visitor, "visitCompare", w_self)

def descr_Dict_new(space, w_subtype, w_items, lineno=-1):
    self = space.allocate_instance(Dict, w_subtype)
    items = []
    for w_tuple in space.unpackiterable(w_items):
        w_key = space.getitem(w_tuple, space.wrap(0))
        w_value = space.getitem(w_tuple, space.wrap(1))
        key = space.interp_w(Node, w_key)
        value = space.interp_w(Node, w_value)
        items.append((key, value))
    self.items = items
    self.lineno = lineno
    return space.wrap(self)

def descr_Dict_mutate(space, w_self, w_visitor): 
    w_list = space.getattr(w_self, space.wrap("items"))
    list_w = space.unpackiterable(w_list)
    newlist_w = []
    for w_item in list_w:
        w_key, w_value = space.unpackiterable(w_item, 2)
        
        w_newkey = space.call_method(w_key, "mutate", w_visitor)
        w_newvalue = space.call_method(w_value, "mutate", w_visitor)
        
        newlist_w.append(space.newtuple([w_newkey, w_newvalue]))
    w_newlist = space.newlist(newlist_w)
    space.setattr(w_self, space.wrap("items"), w_newlist)
    return space.call_method(w_visitor, "visitDict", w_self)

def descr_If_new(space, w_subtype, w_tests, w_else_, lineno=-1):
    self = space.allocate_instance(If, w_subtype)
    tests = []
    for w_tuple in space.unpackiterable(w_tests):
        w_test = space.getitem(w_tuple, space.wrap(0))
        w_suite = space.getitem(w_tuple, space.wrap(1))
        test = space.interp_w(Node, w_test)
        suite = space.interp_w(Node, w_suite)
        tests.append((test, suite))
    self.tests = tests
    self.else_ = space.interp_w(Node, w_else_, can_be_None=True)
    self.lineno = lineno
    return space.wrap(self)

def descr_If_mutate(space, w_self, w_visitor):
    w_list = space.getattr(w_self, space.wrap("tests"))
    list_w = space.unpackiterable(w_list)
    newlist_w = []
    for w_item in list_w:
        w_test, w_suite = space.unpackiterable(w_item, 2)

        w_newtest = space.call_method(w_test, "mutate", w_visitor)
        w_newsuite = space.call_method(w_suite, "mutate", w_visitor)
        newlist_w.append(space.newtuple([w_newtest, w_newsuite]))
    
    w_newlist = space.newlist(newlist_w)
    space.setattr(w_self, space.wrap("tests"), w_newlist)
    w_else_ = space.getattr(w_self, space.wrap("else_"))
    if not space.is_w(w_else_, space.w_None):
        w_new_else_ = space.call_method(w_else_, "mutate", w_visitor)
        space.setattr(w_self, space.wrap("else_"), w_new_else_)


def descr_TryExcept_new(space, w_subtype, w_body, w_handlers, w_else_, lineno=-1):
    self = space.allocate_instance(TryExcept, w_subtype)
    self.body = space.interp_w(Node, w_body)
    handlers = []
    for w_tuple in space.unpackiterable( w_handlers ):
        w_expr1 = space.getitem( w_tuple, space.wrap(0) )
        w_expr2 = space.getitem( w_tuple, space.wrap(1) )
        w_body = space.getitem( w_tuple, space.wrap(2) )
        expr1 = space.interp_w(Node, w_expr1, can_be_None=True)
        expr2 = space.interp_w(Node, w_expr2, can_be_None=True)
        body = space.interp_w(Node, w_body, can_be_None=False)
        handlers.append((expr1, expr2, body))
    self.handlers = handlers
    self.else_ = space.interp_w(Node, w_else_, can_be_None=True)
    self.lineno = lineno
    return space.wrap(self)

def descr_TryExcept_mutate(space, w_self, w_visitor): 
    w_body = space.getattr(w_self, space.wrap("body"))
    w_new_body = space.call_method(w_body, "mutate", w_visitor)
    space.setattr(w_self, space.wrap("body"), w_new_body)

    w_list = space.getattr(w_self, space.wrap("handlers"))
    list_w = space.unpackiterable(w_list)
    newlist_w = []
    for w_item in list_w:
        w_expr1, w_expr2, w_body = space.unpackiterable(w_item, 3)

        if space.is_w(w_expr1, space.w_None):
            w_newexpr1 = w_expr1
        else:
            w_newexpr1 = space.call_method(w_expr1, "mutate", w_visitor)
        
        if space.is_w(w_expr2, space.w_None):
            w_newexpr2 = w_expr2
        else:
            w_newexpr2 = space.call_method(w_expr2, "mutate", w_visitor)

        if space.is_w(w_body, space.w_None):
            w_newbody = w_body
        else:
            w_newbody = space.call_method(w_body, "mutate", w_visitor)
        
        newlist_w.append(space.newtuple([w_newexpr1, w_newexpr2, w_newbody]))
    w_newlist = space.newlist(newlist_w)
    space.setattr(w_self, space.wrap("handlers"), w_newlist)
    w_else_ = space.getattr(w_self, space.wrap("else_"))
    if not space.is_w(w_else_, space.w_None):
        w_new_else_ = space.call_method(w_else_, "mutate", w_visitor)
        space.setattr(w_self, space.wrap("else_"), w_new_else_)

    return space.call_method(w_visitor, "visitTryExcept", w_self)
