    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE DerivingVia #-}
    {-# LANGUAGE BlockArguments #-}
    {-# LANGUAGE PatternSynonyms #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  GHC.JS.Syntax
    -- Copyright   :  (c) The University of Glasgow 2001
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  Jeffrey Young  <jeffrey.young@iohk.io>
    --                Luite Stegeman <luite.stegeman@iohk.io>
    --                Sylvain Henry  <sylvain.henry@iohk.io>
    --                Josh Meredith  <josh.meredith@iohk.io>
    -- Stability   :  experimental
    --
    --
    -- * Domain and Purpose
    --
    --     GHC.JS.Syntax defines the Syntax for the JS backend in GHC. It comports
    --     with the [ECMA-262](https://tc39.es/ecma262/) although not every
    --     production rule of the standard is represented. Code in this module is a
    --     fork of [JMacro](https://hackage.haskell.org/package/jmacro) (BSD 3
    --     Clause) by Gershom Bazerman, heavily modified to accomodate GHC's
    --     constraints.
    --
    --
    -- * Strategy
    --
    --     Nothing fancy in this module, this is a classic deeply embedded AST for
    --     JS. We define numerous ADTs and pattern synonyms to make pattern matching
    --     and constructing ASTs easier.
    --
    --
    -- * Consumers
    --
    --     The entire JS backend consumes this module, e.g., the modules in
    --     GHC.StgToJS.\*. Please see 'GHC.JS.Make' for a module which provides
    --     helper functions that use the deeply embedded DSL defined in this module
    --     to provide some of the benefits of a shallow embedding.
    --
    -----------------------------------------------------------------------------

    module GHC.JS.Syntax
      ( -- * Deeply embedded JS datatypes
        JStat(..)
      , JExpr(..)
      , JVal(..)
      , Op(..)
      , UOp(..)
      , AOp(..)
      , Ident(..)
      , JLabel
      -- * pattern synonyms over JS operators
      , pattern New
      , pattern Not
      , pattern Negate
      , pattern Add
      , pattern Sub
      , pattern Mul
      , pattern Div
      , pattern Mod
      , pattern BOr
      , pattern BAnd
      , pattern BXor
      , pattern BNot
      , pattern LOr
      , pattern LAnd
      , pattern Int
      , pattern String
      , pattern Var
      , pattern PreInc
      , pattern PostInc
      , pattern PreDec
      , pattern PostDec
      -- * Utility
      , SaneDouble(..)
      , var
      , true_
      , false_
      ) where

    import GHC.Prelude

    import GHC.JS.Ident

    import GHC.Data.FastString
    import GHC.Types.Unique.Map
    import GHC.Types.SaneDouble

    import Control.DeepSeq

    import Data.Data
    import qualified Data.Semigroup as Semigroup

    import GHC.Generics

    --------------------------------------------------------------------------------
    --                            Statements
    --------------------------------------------------------------------------------
    -- | JavaScript statements, see the [ECMA262
    -- Reference](https://tc39.es/ecma262/#sec-ecmascript-language-statements-and-declarations)
    -- for details
    data JStat
      = DeclStat   !Ident !(Maybe JExpr)  -- ^ Variable declarations: var foo [= e]
      | ReturnStat JExpr                  -- ^ Return
      | IfStat     JExpr JStat JStat      -- ^ If
      | WhileStat  Bool JExpr JStat       -- ^ While, bool is "do" when True
      | ForStat    JStat JExpr JStat JStat  -- ^ For
      | ForInStat  Bool Ident JExpr JStat -- ^ For-in, bool is "each' when True
      | SwitchStat JExpr [(JExpr, JStat)] JStat  -- ^ Switch
      | TryStat    JStat Ident JStat JStat -- ^ Try
      | BlockStat  [JStat]                 -- ^ Blocks
      | ApplStat   JExpr [JExpr]           -- ^ Application
      | UOpStat UOp JExpr                  -- ^ Unary operators
      | AssignStat JExpr AOp JExpr         -- ^ Binding form: @<foo> <op> <bar>@
      | LabelStat JLabel JStat             -- ^ Statement Labels, makes me nostalgic for qbasic
      | BreakStat (Maybe JLabel)           -- ^ Break
      | ContinueStat (Maybe JLabel)        -- ^ Continue
      | FuncStat   !Ident [Ident] JStat    -- ^ an explicit function definition
      deriving (JStat -> JStat -> Bool
    (JStat -> JStat -> Bool) -> (JStat -> JStat -> Bool) -> Eq JStat
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: JStat -> JStat -> Bool
    == :: JStat -> JStat -> Bool
    $c/= :: JStat -> JStat -> Bool
    /= :: JStat -> JStat -> Bool
    Eq, Typeable, (forall x. JStat -> Rep JStat x)
    -> (forall x. Rep JStat x -> JStat) -> Generic JStat
    forall x. Rep JStat x -> JStat
    forall x. JStat -> Rep JStat x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. JStat -> Rep JStat x
    from :: forall x. JStat -> Rep JStat x
    $cto :: forall x. Rep JStat x -> JStat
    to :: forall x. Rep JStat x -> JStat
    Generic)

    -- | A Label used for 'JStat', specifically 'BreakStat', 'ContinueStat' and of
    -- course 'LabelStat'
    type JLabel = LexicalFastString

    instance Semigroup JStat where
      <> :: JStat -> JStat -> JStat
    (<>) = JStat -> JStat -> JStat
    appendJStat

    instance Monoid JStat where
      mempty :: JStat
    mempty = [JStat] -> JStat
    BlockStat []

    -- | Append a statement to another statement. 'appendJStat' only returns a
    -- 'JStat' that is /not/ a 'BlockStat' when either @mx@ or @my is an empty
    -- 'BlockStat'. That is:
    -- > (BlockStat [] , y           ) = y
    -- > (x            , BlockStat []) = x
    appendJStat :: JStat -> JStat -> JStat
    appendJStat :: JStat -> JStat -> JStat
    appendJStat JStat
    mx JStat
    my = case (JStat
    mx,JStat
    my) of
      (BlockStat [] , JStat
    y           ) -> JStat
    y
      (JStat
    x            , BlockStat []) -> JStat
    x
      (BlockStat [JStat]
    xs , BlockStat [JStat]
    ys) -> [JStat] -> JStat
    BlockStat ([JStat] -> JStat) -> [JStat] -> JStat
    forall a b. (a -> b) -> a -> b
    $! [JStat]
    xs [JStat] -> [JStat] -> [JStat]
    forall a. [a] -> [a] -> [a]
    ++ [JStat]
    ys
      (BlockStat [JStat]
    xs , JStat
    ys          ) -> [JStat] -> JStat
    BlockStat ([JStat] -> JStat) -> [JStat] -> JStat
    forall a b. (a -> b) -> a -> b
    $! [JStat]
    xs [JStat] -> [JStat] -> [JStat]
    forall a. [a] -> [a] -> [a]
    ++ [JStat
    ys]
      (JStat
    xs           , BlockStat [JStat]
    ys) -> [JStat] -> JStat
    BlockStat ([JStat] -> JStat) -> [JStat] -> JStat
    forall a b. (a -> b) -> a -> b
    $! JStat
    xs JStat -> [JStat] -> [JStat]
    forall a. a -> [a] -> [a]
    : [JStat]
    ys
      (JStat
    xs           , JStat
    ys          ) -> [JStat] -> JStat
    BlockStat [JStat
    xs,JStat
    ys]

    --------------------------------------------------------------------------------
    --                            Expressions
    --------------------------------------------------------------------------------
    -- | JavaScript Expressions
    data JExpr
      = ValExpr    JVal              -- ^ All values are trivially expressions
      | SelExpr    JExpr Ident       -- ^ Selection: Obj.foo, see 'GHC.JS.Make..^'
      | IdxExpr    JExpr JExpr       -- ^ Indexing:  Obj[foo], see 'GHC.JS.Make..!'
      | InfixExpr  Op JExpr JExpr    -- ^ Infix Expressions, see 'JExpr' pattern synonyms
      | UOpExpr    UOp JExpr         -- ^ Unary Expressions
      | IfExpr     JExpr JExpr JExpr -- ^ If-expression
      | ApplExpr   JExpr [JExpr]     -- ^ Application
      deriving (JExpr -> JExpr -> Bool
    (JExpr -> JExpr -> Bool) -> (JExpr -> JExpr -> Bool) -> Eq JExpr
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: JExpr -> JExpr -> Bool
    == :: JExpr -> JExpr -> Bool
    $c/= :: JExpr -> JExpr -> Bool
    /= :: JExpr -> JExpr -> Bool
    Eq, Typeable, (forall x. JExpr -> Rep JExpr x)
    -> (forall x. Rep JExpr x -> JExpr) -> Generic JExpr
    forall x. Rep JExpr x -> JExpr
    forall x. JExpr -> Rep JExpr x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. JExpr -> Rep JExpr x
    from :: forall x. JExpr -> Rep JExpr x
    $cto :: forall x. Rep JExpr x -> JExpr
    to :: forall x. Rep JExpr x -> JExpr
    Generic)

    -- * Useful pattern synonyms to ease programming with the deeply embedded JS
    --   AST. Each pattern wraps @UOp@ and @Op@ into a @JExpr@s to save typing and
    --   for convienience. In addition we include a string wrapper for JS string
    --   and Integer literals.

    -- | pattern synonym for a unary operator new
    pattern New :: JExpr -> JExpr
    pattern $mNew :: forall {r}. JExpr -> (JExpr -> r) -> ((# #) -> r) -> r
    $bNew :: JExpr -> JExpr
    New x = UOpExpr NewOp x

    -- | pattern synonym for prefix increment @++x@
    pattern PreInc :: JExpr -> JExpr
    pattern $mPreInc :: forall {r}. JExpr -> (JExpr -> r) -> ((# #) -> r) -> r
    $bPreInc :: JExpr -> JExpr
    PreInc x = UOpExpr PreIncOp x

    -- | pattern synonym for postfix increment @x++@
    pattern PostInc :: JExpr -> JExpr
    pattern $mPostInc :: forall {r}. JExpr -> (JExpr -> r) -> ((# #) -> r) -> r
    $bPostInc :: JExpr -> JExpr
    PostInc x = UOpExpr PostIncOp x

    -- | pattern synonym for prefix decrement @--x@
    pattern PreDec :: JExpr -> JExpr
    pattern $mPreDec :: forall {r}. JExpr -> (JExpr -> r) -> ((# #) -> r) -> r
    $bPreDec :: JExpr -> JExpr
    PreDec x = UOpExpr PreDecOp x

    -- | pattern synonym for postfix decrement @--x@
    pattern PostDec :: JExpr -> JExpr
    pattern $mPostDec :: forall {r}. JExpr -> (JExpr -> r) -> ((# #) -> r) -> r
    $bPostDec :: JExpr -> JExpr
    PostDec x = UOpExpr PostDecOp x

    -- | pattern synonym for logical not @!@
    pattern Not :: JExpr -> JExpr
    pattern $mNot :: forall {r}. JExpr -> (JExpr -> r) -> ((# #) -> r) -> r
    $bNot :: JExpr -> JExpr
    Not x = UOpExpr NotOp x

    -- | pattern synonym for unary negation @-@
    pattern Negate :: JExpr -> JExpr
    pattern $mNegate :: forall {r}. JExpr -> (JExpr -> r) -> ((# #) -> r) -> r
    $bNegate :: JExpr -> JExpr
    Negate x = UOpExpr NegOp x

    -- | pattern synonym for addition @+@
    pattern Add :: JExpr -> JExpr -> JExpr
    pattern $mAdd :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bAdd :: JExpr -> JExpr -> JExpr
    Add x y = InfixExpr AddOp x y

    -- | pattern synonym for subtraction @-@
    pattern Sub :: JExpr -> JExpr -> JExpr
    pattern $mSub :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bSub :: JExpr -> JExpr -> JExpr
    Sub x y = InfixExpr SubOp x y

    -- | pattern synonym for multiplication @*@
    pattern Mul :: JExpr -> JExpr -> JExpr
    pattern $mMul :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bMul :: JExpr -> JExpr -> JExpr
    Mul x y = InfixExpr MulOp x y

    -- | pattern synonym for division @*@
    pattern Div :: JExpr -> JExpr -> JExpr
    pattern $mDiv :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bDiv :: JExpr -> JExpr -> JExpr
    Div x y = InfixExpr DivOp x y

    -- | pattern synonym for remainder @%@
    pattern Mod :: JExpr -> JExpr -> JExpr
    pattern $mMod :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bMod :: JExpr -> JExpr -> JExpr
    Mod x y = InfixExpr ModOp x y

    -- | pattern synonym for Bitwise Or @|@
    pattern BOr :: JExpr -> JExpr -> JExpr
    pattern $mBOr :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bBOr :: JExpr -> JExpr -> JExpr
    BOr x y = InfixExpr BOrOp x y

    -- | pattern synonym for Bitwise And @&@
    pattern BAnd :: JExpr -> JExpr -> JExpr
    pattern $mBAnd :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bBAnd :: JExpr -> JExpr -> JExpr
    BAnd x y = InfixExpr BAndOp x y

    -- | pattern synonym for Bitwise XOr @^@
    pattern BXor :: JExpr -> JExpr -> JExpr
    pattern $mBXor :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bBXor :: JExpr -> JExpr -> JExpr
    BXor x y = InfixExpr BXorOp x y

    -- | pattern synonym for Bitwise Not @~@
    pattern BNot :: JExpr -> JExpr
    pattern $mBNot :: forall {r}. JExpr -> (JExpr -> r) -> ((# #) -> r) -> r
    $bBNot :: JExpr -> JExpr
    BNot x = UOpExpr BNotOp x

    -- | pattern synonym for logical Or @||@
    pattern LOr :: JExpr -> JExpr -> JExpr
    pattern $mLOr :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bLOr :: JExpr -> JExpr -> JExpr
    LOr x y = InfixExpr LOrOp x y

    -- | pattern synonym for logical And @&&@
    pattern LAnd :: JExpr -> JExpr -> JExpr
    pattern $mLAnd :: forall {r}. JExpr -> (JExpr -> JExpr -> r) -> ((# #) -> r) -> r
    $bLAnd :: JExpr -> JExpr -> JExpr
    LAnd x y = InfixExpr LAndOp x y

    -- | pattern synonym to create integer values
    pattern Int :: Integer -> JExpr
    pattern $mInt :: forall {r}. JExpr -> (Integer -> r) -> ((# #) -> r) -> r
    $bInt :: Integer -> JExpr
    Int x = ValExpr (JInt x)

    -- | pattern synonym to create string values
    pattern String :: FastString -> JExpr
    pattern $mString :: forall {r}. JExpr -> (FastString -> r) -> ((# #) -> r) -> r
    $bString :: FastString -> JExpr
    String x = ValExpr (JStr x)

    -- | pattern synonym to create a local variable reference
    pattern Var :: Ident -> JExpr
    pattern $mVar :: forall {r}. JExpr -> (Ident -> r) -> ((# #) -> r) -> r
    $bVar :: Ident -> JExpr
    Var x = ValExpr (JVar x)

    --------------------------------------------------------------------------------
    --                            Values
    --------------------------------------------------------------------------------

    -- | JavaScript values
    data JVal
      = JVar     Ident        -- ^ A variable reference
      | JList    [JExpr]      -- ^ A JavaScript list, or what JS calls an Array
      | JDouble  SaneDouble   -- ^ A Double
      | JInt     Integer      -- ^ A BigInt
      | JStr     FastString   -- ^ A String
      | JRegEx   FastString   -- ^ A Regex
      | JBool    Bool         -- ^ A Boolean
      | JHash    (UniqMap FastString JExpr) -- ^ A JS HashMap: @{"foo": 0}@
      | JFunc    [Ident] JStat             -- ^ A function
      deriving (JVal -> JVal -> Bool
    (JVal -> JVal -> Bool) -> (JVal -> JVal -> Bool) -> Eq JVal
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: JVal -> JVal -> Bool
    == :: JVal -> JVal -> Bool
    $c/= :: JVal -> JVal -> Bool
    /= :: JVal -> JVal -> Bool
    Eq, Typeable, (forall x. JVal -> Rep JVal x)
    -> (forall x. Rep JVal x -> JVal) -> Generic JVal
    forall x. Rep JVal x -> JVal
    forall x. JVal -> Rep JVal x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. JVal -> Rep JVal x
    from :: forall x. JVal -> Rep JVal x
    $cto :: forall x. Rep JVal x -> JVal
    to :: forall x. Rep JVal x -> JVal
    Generic)

    --------------------------------------------------------------------------------
    --                            Operators
    --------------------------------------------------------------------------------

    -- | JS Binary Operators. We do not deeply embed the comma operator and the
    -- assignment operators
    data Op
      = EqOp            -- ^ Equality:              `==`
      | StrictEqOp      -- ^ Strict Equality:       `===`
      | NeqOp           -- ^ InEquality:            `!=`
      | StrictNeqOp     -- ^ Strict InEquality      `!==`
      | GtOp            -- ^ Greater Than:          `>`
      | GeOp            -- ^ Greater Than or Equal: `>=`
      | LtOp            -- ^ Less Than:              <
      | LeOp            -- ^ Less Than or Equal:     <=
      | AddOp           -- ^ Addition:               +
      | SubOp           -- ^ Subtraction:            -
      | MulOp           -- ^ Multiplication          \*
      | DivOp           -- ^ Division:               \/
      | ModOp           -- ^ Remainder:              %
      | LeftShiftOp     -- ^ Left Shift:             \<\<
      | RightShiftOp    -- ^ Right Shift:            \>\>
      | ZRightShiftOp   -- ^ Unsigned RightShift:    \>\>\>
      | BAndOp          -- ^ Bitwise And:            &
      | BOrOp           -- ^ Bitwise Or:             |
      | BXorOp          -- ^ Bitwise XOr:            ^
      | LAndOp          -- ^ Logical And:            &&
      | LOrOp           -- ^ Logical Or:             ||
      | InstanceofOp    -- ^ @instanceof@
      | InOp            -- ^ @in@
      deriving (Int -> Op -> ShowS
    [Op] -> ShowS
    Op -> String
    (Int -> Op -> ShowS)
    -> (Op -> String) -> ([Op] -> ShowS) -> Show Op
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Op -> ShowS
    showsPrec :: Int -> Op -> ShowS
    $cshow :: Op -> String
    show :: Op -> String
    $cshowList :: [Op] -> ShowS
    showList :: [Op] -> ShowS
    Show, Op -> Op -> Bool
    (Op -> Op -> Bool) -> (Op -> Op -> Bool) -> Eq Op
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Op -> Op -> Bool
    == :: Op -> Op -> Bool
    $c/= :: Op -> Op -> Bool
    /= :: Op -> Op -> Bool
    Eq, Eq Op
    Eq Op =>
    (Op -> Op -> Ordering)
    -> (Op -> Op -> Bool)
    -> (Op -> Op -> Bool)
    -> (Op -> Op -> Bool)
    -> (Op -> Op -> Bool)
    -> (Op -> Op -> Op)
    -> (Op -> Op -> Op)
    -> Ord Op
    Op -> Op -> Bool
    Op -> Op -> Ordering
    Op -> Op -> Op
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Op -> Op -> Ordering
    compare :: Op -> Op -> Ordering
    $c< :: Op -> Op -> Bool
    < :: Op -> Op -> Bool
    $c<= :: Op -> Op -> Bool
    <= :: Op -> Op -> Bool
    $c> :: Op -> Op -> Bool
    > :: Op -> Op -> Bool
    $c>= :: Op -> Op -> Bool
    >= :: Op -> Op -> Bool
    $cmax :: Op -> Op -> Op
    max :: Op -> Op -> Op
    $cmin :: Op -> Op -> Op
    min :: Op -> Op -> Op
    Ord, Int -> Op
    Op -> Int
    Op -> [Op]
    Op -> Op
    Op -> Op -> [Op]
    Op -> Op -> Op -> [Op]
    (Op -> Op)
    -> (Op -> Op)
    -> (Int -> Op)
    -> (Op -> Int)
    -> (Op -> [Op])
    -> (Op -> Op -> [Op])
    -> (Op -> Op -> [Op])
    -> (Op -> Op -> Op -> [Op])
    -> Enum Op
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: Op -> Op
    succ :: Op -> Op
    $cpred :: Op -> Op
    pred :: Op -> Op
    $ctoEnum :: Int -> Op
    toEnum :: Int -> Op
    $cfromEnum :: Op -> Int
    fromEnum :: Op -> Int
    $cenumFrom :: Op -> [Op]
    enumFrom :: Op -> [Op]
    $cenumFromThen :: Op -> Op -> [Op]
    enumFromThen :: Op -> Op -> [Op]
    $cenumFromTo :: Op -> Op -> [Op]
    enumFromTo :: Op -> Op -> [Op]
    $cenumFromThenTo :: Op -> Op -> Op -> [Op]
    enumFromThenTo :: Op -> Op -> Op -> [Op]
    Enum, Typeable Op
    Typeable Op =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Op -> c Op)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Op)
    -> (Op -> Constr)
    -> (Op -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Op))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Op))
    -> ((forall b. Data b => b -> b) -> Op -> Op)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Op -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Op -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Op -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Op -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Op -> m Op)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Op -> m Op)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Op -> m Op)
    -> Data Op
    Op -> Constr
    Op -> DataType
    (forall b. Data b => b -> b) -> Op -> Op
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Op -> u
    forall u. (forall d. Data d => d -> u) -> Op -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Op -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Op -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Op -> m Op
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Op -> m Op
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Op
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Op -> c Op
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Op)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Op)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Op -> c Op
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Op -> c Op
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Op
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Op
    $ctoConstr :: Op -> Constr
    toConstr :: Op -> Constr
    $cdataTypeOf :: Op -> DataType
    dataTypeOf :: Op -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Op)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Op)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Op)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Op)
    $cgmapT :: (forall b. Data b => b -> b) -> Op -> Op
    gmapT :: (forall b. Data b => b -> b) -> Op -> Op
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Op -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Op -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Op -> r
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Op -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Op -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Op -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Op -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Op -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Op -> m Op
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Op -> m Op
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Op -> m Op
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Op -> m Op
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Op -> m Op
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Op -> m Op
    Data, Typeable, (forall x. Op -> Rep Op x)
    -> (forall x. Rep Op x -> Op) -> Generic Op
    forall x. Rep Op x -> Op
    forall x. Op -> Rep Op x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. Op -> Rep Op x
    from :: forall x. Op -> Rep Op x
    $cto :: forall x. Rep Op x -> Op
    to :: forall x. Rep Op x -> Op
    Generic)

    instance NFData Op

    -- | JS Unary Operators
    data UOp
      = NotOp           -- ^ Logical Not: @!@
      | BNotOp          -- ^ Bitwise Not: @~@
      | NegOp           -- ^ Negation:    @-@
      | PlusOp          -- ^ Unary Plus:  @+x@
      | NewOp           -- ^ new    x
      | TypeofOp        -- ^ typeof x
      | DeleteOp        -- ^ delete x
      | YieldOp         -- ^ yield  x
      | VoidOp          -- ^ void   x
      | PreIncOp        -- ^ Prefix Increment:  @++x@
      | PostIncOp       -- ^ Postfix Increment: @x++@
      | PreDecOp        -- ^ Prefix Decrement:  @--x@
      | PostDecOp       -- ^ Postfix Decrement: @x--@
      deriving (Int -> UOp -> ShowS
    [UOp] -> ShowS
    UOp -> String
    (Int -> UOp -> ShowS)
    -> (UOp -> String) -> ([UOp] -> ShowS) -> Show UOp
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> UOp -> ShowS
    showsPrec :: Int -> UOp -> ShowS
    $cshow :: UOp -> String
    show :: UOp -> String
    $cshowList :: [UOp] -> ShowS
    showList :: [UOp] -> ShowS
    Show, UOp -> UOp -> Bool
    (UOp -> UOp -> Bool) -> (UOp -> UOp -> Bool) -> Eq UOp
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: UOp -> UOp -> Bool
    == :: UOp -> UOp -> Bool
    $c/= :: UOp -> UOp -> Bool
    /= :: UOp -> UOp -> Bool
    Eq, Eq UOp
    Eq UOp =>
    (UOp -> UOp -> Ordering)
    -> (UOp -> UOp -> Bool)
    -> (UOp -> UOp -> Bool)
    -> (UOp -> UOp -> Bool)
    -> (UOp -> UOp -> Bool)
    -> (UOp -> UOp -> UOp)
    -> (UOp -> UOp -> UOp)
    -> Ord UOp
    UOp -> UOp -> Bool
    UOp -> UOp -> Ordering
    UOp -> UOp -> UOp
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: UOp -> UOp -> Ordering
    compare :: UOp -> UOp -> Ordering
    $c< :: UOp -> UOp -> Bool
    < :: UOp -> UOp -> Bool
    $c<= :: UOp -> UOp -> Bool
    <= :: UOp -> UOp -> Bool
    $c> :: UOp -> UOp -> Bool
    > :: UOp -> UOp -> Bool
    $c>= :: UOp -> UOp -> Bool
    >= :: UOp -> UOp -> Bool
    $cmax :: UOp -> UOp -> UOp
    max :: UOp -> UOp -> UOp
    $cmin :: UOp -> UOp -> UOp
    min :: UOp -> UOp -> UOp
    Ord, Int -> UOp
    UOp -> Int
    UOp -> [UOp]
    UOp -> UOp
    UOp -> UOp -> [UOp]
    UOp -> UOp -> UOp -> [UOp]
    (UOp -> UOp)
    -> (UOp -> UOp)
    -> (Int -> UOp)
    -> (UOp -> Int)
    -> (UOp -> [UOp])
    -> (UOp -> UOp -> [UOp])
    -> (UOp -> UOp -> [UOp])
    -> (UOp -> UOp -> UOp -> [UOp])
    -> Enum UOp
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: UOp -> UOp
    succ :: UOp -> UOp
    $cpred :: UOp -> UOp
    pred :: UOp -> UOp
    $ctoEnum :: Int -> UOp
    toEnum :: Int -> UOp
    $cfromEnum :: UOp -> Int
    fromEnum :: UOp -> Int
    $cenumFrom :: UOp -> [UOp]
    enumFrom :: UOp -> [UOp]
    $cenumFromThen :: UOp -> UOp -> [UOp]
    enumFromThen :: UOp -> UOp -> [UOp]
    $cenumFromTo :: UOp -> UOp -> [UOp]
    enumFromTo :: UOp -> UOp -> [UOp]
    $cenumFromThenTo :: UOp -> UOp -> UOp -> [UOp]
    enumFromThenTo :: UOp -> UOp -> UOp -> [UOp]
    Enum, Typeable UOp
    Typeable UOp =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> UOp -> c UOp)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c UOp)
    -> (UOp -> Constr)
    -> (UOp -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c UOp))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UOp))
    -> ((forall b. Data b => b -> b) -> UOp -> UOp)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> UOp -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> UOp -> r)
    -> (forall u. (forall d. Data d => d -> u) -> UOp -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> UOp -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> UOp -> m UOp)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> UOp -> m UOp)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> UOp -> m UOp)
    -> Data UOp
    UOp -> Constr
    UOp -> DataType
    (forall b. Data b => b -> b) -> UOp -> UOp
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> UOp -> u
    forall u. (forall d. Data d => d -> u) -> UOp -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> UOp -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> UOp -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> UOp -> m UOp
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UOp -> m UOp
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c UOp
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> UOp -> c UOp
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c UOp)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UOp)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> UOp -> c UOp
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> UOp -> c UOp
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c UOp
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c UOp
    $ctoConstr :: UOp -> Constr
    toConstr :: UOp -> Constr
    $cdataTypeOf :: UOp -> DataType
    dataTypeOf :: UOp -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c UOp)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c UOp)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UOp)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c UOp)
    $cgmapT :: (forall b. Data b => b -> b) -> UOp -> UOp
    gmapT :: (forall b. Data b => b -> b) -> UOp -> UOp
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> UOp -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> UOp -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> UOp -> r
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> UOp -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> UOp -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> UOp -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UOp -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> UOp -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> UOp -> m UOp
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> UOp -> m UOp
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UOp -> m UOp
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UOp -> m UOp
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UOp -> m UOp
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> UOp -> m UOp
    Data, Typeable, (forall x. UOp -> Rep UOp x)
    -> (forall x. Rep UOp x -> UOp) -> Generic UOp
    forall x. Rep UOp x -> UOp
    forall x. UOp -> Rep UOp x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. UOp -> Rep UOp x
    from :: forall x. UOp -> Rep UOp x
    $cto :: forall x. Rep UOp x -> UOp
    to :: forall x. Rep UOp x -> UOp
    Generic)

    instance NFData UOp

    -- | JS Unary Operators
    data AOp
      = AssignOp    -- ^ Vanilla  Assignment: =
      | AddAssignOp -- ^ Addition Assignment: +=
      | SubAssignOp -- ^ Subtraction Assignment: -=
      deriving (Int -> AOp -> ShowS
    [AOp] -> ShowS
    AOp -> String
    (Int -> AOp -> ShowS)
    -> (AOp -> String) -> ([AOp] -> ShowS) -> Show AOp
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> AOp -> ShowS
    showsPrec :: Int -> AOp -> ShowS
    $cshow :: AOp -> String
    show :: AOp -> String
    $cshowList :: [AOp] -> ShowS
    showList :: [AOp] -> ShowS
    Show, AOp -> AOp -> Bool
    (AOp -> AOp -> Bool) -> (AOp -> AOp -> Bool) -> Eq AOp
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: AOp -> AOp -> Bool
    == :: AOp -> AOp -> Bool
    $c/= :: AOp -> AOp -> Bool
    /= :: AOp -> AOp -> Bool
    Eq, Eq AOp
    Eq AOp =>
    (AOp -> AOp -> Ordering)
    -> (AOp -> AOp -> Bool)
    -> (AOp -> AOp -> Bool)
    -> (AOp -> AOp -> Bool)
    -> (AOp -> AOp -> Bool)
    -> (AOp -> AOp -> AOp)
    -> (AOp -> AOp -> AOp)
    -> Ord AOp
    AOp -> AOp -> Bool
    AOp -> AOp -> Ordering
    AOp -> AOp -> AOp
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: AOp -> AOp -> Ordering
    compare :: AOp -> AOp -> Ordering
    $c< :: AOp -> AOp -> Bool
    < :: AOp -> AOp -> Bool
    $c<= :: AOp -> AOp -> Bool
    <= :: AOp -> AOp -> Bool
    $c> :: AOp -> AOp -> Bool
    > :: AOp -> AOp -> Bool
    $c>= :: AOp -> AOp -> Bool
    >= :: AOp -> AOp -> Bool
    $cmax :: AOp -> AOp -> AOp
    max :: AOp -> AOp -> AOp
    $cmin :: AOp -> AOp -> AOp
    min :: AOp -> AOp -> AOp
    Ord, Int -> AOp
    AOp -> Int
    AOp -> [AOp]
    AOp -> AOp
    AOp -> AOp -> [AOp]
    AOp -> AOp -> AOp -> [AOp]
    (AOp -> AOp)
    -> (AOp -> AOp)
    -> (Int -> AOp)
    -> (AOp -> Int)
    -> (AOp -> [AOp])
    -> (AOp -> AOp -> [AOp])
    -> (AOp -> AOp -> [AOp])
    -> (AOp -> AOp -> AOp -> [AOp])
    -> Enum AOp
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: AOp -> AOp
    succ :: AOp -> AOp
    $cpred :: AOp -> AOp
    pred :: AOp -> AOp
    $ctoEnum :: Int -> AOp
    toEnum :: Int -> AOp
    $cfromEnum :: AOp -> Int
    fromEnum :: AOp -> Int
    $cenumFrom :: AOp -> [AOp]
    enumFrom :: AOp -> [AOp]
    $cenumFromThen :: AOp -> AOp -> [AOp]
    enumFromThen :: AOp -> AOp -> [AOp]
    $cenumFromTo :: AOp -> AOp -> [AOp]
    enumFromTo :: AOp -> AOp -> [AOp]
    $cenumFromThenTo :: AOp -> AOp -> AOp -> [AOp]
    enumFromThenTo :: AOp -> AOp -> AOp -> [AOp]
    Enum, Typeable AOp
    Typeable AOp =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> AOp -> c AOp)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c AOp)
    -> (AOp -> Constr)
    -> (AOp -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c AOp))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AOp))
    -> ((forall b. Data b => b -> b) -> AOp -> AOp)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> AOp -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> AOp -> r)
    -> (forall u. (forall d. Data d => d -> u) -> AOp -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> AOp -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> AOp -> m AOp)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> AOp -> m AOp)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> AOp -> m AOp)
    -> Data AOp
    AOp -> Constr
    AOp -> DataType
    (forall b. Data b => b -> b) -> AOp -> AOp
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> AOp -> u
    forall u. (forall d. Data d => d -> u) -> AOp -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> AOp -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> AOp -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AOp -> m AOp
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AOp -> m AOp
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AOp
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AOp -> c AOp
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AOp)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AOp)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AOp -> c AOp
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AOp -> c AOp
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AOp
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AOp
    $ctoConstr :: AOp -> Constr
    toConstr :: AOp -> Constr
    $cdataTypeOf :: AOp -> DataType
    dataTypeOf :: AOp -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AOp)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AOp)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AOp)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AOp)
    $cgmapT :: (forall b. Data b => b -> b) -> AOp -> AOp
    gmapT :: (forall b. Data b => b -> b) -> AOp -> AOp
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> AOp -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> AOp -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> AOp -> r
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> AOp -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> AOp -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> AOp -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> AOp -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> AOp -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AOp -> m AOp
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AOp -> m AOp
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AOp -> m AOp
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AOp -> m AOp
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AOp -> m AOp
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AOp -> m AOp
    Data, Typeable, (forall x. AOp -> Rep AOp x)
    -> (forall x. Rep AOp x -> AOp) -> Generic AOp
    forall x. Rep AOp x -> AOp
    forall x. AOp -> Rep AOp x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cfrom :: forall x. AOp -> Rep AOp x
    from :: forall x. AOp -> Rep AOp x
    $cto :: forall x. Rep AOp x -> AOp
    to :: forall x. Rep AOp x -> AOp
    Generic)

    instance NFData AOp

    -- | construct a JS variable reference
    var :: FastString -> JExpr
    var :: FastString -> JExpr
    var = Ident -> JExpr
    Var (Ident -> JExpr) -> (FastString -> Ident) -> FastString -> JExpr
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FastString -> Ident
    global

    -- | The JS literal 'true'
    true_ :: JExpr
    true_ :: JExpr
    true_ = JVal -> JExpr
    ValExpr (Bool -> JVal
    JBool Bool
    True)

    -- | The JS literal 'false'
    false_ :: JExpr
    false_ :: JExpr
    false_ = JVal -> JExpr
    ValExpr (Bool -> JVal
    JBool Bool
    False)