-- ASDL's three builtin types are identifier, int, string

-- some useful references: 
-- python grammar: http://svn.python.org/view/python/trunk/Grammar/
-- python parser (contains a version of this file for python: http://svn.python.org/view/python/trunk/Parser/)
-- what's new in python 2.5: http://docs.python.org/dev/whatsnew/whatsnew25.html

module Python
{
	mod = Module(stmt* body)
	    | Interactive(stmt* body)
	    | Expression(expr body)

	    -- not really an actual node but useful in Jython's typesystem.
	    -- | Suite(stmt* body) Removed (it's now a 'real' node we can visit).

	NameTok = NameTok(identifier id, name_context ctx)

	name_context = ClassName | FunctionName | KeywordName | ImportName | VarArg | KwArg | ImportModule | Attrib | GlobalName | NonLocalName

	-- the body is an array of statements (this is not used for all constructs because initially the suite was 'inlined'
	-- in the constructs, but some information was lost in this way).
	suite = Suite(stmt* body)

	--with item because the With() construct may have multiple items in the same construct in python 3.1
	WithItem = WithItem(expr context_expr, expr? optional_vars)
	
	stmt = FunctionDef(NameTok name, arguments args, stmt* body, decorators* decs, expr? returns, bool? async)
	      | ClassDef(NameTok name, expr* bases, stmt* body, decorators* decs, keyword* keywords, expr? starargs, expr? kwargs)
	      | Return(expr? value) 

	      | Delete(expr* targets)
	      | Assign(expr* targets, expr value, expr? type)
	      | AugAssign(expr target, operator op, expr value)

	      -- not sure if bool is allowed, can always use int
 	      | Print(expr? dest, expr* values, bool nl)

	      -- use 'orelse' because else is a keyword in target languages
	      | For(expr target, expr iter, stmt* body, suite orelse, bool? async)
	      | While(expr test, stmt* body, suite orelse)
	      | If(expr test, stmt* body, suite orelse)
	      | With(WithItem* with_item, suite body, bool? async)
	      
	      -- 'type' is a bad name
	      | Raise(expr? type, expr? inst, expr? tback, expr? cause)
	      | TryExcept(stmt* body, excepthandler* handlers, suite orelse)
	      | TryFinally(stmt* body, suite finalbody)
	      | Assert(expr test, expr? msg)

	      | Import(alias* names)
	      | ImportFrom(NameTok module, alias* names, int? level)

	      -- Doesn't capture requirement that locals must be
	      -- defined if globals is
	      -- still supports use as a function!
	      | Exec(expr body, expr? globals, expr? locals)

	      | Global(NameTok* names, expr? value)
	      | NonLocal(NameTok* names, expr? value)
	      | Expr(expr value)
	      | Pass | Break | Continue

	      -- XXX Jython will be different
	      attributes (int lineno)

	      -- BoolOp() can use left & right?
	
	-- strings:    '''             """            '              "
	str_type = TripleSingle | TripleDouble | SingleSingle | SingleDouble
	
	-- numbers:    integer  |     long     |     float    |       hex      |     octcal   |      complex
	num_type =      Int     |     Long     |     Float    |       Hex      |       Oct    |       Comp	

	expr = BoolOp(boolop op, expr* values)
	     | BinOp(expr left, operator op, expr right)
	     | UnaryOp(unaryop op, expr operand)
	     | Lambda(arguments args, expr body)
	     
	      -- added in version 2.5
         | IfExp(expr test, expr body, expr orelse)
         
	     | Dict(expr* keys, expr* values)
	     | Set(expr* elts)
	     | ListComp(expr elt, comprehension* generators, comp_context ctx)
	     | SetComp(expr elt, comprehension* generators)
	     | DictComp(expr key, expr value, comprehension* generators)
	     | GeneratorExp(expr elt, comprehension* generators)
	     -- yield is an expr on 2.5
	     | Yield(expr? value, bool? yield_from)
	     | Await(expr? value)
	     -- need sequences for compare to distinguish between
	     -- x < 4 < 3 and (x < 4) < 3
	     | Compare(expr left, cmpop* ops, expr* comparators)
	     | Call(expr func, expr* args, keyword* keywords, expr? starargs, expr? kwargs)
	     | Repr(expr value)
	     | Num(object n, num_type type, string num) -- a number as a PyObject.
	     | Str(string s, str_type type, bool unicode, bool raw, bool binary, bool fstring) 
	     | StrJoin(expr* strs) -- the inner expr should always be of type Str
	     -- other literals? bools?

	     -- the following expression can appear in assignment context
	     | Attribute(expr value, NameTok attr, expr_context ctx)
	     | Subscript(expr value, slice slice, expr_context ctx)
	     | Starred(expr value, expr_context ctx)
	     --reserved in the name means that it's a keyword (cannot be assigned to)
	     | Name(identifier id, expr_context ctx, bool reserved)
	     | List(expr* elts, expr_context ctx) 
	     | Tuple(expr *elts, expr_context ctx, bool? endsWithComma)

	-- the Artificial context is not actually used in the parser directly. It is used in the application
	-- to create 'artificial' names, as if it was a regular name (e.g.: create a name for a match inside
	-- a comment or string)
	expr_context = Load | Store | Del | AugLoad | AugStore | Param | Artificial | KwOnlyParam
	
	-- This identifies whether the list comprehension was created when we were matching a list, tuple or none of those.
	comp_context = ListCtx | TupleCtx | EmptyCtx

	slice = Ellipsis | Slice(expr? lower, expr? upper, expr? step) 
	      | ExtSlice(slice* dims) 
	      | Index(expr value) 

	boolop = And | Or 

	operator = Add | Sub | Mult | Div | Mod | Pow | LShift 
                 | RShift | BitOr | BitXor | BitAnd | FloorDiv | Dot

	unaryop = Invert | Not | UAdd | USub

	cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn

	comprehension = Comprehension(expr target, expr iter, expr* ifs)

	-- not sure what to call the first argument for raise and except
	
	excepthandler = (expr? type, expr? name, stmt* body)

	arguments = (expr* args,     --regular arguments 
	         NameTok? vararg,    --varargs (has no defaults)
		     NameTok? kwarg,     --kwargs (has no defaults)
		     expr* defaults,     --default values for the args
		     expr* kwonlyargs,   --keyword only (new in 3.0)
		     expr* kw_defaults,  --defaults for the keyword only
		     
		     expr* annotation,         --from args 
		     expr? varargannotation,   --from vararg
		     expr? kwargannotation,    --from kwarg
		     expr* kwonlyargannotation --from kwargonly
		     )

        
    -- keyword arguments supplied to call
    keyword = (NameTok arg, expr value, bool afterstarargs)

    -- import name with optional 'as' alias.
    alias = (NameTok name, NameTok? asname)

	--decorators work as '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
	--changed so that we have the name separated from the arguments for each decorator (fabioz)
	--it works basically equal to the call.
	decorators = (expr func, expr* args, keyword* keywords, expr? starargs, expr? kwargs, bool? isCall)

	comment = (identifier id)
}
