{-# 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 embeded 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 JNew
  , pattern JNot
  , pattern JNegate
  , pattern JAdd
  , pattern JSub
  , pattern JMul
  , pattern JDiv
  , pattern JMod
  , pattern JBOr
  , pattern JBAnd
  , pattern JBXor
  , pattern JBNot
  , pattern JLOr
  , pattern JLAnd
  , pattern SatInt
  , pattern JString
  , pattern JPreInc
  , pattern JPostInc
  , pattern JPreDec
  , pattern JPostDec
  -- * Utility
  , SaneDouble(..)
  , jassignAll
  , jassignAllEqual
  , jvar
  ) where

import GHC.Prelude

import GHC.JS.Unsat.Syntax (Ident(..))
import GHC.Data.FastString
import GHC.Types.Unique.Map
import GHC.Types.SaneDouble
import GHC.Utils.Misc

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 @JUOp@ and @JOp@ 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 JNew :: JExpr -> JExpr
pattern $mJNew :: forall {r}. JExpr -> (JExpr -> r) -> ((# #) -> r) -> r
$bJNew :: JExpr -> JExpr
JNew x = UOpExpr NewOp x

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-- | pattern synonym to create string values
pattern JString :: FastString -> JExpr
pattern $mJString :: forall {r}. JExpr -> (FastString -> r) -> ((# #) -> r) -> r
$bJString :: FastString -> JExpr
JString x = ValExpr (JStr 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
  | 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

--------------------------------------------------------------------------------
--                            Helper Functions
--------------------------------------------------------------------------------

jassignAllEqual :: [JExpr] -> [JExpr] -> JStat
jassignAllEqual :: [JExpr] -> [JExpr] -> JStat
jassignAllEqual [JExpr]
xs [JExpr]
ys = [JStat] -> JStat
forall a. Monoid a => [a] -> a
mconcat (String
-> (JExpr -> JExpr -> JStat) -> [JExpr] -> [JExpr] -> [JStat]
forall a b c.
HasDebugCallStack =>
String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithEqual String
"assignAllEqual" JExpr -> JExpr -> JStat
go [JExpr]
xs [JExpr]
ys)
  where go :: JExpr -> JExpr -> JStat
go JExpr
l JExpr
r = JExpr -> AOp -> JExpr -> JStat
AssignStat JExpr
l AOp
AssignOp JExpr
r

jassignAll :: [JExpr] -> [JExpr] -> JStat
jassignAll :: [JExpr] -> [JExpr] -> JStat
jassignAll [JExpr]
xs [JExpr]
ys = [JStat] -> JStat
forall a. Monoid a => [a] -> a
mconcat ([JStat] -> JStat) -> [JStat] -> JStat
forall a b. (a -> b) -> a -> b
$ (JExpr -> JExpr -> JStat) -> [JExpr] -> [JExpr] -> [JStat]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith JExpr -> JExpr -> JStat
go [JExpr]
xs [JExpr]
ys
  where go :: JExpr -> JExpr -> JStat
go JExpr
l JExpr
r = JExpr -> AOp -> JExpr -> JStat
AssignStat JExpr
l AOp
AssignOp JExpr
r

jvar :: FastString -> JExpr
jvar :: FastString -> JExpr
jvar = JVal -> JExpr
ValExpr (JVal -> JExpr) -> (FastString -> JVal) -> FastString -> JExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ident -> JVal
JVar (Ident -> JVal) -> (FastString -> Ident) -> FastString -> JVal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FastString -> Ident
TxtI