{-# LANGUAGE FlexibleContexts #-}
module Language.JS.Parser where

import Control.Applicative ((<|>))
import Control.Monad (liftM2)
import qualified Text.Parsec as P
import Language.JS.Types
import Language.JS.Common
import Language.JS.Operators

-- | Identifier name.
identifierName :: ParsecT String u Identity String
identifierName =
  (String -> String -> String)
-> ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 String -> String -> String
forall a. [a] -> [a] -> [a]
(++) (ParsecT String u Identity Char -> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"_$")) (ParsecT String u Identity Char -> ParsecT String u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
P.many1 ParsecT String u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.alphaNum)

-- | Parse identifier (no reserved words).
identifier :: ParsecT String u Identity Expression
identifier =
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> Expression
LI (String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (do String
i <- ParsecT String u Identity String
forall u. ParsecT String u Identity String
identifierName
                    case String
i String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
reservedWords of
                      Bool
True -> String -> ParsecT String u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
String -> ParsecT s u m a
P.unexpected String
"reserved word"
                      Bool
_    -> String -> ParsecT String u Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return String
i)) ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[identifier]"

-- | Parse numeric literal.
-- Here we don't distinguish between kinds.
numericLiteral :: ParsecT String u Identity Expression
numericLiteral =
  String -> Expression
LN (String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity String
binN ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity String
octN ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity String
hexN ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity String
forall u. ParsecT String u Identity String
decN)
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[number-literal]"
  where prefix :: String -> ParsecT s u m String
prefix String
p = do
          Char
i <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'0'
          Char
x <- String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
p
          String -> ParsecT s u m String
forall (m :: * -> *) a. Monad m => a -> m a
return [Char
i, Char
x]
        combine :: ParsecT String u Identity [a]
-> ParsecT String u Identity [a] -> ParsecT String u Identity [a]
combine = ([a] -> [a] -> [a])
-> ParsecT String u Identity [a]
-> ParsecT String u Identity [a]
-> ParsecT String u Identity [a]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++)
        hexN :: ParsecT String u Identity String
hexN = ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall a.
ParsecT String u Identity [a]
-> ParsecT String u Identity [a] -> ParsecT String u Identity [a]
combine (ParsecT String u Identity String
-> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
prefix String
"xX")) (ParsecT String u Identity Char -> ParsecT String u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
P.many1 (String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"0123456789abcdefABCDEF"))
        octN :: ParsecT String u Identity String
octN = ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall a.
ParsecT String u Identity [a]
-> ParsecT String u Identity [a] -> ParsecT String u Identity [a]
combine (ParsecT String u Identity String
-> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
prefix String
"oO")) (ParsecT String u Identity Char -> ParsecT String u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
P.many1 (String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"01234567"))
        binN :: ParsecT String u Identity String
binN = ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall a.
ParsecT String u Identity [a]
-> ParsecT String u Identity [a] -> ParsecT String u Identity [a]
combine (ParsecT String u Identity String
-> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
prefix String
"bB")) (ParsecT String u Identity Char -> ParsecT String u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
P.many1 (String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"01"))
        decN :: ParsecT String u Identity String
decN = do
          String
lead <- ParsecT String u Identity Char -> ParsecT String u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
P.many1 ParsecT String u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.digit
          String
fraction <- (Char -> String -> String)
-> ParsecT String u Identity Char
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'.') (ParsecT String u Identity Char -> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many ParsecT String u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.digit) ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String u Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return String
""
          String
expo <- ParsecT String u Identity String
forall u. ParsecT String u Identity String
expoN
          String -> ParsecT String u Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return (String
lead String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
fraction String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
expo)
        expoN :: ParsecT String u Identity String
expoN = (Char -> String -> String)
-> ParsecT String u Identity Char
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) (String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"eE") (ParsecT String u Identity Char -> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many ParsecT String u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
P.digit) ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String u Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return String
""

-- | Parse boolean literal.
booleanLiteral :: ParsecT String u Identity Expression
booleanLiteral =
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> ParsecT String u Identity Expression
forall u. String -> ParsecT String u Identity Expression
boolA String
"true" ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String u Identity Expression
forall u. String -> ParsecT String u Identity Expression
boolA String
"false")
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[boolean]"
  where boolA :: String -> ParsecT String u Identity Expression
boolA = (String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Bool -> Expression
LB (Bool -> Expression) -> (String -> Bool) -> String -> Expression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Bool
toHask) (ParsecT String u Identity String
 -> ParsecT String u Identity Expression)
-> (String -> ParsecT String u Identity String)
-> String
-> ParsecT String u Identity Expression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB
        toHask :: String -> Bool
toHask String
s | String
s String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"true" = Bool
True
                 | Bool
otherwise = Bool
False

-- | this identifier
thisIdent :: ParsecT String u Identity Expression
thisIdent =
  Expression -> String -> Expression
forall a b. a -> b -> a
const Expression
LThis (String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"this" ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[this]"

-- | null identifier
nullIdent :: ParsecT String u Identity Expression
nullIdent =
  Expression -> String -> Expression
forall a b. a -> b -> a
const Expression
LNull (String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"null" ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[null]"

-- | Parse string literal.
stringLiteral :: ParsecT String u Identity Expression
stringLiteral =
  Char -> ParsecT String u Identity Expression
forall u. Char -> ParsecT String u Identity Expression
buildExpression Char
'"'
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Char -> ParsecT String u Identity Expression
forall u. Char -> ParsecT String u Identity Expression
buildExpression Char
'\''
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [TemplateString] -> Expression
LTS ([TemplateString] -> Expression)
-> ParsecT String u Identity [TemplateString]
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'`' ParsecT String u Identity Char
-> ParsecT String u Identity [TemplateString]
-> ParsecT String u Identity [TemplateString]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String
-> [TemplateString] -> ParsecT String u Identity [TemplateString]
templateString String
"" [])
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[string-literal]"
  where
    buildExpression :: Char -> ParsecT String u Identity Expression
buildExpression Char
wc = do
      Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
wc
      String
content <- ParsecT String u Identity Char -> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String u Identity Char
forall u. ParsecT String u Identity Char
escaped ParsecT String u Identity Char
-> ParsecT String u Identity Char -> ParsecT String u Identity Char
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.noneOf [Char
wc, Char
'\n'])
      Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
wc
      Expression -> ParsecT String u Identity Expression
forall (m :: * -> *) a. Monad m => a -> m a
return (Expression -> ParsecT String u Identity Expression)
-> Expression -> ParsecT String u Identity Expression
forall a b. (a -> b) -> a -> b
$ String -> Expression
LS String
content
    escaped :: ParsecT String u Identity Char
escaped = do
      Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'\\'
      [ParsecT String u Identity Char] -> ParsecT String u Identity Char
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
P.choice ([ParsecT String u Identity Char]
 -> ParsecT String u Identity Char)
-> [ParsecT String u Identity Char]
-> ParsecT String u Identity Char
forall a b. (a -> b) -> a -> b
$ (Char -> Char -> ParsecT String u Identity Char)
-> String -> String -> [ParsecT String u Identity Char]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Char -> Char -> ParsecT String u Identity Char
forall s (m :: * -> *) b u.
Stream s m Char =>
Char -> b -> ParsecT s u m b
escapedChar String
codes String
replacements
    escapedChar :: Char -> b -> ParsecT s u m b
escapedChar Char
code b
replacement = do
      Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
code
      b -> ParsecT s u m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
replacement
    codes :: String
codes        = [Char
'b',  Char
'n',  Char
'f',  Char
'r',  Char
't',  Char
'\\', Char
'\"', Char
'\'']
    replacements :: String
replacements = [Char
'\b', Char
'\n', Char
'\f', Char
'\r', Char
'\t', Char
'\\', Char
'\"', Char
'\'']



-- | Parse template strings.
templateString :: String
-> [TemplateString] -> ParsecT String u Identity [TemplateString]
templateString String
str [TemplateString]
ls = (do
  Char
t <- ParsecT String u Identity Char
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m t
P.anyToken
  case Char
t of
    Char
'$' -> do
      TemplateString
e <- Expression -> TemplateString
TExpression (Expression -> TemplateString)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity TemplateString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
True)
      let s' :: [TemplateString]
s' = if String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then [String -> TemplateString
TString String
str, TemplateString
e] else [TemplateString
e]
      String
-> [TemplateString] -> ParsecT String u Identity [TemplateString]
templateString String
"" ([TemplateString]
ls [TemplateString] -> [TemplateString] -> [TemplateString]
forall a. [a] -> [a] -> [a]
++ [TemplateString]
s')
    Char
'`' -> [TemplateString] -> ParsecT String u Identity [TemplateString]
forall (m :: * -> *) a. Monad m => a -> m a
return ([TemplateString]
ls [TemplateString] -> [TemplateString] -> [TemplateString]
forall a. [a] -> [a] -> [a]
++ (if String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
str Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then [String -> TemplateString
TString String
str] else []))
    Char
_   -> String
-> [TemplateString] -> ParsecT String u Identity [TemplateString]
templateString (String
str String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
t]) [TemplateString]
ls) ParsecT String u Identity [TemplateString]
-> ParsecT String u Identity [TemplateString]
-> ParsecT String u Identity [TemplateString]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [TemplateString] -> ParsecT String u Identity [TemplateString]
forall (m :: * -> *) a. Monad m => a -> m a
return [TemplateString]
ls

-- | Parse regular expression literal.
regexLiteral :: ParsecT String u Identity Expression
regexLiteral =
  let re :: ParsecT String u Identity String
re = (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"/" ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> ParsecT String u Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return String
"") ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
           (do Char
es <- Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'\\' -- escaped char
               Char
t <- ParsecT String u Identity Char
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m t
P.anyToken
               String
n <- ParsecT String u Identity String
re
               String -> ParsecT String u Identity String
forall (m :: * -> *) a. Monad m => a -> m a
return (Char
esChar -> String -> String
forall a. a -> [a] -> [a]
:Char
tChar -> String -> String
forall a. a -> [a] -> [a]
:String
n)) ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
           ((Char -> String -> String)
-> ParsecT String u Identity Char
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) ParsecT String u Identity Char
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m t
P.anyToken ParsecT String u Identity String
re)
  in String -> String -> Expression
RegExp (String -> String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity (String -> Expression)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'/') ParsecT String u Identity Char
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity String
forall u. ParsecT String u Identity String
re) ParsecT String u Identity (String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Char -> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
"mgi")

-- | Parse elision (aka ',' without a value on array).
elision :: ParsecT String u Identity Expression
elision =
  Expression -> String -> Expression
forall a b. a -> b -> a
const Expression
Elision (String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
","
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"elision"

-- | Parse many items on a array declaration.
arrayItems :: [Expression] -> ParsecT String u Identity [Expression]
arrayItems [Expression]
ls =
  (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
elision ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
item) ParsecT String u Identity Expression
-> (Expression -> ParsecT String u Identity [Expression])
-> ParsecT String u Identity [Expression]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Expression
x -> [Expression] -> ParsecT String u Identity [Expression]
arrayItems ([Expression]
ls [Expression] -> [Expression] -> [Expression]
forall a. [a] -> [a] -> [a]
++ [Expression
x])) ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [Expression] -> ParsecT String u Identity [Expression]
forall (m :: * -> *) a. Monad m => a -> m a
return [Expression]
ls
  where item :: ParsecT String u Identity Expression
item = (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) b u.
Stream s m Char =>
(b -> b) -> ParsecT s u m b -> ParsecT s u m b
checkSpread Expression -> Expression
Spread (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False) ParsecT String u Identity Expression
-> ParsecT String u Identity ()
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String u Identity Char -> ParsecT String u Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
P.optional (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
',')

-- | Parse array literal.
arrayLiteral :: ParsecT String u Identity Expression
arrayLiteral =
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try ([Expression] -> Expression
LA ([Expression] -> Expression)
-> ParsecT String u Identity [Expression]
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
brackets (ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces ([Expression] -> ParsecT String u Identity [Expression]
arrayItems [])))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[array]"

-- | key and/or value property pair.
objectBinds :: ParsecT String u Identity ObjectProperty
objectBinds = do
  Maybe String
sp <- ParsecT String u Identity String
-> ParsecT String u Identity (Maybe String)
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"...")
  case Maybe String
sp of
    Just String
_ -> Expression -> ObjectProperty
OPI (Expression -> ObjectProperty)
-> (Expression -> Expression) -> Expression -> ObjectProperty
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expression -> Expression
Spread (Expression -> ObjectProperty)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ObjectProperty
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
literals
    Maybe String
Nothing -> (Expression -> ObjectProperty
OPM (Expression -> ObjectProperty)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ObjectProperty
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Expression
asyncMethodDef ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
classGetSetMethodDef ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
propertyMethodDef)) ParsecT String u Identity ObjectProperty
-> ParsecT String u Identity ObjectProperty
-> ParsecT String u Identity ObjectProperty
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (do
      Expression
k <- ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier
      Char
x <- ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
P.lookAhead (String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
P.oneOf String
",:}"))
      case Char
x of
        Char
':' -> ParsecT String u Identity ObjectProperty
-> ParsecT String u Identity ObjectProperty
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Expression -> Expression -> ObjectProperty
OPKV Expression
k (Expression -> ObjectProperty)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ObjectProperty
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
':') ParsecT String u Identity Char
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ((Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) b u.
Stream s m Char =>
(b -> b) -> ParsecT s u m b -> ParsecT s u m b
checkSpread Expression -> Expression
Spread (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False)) ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[object-value-expression]"))
        Char
_ -> ObjectProperty -> ParsecT String u Identity ObjectProperty
forall (m :: * -> *) a. Monad m => a -> m a
return (Expression -> ObjectProperty
OPI Expression
k))

-- | Parse object literal.
-- objectLiteral :: P.ParsecT s u m Expression
objectLiteral :: ParsecT String u Identity Expression
objectLiteral =
  [ObjectProperty] -> Expression
LO ([ObjectProperty] -> Expression)
-> ParsecT String u Identity [ObjectProperty]
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [ObjectProperty]
-> ParsecT String u Identity [ObjectProperty]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity [ObjectProperty]
-> ParsecT String u Identity [ObjectProperty]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (ParsecT String u Identity ObjectProperty
-> ParsecT String u Identity Char
-> ParsecT String u Identity [ObjectProperty]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
P.sepBy (ParsecT String u Identity ObjectProperty
-> ParsecT String u Identity ObjectProperty
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces ParsecT String u Identity ObjectProperty
objectBinds) (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
',')))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[object-literal]"

-- | Parse parenthesis expression.
parensExpression :: ParsecT String u Identity Expression
parensExpression =
  Expression -> Expression
LP (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
parens (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
True))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[parenthesis]"

-- | Check for spread operation before parse 'p'.
checkSpread :: (b -> b) -> ParsecT s u m b -> ParsecT s u m b
checkSpread b -> b
ctor ParsecT s u m b
p =
  do Maybe String
i <- ParsecT s u m String -> ParsecT s u m (Maybe String)
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"...")
     case Maybe String
i of
       Just String
_ -> b -> b
ctor (b -> b) -> ParsecT s u m b -> ParsecT s u m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m b
p
       Maybe String
Nothing -> ParsecT s u m b
p

-- | Parse used by function declarations.
formalParameter :: ParsecT String u Identity BindExpression
formalParameter =
  ParsecT String u Identity BindExpression
-> ParsecT String u Identity BindExpression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces ParsecT String u Identity BindExpression
bindExpression
  ParsecT String u Identity BindExpression
-> String -> ParsecT String u Identity BindExpression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[formal-parameters]"

-- | Parse function declaration
functionDeclaration :: ParsecT String u Identity Expression
functionDeclaration =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"function" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
    (ExpressionOpt -> [BindExpression] -> Statement -> Expression
Function (ExpressionOpt -> [BindExpression] -> Statement -> Expression)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT
     String u Identity ([BindExpression] -> Statement -> Expression)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier)
              ParsecT
  String u Identity ([BindExpression] -> Statement -> Expression)
-> ParsecT String u Identity [BindExpression]
-> ParsecT String u Identity (Statement -> Expression)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity [BindExpression]
-> ParsecT String u Identity [BindExpression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity [BindExpression]
-> ParsecT String u Identity [BindExpression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
parens (ParsecT String u Identity BindExpression
-> ParsecT String u Identity [BindExpression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [a]
commaSep ParsecT String u Identity BindExpression
formalParameter))
              ParsecT String u Identity (Statement -> Expression)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ([Statement] -> Statement
SBlock ([Statement] -> Statement)
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces (ParsecT String u Identity Statement
-> ParsecT String u Identity [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Statement
statements)))))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[function]"

-- | Prase arrow function declaration.
arrowFunctionDeclaration :: ParsecT String u Identity Expression
arrowFunctionDeclaration =
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Either BindExpression [BindExpression] -> Statement -> Expression
Arrow (Either BindExpression [BindExpression] -> Statement -> Expression)
-> ParsecT
     String u Identity (Either BindExpression [BindExpression])
-> ParsecT String u Identity (Statement -> Expression)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity (Either BindExpression [BindExpression])
-> ParsecT
     String u Identity (Either BindExpression [BindExpression])
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity (Either BindExpression [BindExpression])
-> ParsecT
     String u Identity (Either BindExpression [BindExpression])
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
parens ParsecT String u Identity (Either BindExpression [BindExpression])
forall a. ParsecT String u Identity (Either a [BindExpression])
manyParams ParsecT String u Identity (Either BindExpression [BindExpression])
-> ParsecT
     String u Identity (Either BindExpression [BindExpression])
-> ParsecT
     String u Identity (Either BindExpression [BindExpression])
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity (Either BindExpression [BindExpression])
forall b. ParsecT String u Identity (Either BindExpression b)
singleParam) ParsecT String u Identity (Either BindExpression [BindExpression])
-> ParsecT String u Identity String
-> ParsecT
     String u Identity (Either BindExpression [BindExpression])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"=>")
               ParsecT String u Identity (Statement -> Expression)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
blockOrStatements)
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[arrow-function]"
  where singleParam :: ParsecT String u Identity (Either BindExpression b)
singleParam = BindExpression -> Either BindExpression b
forall a b. a -> Either a b
Left (BindExpression -> Either BindExpression b)
-> ParsecT String u Identity BindExpression
-> ParsecT String u Identity (Either BindExpression b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity BindExpression
bindVar
        manyParams :: ParsecT String u Identity (Either a [BindExpression])
manyParams = [BindExpression] -> Either a [BindExpression]
forall a b. b -> Either a b
Right ([BindExpression] -> Either a [BindExpression])
-> ParsecT String u Identity [BindExpression]
-> ParsecT String u Identity (Either a [BindExpression])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity BindExpression
-> ParsecT String u Identity [BindExpression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [a]
commaSep ParsecT String u Identity BindExpression
formalParameter

-- | Parse any kind of funcion declaration (function or arrow function).
functionExpression :: ParsecT String u Identity Expression
functionExpression =
  ParsecT String u Identity Expression
arrowFunctionDeclaration ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
functionDeclaration

-- | Parse property method of a class or object literal.
propertyMethodDef :: ParsecT String u Identity Expression
propertyMethodDef =
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Expression -> [BindExpression] -> Statement -> Expression
PropertyMethod (Expression -> [BindExpression] -> Statement -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT
     String u Identity ([BindExpression] -> Statement -> Expression)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier
                        ParsecT
  String u Identity ([BindExpression] -> Statement -> Expression)
-> ParsecT String u Identity [BindExpression]
-> ParsecT String u Identity (Statement -> Expression)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity [BindExpression]
-> ParsecT String u Identity [BindExpression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity [BindExpression]
-> ParsecT String u Identity [BindExpression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
parens (ParsecT String u Identity BindExpression
-> ParsecT String u Identity [BindExpression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [a]
commaSep ParsecT String u Identity BindExpression
formalParameter))
                        ParsecT String u Identity (Statement -> Expression)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ([Statement] -> Statement
SBlock ([Statement] -> Statement)
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (ParsecT String u Identity String
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m String
whiteSpaces ParsecT String u Identity String
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Statement
-> ParsecT String u Identity [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Statement
statements))))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[class-method-definition]"

-- | Parse a static property of a class.
classStaticDef :: ParsecT String u Identity Expression
classStaticDef =
  ParsecT String u Identity String
-> ParsecT String u Identity String
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"static") ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
    (Expression -> Expression
ClassStatic (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Expression
propertyMethodDef ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
classPropertyDef))

-- | Parse a getter or setter method.
classGetSetMethodDef :: ParsecT String u Identity Expression
classGetSetMethodDef =
  (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"set" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Expression -> Expression
ClassSetMethod (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
propertyMethodDef)) ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"get" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Expression -> Expression
ClassGetMethod (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
propertyMethodDef))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[class-get-set-definition]"

-- | Check for a async property method.
asyncMethodDef :: ParsecT String u Identity Expression
asyncMethodDef =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"async" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Expression -> Expression
Async (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
propertyMethodDef)
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[async-definition]"

-- | Parse a class property definition.
classPropertyDef :: ParsecT String u Identity Expression
classPropertyDef =
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Expression -> Expression -> Expression
ClassProperty (Expression -> Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity (Expression -> Expression)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier ParsecT String u Identity Expression
-> ParsecT String u Identity Char
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'=' ParsecT String u Identity Expression
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String u Identity String
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m String
whiteSpaces)
                       ParsecT String u Identity (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[class-property]"

-- | Parse a class declaration.
classDeclaration :: ParsecT String u Identity Expression
classDeclaration =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"class" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ExpressionOpt -> ExpressionOpt -> Statement -> Expression
Class (ExpressionOpt -> ExpressionOpt -> Statement -> Expression)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT
     String u Identity (ExpressionOpt -> Statement -> Expression)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier))
                             ParsecT
  String u Identity (ExpressionOpt -> Statement -> Expression)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity (Statement -> Expression)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"extends" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier)
                             ParsecT String u Identity (Statement -> Expression)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ([Statement] -> Statement
SBlock ([Statement] -> Statement)
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (ParsecT String u Identity String
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m String
whiteSpaces ParsecT String u Identity String
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity [Statement]
classBlock)))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[class-expression]"
  where classBlock :: ParsecT String u Identity [Statement]
classBlock = ParsecT String u Identity Statement
-> ParsecT String u Identity [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (Expression -> Statement
toStatement (Expression -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
classBlockDecls))
        classBlockDecls :: ParsecT String u Identity Expression
classBlockDecls = (ParsecT String u Identity Expression
classPropertyDef
                            ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
asyncMethodDef
                            ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
classStaticDef
                            ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
classGetSetMethodDef
                            ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
propertyMethodDef)

-- | Dot member.
dotMember :: Expression -> ParsecT String u Identity Expression
dotMember Expression
p =
  Expression -> Expression -> Expression
Dot Expression
p (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'.') ParsecT String u Identity Char
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier)
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[dot-expression]"

-- | Array like accessor.
accessor :: Expression -> ParsecT String u Identity Expression
accessor Expression
p =
  Expression -> Expression -> Expression
Acc Expression
p (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
brackets (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
True))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[array-expression]"

-- | Function call.
functionCall :: Expression -> ParsecT String u Identity Expression
functionCall Expression
p =
  Expression -> [Expression] -> Expression
FCall Expression
p ([Expression] -> Expression)
-> ParsecT String u Identity [Expression]
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
parens (ParsecT String u Identity Expression
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [a]
commaSep (ParsecT String u Identity String
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m String
whiteSpaces ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False)))
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[function-call]"

-- | new
newIdent :: ParsecT String u Identity (Maybe a)
newIdent =
  Maybe a -> String -> Maybe a
forall a b. a -> b -> a
const Maybe a
forall a. Maybe a
Nothing (String -> Maybe a)
-> ParsecT String u Identity String
-> ParsecT String u Identity (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"new" ParsecT String u Identity (Maybe a)
-> String -> ParsecT String u Identity (Maybe a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[new]"

-- | Parse member expression.
memberExpression :: ExpressionOpt -> ParsecT String u Identity Expression
memberExpression (Just Expression
p) =
  (do Expression
dt <- (Expression -> ParsecT String u Identity Expression
functionCall Expression
p ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Expression -> ParsecT String u Identity Expression
forall u. Expression -> ParsecT String u Identity Expression
dotMember Expression
p ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Expression -> ParsecT String u Identity Expression
accessor Expression
p) ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[member-expression]"
      ExpressionOpt -> ParsecT String u Identity Expression
memberExpression (Expression -> ExpressionOpt
forall a. a -> Maybe a
Just Expression
dt)) ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Expression -> ParsecT String u Identity Expression
forall (m :: * -> *) a. Monad m => a -> m a
return Expression
p
memberExpression ExpressionOpt
Nothing =
  (Expression -> Expression
New (Expression -> Expression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
expressions) ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[new-expression]"

-- | Parse literals.
literals :: ParsecT String u Identity Expression
literals =
  ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
thisIdent
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
nullIdent
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
booleanLiteral
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
stringLiteral
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
arrayLiteral
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
objectLiteral
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
regexLiteral
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
numericLiteral
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier

-- | Parse primary expressions.
primaryExpression :: ParsecT String u Identity Expression
primaryExpression =
  ParsecT String u Identity Expression
literals
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
functionDeclaration
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
classDeclaration
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
parensExpression

-- | Check for maybe semi.
-- TODO: There are some rules for expression termination...need to check that.
maybeSemi :: ParsecT String u Identity ()
maybeSemi =
  ParsecT String u Identity Char -> ParsecT String u Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
P.optional (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
';')

-- | Parse a empty expression.
emptyExpression :: ParsecT String u Identity Expression
emptyExpression =
  (Expression -> Char -> Expression
forall a b. a -> b -> a
const Expression
Empty) (Char -> Expression)
-> ParsecT String u Identity Char
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
';')
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[empty-expressions]"

-- | Parse rules for left hand side expression.
leftHandSideExpression :: ParsecT String u Identity Expression
leftHandSideExpression =
  (ParsecT String u Identity ExpressionOpt
forall u a. ParsecT String u Identity (Maybe a)
newIdent ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity ExpressionOpt
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Expression -> ExpressionOpt
forall a. a -> Maybe a
Just (Expression -> ExpressionOpt)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
primaryExpression)) ParsecT String u Identity ExpressionOpt
-> (ExpressionOpt -> ParsecT String u Identity Expression)
-> ParsecT String u Identity Expression
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ExpressionOpt -> ParsecT String u Identity Expression
memberExpression
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"left-hand-side-expression"

-- | Parse expressions.
expressions :: ParsecT String u Identity Expression
expressions =
  ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
emptyExpression ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
True ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[expressions]"

-- | Parse single line comment.
comment :: ParsecT String u Identity Expression
comment =
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> Expression
Comment (String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"//" ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Char -> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many ((Char -> Bool) -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
P.satisfy (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\n'))))

-- | Parse multiline comment.
multilineComment :: ParsecT String u Identity Expression
multilineComment =
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> Expression
MultilineComment (String -> Expression)
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
P.between (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"/*") (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
P.string String
"*/") (ParsecT String u Identity Char -> ParsecT String u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many ParsecT String u Identity Char
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m t
P.anyToken)))

-- | Parse comment like an expression.
commentExpression :: ParsecT String u Identity Expression
commentExpression =
  ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
comment ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
multilineComment

-- | Parse expressions excluding emptyExpression.
expressionNonEmpty :: Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
notComma =
  ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
commentExpression
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
functionExpression
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
classDeclaration
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Bool
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u.
Stream s m Char =>
Bool
-> ParsecT s u m Expression
-> ParsecT s u m Expression
-> ParsecT s u m Expression
operationExpression Bool
notComma (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
notComma) ParsecT String u Identity Expression
leftHandSideExpression)
  ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
primaryExpression
  ParsecT String u Identity Expression
-> String -> ParsecT String u Identity Expression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[non-empty-expressions]"

-- | Convert a expression into a statement.
toStatement :: Expression -> Statement
toStatement :: Expression -> Statement
toStatement (Function (Just (LI String
a)) [BindExpression]
b Statement
c) = String -> [BindExpression] -> Statement -> Statement
SF String
a [BindExpression]
b Statement
c
toStatement (Class (Just (LI String
a)) ExpressionOpt
b Statement
c)    = String -> ExpressionOpt -> Statement -> Statement
SC String
a ExpressionOpt
b Statement
c
toStatement Expression
a                            = Expression -> Statement
SExp Expression
a

-- Statements

-- | Parse import namespace clauses.
importNamespaceClause :: ParsecT String u Identity ImportClause
importNamespaceClause =
  Expression -> ImportClause
Namespace (Expression -> ImportClause)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ImportClause
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"*" ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"as") ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier)

-- | Parse import bind clauses.
importBindClause :: ParsecT String u Identity ImportClause
importBindClause =
  [Expression] -> ImportClause
BindNames ([Expression] -> ImportClause)
-> ParsecT String u Identity [Expression]
-> ParsecT String u Identity ImportClause
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (ParsecT String u Identity Expression
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [a]
commaSep (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier))

-- | Parse default clauses.
importDefaultNameClause :: ParsecT String u Identity ImportClause
importDefaultNameClause =
  Expression -> ImportClause
DefaultName (Expression -> ImportClause)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ImportClause
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier

-- | Parse import clauses excluding namespace clause.
importManyClauses :: ParsecT String u Identity [ImportClause]
importManyClauses =
  ParsecT String u Identity ImportClause
-> ParsecT String u Identity [ImportClause]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [a]
commaSep1 (ParsecT String u Identity String
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m String
whiteSpaces ParsecT String u Identity String
-> ParsecT String u Identity ImportClause
-> ParsecT String u Identity ImportClause
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ParsecT String u Identity ImportClause
forall u. ParsecT String u Identity ImportClause
importBindClause ParsecT String u Identity ImportClause
-> ParsecT String u Identity ImportClause
-> ParsecT String u Identity ImportClause
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity ImportClause
forall u. ParsecT String u Identity ImportClause
importDefaultNameClause))

-- | Parse all import clauses.
importClauses :: ParsecT String u Identity (Either ImportClause [ImportClause])
importClauses =
  (ImportClause -> Either ImportClause [ImportClause]
forall a b. a -> Either a b
Left (ImportClause -> Either ImportClause [ImportClause])
-> ParsecT String u Identity ImportClause
-> ParsecT String u Identity (Either ImportClause [ImportClause])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity ImportClause
forall u. ParsecT String u Identity ImportClause
importNamespaceClause) ParsecT String u Identity (Either ImportClause [ImportClause])
-> ParsecT String u Identity (Either ImportClause [ImportClause])
-> ParsecT String u Identity (Either ImportClause [ImportClause])
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
  ([ImportClause] -> Either ImportClause [ImportClause]
forall a b. b -> Either a b
Right ([ImportClause] -> Either ImportClause [ImportClause])
-> ParsecT String u Identity [ImportClause]
-> ParsecT String u Identity (Either ImportClause [ImportClause])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [ImportClause]
forall u. ParsecT String u Identity [ImportClause]
importManyClauses)

-- | Parse import file statement.
importFileStatement :: ParsecT String u Identity Statement
importFileStatement =
  Expression -> Statement
SImportFile (Expression -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
stringLiteral

-- | Parse import statement.
importStatement :: ParsecT String u Identity Statement
importStatement =
  Either ImportClause [ImportClause] -> Expression -> Statement
SImport (Either ImportClause [ImportClause] -> Expression -> Statement)
-> ParsecT String u Identity (Either ImportClause [ImportClause])
-> ParsecT String u Identity (Expression -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity (Either ImportClause [ImportClause])
-> ParsecT String u Identity (Either ImportClause [ImportClause])
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity (Either ImportClause [ImportClause])
forall u.
ParsecT String u Identity (Either ImportClause [ImportClause])
importClauses ParsecT String u Identity (Either ImportClause [ImportClause])
-> ParsecT String u Identity String
-> ParsecT String u Identity (Either ImportClause [ImportClause])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"from") ParsecT String u Identity (Expression -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
stringLiteral

-- | Parse import statements.
importStatements :: ParsecT String u Identity Statement
importStatements =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"import" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
importStatement ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
importFileStatement)
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[import-statement]"

reexportStatement :: ParsecT String u Identity Statement
reexportStatement = ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (Expression -> Expression -> Statement
SRExport (Expression -> Expression -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity (Expression -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (Bool -> ParsecT String u Identity Expression
forall u. Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False) ParsecT String u Identity Expression
-> ParsecT String u Identity String
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"from") ParsecT String u Identity (Expression -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
stringLiteral)
exportDefaultStatement :: ParsecT String u Identity Statement
exportDefaultStatement = String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"default" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Expression -> Statement
SExportDefault (Expression -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> ParsecT String u Identity Expression
forall u. Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False)
exportStatement :: ParsecT String u Identity Statement
exportStatement = Statement -> Statement
SExport (Statement -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
statements

-- | Parse export statements.
exportStatements :: ParsecT String u Identity Statement
exportStatements = String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"export" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
reexportStatement ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
exportDefaultStatement ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
exportStatement)
                   ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[export-statement]"

-- | Parse continue statement.
continueStatement :: ParsecT String u Identity Statement
continueStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"continue" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ExpressionOpt -> Statement
SContinue (ExpressionOpt -> Statement)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier))
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[continue-statement]"

-- | Parse break statement.
breakStatement :: ParsecT String u Identity Statement
breakStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"break" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ExpressionOpt -> Statement
SBreak (ExpressionOpt -> Statement)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier))
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[break-statement]"

-- | Parse block statement.
blockStatement :: ParsecT s u m Statement -> ParsecT s u m Statement
blockStatement ParsecT s u m Statement
allowedStmt =
  [Statement] -> Statement
SBlock ([Statement] -> Statement)
-> ParsecT s u m [Statement] -> ParsecT s u m Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m [Statement] -> ParsecT s u m [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (ParsecT s u m [Statement] -> ParsecT s u m [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (ParsecT s u m [Statement] -> ParsecT s u m [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces (ParsecT s u m Statement -> ParsecT s u m [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many ParsecT s u m Statement
allowedStmt)))
  ParsecT s u m Statement -> String -> ParsecT s u m Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[block-statement]"

blockOrStatements :: ParsecT String u Identity Statement
blockOrStatements =
  [Statement] -> Statement
SBlock ([Statement] -> Statement)
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (ParsecT String u Identity String
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m String
whiteSpaces ParsecT String u Identity String
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Statement
-> ParsecT String u Identity [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Statement
statements)) ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
statements

-- | Parse if statement.
ifStatement :: ParsecT String u Identity Statement
ifStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"if" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Expression -> Statement -> StatementOpt -> Statement
SIf (Expression -> Statement -> StatementOpt -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT
     String u Identity (Statement -> StatementOpt -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
parensExpression)
                        ParsecT String u Identity (Statement -> StatementOpt -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity (StatementOpt -> Statement)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Statement
blockOrStatements
                        ParsecT String u Identity (StatementOpt -> Statement)
-> ParsecT String u Identity StatementOpt
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
-> ParsecT String u Identity StatementOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"else" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Statement
blockOrStatements))
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[if-statement]"

-- | Parse catch part of try statement.
catchBlock :: ParsecT String u Identity Statement
catchBlock =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"catch" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ExpressionOpt -> Statement -> Statement
SCatch (ExpressionOpt -> Statement -> Statement)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity (Statement -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe ParsecT String u Identity Expression
parensExpression)
                              ParsecT String u Identity (Statement -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u.
Stream s m Char =>
ParsecT s u m Statement -> ParsecT s u m Statement
blockStatement ParsecT String u Identity Statement
statements)
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[try/catch-statement]"

-- | Parse finally part of try statement.
finallyBlock :: ParsecT String u Identity Statement
finallyBlock =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"finally" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Statement -> Statement
SFinally (Statement -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u.
Stream s m Char =>
ParsecT s u m Statement -> ParsecT s u m Statement
blockStatement ParsecT String u Identity Statement
statements))
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[try/catch/finally-statement]"

-- | Parse try statement.
tryStatement :: ParsecT String u Identity Statement
tryStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"try" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Statement -> Statement -> StatementOpt -> Statement
STry (Statement -> Statement -> StatementOpt -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT
     String u Identity (Statement -> StatementOpt -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u.
Stream s m Char =>
ParsecT s u m Statement -> ParsecT s u m Statement
blockStatement ParsecT String u Identity Statement
statements)
                          ParsecT String u Identity (Statement -> StatementOpt -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity (StatementOpt -> Statement)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
catchBlock
                          ParsecT String u Identity (StatementOpt -> Statement)
-> ParsecT String u Identity StatementOpt
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
-> ParsecT String u Identity StatementOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe ParsecT String u Identity Statement
finallyBlock)
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[try-statement]"

-- | Parse throw statement.
throwStatement :: ParsecT String u Identity Statement
throwStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"throw" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Expression -> Statement
SThrow (Expression -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False))
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[throw-statement]"

-- | Parse return statement.
returnStatement :: ParsecT String u Identity Statement
returnStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"return" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Expression -> Statement
SReturn (Expression -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
expressions)
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[return-statement]"

bindVar :: ParsecT String u Identity BindExpression
bindVar =
  Expression -> ExpressionOpt -> BindExpression
BindVar (Expression -> ExpressionOpt -> BindExpression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity (ExpressionOpt -> BindExpression)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier ParsecT String u Identity (ExpressionOpt -> BindExpression)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity BindExpression
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (ParsecT String u Identity String -> ParsecT String u Identity ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
P.notFollowedBy (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"=>") ParsecT String u Identity ()
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'=') ParsecT String u Identity Char
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False)))
bindPatternDecl :: ParsecT String u Identity BindExpression
bindPatternDecl =
  Expression -> ExpressionOpt -> BindExpression
BindPattern (Expression -> ExpressionOpt -> BindExpression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity (ExpressionOpt -> BindExpression)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity Expression
objectLiteral ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Expression
arrayLiteral)) ParsecT String u Identity (ExpressionOpt -> BindExpression)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity BindExpression
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (ParsecT String u Identity Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'=') ParsecT String u Identity Char
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False))
bindSpread :: ParsecT String u Identity BindExpression
bindSpread =
  Expression -> BindExpression
BindRest (Expression -> BindExpression)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity BindExpression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"..." ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Expression
leftHandSideExpression)
bindExpression :: ParsecT String u Identity BindExpression
bindExpression =
  (ParsecT String u Identity BindExpression
bindVar ParsecT String u Identity BindExpression
-> ParsecT String u Identity BindExpression
-> ParsecT String u Identity BindExpression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity BindExpression
bindPatternDecl ParsecT String u Identity BindExpression
-> ParsecT String u Identity BindExpression
-> ParsecT String u Identity BindExpression
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity BindExpression
bindSpread) ParsecT String u Identity BindExpression
-> String -> ParsecT String u Identity BindExpression
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[var-binds]"

constVariableStatement :: ParsecT String u Identity Statement
constVariableStatement =
  ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> [BindExpression] -> Statement
SVariable (String -> [BindExpression] -> Statement)
-> ParsecT String u Identity String
-> ParsecT String u Identity ([BindExpression] -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"const") ParsecT String u Identity ([BindExpression] -> Statement)
-> ParsecT String u Identity [BindExpression]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity BindExpression
-> ParsecT String u Identity [BindExpression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [a]
commaSep1 (ParsecT String u Identity BindExpression
-> ParsecT String u Identity BindExpression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces ParsecT String u Identity BindExpression
bindExpression))
notConstVariableStatement :: ParsecT String u Identity Statement
notConstVariableStatement =
  ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> [BindExpression] -> Statement
SVariable (String -> [BindExpression] -> Statement)
-> ParsecT String u Identity String
-> ParsecT String u Identity ([BindExpression] -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"let" ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"var") ParsecT String u Identity ([BindExpression] -> Statement)
-> ParsecT String u Identity [BindExpression]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity BindExpression
-> ParsecT String u Identity [BindExpression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [a]
commaSep1 (ParsecT String u Identity BindExpression
-> ParsecT String u Identity BindExpression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces ParsecT String u Identity BindExpression
bindExpression))

-- | Parse variable statement.
variableStatement :: ParsecT String u Identity Statement
variableStatement =
  ParsecT String u Identity Statement
constVariableStatement ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
notConstVariableStatement ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[variable-statement]"

-- | Parse case clause switch statement.
caseClause :: ParsecT String u Identity SwitchCase
caseClause =
  ParsecT String u Identity SwitchCase
-> ParsecT String u Identity SwitchCase
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ((ParsecT String u Identity SwitchCase
caseB ParsecT String u Identity SwitchCase
-> ParsecT String u Identity SwitchCase
-> ParsecT String u Identity SwitchCase
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity SwitchCase
forall u. ParsecT String u Identity SwitchCase
defaultCase) ParsecT String u Identity SwitchCase
-> ParsecT String u Identity Char
-> ParsecT String u Identity SwitchCase
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
':'))
  ParsecT String u Identity SwitchCase
-> String -> ParsecT String u Identity SwitchCase
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[switch/case-expression]"
  where defaultCase :: ParsecT String u Identity SwitchCase
defaultCase = SwitchCase -> String -> SwitchCase
forall a b. a -> b -> a
const SwitchCase
DefaultCase (String -> SwitchCase)
-> ParsecT String u Identity String
-> ParsecT String u Identity SwitchCase
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"default")
        caseB :: ParsecT String u Identity SwitchCase
caseB       = String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"case" ParsecT String u Identity String
-> ParsecT String u Identity SwitchCase
-> ParsecT String u Identity SwitchCase
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Expression -> SwitchCase
Case (Expression -> SwitchCase)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity SwitchCase
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
literals)

-- | Parse case clause switch statement.
caseDeclaration :: ParsecT String u Identity Statement
caseDeclaration =
  [SwitchCase] -> [Statement] -> Statement
SCase ([SwitchCase] -> [Statement] -> Statement)
-> ParsecT String u Identity [SwitchCase]
-> ParsecT String u Identity ([Statement] -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [SwitchCase]
-> ParsecT String u Identity [SwitchCase]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity SwitchCase
-> ParsecT String u Identity [SwitchCase]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
P.many1 ParsecT String u Identity SwitchCase
caseClause)
        ParsecT String u Identity ([Statement] -> Statement)
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
-> ParsecT String u Identity [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ((ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
breakStatement ParsecT String u Identity Statement
-> ParsecT String u Identity ()
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String u Identity ()
forall u. ParsecT String u Identity ()
maybeSemi) ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
statements))

-- | Parse switch statement.
switchStatement :: ParsecT String u Identity Statement
switchStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"switch" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
    (Expression -> [Statement] -> Statement
SSwitch (Expression -> [Statement] -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ([Statement] -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Expression
parensExpression
             ParsecT String u Identity ([Statement] -> Statement)
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces (ParsecT String u Identity Statement
-> ParsecT String u Identity [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many ParsecT String u Identity Statement
caseDeclaration)))
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[switch-statement]"

-- | Parse debugger statement.
debuggerStatement :: ParsecT String u Identity Statement
debuggerStatement =
  Statement -> String -> Statement
forall a b. a -> b -> a
const Statement
SDebugger (String -> Statement)
-> ParsecT String u Identity String
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"debugger"
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[debugger-statement]"

-- | Parse breakable statement.
-- TODO: this parser can be improved to parse vaild javascript code
-- by passing to the break statement to subsequent statements.
breakableStatement :: ParsecT String u Identity Statement
breakableStatement =
  ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u.
Stream s m Char =>
ParsecT s u m Statement -> ParsecT s u m Statement
blockStatement ((ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
breakStatement ParsecT String u Identity Statement
-> ParsecT String u Identity ()
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String u Identity ()
forall u. ParsecT String u Identity ()
maybeSemi) ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
statements) ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
statements

-- | Parse while statement.
whileStatement :: ParsecT String u Identity Statement
whileStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"while" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
    ([Expression] -> Statement -> Statement
SWhile ([Expression] -> Statement -> Statement)
-> ParsecT String u Identity [Expression]
-> ParsecT String u Identity (Statement -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
parens (ParsecT String u Identity Expression
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
P.many1 ParsecT String u Identity Expression
expressions))
            ParsecT String u Identity (Statement -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
breakableStatement)
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[while-statement]"

-- | parse do-while statement.
doWhileStatement :: ParsecT String u Identity Statement
doWhileStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"do" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
    (Statement -> [Expression] -> Statement
SDoWhile (Statement -> [Expression] -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity ([Expression] -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Statement
breakableStatement
              ParsecT String u Identity ([Expression] -> Statement)
-> ParsecT String u Identity [Expression]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"while" ParsecT String u Identity String
-> ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity [Expression]
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
parens (ParsecT String u Identity Expression
-> ParsecT String u Identity [Expression]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
P.many1 ParsecT String u Identity Expression
expressions)))
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[do/while-statement]"

forInVStyle :: ParsecT String u Identity ForStyle
forInVStyle =
  ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> BindExpression -> Expression -> ForStyle
ForInV (String -> BindExpression -> Expression -> ForStyle)
-> ParsecT String u Identity String
-> ParsecT
     String u Identity (BindExpression -> Expression -> ForStyle)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity String
-> ParsecT String u Identity String
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"let" ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"const" ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"var")
                ParsecT
  String u Identity (BindExpression -> Expression -> ForStyle)
-> ParsecT String u Identity BindExpression
-> ParsecT String u Identity (Expression -> ForStyle)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity BindExpression
bindExpression
                ParsecT String u Identity (Expression -> ForStyle)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"in" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False)))
forOfVStyle :: ParsecT String u Identity ForStyle
forOfVStyle =
  ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (String -> BindExpression -> Expression -> ForStyle
ForOfV (String -> BindExpression -> Expression -> ForStyle)
-> ParsecT String u Identity String
-> ParsecT
     String u Identity (BindExpression -> Expression -> ForStyle)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity String
-> ParsecT String u Identity String
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"let" ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"const" ParsecT String u Identity String
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"var")
                ParsecT
  String u Identity (BindExpression -> Expression -> ForStyle)
-> ParsecT String u Identity BindExpression
-> ParsecT String u Identity (Expression -> ForStyle)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity BindExpression
bindExpression
                ParsecT String u Identity (Expression -> ForStyle)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"of" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False ))
forInStyle :: ParsecT String u Identity ForStyle
forInStyle =
  ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (BindExpression -> Expression -> ForStyle
ForIn (BindExpression -> Expression -> ForStyle)
-> ParsecT String u Identity BindExpression
-> ParsecT String u Identity (Expression -> ForStyle)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity BindExpression
bindExpression ParsecT String u Identity (Expression -> ForStyle)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"in" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False))
forOfStyle :: ParsecT String u Identity ForStyle
forOfStyle =
  ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (BindExpression -> Expression -> ForStyle
ForOf (BindExpression -> Expression -> ForStyle)
-> ParsecT String u Identity BindExpression
-> ParsecT String u Identity (Expression -> ForStyle)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity BindExpression
bindExpression ParsecT String u Identity (Expression -> ForStyle)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"of" ParsecT String u Identity String
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
False))
forRegularStyle :: ParsecT String u Identity ForStyle
forRegularStyle =
  Maybe BindExpression -> ExpressionOpt -> ExpressionOpt -> ForStyle
ForRegular (Maybe BindExpression
 -> ExpressionOpt -> ExpressionOpt -> ForStyle)
-> ParsecT String u Identity (Maybe BindExpression)
-> ParsecT
     String u Identity (ExpressionOpt -> ExpressionOpt -> ForStyle)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity (Maybe BindExpression)
-> ParsecT String u Identity (Maybe BindExpression)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (ParsecT String u Identity BindExpression
-> ParsecT String u Identity (Maybe BindExpression)
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe ParsecT String u Identity BindExpression
bindExpression ParsecT String u Identity (Maybe BindExpression)
-> ParsecT String u Identity Char
-> ParsecT String u Identity (Maybe BindExpression)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
';'))
             ParsecT
  String u Identity (ExpressionOpt -> ExpressionOpt -> ForStyle)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity (ExpressionOpt -> ForStyle)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity ExpressionOpt
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
True) ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity Char
-> ParsecT String u Identity ExpressionOpt
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* (Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
';'))
             ParsecT String u Identity (ExpressionOpt -> ForStyle)
-> ParsecT String u Identity ExpressionOpt
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Expression
-> ParsecT String u Identity ExpressionOpt
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
P.optionMaybe (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
True)
forStyle :: ParsecT String u Identity ForStyle
forStyle =
  ParsecT String u Identity ForStyle
forInVStyle ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity ForStyle
forOfVStyle ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity ForStyle
forInStyle ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity ForStyle
forOfStyle ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity ForStyle
forRegularStyle ParsecT String u Identity ForStyle
-> String -> ParsecT String u Identity ForStyle
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[for-style]"

-- | Parse for statement.
forStatement :: ParsecT String u Identity Statement
forStatement =
  ForStyle -> Statement -> Statement
SFor (ForStyle -> Statement -> Statement)
-> ParsecT String u Identity ForStyle
-> ParsecT String u Identity (Statement -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"for" ParsecT String u Identity String
-> ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ParsecT String u Identity ForStyle
-> ParsecT String u Identity ForStyle
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
parens ParsecT String u Identity ForStyle
forStyle)) ParsecT String u Identity (Statement -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
breakableStatement

-- | Parse iteration statements (for, white, do/while).
iterationStatement :: ParsecT String u Identity Statement
iterationStatement = ParsecT String u Identity Statement
forStatement ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
whileStatement ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
doWhileStatement

-- | Parse with statement.
withStatement :: ParsecT String u Identity Statement
withStatement =
  String -> ParsecT String u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
keywordB String
"with" ParsecT String u Identity String
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Expression -> Statement -> Statement
SWith (Expression -> Statement -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity (Statement -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
parens (Bool -> ParsecT String u Identity Expression
expressionNonEmpty Bool
True))
                            ParsecT String u Identity (Statement -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ([Statement] -> Statement
SBlock ([Statement] -> Statement)
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
braces (ParsecT String u Identity String
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m String
whiteSpaces ParsecT String u Identity String
-> ParsecT String u Identity [Statement]
-> ParsecT String u Identity [Statement]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String u Identity Statement
-> ParsecT String u Identity [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme ParsecT String u Identity Statement
statements)) ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
statements))
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[with-statement]"

-- | Parse labelled statement.
labelledStatement :: ParsecT String u Identity Statement
labelledStatement =
  Expression -> Statement -> Statement
SLabel (Expression -> Statement -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity (Statement -> Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
P.try (ParsecT String u Identity Expression
-> ParsecT String u Identity Expression
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
lexeme (ParsecT String u Identity Expression
forall u. ParsecT String u Identity Expression
identifier ParsecT String u Identity Expression
-> ParsecT String u Identity Char
-> ParsecT String u Identity Expression
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
':')) ParsecT String u Identity (Statement -> Statement)
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Statement
statements
  ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[labelled-statement]"

-- | Parse statements.
statements :: ParsecT String u Identity Statement
statements = ((ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u.
Stream s m Char =>
ParsecT s u m Statement -> ParsecT s u m Statement
blockStatement ParsecT String u Identity Statement
statements
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
ifStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
iterationStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
debuggerStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
labelledStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
continueStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
tryStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
throwStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
returnStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
switchStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
withStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
variableStatement
               ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Expression -> Statement)
-> ParsecT String u Identity Expression
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Expression -> Statement
toStatement ParsecT String u Identity Expression
expressions) ParsecT String u Identity Statement
-> ParsecT String u Identity ()
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String u Identity ()
forall u. ParsecT String u Identity ()
maybeSemi) ParsecT String u Identity Statement
-> String -> ParsecT String u Identity Statement
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
P.<?> String
"[statements]"

-- | Parse all statements allowed to be on top level.
-- This helps to not allow import and export expressions
-- in any other part of the code.
topLevelStatements :: ParsecT String u Identity Statement
topLevelStatements = ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
importStatements ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
exportStatements ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
statements

-- | parser
parseJs :: ParsecT String u Identity [Statement]
parseJs = ParsecT String u Identity Statement
-> ParsecT String u Identity [Statement]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
P.many (ParsecT String u Identity Statement
-> ParsecT String u Identity Statement
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
betweenSpaces (ParsecT String u Identity Statement
forall u. ParsecT String u Identity Statement
topLevelStatements ParsecT String u Identity Statement
-> ParsecT String u Identity ()
-> ParsecT String u Identity Statement
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT String u Identity ()
forall u. ParsecT String u Identity ()
maybeSemi))

-- | Parse a script with a filename.
parse :: String -> String -> Either ParseError [Statement]
parse = Parsec String () [Statement]
-> String -> String -> Either ParseError [Statement]
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
P.parse Parsec String () [Statement]
forall u. ParsecT String u Identity [Statement]
parseJs

-- | Parse a script from a file. Just for convinience.
parseFromFile :: String -> IO (Either ParseError [Statement])
parseFromFile String
filename = Parsec String () [Statement]
-> String -> String -> Either ParseError [Statement]
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
P.parse Parsec String () [Statement]
forall u. ParsecT String u Identity [Statement]
parseJs String
filename (String -> Either ParseError [Statement])
-> IO String -> IO (Either ParseError [Statement])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
readFile String
filename