{-# OPTIONS #-} ----------------------------------------------------------------------------- -- | -- Module : Language.Python.Version3.Syntax.AST -- Copyright : (c) 2009 Bernie Pope -- License : BSD-style -- Maintainer : bjpop@csse.unimelb.edu.au -- Stability : experimental -- Portability : ghc -- -- Representation of the Python version 3 abstract syntax. -- -- See: -- -- * for an overview of the language. -- -- * for the full grammar. -- -- Note: there are cases where the AST is more liberal than the formal grammar -- of the language. Therefore some care must be taken when constructing -- Python programs using the raw AST. XXX At some point we should provide -- smart constructors which ensure syntactic correctness of the AST. ----------------------------------------------------------------------------- module Language.Python.Version3.Syntax.AST ( -- * Modules Module (..) -- * Identifiers and dotted names , Ident (..) , DottedName -- * Statements, suites, parameters, decorators and assignment operators , Statement (..) , Suite , Parameter (..) , Decorator (..) , AssignOp (..) -- * Expressions, operators, arguments and slices , Expr (..) , Op (..) , Argument (..) , Slice (..) -- * Imports , ImportItem (..) , FromItem (..) , FromItems (..) , ImportModule (..) -- * Exceptions , Handler , ExceptClause -- * Comprehensions , Comprehension (..) , CompFor (..) , CompIf (..) , CompIter (..) ) where import Language.Python.Version3.Parser.Token ( Ident (..) ) import qualified Data.ByteString.Char8 as BS -------------------------------------------------------------------------------- -- | A module (Python source file). See . newtype Module = Module [Statement] -- ^ A module is just a sequence of top-level statements. deriving Show -- | A block of statements. A suite is a group of statements controlled by a clause, -- for example, the body of a loop. See . type Suite = [Statement] -- | A compound name constructed with the dot operator. type DottedName = [Ident] -- | An entity imported using the \'import\' keyword. -- See . data ImportItem = ImportItem { import_item_name :: DottedName -- ^ The name of module to import. , import_as_name :: Maybe Ident -- ^ An optional name to refer to the entity (the \'as\' name). } deriving Show -- | An entity imported using the \'from ... import\' construct. -- See data FromItem = FromItem { from_item_name :: Ident -- ^ The name of the entity imported. , from_as_name :: Maybe Ident -- ^ An optional name to refer to the entity (the \'as\' name). } deriving Show -- | Items imported using the \'from ... import\' construct. data FromItems = ImportEverything -- ^ Import everything exported from the module. | FromItems [FromItem] -- ^ Import a specific list of items from the module. deriving Show -- | A reference to the module to import from using the \'from ... import\' construct. data ImportModule = ImportRelative ImportModule -- ^ Relative import. A dot followed by something. | ImportDot -- ^ Relative import. Dot on its own. | ImportName DottedName -- ^ The name of the module to import from. deriving Show -- | Statements. -- -- See: -- -- * -- -- * data Statement -- | Import statement. = Import { import_items :: [ImportItem] -- ^ Items to import. } -- | From ... import statement. | FromImport { from_module :: ImportModule -- ^ Module to import from. , from_items :: FromItems -- ^ Items to import. } -- | While loop. See . | While { while_cond :: Expr -- ^ Loop condition. , while_body :: Suite -- ^ Loop body. , while_else :: Suite -- ^ Else clause. } -- | For loop. See . | For { for_targets :: [Expr] -- ^ Loop variables. , for_generator :: Expr -- ^ Loop generator. , for_body :: Suite -- ^ Loop body , for_else :: Suite -- ^ Else clause. } -- | Function definition. See . | Fun { fun_name :: Ident -- ^ Function name. , fun_args :: [Parameter] -- ^ Function parameter list. , fun_result_annotation :: Maybe Expr -- ^ Optional result annotation. , fun_body :: Suite -- ^ Function body. } -- | Class definition. See . | Class { class_name :: Ident -- ^ Class name. , class_args :: [Argument] -- ^ Class argument list. , class_body :: Suite -- ^ Class body. } -- | Conditional statement (if-elif-else). See . | Conditional { cond_guards :: [(Expr, Suite)] -- ^ Sequence of if-elif conditional clauses. , cond_else :: Suite -- ^ Possibly empty unconditional else clause. } -- | Assignment statement. See . | Assign { assign_to :: [Expr] -- ^ Entity to assign to. XXX perhaps this should not be a list. , assign_expr :: Expr -- ^ Expression to evaluate. } -- | Augmented assignment statement. See . | AugmentedAssign { aug_assign_to :: Expr -- ^ Entity to assign to. , aug_assign_op :: AssignOp -- ^ Assignment operator (for example \'+=\'). , aug_assign_expr :: Expr -- ^ Expression to evaluate. } -- | Decorated definition of a function or class. | Decorated { decorated_decorators :: [Decorator] -- ^ Decorators. , decorated_def :: Statement -- ^ Function or class definition to be decorated. } -- | Return statement (may only occur syntactically nested in a function definition). See . | Return { return_expr :: Maybe Expr -- ^ Optional expression to evaluate and return to caller. } -- | Try statement (exception handling). See . | Try { try_body :: Suite -- ^ Try clause. , try_excepts :: [Handler] -- ^ Exception handlers. , try_else :: Suite -- ^ Possibly empty else clause, executed if and when control flows off the end of the try clause. , try_finally :: Suite -- ^ Possibly empty finally clause. } -- | Raise statement (exception throwing). See: | Raise { raise_expr :: Maybe (Expr, Maybe Expr) -- ^ Optional expression to evaluate, and optional \'from\' clause. } -- | With statement (context management). See . And also see: . | With { with_context :: Expr -- ^ Context expression (yields a context manager). , with_as :: Maybe Expr -- ^ Optional target. , with_body :: Suite -- ^ Suite to be managed. } -- | Pass statement (null operation). See: | Pass -- | Break statement (may only occur syntactically nested in a for or while loop, but not nested in a function or class definition within that loop). See: . | Break -- | Continue statement (may only occur syntactically nested in a for or while loop, but not nested in a function or class definition or finally clause within that loop). See: . | Continue -- | Del statement (delete). See: . | Delete { del_exprs :: [Expr] -- ^ Items to delete. } -- | Expression statement. See: . | StmtExpr { stmt_expr :: Expr } -- | Global declaration. See: . | Global { global_vars :: [Ident] -- ^ Variables declared global in the current block. } -- | Nonlocal declaration. See: . | NonLocal { nonLocal_vars :: [Ident] -- ^ Variables declared nonlocal in the current block (their binding comes from bound the nearest enclosing scope). } -- | Assertion. See: . | Assert { assert_exprs :: [Expr] -- ^ Expressions being asserted. } deriving Show -- | Decorator. data Decorator = Decorator { decorator_name :: DottedName -- ^ Decorator name. , decorator_args :: [Argument] -- ^ Decorator arguments. } deriving Show -- | Formal parameter of function definitions and lambda expressions. -- -- See: -- -- * -- -- * data Parameter -- | Ordinary named parameter. = Param { param_name :: Ident -- ^ Parameter name. , param_annotation :: Maybe Expr -- ^ Optional annotation. , param_default :: Maybe Expr -- ^ Optional default value. } -- | Excess positional parameter (single asterisk before its name in the concrete syntax). | VarArgsPos { param_name :: Ident -- ^ Parameter name. , param_annotation :: Maybe Expr -- ^ Optional annotation. } -- | Excess keyword parameter (double asterisk before its name in the concrete syntax). | VarArgsKeyword { param_name :: Ident -- ^ Parameter name. , param_annotation :: Maybe Expr -- ^ Optional annotation. } -- | Marker for the end of positional parameters (not a parameter itself). | EndPositional deriving Show -- | Arguments to function calls, class declarations and decorators. data Argument -- | Ordinary argument expression. = ArgExpr { arg_expr :: Expr } -- | Excess positional argument. | ArgVarArgsPos { arg_expr :: Expr } -- | Excess keyword argument. | ArgVarArgsKeyword { arg_expr :: Expr } -- | Keyword argument. | ArgKeyword { arg_keyword :: Ident -- ^ Keyword name. , arg_expr :: Expr -- ^ Argument expression. } deriving Show -- | Exception handler. See: . type Handler = (ExceptClause, Suite) -- | Exception clause. See: . type ExceptClause = Maybe (Expr, Maybe Ident) -- | Comprehension. See: data Comprehension e = Comprehension { comprehension_expr :: e, comprehension_for :: CompFor } deriving Show -- | Comprehension \'for\' component. See: data CompFor = CompFor { comp_for_exprs :: [Expr], comp_in_expr :: Expr, comp_for_iter :: Maybe CompIter } deriving Show -- | Comprehension guard. See: . data CompIf = CompIf { comp_if :: Expr, comp_if_iter :: Maybe CompIter } deriving Show -- | Comprehension iterator (either a \'for\' or an \'if\'). See: . data CompIter = IterFor CompFor | IterIf CompIf deriving Show -- | Expression. -- -- See: . data Expr -- | Variable. = Var Ident -- | Literal integer. | Int Integer -- | Literal floating point number. | Float Double -- | Literal imaginary number. | Imaginary { imaginary_value :: Double } -- | Literal boolean. | Bool Bool -- | Literal \'None\' value. | None -- | Ellipsis \'...\'. | Ellipsis -- | Literal byte string. | ByteStrings [BS.ByteString] -- | Literal strings (to be concatentated together). | Strings [String] -- | Function call. See: . | Call { call_fun :: Expr -- ^ Expression yielding a callable object (such as a function). , call_args :: [Argument] -- ^ Call arguments. } -- | Subscription, for example \'x [y]\'. See: . | Subscript { subscriptee :: Expr, subscript_exprs :: [Expr] } -- | Slicing, for example \'w [x:y:z]\'. See: . | SlicedExpr { slicee :: Expr, slices :: [Slice] } -- | Conditional expresison. See: . | CondExpr { ce_true_branch :: Expr -- ^ Expression to evaluate if condition is True. , ce_condition :: Expr -- ^ Boolean condition. , ce_false_branch :: Expr -- ^ Expression to evaluate if condition is False. } -- | Binary operator application. | BinaryOp { operator :: Op, left_op_arg :: Expr, right_op_arg :: Expr } -- | Unary operator application. | UnaryOp { operator :: Op, op_arg :: Expr } -- | Anonymous function definition (lambda). See: . | Lambda { lambda_args :: [Parameter], lambda_body :: Expr } -- | N-ary tuple of arity greater than 0. The list should not be empty. | Tuple { tuple_exprs :: [Expr] } -- | Generator yield. See: . | Yield { yield_expr :: Maybe Expr -- ^ Optional expression to yield. } -- | Generator. See: . | Generator { gen_comprehension :: Comprehension Expr } -- | List comprehension. See: . | ListComp { list_comprehension :: Comprehension Expr } -- | List. See: . | List { list_exprs :: [Expr] } -- | Dictionary. See: . | Dictionary { dict_mappings :: [(Expr, Expr)] } -- | Dictionary comprehension. See: . | DictComp { dict_comprehension :: Comprehension (Expr, Expr) } -- | Set. See: . | Set { set_exprs :: [Expr] } -- | Set comprehension. . | SetComp { set_comprehension :: Comprehension Expr } -- | Starred expression. | Starred { starred_expr :: Expr } deriving Show data Slice = SliceProper { slice_lower :: Maybe Expr, slice_upper :: Maybe Expr, slice_stride :: Maybe (Maybe Expr) } | SliceExpr { slice_expr :: Expr } deriving Show -- | Operators. data Op = And -- ^ \'and\' | Or -- ^ \'or\' | Not -- ^ \'not\' | Exponent -- ^ \'**\' | LessThan -- ^ \'<\' | GreaterThan -- ^ \'>\' | Equality -- ^ \'==\' | GreaterThanEquals -- ^ \'>=\' | LessThanEquals -- ^ \'<=\' | NotEquals -- ^ \'!=\' | In -- ^ \'in\' | Is -- ^ \'is\' | IsNot -- ^ \'is not\' | NotIn -- ^ \'not in\' | BinaryOr -- ^ \'|\' | Xor -- ^ \'^\' | BinaryAnd -- ^ \'&\' | ShiftLeft -- ^ \'<<\' | ShiftRight -- ^ \'>>\' | Multiply -- ^ \'*\' | Plus -- ^ \'+\' | Minus -- ^ \'-\' | Divide -- ^ \'\/\' | FloorDivide -- ^ \'\/\/\' | Invert -- ^ \'~\' (bitwise inversion of its integer argument) | Modulo -- ^ \'%\' | Dot -- ^ \'.\' deriving (Eq, Show) -- | Augmented assignment operators. data AssignOp = PlusAssign -- ^ \'+=\' | MinusAssign -- ^ \'-=\' | MultAssign -- ^ \'*=\' | DivAssign -- ^ \'\/=\' | ModAssign -- ^ \'%=\' | PowAssign -- ^ \'*=\' | BinAndAssign -- ^ \'&=\' | BinOrAssign -- ^ \'|=\' | BinXorAssign -- ^ \'^=\' | LeftShiftAssign -- ^ \'<<=\' | RightShiftAssign -- ^ \'>>=\' | FloorDivAssign -- ^ \'\/\/=\' deriving (Eq, Show)