-- | Data types for the imperative core AST
module Language.PureScript.CoreImp.AST where

import Prelude

import Control.Monad ((>=>))
import Control.Monad.Identity (Identity(..), runIdentity)
import Data.Text (Text)

import Language.PureScript.AST (SourceSpan(..))
import Language.PureScript.Comments (Comment)
import Language.PureScript.Names (ModuleName)
import Language.PureScript.PSString (PSString)
import Language.PureScript.Traversals (sndM)

-- | Built-in unary operators
data UnaryOperator
  = Negate
  | Not
  | BitwiseNot
  | Positive
  | New
  deriving (Int -> UnaryOperator -> ShowS
[UnaryOperator] -> ShowS
UnaryOperator -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UnaryOperator] -> ShowS
$cshowList :: [UnaryOperator] -> ShowS
show :: UnaryOperator -> String
$cshow :: UnaryOperator -> String
showsPrec :: Int -> UnaryOperator -> ShowS
$cshowsPrec :: Int -> UnaryOperator -> ShowS
Show, UnaryOperator -> UnaryOperator -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnaryOperator -> UnaryOperator -> Bool
$c/= :: UnaryOperator -> UnaryOperator -> Bool
== :: UnaryOperator -> UnaryOperator -> Bool
$c== :: UnaryOperator -> UnaryOperator -> Bool
Eq)

-- | Built-in binary operators
data BinaryOperator
  = Add
  | Subtract
  | Multiply
  | Divide
  | Modulus
  | EqualTo
  | NotEqualTo
  | LessThan
  | LessThanOrEqualTo
  | GreaterThan
  | GreaterThanOrEqualTo
  | And
  | Or
  | BitwiseAnd
  | BitwiseOr
  | BitwiseXor
  | ShiftLeft
  | ShiftRight
  | ZeroFillShiftRight
  deriving (Int -> BinaryOperator -> ShowS
[BinaryOperator] -> ShowS
BinaryOperator -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BinaryOperator] -> ShowS
$cshowList :: [BinaryOperator] -> ShowS
show :: BinaryOperator -> String
$cshow :: BinaryOperator -> String
showsPrec :: Int -> BinaryOperator -> ShowS
$cshowsPrec :: Int -> BinaryOperator -> ShowS
Show, BinaryOperator -> BinaryOperator -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BinaryOperator -> BinaryOperator -> Bool
$c/= :: BinaryOperator -> BinaryOperator -> Bool
== :: BinaryOperator -> BinaryOperator -> Bool
$c== :: BinaryOperator -> BinaryOperator -> Bool
Eq)

-- | Data type for CoreImp comments, which can come from either the PureScript
-- source or internal transformations.
data CIComments
  = SourceComments [Comment]
  | PureAnnotation
  deriving (Int -> CIComments -> ShowS
[CIComments] -> ShowS
CIComments -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CIComments] -> ShowS
$cshowList :: [CIComments] -> ShowS
show :: CIComments -> String
$cshow :: CIComments -> String
showsPrec :: Int -> CIComments -> ShowS
$cshowsPrec :: Int -> CIComments -> ShowS
Show, CIComments -> CIComments -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CIComments -> CIComments -> Bool
$c/= :: CIComments -> CIComments -> Bool
== :: CIComments -> CIComments -> Bool
$c== :: CIComments -> CIComments -> Bool
Eq)

-- |
-- Indicates whether the initializer of a variable is known not to have side
-- effects, and thus can be inlined if needed or removed if unneeded.
--
data InitializerEffects = NoEffects | UnknownEffects deriving (Int -> InitializerEffects -> ShowS
[InitializerEffects] -> ShowS
InitializerEffects -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [InitializerEffects] -> ShowS
$cshowList :: [InitializerEffects] -> ShowS
show :: InitializerEffects -> String
$cshow :: InitializerEffects -> String
showsPrec :: Int -> InitializerEffects -> ShowS
$cshowsPrec :: Int -> InitializerEffects -> ShowS
Show, InitializerEffects -> InitializerEffects -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: InitializerEffects -> InitializerEffects -> Bool
$c/= :: InitializerEffects -> InitializerEffects -> Bool
== :: InitializerEffects -> InitializerEffects -> Bool
$c== :: InitializerEffects -> InitializerEffects -> Bool
Eq)

-- | Data type for simplified JavaScript expressions
data AST
  = NumericLiteral (Maybe SourceSpan) (Either Integer Double)
  -- ^ A numeric literal
  | StringLiteral (Maybe SourceSpan) PSString
  -- ^ A string literal
  | BooleanLiteral (Maybe SourceSpan) Bool
  -- ^ A boolean literal
  | Unary (Maybe SourceSpan) UnaryOperator AST
  -- ^ A unary operator application
  | Binary (Maybe SourceSpan) BinaryOperator AST AST
  -- ^ A binary operator application
  | ArrayLiteral (Maybe SourceSpan) [AST]
  -- ^ An array literal
  | Indexer (Maybe SourceSpan) AST AST
  -- ^ An array indexer expression
  | ObjectLiteral (Maybe SourceSpan) [(PSString, AST)]
  -- ^ An object literal
  | Function (Maybe SourceSpan) (Maybe Text) [Text] AST
  -- ^ A function introduction (optional name, arguments, body)
  | App (Maybe SourceSpan) AST [AST]
  -- ^ Function application
  | Var (Maybe SourceSpan) Text
  -- ^ Variable
  | ModuleAccessor (Maybe SourceSpan) ModuleName PSString
  -- ^ Value from another module
  | Block (Maybe SourceSpan) [AST]
  -- ^ A block of expressions in braces
  | VariableIntroduction (Maybe SourceSpan) Text (Maybe (InitializerEffects, AST))
  -- ^ A variable introduction and optional initialization
  | Assignment (Maybe SourceSpan) AST AST
  -- ^ A variable assignment
  | While (Maybe SourceSpan) AST AST
  -- ^ While loop
  | For (Maybe SourceSpan) Text AST AST AST
  -- ^ For loop
  | ForIn (Maybe SourceSpan) Text AST AST
  -- ^ ForIn loop
  | IfElse (Maybe SourceSpan) AST AST (Maybe AST)
  -- ^ If-then-else statement
  | Return (Maybe SourceSpan) AST
  -- ^ Return statement
  | ReturnNoResult (Maybe SourceSpan)
  -- ^ Return statement with no return value
  | Throw (Maybe SourceSpan) AST
  -- ^ Throw statement
  | InstanceOf (Maybe SourceSpan) AST AST
  -- ^ instanceof check
  | Comment CIComments AST
  -- ^ Commented JavaScript
  deriving (Int -> AST -> ShowS
[AST] -> ShowS
AST -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AST] -> ShowS
$cshowList :: [AST] -> ShowS
show :: AST -> String
$cshow :: AST -> String
showsPrec :: Int -> AST -> ShowS
$cshowsPrec :: Int -> AST -> ShowS
Show, AST -> AST -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AST -> AST -> Bool
$c/= :: AST -> AST -> Bool
== :: AST -> AST -> Bool
$c== :: AST -> AST -> Bool
Eq)

withSourceSpan :: SourceSpan -> AST -> AST
withSourceSpan :: SourceSpan -> AST -> AST
withSourceSpan SourceSpan
withSpan = AST -> AST
go where
  ss :: Maybe SourceSpan
  ss :: Maybe SourceSpan
ss = forall a. a -> Maybe a
Just SourceSpan
withSpan

  go :: AST -> AST
  go :: AST -> AST
go (NumericLiteral Maybe SourceSpan
_ Either Integer Double
n) = Maybe SourceSpan -> Either Integer Double -> AST
NumericLiteral Maybe SourceSpan
ss Either Integer Double
n
  go (StringLiteral Maybe SourceSpan
_ PSString
s) = Maybe SourceSpan -> PSString -> AST
StringLiteral Maybe SourceSpan
ss PSString
s
  go (BooleanLiteral Maybe SourceSpan
_ Bool
b) = Maybe SourceSpan -> Bool -> AST
BooleanLiteral Maybe SourceSpan
ss Bool
b
  go (Unary Maybe SourceSpan
_ UnaryOperator
op AST
j) = Maybe SourceSpan -> UnaryOperator -> AST -> AST
Unary Maybe SourceSpan
ss UnaryOperator
op AST
j
  go (Binary Maybe SourceSpan
_ BinaryOperator
op AST
j1 AST
j2) = Maybe SourceSpan -> BinaryOperator -> AST -> AST -> AST
Binary Maybe SourceSpan
ss BinaryOperator
op AST
j1 AST
j2
  go (ArrayLiteral Maybe SourceSpan
_ [AST]
js) = Maybe SourceSpan -> [AST] -> AST
ArrayLiteral Maybe SourceSpan
ss [AST]
js
  go (Indexer Maybe SourceSpan
_ AST
j1 AST
j2) = Maybe SourceSpan -> AST -> AST -> AST
Indexer Maybe SourceSpan
ss AST
j1 AST
j2
  go (ObjectLiteral Maybe SourceSpan
_ [(PSString, AST)]
js) = Maybe SourceSpan -> [(PSString, AST)] -> AST
ObjectLiteral Maybe SourceSpan
ss [(PSString, AST)]
js
  go (Function Maybe SourceSpan
_ Maybe Text
name [Text]
args AST
j) = Maybe SourceSpan -> Maybe Text -> [Text] -> AST -> AST
Function Maybe SourceSpan
ss Maybe Text
name [Text]
args AST
j
  go (App Maybe SourceSpan
_ AST
j [AST]
js) = Maybe SourceSpan -> AST -> [AST] -> AST
App Maybe SourceSpan
ss AST
j [AST]
js
  go (Var Maybe SourceSpan
_ Text
s) = Maybe SourceSpan -> Text -> AST
Var Maybe SourceSpan
ss Text
s
  go (ModuleAccessor Maybe SourceSpan
_ ModuleName
s1 PSString
s2) = Maybe SourceSpan -> ModuleName -> PSString -> AST
ModuleAccessor Maybe SourceSpan
ss ModuleName
s1 PSString
s2
  go (Block Maybe SourceSpan
_ [AST]
js) = Maybe SourceSpan -> [AST] -> AST
Block Maybe SourceSpan
ss [AST]
js
  go (VariableIntroduction Maybe SourceSpan
_ Text
name Maybe (InitializerEffects, AST)
j) = Maybe SourceSpan -> Text -> Maybe (InitializerEffects, AST) -> AST
VariableIntroduction Maybe SourceSpan
ss Text
name Maybe (InitializerEffects, AST)
j
  go (Assignment Maybe SourceSpan
_ AST
j1 AST
j2) = Maybe SourceSpan -> AST -> AST -> AST
Assignment Maybe SourceSpan
ss AST
j1 AST
j2
  go (While Maybe SourceSpan
_ AST
j1 AST
j2) = Maybe SourceSpan -> AST -> AST -> AST
While Maybe SourceSpan
ss AST
j1 AST
j2
  go (For Maybe SourceSpan
_ Text
name AST
j1 AST
j2 AST
j3) = Maybe SourceSpan -> Text -> AST -> AST -> AST -> AST
For Maybe SourceSpan
ss Text
name AST
j1 AST
j2 AST
j3
  go (ForIn Maybe SourceSpan
_ Text
name AST
j1 AST
j2) = Maybe SourceSpan -> Text -> AST -> AST -> AST
ForIn Maybe SourceSpan
ss Text
name AST
j1 AST
j2
  go (IfElse Maybe SourceSpan
_ AST
j1 AST
j2 Maybe AST
j3) = Maybe SourceSpan -> AST -> AST -> Maybe AST -> AST
IfElse Maybe SourceSpan
ss AST
j1 AST
j2 Maybe AST
j3
  go (Return Maybe SourceSpan
_ AST
js) = Maybe SourceSpan -> AST -> AST
Return Maybe SourceSpan
ss AST
js
  go (ReturnNoResult Maybe SourceSpan
_) = Maybe SourceSpan -> AST
ReturnNoResult Maybe SourceSpan
ss
  go (Throw Maybe SourceSpan
_ AST
js) = Maybe SourceSpan -> AST -> AST
Throw Maybe SourceSpan
ss AST
js
  go (InstanceOf Maybe SourceSpan
_ AST
j1 AST
j2) = Maybe SourceSpan -> AST -> AST -> AST
InstanceOf Maybe SourceSpan
ss AST
j1 AST
j2
  go c :: AST
c@Comment{} = AST
c

getSourceSpan :: AST -> Maybe SourceSpan
getSourceSpan :: AST -> Maybe SourceSpan
getSourceSpan = AST -> Maybe SourceSpan
go where
  go :: AST -> Maybe SourceSpan
  go :: AST -> Maybe SourceSpan
go (NumericLiteral Maybe SourceSpan
ss Either Integer Double
_) = Maybe SourceSpan
ss
  go (StringLiteral Maybe SourceSpan
ss PSString
_) = Maybe SourceSpan
ss
  go (BooleanLiteral Maybe SourceSpan
ss Bool
_) = Maybe SourceSpan
ss
  go (Unary Maybe SourceSpan
ss UnaryOperator
_ AST
_) = Maybe SourceSpan
ss
  go (Binary Maybe SourceSpan
ss BinaryOperator
_ AST
_ AST
_) = Maybe SourceSpan
ss
  go (ArrayLiteral Maybe SourceSpan
ss [AST]
_) = Maybe SourceSpan
ss
  go (Indexer Maybe SourceSpan
ss AST
_ AST
_) = Maybe SourceSpan
ss
  go (ObjectLiteral Maybe SourceSpan
ss [(PSString, AST)]
_) = Maybe SourceSpan
ss
  go (Function Maybe SourceSpan
ss Maybe Text
_ [Text]
_ AST
_) = Maybe SourceSpan
ss
  go (App Maybe SourceSpan
ss AST
_ [AST]
_) = Maybe SourceSpan
ss
  go (Var Maybe SourceSpan
ss Text
_) = Maybe SourceSpan
ss
  go (ModuleAccessor Maybe SourceSpan
ss ModuleName
_ PSString
_) = Maybe SourceSpan
ss
  go (Block Maybe SourceSpan
ss [AST]
_) = Maybe SourceSpan
ss
  go (VariableIntroduction Maybe SourceSpan
ss Text
_ Maybe (InitializerEffects, AST)
_) = Maybe SourceSpan
ss
  go (Assignment Maybe SourceSpan
ss AST
_ AST
_) = Maybe SourceSpan
ss
  go (While Maybe SourceSpan
ss AST
_ AST
_) = Maybe SourceSpan
ss
  go (For Maybe SourceSpan
ss Text
_ AST
_ AST
_ AST
_) = Maybe SourceSpan
ss
  go (ForIn Maybe SourceSpan
ss Text
_ AST
_ AST
_) = Maybe SourceSpan
ss
  go (IfElse Maybe SourceSpan
ss AST
_ AST
_ Maybe AST
_) = Maybe SourceSpan
ss
  go (Return Maybe SourceSpan
ss AST
_) = Maybe SourceSpan
ss
  go (ReturnNoResult Maybe SourceSpan
ss) = Maybe SourceSpan
ss
  go (Throw Maybe SourceSpan
ss AST
_) = Maybe SourceSpan
ss
  go (InstanceOf Maybe SourceSpan
ss AST
_ AST
_) = Maybe SourceSpan
ss
  go (Comment CIComments
_ AST
_) = forall a. Maybe a
Nothing

everywhere :: (AST -> AST) -> AST -> AST
everywhere :: (AST -> AST) -> AST -> AST
everywhere AST -> AST
f = AST -> AST
go where
  go :: AST -> AST
  go :: AST -> AST
go (Unary Maybe SourceSpan
ss UnaryOperator
op AST
j) = AST -> AST
f (Maybe SourceSpan -> UnaryOperator -> AST -> AST
Unary Maybe SourceSpan
ss UnaryOperator
op (AST -> AST
go AST
j))
  go (Binary Maybe SourceSpan
ss BinaryOperator
op AST
j1 AST
j2) = AST -> AST
f (Maybe SourceSpan -> BinaryOperator -> AST -> AST -> AST
Binary Maybe SourceSpan
ss BinaryOperator
op (AST -> AST
go AST
j1) (AST -> AST
go AST
j2))
  go (ArrayLiteral Maybe SourceSpan
ss [AST]
js) = AST -> AST
f (Maybe SourceSpan -> [AST] -> AST
ArrayLiteral Maybe SourceSpan
ss (forall a b. (a -> b) -> [a] -> [b]
map AST -> AST
go [AST]
js))
  go (Indexer Maybe SourceSpan
ss AST
j1 AST
j2) = AST -> AST
f (Maybe SourceSpan -> AST -> AST -> AST
Indexer Maybe SourceSpan
ss (AST -> AST
go AST
j1) (AST -> AST
go AST
j2))
  go (ObjectLiteral Maybe SourceSpan
ss [(PSString, AST)]
js) = AST -> AST
f (Maybe SourceSpan -> [(PSString, AST)] -> AST
ObjectLiteral Maybe SourceSpan
ss (forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AST -> AST
go) [(PSString, AST)]
js))
  go (Function Maybe SourceSpan
ss Maybe Text
name [Text]
args AST
j) = AST -> AST
f (Maybe SourceSpan -> Maybe Text -> [Text] -> AST -> AST
Function Maybe SourceSpan
ss Maybe Text
name [Text]
args (AST -> AST
go AST
j))
  go (App Maybe SourceSpan
ss AST
j [AST]
js) = AST -> AST
f (Maybe SourceSpan -> AST -> [AST] -> AST
App Maybe SourceSpan
ss (AST -> AST
go AST
j) (forall a b. (a -> b) -> [a] -> [b]
map AST -> AST
go [AST]
js))
  go (Block Maybe SourceSpan
ss [AST]
js) = AST -> AST
f (Maybe SourceSpan -> [AST] -> AST
Block Maybe SourceSpan
ss (forall a b. (a -> b) -> [a] -> [b]
map AST -> AST
go [AST]
js))
  go (VariableIntroduction Maybe SourceSpan
ss Text
name Maybe (InitializerEffects, AST)
j) = AST -> AST
f (Maybe SourceSpan -> Text -> Maybe (InitializerEffects, AST) -> AST
VariableIntroduction Maybe SourceSpan
ss Text
name (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AST -> AST
go) Maybe (InitializerEffects, AST)
j))
  go (Assignment Maybe SourceSpan
ss AST
j1 AST
j2) = AST -> AST
f (Maybe SourceSpan -> AST -> AST -> AST
Assignment Maybe SourceSpan
ss (AST -> AST
go AST
j1) (AST -> AST
go AST
j2))
  go (While Maybe SourceSpan
ss AST
j1 AST
j2) = AST -> AST
f (Maybe SourceSpan -> AST -> AST -> AST
While Maybe SourceSpan
ss (AST -> AST
go AST
j1) (AST -> AST
go AST
j2))
  go (For Maybe SourceSpan
ss Text
name AST
j1 AST
j2 AST
j3) = AST -> AST
f (Maybe SourceSpan -> Text -> AST -> AST -> AST -> AST
For Maybe SourceSpan
ss Text
name (AST -> AST
go AST
j1) (AST -> AST
go AST
j2) (AST -> AST
go AST
j3))
  go (ForIn Maybe SourceSpan
ss Text
name AST
j1 AST
j2) = AST -> AST
f (Maybe SourceSpan -> Text -> AST -> AST -> AST
ForIn Maybe SourceSpan
ss Text
name (AST -> AST
go AST
j1) (AST -> AST
go AST
j2))
  go (IfElse Maybe SourceSpan
ss AST
j1 AST
j2 Maybe AST
j3) = AST -> AST
f (Maybe SourceSpan -> AST -> AST -> Maybe AST -> AST
IfElse Maybe SourceSpan
ss (AST -> AST
go AST
j1) (AST -> AST
go AST
j2) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AST -> AST
go Maybe AST
j3))
  go (Return Maybe SourceSpan
ss AST
js) = AST -> AST
f (Maybe SourceSpan -> AST -> AST
Return Maybe SourceSpan
ss (AST -> AST
go AST
js))
  go (Throw Maybe SourceSpan
ss AST
js) = AST -> AST
f (Maybe SourceSpan -> AST -> AST
Throw Maybe SourceSpan
ss (AST -> AST
go AST
js))
  go (InstanceOf Maybe SourceSpan
ss AST
j1 AST
j2) = AST -> AST
f (Maybe SourceSpan -> AST -> AST -> AST
InstanceOf Maybe SourceSpan
ss (AST -> AST
go AST
j1) (AST -> AST
go AST
j2))
  go (Comment CIComments
com AST
j) = AST -> AST
f (CIComments -> AST -> AST
Comment CIComments
com (AST -> AST
go AST
j))
  go AST
other = AST -> AST
f AST
other

everywhereTopDown :: (AST -> AST) -> AST -> AST
everywhereTopDown :: (AST -> AST) -> AST -> AST
everywhereTopDown AST -> AST
f = forall a. Identity a -> a
runIdentity forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). Monad m => (AST -> m AST) -> AST -> m AST
everywhereTopDownM (forall a. a -> Identity a
Identity forall b c a. (b -> c) -> (a -> b) -> a -> c
. AST -> AST
f)

everywhereTopDownM :: (Monad m) => (AST -> m AST) -> AST -> m AST
everywhereTopDownM :: forall (m :: * -> *). Monad m => (AST -> m AST) -> AST -> m AST
everywhereTopDownM AST -> m AST
f = AST -> m AST
f forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> AST -> m AST
go where
  f' :: AST -> m AST
f' = AST -> m AST
f forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> AST -> m AST
go
  go :: AST -> m AST
go (Unary Maybe SourceSpan
ss UnaryOperator
op AST
j) = Maybe SourceSpan -> UnaryOperator -> AST -> AST
Unary Maybe SourceSpan
ss UnaryOperator
op forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j
  go (Binary Maybe SourceSpan
ss BinaryOperator
op AST
j1 AST
j2) = Maybe SourceSpan -> BinaryOperator -> AST -> AST -> AST
Binary Maybe SourceSpan
ss BinaryOperator
op forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AST -> m AST
f' AST
j2
  go (ArrayLiteral Maybe SourceSpan
ss [AST]
js) = Maybe SourceSpan -> [AST] -> AST
ArrayLiteral Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse AST -> m AST
f' [AST]
js
  go (Indexer Maybe SourceSpan
ss AST
j1 AST
j2) = Maybe SourceSpan -> AST -> AST -> AST
Indexer Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AST -> m AST
f' AST
j2
  go (ObjectLiteral Maybe SourceSpan
ss [(PSString, AST)]
js) = Maybe SourceSpan -> [(PSString, AST)] -> AST
ObjectLiteral Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (forall (f :: * -> *) b c a.
Functor f =>
(b -> f c) -> (a, b) -> f (a, c)
sndM AST -> m AST
f') [(PSString, AST)]
js
  go (Function Maybe SourceSpan
ss Maybe Text
name [Text]
args AST
j) = Maybe SourceSpan -> Maybe Text -> [Text] -> AST -> AST
Function Maybe SourceSpan
ss Maybe Text
name [Text]
args forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j
  go (App Maybe SourceSpan
ss AST
j [AST]
js) = Maybe SourceSpan -> AST -> [AST] -> AST
App Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse AST -> m AST
f' [AST]
js
  go (Block Maybe SourceSpan
ss [AST]
js) = Maybe SourceSpan -> [AST] -> AST
Block Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse AST -> m AST
f' [AST]
js
  go (VariableIntroduction Maybe SourceSpan
ss Text
name Maybe (InitializerEffects, AST)
j) = Maybe SourceSpan -> Text -> Maybe (InitializerEffects, AST) -> AST
VariableIntroduction Maybe SourceSpan
ss Text
name forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse AST -> m AST
f') Maybe (InitializerEffects, AST)
j
  go (Assignment Maybe SourceSpan
ss AST
j1 AST
j2) = Maybe SourceSpan -> AST -> AST -> AST
Assignment Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AST -> m AST
f' AST
j2
  go (While Maybe SourceSpan
ss AST
j1 AST
j2) = Maybe SourceSpan -> AST -> AST -> AST
While Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AST -> m AST
f' AST
j2
  go (For Maybe SourceSpan
ss Text
name AST
j1 AST
j2 AST
j3) = Maybe SourceSpan -> Text -> AST -> AST -> AST -> AST
For Maybe SourceSpan
ss Text
name forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AST -> m AST
f' AST
j2 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AST -> m AST
f' AST
j3
  go (ForIn Maybe SourceSpan
ss Text
name AST
j1 AST
j2) = Maybe SourceSpan -> Text -> AST -> AST -> AST
ForIn Maybe SourceSpan
ss Text
name forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AST -> m AST
f' AST
j2
  go (IfElse Maybe SourceSpan
ss AST
j1 AST
j2 Maybe AST
j3) = Maybe SourceSpan -> AST -> AST -> Maybe AST -> AST
IfElse Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AST -> m AST
f' AST
j2 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse AST -> m AST
f' Maybe AST
j3
  go (Return Maybe SourceSpan
ss AST
j) = Maybe SourceSpan -> AST -> AST
Return Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j
  go (Throw Maybe SourceSpan
ss AST
j) = Maybe SourceSpan -> AST -> AST
Throw Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j
  go (InstanceOf Maybe SourceSpan
ss AST
j1 AST
j2) = Maybe SourceSpan -> AST -> AST -> AST
InstanceOf Maybe SourceSpan
ss forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j1 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> AST -> m AST
f' AST
j2
  go (Comment CIComments
com AST
j) = CIComments -> AST -> AST
Comment CIComments
com forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> AST -> m AST
f' AST
j
  go AST
other = AST -> m AST
f AST
other

everything :: (r -> r -> r) -> (AST -> r) -> AST -> r
everything :: forall r. (r -> r -> r) -> (AST -> r) -> AST -> r
everything r -> r -> r
(<>.) AST -> r
f = AST -> r
go where
  go :: AST -> r
go j :: AST
j@(Unary Maybe SourceSpan
_ UnaryOperator
_ AST
j1) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1
  go j :: AST
j@(Binary Maybe SourceSpan
_ BinaryOperator
_ AST
j1 AST
j2) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1 r -> r -> r
<>. AST -> r
go AST
j2
  go j :: AST
j@(ArrayLiteral Maybe SourceSpan
_ [AST]
js) = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl r -> r -> r
(<>.) (AST -> r
f AST
j) (forall a b. (a -> b) -> [a] -> [b]
map AST -> r
go [AST]
js)
  go j :: AST
j@(Indexer Maybe SourceSpan
_ AST
j1 AST
j2) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1 r -> r -> r
<>. AST -> r
go AST
j2
  go j :: AST
j@(ObjectLiteral Maybe SourceSpan
_ [(PSString, AST)]
js) = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl r -> r -> r
(<>.) (AST -> r
f AST
j) (forall a b. (a -> b) -> [a] -> [b]
map (AST -> r
go forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd) [(PSString, AST)]
js)
  go j :: AST
j@(Function Maybe SourceSpan
_ Maybe Text
_ [Text]
_ AST
j1) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1
  go j :: AST
j@(App Maybe SourceSpan
_ AST
j1 [AST]
js) = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl r -> r -> r
(<>.) (AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1) (forall a b. (a -> b) -> [a] -> [b]
map AST -> r
go [AST]
js)
  go j :: AST
j@(Block Maybe SourceSpan
_ [AST]
js) = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl r -> r -> r
(<>.) (AST -> r
f AST
j) (forall a b. (a -> b) -> [a] -> [b]
map AST -> r
go [AST]
js)
  go j :: AST
j@(VariableIntroduction Maybe SourceSpan
_ Text
_ (Just (InitializerEffects
_, AST
j1))) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1
  go j :: AST
j@(Assignment Maybe SourceSpan
_ AST
j1 AST
j2) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1 r -> r -> r
<>. AST -> r
go AST
j2
  go j :: AST
j@(While Maybe SourceSpan
_ AST
j1 AST
j2) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1 r -> r -> r
<>. AST -> r
go AST
j2
  go j :: AST
j@(For Maybe SourceSpan
_ Text
_ AST
j1 AST
j2 AST
j3) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1 r -> r -> r
<>. AST -> r
go AST
j2 r -> r -> r
<>. AST -> r
go AST
j3
  go j :: AST
j@(ForIn Maybe SourceSpan
_ Text
_ AST
j1 AST
j2) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1 r -> r -> r
<>. AST -> r
go AST
j2
  go j :: AST
j@(IfElse Maybe SourceSpan
_ AST
j1 AST
j2 Maybe AST
Nothing) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1 r -> r -> r
<>. AST -> r
go AST
j2
  go j :: AST
j@(IfElse Maybe SourceSpan
_ AST
j1 AST
j2 (Just AST
j3)) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1 r -> r -> r
<>. AST -> r
go AST
j2 r -> r -> r
<>. AST -> r
go AST
j3
  go j :: AST
j@(Return Maybe SourceSpan
_ AST
j1) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1
  go j :: AST
j@(Throw Maybe SourceSpan
_ AST
j1) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1
  go j :: AST
j@(InstanceOf Maybe SourceSpan
_ AST
j1 AST
j2) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1 r -> r -> r
<>. AST -> r
go AST
j2
  go j :: AST
j@(Comment CIComments
_ AST
j1) = AST -> r
f AST
j r -> r -> r
<>. AST -> r
go AST
j1
  go AST
other = AST -> r
f AST
other