-- | Parser for ECMAScript 3.
{-# LANGUAGE FlexibleContexts #-}
module Language.ECMAScript3.Parser
  (parse
  , Parser  
  , expression
  , statement
  , program
  , parseFromString
  , parseFromFile
  -- old and deprecated   
  , parseScriptFromString
  , parseJavaScriptFromFile
  , parseScript
  , parseExpression
  , parseString
  , ParsedStatement
  , ParsedExpression
  , parseSimpleExpr'
  , parseBlockStmt
  , parseStatement
  , StatementParser
  , ExpressionParser
  , assignExpr
  , parseObjectLit  
  ) where

import Language.ECMAScript3.Lexer hiding (identifier)
import qualified Language.ECMAScript3.Lexer as Lexer
import Language.ECMAScript3.Parser.State
import Language.ECMAScript3.Parser.Type
import Language.ECMAScript3.Syntax hiding (pushLabel)
import Language.ECMAScript3.Syntax.Annotations
import Data.Default.Class
import Text.Parsec hiding (parse)
import Text.Parsec.Expr
import Control.Monad(liftM,liftM2)
import Control.Monad.Trans (MonadIO,liftIO)
import Numeric(readDec,readOct,readHex, readFloat)
import Data.Char
import Control.Monad.Identity
import Data.Maybe (isJust, isNothing, fromMaybe)
import Control.Monad.Error.Class
import Control.Applicative ((<$>), (<*>))
import Control.Exception (throwIO)

{-# DEPRECATED ParsedStatement, ParsedExpression, StatementParser,
               ExpressionParser
    "These type aliases will be hidden in the next version" #-}

{-# DEPRECATED parseSimpleExpr', parseBlockStmt, parseObjectLit
   "These parsers will be hidden in the next version" #-}

{-# DEPRECATED assignExpr, parseExpression "Use 'expression' instead" #-}

{-# DEPRECATED parseStatement "Use 'statement' instead" #-}

{-# DEPRECATED parseScript "Use 'program' instead" #-}

{-# DEPRECATED parseScriptFromString, parseString "Use 'parseFromString' instead" #-}

{-# DEPRECATED parseJavaScriptFromFile "Use 'parseFromFile' instead" #-}

-- We parameterize the parse tree over source-locations.
type ParsedStatement = Statement SourcePos
type ParsedExpression = Expression SourcePos

-- These parsers can store some arbitrary state
type StatementParser s = Parser s ParsedStatement
type ExpressionParser s = Parser s ParsedExpression

initialParserState :: ParserState
initialParserState :: ParserState
initialParserState = []

-- | checks if the label is not yet on the stack, if it is -- throws
-- an error; otherwise it pushes it onto the stack
pushLabel :: String -> Parser s ()
pushLabel :: forall s. String -> Parser s ()
pushLabel String
lab = do ParserState
labs <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
                   SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                   if String
lab forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ParserState
labs 
                     then forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Duplicate label at " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show SourcePos
pos
                     else forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState (String
labforall a. a -> [a] -> [a]
:ParserState
labs)

popLabel :: Parser s ()
popLabel :: forall s. Parser s ()
popLabel = forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
modifyState forall {a}. [a] -> [a]
safeTail
  where safeTail :: [a] -> [a]
safeTail [] = []
        safeTail (a
_:[a]
xs) = [a]
xs

clearLabels :: ParserState -> ParserState
clearLabels :: ParserState -> ParserState
clearLabels ParserState
_ = []

withFreshLabelStack :: Parser s a -> Parser s a
withFreshLabelStack :: forall s a. Parser s a -> Parser s a
withFreshLabelStack Parser s a
p = do ParserState
oldState <- forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
                           forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState forall a b. (a -> b) -> a -> b
$ ParserState -> ParserState
clearLabels ParserState
oldState
                           a
a <- Parser s a
p
                           forall (m :: * -> *) u s. Monad m => u -> ParsecT s u m ()
putState ParserState
oldState
                           forall (m :: * -> *) a. Monad m => a -> m a
return a
a

identifier :: Stream s Identity Char => Parser s (Id SourcePos)
identifier :: forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier =
  forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. a -> String -> Id a
Id forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition forall s. Stream s Identity Char => Parser s String
Lexer.identifier

--{{{ Statements

-- Keep in mind that Token.reserved parsers (exported from the lexer) do not
-- consume any input on failure.  Note that all statements (expect for labelled
-- and expression statements) begin with a reserved-word.  If we fail to parse
-- this reserved-word, no input is consumed.  Hence, we can have the massive or
-- block that is parseExpression.  Note that if the reserved-word is parsed, it 
-- must be whatever statement the reserved-word indicates.  If we fail after the
-- reserved-word, we truly have a syntax error.  Since input has been consumed,
-- <|> will not try its alternate in parseExpression, and we will fail.

parseIfStmt:: Stream s Identity Char => StatementParser s 
parseIfStmt :: forall s. Stream s Identity Char => StatementParser s
parseIfStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"if"
  ParsedExpression
test <- forall s. Stream s Identity Char => ExpressionParser s
parseParenExpr forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"parenthesized test-expression in if statement"
  ParsedStatement
consequent <- forall s. Stream s Identity Char => StatementParser s
parseStatement forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"true-branch of if statement"
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall s. Stream s Identity Char => Parser s String
semi -- TODO: in spec?
  ((do forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"else"
       ParsedStatement
alternate <- forall s. Stream s Identity Char => StatementParser s
parseStatement
       forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a.
a -> Expression a -> Statement a -> Statement a -> Statement a
IfStmt SourcePos
pos ParsedExpression
test ParsedStatement
consequent ParsedStatement
alternate)
   forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a -> Statement a -> Statement a
IfSingleStmt SourcePos
pos ParsedExpression
test ParsedStatement
consequent))

parseSwitchStmt :: Stream s Identity Char => StatementParser s
parseSwitchStmt :: forall s. Stream s Identity Char => StatementParser s
parseSwitchStmt =
  let parseDefault :: ParsecT s ParserState Identity (CaseClause SourcePos)
parseDefault = do
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"default"
        forall s. Stream s Identity Char => Parser s String
colon
        [ParsedStatement]
statements <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall s. Stream s Identity Char => StatementParser s
parseStatement
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> [Statement a] -> CaseClause a
CaseDefault SourcePos
pos [ParsedStatement]
statements)
      parseCase :: ParsecT s ParserState Identity (CaseClause SourcePos)
parseCase = do
         SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
         forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"case"
         ParsedExpression
condition <- forall s. Stream s Identity Char => ExpressionParser s
parseListExpr
         forall s. Stream s Identity Char => Parser s String
colon
         [ParsedStatement]
actions <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall s. Stream s Identity Char => StatementParser s
parseStatement
         forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a -> [Statement a] -> CaseClause a
CaseClause SourcePos
pos ParsedExpression
condition [ParsedStatement]
actions)
      isCaseDefault :: CaseClause a -> Bool
isCaseDefault (CaseDefault a
_ [Statement a]
_) = Bool
True   
      isCaseDefault CaseClause a
_                 = Bool
False
      checkClauses :: [CaseClause a] -> m ()
checkClauses [CaseClause a]
cs = case forall a. (a -> Bool) -> [a] -> [a]
filter forall {a}. CaseClause a -> Bool
isCaseDefault [CaseClause a]
cs of
        (CaseClause a
_:CaseClause a
c:[CaseClause a]
_) -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"duplicate default clause in switch statement at " forall a. [a] -> [a] -> [a]
++
                          forall a. Show a => a -> String
show (forall (a :: * -> *) b. HasAnnotation a => a b -> b
getAnnotation CaseClause a
c)
        [CaseClause a]
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()                  
    in do SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
          forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"switch"
          ParsedExpression
test <- forall s. Stream s Identity Char => ExpressionParser s
parseParenExpr
          [CaseClause SourcePos]
clauses <- forall s a. Stream s Identity Char => Parser s a -> Parser s a
braces forall a b. (a -> b) -> a -> b
$ forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall a b. (a -> b) -> a -> b
$ ParsecT s ParserState Identity (CaseClause SourcePos)
parseDefault forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s ParserState Identity (CaseClause SourcePos)
parseCase
          forall {m :: * -> *} {a}.
(MonadFail m, Show a) =>
[CaseClause a] -> m ()
checkClauses [CaseClause SourcePos]
clauses
          forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a -> [CaseClause a] -> Statement a
SwitchStmt SourcePos
pos ParsedExpression
test [CaseClause SourcePos]
clauses)

parseWhileStmt:: Stream s Identity Char => StatementParser s
parseWhileStmt :: forall s. Stream s Identity Char => StatementParser s
parseWhileStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"while"
  ParsedExpression
test <- forall s. Stream s Identity Char => ExpressionParser s
parseParenExpr forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"parenthesized test-expression in while loop"
  ParsedStatement
body <- forall s. Stream s Identity Char => StatementParser s
parseStatement
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a -> Statement a -> Statement a
WhileStmt SourcePos
pos ParsedExpression
test ParsedStatement
body)

parseDoWhileStmt:: Stream s Identity Char => StatementParser s
parseDoWhileStmt :: forall s. Stream s Identity Char => StatementParser s
parseDoWhileStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"do"
  ParsedStatement
body <- forall s. Stream s Identity Char => StatementParser s
parseStatement
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"while" forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"while at the end of a do block"
  ParsedExpression
test <- forall s. Stream s Identity Char => ExpressionParser s
parseParenExpr forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"parenthesized test-expression in do loop"
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall s. Stream s Identity Char => Parser s String
semi
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Statement a -> Expression a -> Statement a
DoWhileStmt SourcePos
pos ParsedStatement
body ParsedExpression
test)

parseContinueStmt:: Stream s Identity Char => StatementParser s
parseContinueStmt :: forall s. Stream s Identity Char => StatementParser s
parseContinueStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"continue"
  SourcePos
pos' <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  -- Ensure that the identifier is on the same line as 'continue.'
  Maybe (Id SourcePos)
id <- if SourcePos -> Line
sourceLine SourcePos
pos forall a. Eq a => a -> a -> Bool
== SourcePos -> Line
sourceLine SourcePos
pos'
        then forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. a -> Maybe a
Just forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
        else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall s. Stream s Identity Char => Parser s String
semi
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe (Id a) -> Statement a
ContinueStmt SourcePos
pos Maybe (Id SourcePos)
id

parseBreakStmt:: Stream s Identity Char => StatementParser s
parseBreakStmt :: forall s. Stream s Identity Char => StatementParser s
parseBreakStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"break"
  SourcePos
pos' <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  -- Ensure that the identifier is on the same line as 'break.'
  Maybe (Id SourcePos)
id <- if SourcePos -> Line
sourceLine SourcePos
pos forall a. Eq a => a -> a -> Bool
== SourcePos -> Line
sourceLine SourcePos
pos'
        then forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. a -> Maybe a
Just forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
        else forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall s. Stream s Identity Char => Parser s String
semi           
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe (Id a) -> Statement a
BreakStmt SourcePos
pos Maybe (Id SourcePos)
id

parseBlockStmt:: Stream s Identity Char => StatementParser s
parseBlockStmt :: forall s. Stream s Identity Char => StatementParser s
parseBlockStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  [ParsedStatement]
statements <- forall s a. Stream s Identity Char => Parser s a -> Parser s a
braces (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many forall s. Stream s Identity Char => StatementParser s
parseStatement)
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> [Statement a] -> Statement a
BlockStmt SourcePos
pos [ParsedStatement]
statements)

parseEmptyStmt:: Stream s Identity Char => StatementParser s
parseEmptyStmt :: forall s. Stream s Identity Char => StatementParser s
parseEmptyStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => Parser s String
semi
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Statement a
EmptyStmt SourcePos
pos)

parseLabelledStmt:: Stream s Identity Char => StatementParser s
parseLabelledStmt :: forall s. Stream s Identity Char => StatementParser s
parseLabelledStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  -- Lookahead for the colon.  If we don't see it, we are parsing an identifier
  -- for an expression statement.
  Id SourcePos
label <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do Id SourcePos
label <- forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier
                   forall s. Stream s Identity Char => Parser s String
colon
                   forall (m :: * -> *) a. Monad m => a -> m a
return Id SourcePos
label)
  forall s. String -> Parser s ()
pushLabel forall a b. (a -> b) -> a -> b
$ forall a. Id a -> String
unId Id SourcePos
label
  ParsedStatement
statement <- forall s. Stream s Identity Char => StatementParser s
parseStatement
  forall s. Parser s ()
popLabel
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Id a -> Statement a -> Statement a
LabelledStmt SourcePos
pos Id SourcePos
label ParsedStatement
statement)

parseExpressionStmt:: Stream s Identity Char => StatementParser s
parseExpressionStmt :: forall s. Stream s Identity Char => StatementParser s
parseExpressionStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  ParsedExpression
expr <- forall s. Stream s Identity Char => ExpressionParser s
parseExpression -- TODO: spec 12.4?
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall s. Stream s Identity Char => Parser s String
semi
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Expression a -> Statement a
ExprStmt SourcePos
pos ParsedExpression
expr


parseForInStmt:: Stream s Identity Char => StatementParser s
parseForInStmt :: forall s. Stream s Identity Char => StatementParser s
parseForInStmt =
  let parseInit :: ParsecT s ParserState Identity (ForInInit SourcePos)
parseInit = (forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"var" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. Id a -> ForInInit a
ForInVar forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier)
               forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. LValue a -> ForInInit a
ForInLVal forall s. Stream s Identity Char => Parser s (LValue SourcePos)
lvalue
  in do SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        -- Lookahead, so that we don't clash with parseForStmt
        (ForInInit SourcePos
init,ParsedExpression
expr) <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try forall a b. (a -> b) -> a -> b
$ do forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"for"
                                forall s a. Stream s Identity Char => Parser s a -> Parser s a
parens forall a b. (a -> b) -> a -> b
$ do ForInInit SourcePos
init <- ParsecT s ParserState Identity (ForInInit SourcePos)
parseInit
                                            forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"in"
                                            ParsedExpression
expr <- forall s. Stream s Identity Char => ExpressionParser s
parseExpression
                                            forall (m :: * -> *) a. Monad m => a -> m a
return (ForInInit SourcePos
init,ParsedExpression
expr)
        ParsedStatement
body <- forall s. Stream s Identity Char => StatementParser s
parseStatement
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a.
a -> ForInInit a -> Expression a -> Statement a -> Statement a
ForInStmt SourcePos
pos ForInInit SourcePos
init ParsedExpression
expr ParsedStatement
body

parseForStmt:: Stream s Identity Char => StatementParser s
parseForStmt :: forall s. Stream s Identity Char => StatementParser s
parseForStmt =
  let parseInit :: ParsecT s ParserState Identity (ForInit SourcePos)
parseInit = (forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"var" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. [VarDecl a] -> ForInit a
VarInit (forall s. Stream s Identity Char => Parser s (VarDecl SourcePos)
parseVarDecl 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]
`sepBy` forall s. Stream s Identity Char => Parser s String
comma))
               forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. Expression a -> ForInit a
ExprInit forall s. Stream s Identity Char => ExpressionParser s
parseListExpr
               forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. ForInit a
NoInit
    in do SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
          forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"for"
          forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"("
          ForInit SourcePos
init <- ParsecT s ParserState Identity (ForInit SourcePos)
parseInit
          forall s. Stream s Identity Char => Parser s String
semi
          Maybe ParsedExpression
test <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall s. Stream s Identity Char => ExpressionParser s
parseExpression
          forall s. Stream s Identity Char => Parser s String
semi
          Maybe ParsedExpression
iter <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall s. Stream s Identity Char => ExpressionParser s
parseExpression
          forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
")" forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"closing paren"
          ParsedStatement
stmt <- forall s. Stream s Identity Char => StatementParser s
parseStatement
          forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a.
a
-> ForInit a
-> Maybe (Expression a)
-> Maybe (Expression a)
-> Statement a
-> Statement a
ForStmt SourcePos
pos ForInit SourcePos
init Maybe ParsedExpression
test Maybe ParsedExpression
iter ParsedStatement
stmt

parseTryStmt:: Stream s Identity Char => StatementParser s
parseTryStmt :: forall s. Stream s Identity Char => StatementParser s
parseTryStmt =
  let parseCatchClause :: ParsecT s ParserState Identity (CatchClause SourcePos)
parseCatchClause = do SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                            forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"catch"
                            Id SourcePos
id <- forall s a. Stream s Identity Char => Parser s a -> Parser s a
parens forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier
                            ParsedStatement
stmt <- forall s. Stream s Identity Char => StatementParser s
parseStatement
                            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Id a -> Statement a -> CatchClause a
CatchClause SourcePos
pos Id SourcePos
id ParsedStatement
stmt
  in do forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"try"
        SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
        ParsedStatement
guarded <- forall s. Stream s Identity Char => StatementParser s
parseStatement
        Maybe (CatchClause SourcePos)
mCatch <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe ParsecT s ParserState Identity (CatchClause SourcePos)
parseCatchClause
        Maybe ParsedStatement
mFinally <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall a b. (a -> b) -> a -> b
$ forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"finally" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s. Stream s Identity Char => StatementParser s
parseStatement
        -- the spec requires at least a catch or a finally block to
        -- be present
        if forall a. Maybe a -> Bool
isJust Maybe (CatchClause SourcePos)
mCatch Bool -> Bool -> Bool
|| forall a. Maybe a -> Bool
isJust Maybe ParsedStatement
mFinally 
          then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a.
a
-> Statement a
-> Maybe (CatchClause a)
-> Maybe (Statement a)
-> Statement a
TryStmt SourcePos
pos ParsedStatement
guarded Maybe (CatchClause SourcePos)
mCatch Maybe ParsedStatement
mFinally
          else forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"A try statement should have at least a catch\ 
                      \ or a finally block, at " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show SourcePos
pos

parseThrowStmt:: Stream s Identity Char => StatementParser s
parseThrowStmt :: forall s. Stream s Identity Char => StatementParser s
parseThrowStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"throw"
  ParsedExpression
expr <- forall s. Stream s Identity Char => ExpressionParser s
parseExpression
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall s. Stream s Identity Char => Parser s String
semi
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a -> Statement a
ThrowStmt SourcePos
pos ParsedExpression
expr)

parseReturnStmt:: Stream s Identity Char => StatementParser s
parseReturnStmt :: forall s. Stream s Identity Char => StatementParser s
parseReturnStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"return"
  Maybe ParsedExpression
expr <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall s. Stream s Identity Char => ExpressionParser s
parseListExpr
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall s. Stream s Identity Char => Parser s String
semi
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe (Expression a) -> Statement a
ReturnStmt SourcePos
pos Maybe ParsedExpression
expr)

parseWithStmt:: Stream s Identity Char => StatementParser s
parseWithStmt :: forall s. Stream s Identity Char => StatementParser s
parseWithStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"with"
  ParsedExpression
context <- forall s. Stream s Identity Char => ExpressionParser s
parseParenExpr
  ParsedStatement
stmt <- forall s. Stream s Identity Char => StatementParser s
parseStatement
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a -> Statement a -> Statement a
WithStmt SourcePos
pos ParsedExpression
context ParsedStatement
stmt)

parseVarDecl :: Stream s Identity Char => Parser s (VarDecl SourcePos) 
parseVarDecl :: forall s. Stream s Identity Char => Parser s (VarDecl SourcePos)
parseVarDecl = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  Id SourcePos
id <- forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier
  Maybe ParsedExpression
init <- (forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM forall a. a -> Maybe a
Just forall s. Stream s Identity Char => ExpressionParser s
assignExpr) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Id a -> Maybe (Expression a) -> VarDecl a
VarDecl SourcePos
pos Id SourcePos
id Maybe ParsedExpression
init)

parseVarDeclStmt:: Stream s Identity Char => StatementParser s
parseVarDeclStmt :: forall s. Stream s Identity Char => StatementParser s
parseVarDeclStmt = do 
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"var"
  [VarDecl SourcePos]
decls <- forall s. Stream s Identity Char => Parser s (VarDecl SourcePos)
parseVarDecl 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]
`sepBy` forall s. Stream s Identity Char => Parser s String
comma
  forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional forall s. Stream s Identity Char => Parser s String
semi
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> [VarDecl a] -> Statement a
VarDeclStmt SourcePos
pos [VarDecl SourcePos]
decls)

parseFunctionStmt:: Stream s Identity Char => StatementParser s
parseFunctionStmt :: forall s. Stream s Identity Char => StatementParser s
parseFunctionStmt = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  Id SourcePos
name <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"function" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier) -- ambiguity with FuncExpr
  [Id SourcePos]
args <- forall s a. Stream s Identity Char => Parser s a -> Parser s a
parens (forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier 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]
`sepBy` forall s. Stream s Identity Char => Parser s String
comma)
  -- label sets don't cross function boundaries
  BlockStmt SourcePos
_ [ParsedStatement]
body <- forall s a. Parser s a -> Parser s a
withFreshLabelStack forall s. Stream s Identity Char => StatementParser s
parseBlockStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> 
                      String
"function body in { ... }"
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Id a -> [Id a] -> [Statement a] -> Statement a
FunctionStmt SourcePos
pos Id SourcePos
name [Id SourcePos]
args [ParsedStatement]
body)

parseStatement :: Stream s Identity Char => StatementParser s
parseStatement :: forall s. Stream s Identity Char => StatementParser s
parseStatement = forall s. Stream s Identity Char => StatementParser s
parseIfStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseSwitchStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseWhileStmt 
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseDoWhileStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseContinueStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseBreakStmt 
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseBlockStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseEmptyStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseForInStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseForStmt
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseTryStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseThrowStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseReturnStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseWithStmt 
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseVarDeclStmt  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseFunctionStmt
  -- labelled, expression and the error message always go last, in this order
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseLabelledStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => StatementParser s
parseExpressionStmt forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"statement"

-- | The parser that parses a single ECMAScript statement
statement :: Stream s Identity Char => Parser s (Statement SourcePos)
statement :: forall s. Stream s Identity Char => StatementParser s
statement = forall s. Stream s Identity Char => StatementParser s
parseStatement

--}}}

--{{{ Expressions

-- References used to construct this stuff:
-- + http://developer.mozilla.org/en/docs/
--     Core_JavaScript_1.5_Reference:Operators:Operator_Precedence
-- + http://www.mozilla.org/js/language/grammar14.html
--
-- Aren't expression tables nice?  Well, we can't quite use them, because of 
-- JavaScript's ternary (?:) operator.  We have to use two expression tables.
-- We use one expression table for the assignment operators that bind looser 
-- than ?: (assignTable).  The terms of assignTable are ternary expressions 
-- (parseTernaryExpr).  parseTernaryExpr left-factors the left-recursive
-- production for ?:, and is defined over the second expression table, 
-- exprTable, which consists of operators that bind tighter than ?:.  The terms
-- of exprTable are atomic expressions, parenthesized expressions, functions and
-- array references.

--{{{ Primary expressions

parseThisRef:: Stream s Identity Char => ExpressionParser s
parseThisRef :: forall s. Stream s Identity Char => ExpressionParser s
parseThisRef = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"this"
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a
ThisRef SourcePos
pos)

parseNullLit:: Stream s Identity Char => ExpressionParser s
parseNullLit :: forall s. Stream s Identity Char => ExpressionParser s
parseNullLit = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"null"
  forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a
NullLit SourcePos
pos)


parseBoolLit:: Stream s Identity Char => ExpressionParser s
parseBoolLit :: forall s. Stream s Identity Char => ExpressionParser s
parseBoolLit = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    let parseTrueLit :: ExpressionParser s
parseTrueLit  = forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"true"  forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Bool -> Expression a
BoolLit SourcePos
pos Bool
True)
        parseFalseLit :: ExpressionParser s
parseFalseLit = forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"false" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Bool -> Expression a
BoolLit SourcePos
pos Bool
False)
    ExpressionParser s
parseTrueLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ExpressionParser s
parseFalseLit

parseVarRef:: Stream s Identity Char => ExpressionParser s
parseVarRef :: forall s. Stream s Identity Char => ExpressionParser s
parseVarRef = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. a -> Id a -> Expression a
VarRef forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier

parseArrayLit:: Stream s Identity Char => ExpressionParser s
parseArrayLit :: forall s. Stream s Identity Char => ExpressionParser s
parseArrayLit = forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. a -> [Expression a] -> Expression a
ArrayLit forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition (forall s a. Stream s Identity Char => Parser s a -> Parser s a
squares (forall s. Stream s Identity Char => ExpressionParser s
assignExpr 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]
`sepEndBy` forall s. Stream s Identity Char => Parser s String
comma))

parseFuncExpr :: Stream s Identity Char => ExpressionParser s
parseFuncExpr :: forall s. Stream s Identity Char => ExpressionParser s
parseFuncExpr = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"function"
  Maybe (Id SourcePos)
name <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier
  [Id SourcePos]
args <- forall s a. Stream s Identity Char => Parser s a -> Parser s a
parens (forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier 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]
`sepBy` forall s. Stream s Identity Char => Parser s String
comma)
  -- labels don't cross function boundaries
  BlockStmt SourcePos
_ [ParsedStatement]
body <- forall s a. Parser s a -> Parser s a
withFreshLabelStack forall s. Stream s Identity Char => StatementParser s
parseBlockStmt
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a.
a -> Maybe (Id a) -> [Id a] -> [Statement a] -> Expression a
FuncExpr SourcePos
pos Maybe (Id SourcePos)
name [Id SourcePos]
args [ParsedStatement]
body

--{{{ parsing strings

escapeChars :: [(Char, Char)]
escapeChars =
 [(Char
'\'',Char
'\''),(Char
'\"',Char
'\"'),(Char
'\\',Char
'\\'),(Char
'b',Char
'\b'),(Char
'f',Char
'\f'),(Char
'n',Char
'\n'),
  (Char
'r',Char
'\r'),(Char
't',Char
'\t'),(Char
'v',Char
'\v'),(Char
'/',Char
'/'),(Char
' ',Char
' '),(Char
'0',Char
'\0')]

allEscapes:: String
allEscapes :: String
allEscapes = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst [(Char, Char)]
escapeChars

parseEscapeChar :: Stream s Identity Char => Parser s Char
parseEscapeChar :: forall s. Stream s Identity Char => Parser s Char
parseEscapeChar = do
  Char
c <- forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
allEscapes
  let (Just Char
c') = forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Char
c [(Char, Char)]
escapeChars -- will succeed due to line above
  forall (m :: * -> *) a. Monad m => a -> m a
return Char
c' 

parseAsciiHexChar :: Stream s Identity Char => Parser s Char
parseAsciiHexChar :: forall s. Stream s Identity Char => Parser s Char
parseAsciiHexChar = do
  forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'x'
  Char
d1 <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
hexDigit
  Char
d2 <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
hexDigit
  forall (m :: * -> *) a. Monad m => a -> m a
return ((Line -> Char
chrforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> a
fstforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. [a] -> a
headforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. (Eq a, Num a) => ReadS a
readHex) (Char
d1forall a. a -> [a] -> [a]
:Char
d2forall a. a -> [a] -> [a]
:String
""))

parseUnicodeHexChar :: Stream s Identity Char => Parser s Char
parseUnicodeHexChar :: forall s. Stream s Identity Char => Parser s Char
parseUnicodeHexChar = do
  forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'u'
  forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Line -> Char
chrforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> a
fstforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. [a] -> a
headforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. (Eq a, Num a) => ReadS a
readHex) 
        (forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
hexDigit,forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
hexDigit,forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
hexDigit,forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
hexDigit])
        
isWhitespace :: Char -> Bool
isWhitespace Char
ch = Char
ch forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
" \t"


-- The endWith argument is either single-quote or double-quote, depending on how
-- we opened the string.
parseStringLit' :: Char -> ParsecT s ParserState Identity String
parseStringLit' Char
endWith =
  (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
endWith forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return String
"") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
  (do forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"\\'")
      String
cs <- Char -> ParsecT s ParserState Identity String
parseStringLit' Char
endWith
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String
"'" forall a. [a] -> [a] -> [a]
++ String
cs) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
  (do forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'
      Char
c <- forall s. Stream s Identity Char => Parser s Char
parseEscapeChar forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => Parser s Char
parseAsciiHexChar forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => Parser s Char
parseUnicodeHexChar forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> 
           forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\r' forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\n'
      String
cs <- Char -> ParsecT s ParserState Identity String
parseStringLit' Char
endWith
      if Char
c forall a. Eq a => a -> a -> Bool
== Char
'\r' Bool -> Bool -> Bool
|| Char
c forall a. Eq a => a -> a -> Bool
== Char
'\n' 
        then forall (m :: * -> *) a. Monad m => a -> m a
return (Char
cforall a. a -> [a] -> [a]
:forall a. (a -> Bool) -> [a] -> [a]
dropWhile Char -> Bool
isWhitespace String
cs) 
        else forall (m :: * -> *) a. Monad m => a -> m a
return (Char
cforall a. a -> [a] -> [a]
:String
cs)) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
   forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar (Char -> ParsecT s ParserState Identity String
parseStringLit' Char
endWith)

parseStringLit:: Stream s Identity Char => ExpressionParser s
parseStringLit :: forall s. Stream s Identity Char => ExpressionParser s
parseStringLit = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  -- parseStringLit' takes as an argument the quote-character that opened the
  -- string.
  String
str <- forall s a. Stream s Identity Char => Parser s a -> Parser s a
lexeme forall a b. (a -> b) -> a -> b
$ (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\'' forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {s}.
Stream s Identity Char =>
Char -> ParsecT s ParserState Identity String
parseStringLit') forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\"' forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {s}.
Stream s Identity Char =>
Char -> ParsecT s ParserState Identity String
parseStringLit')
  -- CRUCIAL: Parsec.Token parsers expect to find their token on the first
  -- character, and read whitespaces beyond their tokens.  Without 'lexeme'
  -- above, expressions like:
  --   var s = "string"   ;
  -- do not parse.
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> String -> Expression a
StringLit SourcePos
pos String
str

--}}}

parseRegexpLit:: Stream s Identity Char => ExpressionParser s
parseRegexpLit :: forall s. Stream s Identity Char => ExpressionParser s
parseRegexpLit = do
  let parseFlags :: ParsecT s u Identity ((Bool -> Bool -> t) -> t)
parseFlags = do
        String
flags <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"mgi")
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ \Bool -> Bool -> t
f -> Bool -> Bool -> t
f (Char
'g' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
flags) (Char
'i' forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
flags) 
  let parseEscape :: Stream s Identity Char => Parser s Char
      parseEscape :: forall s. Stream s Identity Char => Parser s Char
parseEscape = forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
  let parseChar :: Stream s Identity Char => Parser s Char
      parseChar :: forall s. Stream s Identity Char => Parser s Char
parseChar = forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"/"
  let parseRe :: ParsecT s u Identity String
parseRe = (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'/' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return String
"") forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> 
                (do forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'
                    Char
ch <- forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar -- TODO: too lenient
                    String
rest <- ParsecT s u Identity String
parseRe
                    forall (m :: * -> *) a. Monad m => a -> m a
return (Char
'\\'forall a. a -> [a] -> [a]
:Char
chforall a. a -> [a] -> [a]
:String
rest)) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> 
                forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar ParsecT s u Identity String
parseRe
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'/'
  forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'/'
  String
pat <- forall {u}. ParsecT s u Identity String
parseRe --many1 parseChar
  (Bool -> Bool -> ParsedExpression) -> ParsedExpression
flags <- forall {u} {t}. ParsecT s u Identity ((Bool -> Bool -> t) -> t)
parseFlags
  forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m ()
spaces -- crucial for Parsec.Token parsers
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (Bool -> Bool -> ParsedExpression) -> ParsedExpression
flags (forall a. a -> String -> Bool -> Bool -> Expression a
RegexpLit SourcePos
pos String
pat)
          
parseObjectLit:: Stream s Identity Char => ExpressionParser s
parseObjectLit :: forall s. Stream s Identity Char => ExpressionParser s
parseObjectLit =
  let parseProp :: ParsecT s ParserState Identity (Prop SourcePos, ParsedExpression)
parseProp = do
        -- Parses a string, identifier or integer as the property name.  I
        -- apologize for the abstruse style, but it really does make the code
        -- much shorter.
        Prop SourcePos
name <- forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (\(StringLit SourcePos
p String
s) -> forall a. a -> String -> Prop a
PropString SourcePos
p String
s) forall s. Stream s Identity Char => ExpressionParser s
parseStringLit
            forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. a -> Id a -> Prop a
PropId forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier
            forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. a -> Integer -> Prop a
PropNum forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition (forall s. Stream s Identity Char => Parser s (Either Line Double)
parseNumber forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {a} {s} {m :: * -> *} {t} {a} {b} {u}.
(Integral a, Stream s m t, Num a) =>
Either a b -> ParsecT s u m a
toInt)
        forall s. Stream s Identity Char => Parser s String
colon
        ParsedExpression
val <- forall s. Stream s Identity Char => ExpressionParser s
assignExpr
        forall (m :: * -> *) a. Monad m => a -> m a
return (Prop SourcePos
name,ParsedExpression
val)
      toInt :: Either a b -> ParsecT s u m a
toInt Either a b
eid = case Either a b
eid of
        Left a
i -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i
        -- Note, the spec actually allows floats in property names.
        -- This is left for legacy reasons and will be fixed in 1.0
        Right b
d-> forall s (m :: * -> *) t u a.
Stream s m t =>
String -> ParsecT s u m a
unexpected String
"Floating point number in property name"
    in do SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
          [(Prop SourcePos, ParsedExpression)]
props <- forall s a. Stream s Identity Char => Parser s a -> Parser s a
braces (ParsecT s ParserState Identity (Prop SourcePos, ParsedExpression)
parseProp 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]
`sepEndBy` forall s. Stream s Identity Char => Parser s String
comma) forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"object literal"
          forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> [(Prop a, Expression a)] -> Expression a
ObjectLit SourcePos
pos [(Prop SourcePos, ParsedExpression)]
props

--{{{ Parsing numbers.  From pg. 17-18 of ECMA-262.
hex :: Stream s Identity Char => Parser s (Either Int Double)
hex :: forall s. Stream s Identity Char => Parser s (Either Line Double)
hex = do String
s <- forall s. Stream s Identity Char => Parser s String
hexIntLit
         forall a b. a -> Either a b
Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. ReadS a -> String -> Parser s a
wrapReadS forall a. (Eq a, Num a) => ReadS a
Numeric.readHex String
s

decimal :: Stream s Identity Char => Parser s (Either Int Double)
decimal :: forall s. Stream s Identity Char => Parser s (Either Line Double)
decimal = do (String
s, Bool
i) <- forall s. Stream s Identity Char => Parser s (String, Bool)
decLit
             if Bool
i then forall a b. a -> Either a b
Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. ReadS a -> String -> Parser s a
wrapReadS forall a. (Eq a, Num a) => ReadS a
readDec String
s
                  else forall a b. b -> Either a b
Right forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a s. ReadS a -> String -> Parser s a
wrapReadS forall a. RealFrac a => ReadS a
readFloat String
s

wrapReadS :: ReadS a -> String -> Parser s a
wrapReadS :: forall a s. ReadS a -> String -> Parser s a
wrapReadS ReadS a
r String
s = case ReadS a
r String
s of
  [(a
a, String
"")] -> forall (m :: * -> *) a. Monad m => a -> m a
return a
a
  [(a, String)]
_         -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Bad parse: could not convert a string to a Haskell value"

parseNumber:: Stream s Identity Char => Parser s (Either Int Double) 
parseNumber :: forall s. Stream s Identity Char => Parser s (Either Line Double)
parseNumber = forall s. Stream s Identity Char => Parser s (Either Line Double)
hex forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => Parser s (Either Line Double)
decimal

parseNumLit:: Stream s Identity Char => ExpressionParser s
parseNumLit :: forall s. Stream s Identity Char => ExpressionParser s
parseNumLit = do SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                 Either Line Double
eid <- forall s a. Stream s Identity Char => Parser s a -> Parser s a
lexeme forall a b. (a -> b) -> a -> b
$ forall s. Stream s Identity Char => Parser s (Either Line Double)
parseNumber
                 forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy forall s. Stream s Identity Char => Parser s Char
identifierStart forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"whitespace"
                 forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Either Line Double
eid of
                   Left Line
i -> forall a. a -> Line -> Expression a
IntLit SourcePos
pos Line
i
                   Right Double
d-> forall a. a -> Double -> Expression a
NumLit SourcePos
pos Double
d

------------------------------------------------------------------------------
-- Position Helper
------------------------------------------------------------------------------

withPos :: (SourcePos -> t -> b) -> ParsecT s u m t -> ParsecT s u m b
withPos SourcePos -> t -> b
cstr ParsecT s u m t
p = do { SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition; t
e <- ParsecT s u m t
p; forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ SourcePos -> t -> b
cstr SourcePos
pos t
e }

-------------------------------------------------------------------------------
-- Compound Expression Parsers
-------------------------------------------------------------------------------

dotRef :: ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
dotRef ParsedExpression
e = (forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"." forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall {m :: * -> *} {t} {b} {s} {u}.
Monad m =>
(SourcePos -> t -> b) -> ParsecT s u m t -> ParsecT s u m b
withPos SourcePos -> Id SourcePos -> ParsedExpression
cstr forall s. Stream s Identity Char => Parser s (Id SourcePos)
identifier) forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"property.ref"
    where cstr :: SourcePos -> Id SourcePos -> ParsedExpression
cstr SourcePos
pos = forall a. a -> Expression a -> Id a -> Expression a
DotRef SourcePos
pos ParsedExpression
e

funcApp :: ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
funcApp ParsedExpression
e = forall s a. Stream s Identity Char => Parser s a -> Parser s a
parens (forall {m :: * -> *} {t} {b} {s} {u}.
Monad m =>
(SourcePos -> t -> b) -> ParsecT s u m t -> ParsecT s u m b
withPos SourcePos -> [ParsedExpression] -> ParsedExpression
cstr (forall s. Stream s Identity Char => ExpressionParser s
assignExpr 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]
`sepBy` forall s. Stream s Identity Char => Parser s String
comma)) 
         forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?>String
"(function application)"
    where cstr :: SourcePos -> [ParsedExpression] -> ParsedExpression
cstr SourcePos
pos = forall a. a -> Expression a -> [Expression a] -> Expression a
CallExpr SourcePos
pos ParsedExpression
e

bracketRef :: ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
bracketRef ParsedExpression
e = forall s a. Stream s Identity Char => Parser s a -> Parser s a
brackets (forall {m :: * -> *} {t} {b} {s} {u}.
Monad m =>
(SourcePos -> t -> b) -> ParsecT s u m t -> ParsecT s u m b
withPos SourcePos -> ParsedExpression -> ParsedExpression
cstr forall s. Stream s Identity Char => ExpressionParser s
parseExpression) forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"[property-ref]"
    where cstr :: SourcePos -> ParsedExpression -> ParsedExpression
cstr SourcePos
pos = forall a. a -> Expression a -> Expression a -> Expression a
BracketRef SourcePos
pos ParsedExpression
e

-------------------------------------------------------------------------------
-- Expression Parsers
-------------------------------------------------------------------------------

parseParenExpr:: Stream s Identity Char => ExpressionParser s
parseParenExpr :: forall s. Stream s Identity Char => ExpressionParser s
parseParenExpr = forall s a. Stream s Identity Char => Parser s a -> Parser s a
parens forall s. Stream s Identity Char => ExpressionParser s
parseListExpr

-- everything above expect functions
parseExprForNew :: Stream s Identity Char => ExpressionParser s
parseExprForNew :: forall s. Stream s Identity Char => ExpressionParser s
parseExprForNew = forall s. Stream s Identity Char => ExpressionParser s
parseThisRef forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseNullLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseBoolLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseStringLit 
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseArrayLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseParenExpr forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseNewExpr forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseNumLit 
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseRegexpLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseObjectLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseVarRef

-- all the expression parsers defined above
parseSimpleExpr' :: Stream s Identity Char => ExpressionParser s
parseSimpleExpr' :: forall s. Stream s Identity Char => ExpressionParser s
parseSimpleExpr' = forall s. Stream s Identity Char => ExpressionParser s
parseThisRef forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseNullLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseBoolLit 
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseStringLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseArrayLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseParenExpr
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseFuncExpr forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseNumLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseRegexpLit forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseObjectLit
  forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall s. Stream s Identity Char => ExpressionParser s
parseVarRef

parseNewExpr :: Stream s Identity Char => ExpressionParser s
parseNewExpr :: forall s. Stream s Identity Char => ExpressionParser s
parseNewExpr =
  (do SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
      forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"new"
      ParsedExpression
constructor <- forall s.
Stream s Identity Char =>
Maybe ParsedExpression -> ExpressionParser s
parseSimpleExprForNew forall a. Maybe a
Nothing -- right-associativity
      [ParsedExpression]
arguments <- forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s a. Stream s Identity Char => Parser s a -> Parser s a
parens (forall s. Stream s Identity Char => ExpressionParser s
assignExpr 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]
`sepBy` forall s. Stream s Identity Char => Parser s String
comma)) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return []
      forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a -> [Expression a] -> Expression a
NewExpr SourcePos
pos ParsedExpression
constructor [ParsedExpression]
arguments)) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
  forall s. Stream s Identity Char => ExpressionParser s
parseSimpleExpr'

parseSimpleExpr :: Maybe ParsedExpression
-> ParsecT s ParserState Identity ParsedExpression
parseSimpleExpr (Just ParsedExpression
e) = ((forall {s}.
Stream s Identity Char =>
ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
dotRef ParsedExpression
e forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s}.
Stream s Identity Char =>
ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
funcApp ParsedExpression
e forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s}.
Stream s Identity Char =>
ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
bracketRef ParsedExpression
e) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                            Maybe ParsedExpression
-> ParsecT s ParserState Identity ParsedExpression
parseSimpleExpr forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just)  
                        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return ParsedExpression
e
parseSimpleExpr Maybe ParsedExpression
Nothing = do
  ParsedExpression
e <- forall s. Stream s Identity Char => ExpressionParser s
parseNewExpr forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"expression (3)"
  Maybe ParsedExpression
-> ParsecT s ParserState Identity ParsedExpression
parseSimpleExpr (forall a. a -> Maybe a
Just ParsedExpression
e)

parseSimpleExprForNew :: Stream s Identity Char
                      =>(Maybe ParsedExpression) -> ExpressionParser s
parseSimpleExprForNew :: forall s.
Stream s Identity Char =>
Maybe ParsedExpression -> ExpressionParser s
parseSimpleExprForNew (Just ParsedExpression
e) = ((forall {s}.
Stream s Identity Char =>
ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
dotRef ParsedExpression
e forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s}.
Stream s Identity Char =>
ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
bracketRef ParsedExpression
e) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                                  forall s.
Stream s Identity Char =>
Maybe ParsedExpression -> ExpressionParser s
parseSimpleExprForNew forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just)
                              forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return ParsedExpression
e
parseSimpleExprForNew Maybe ParsedExpression
Nothing = do
  ParsedExpression
e <- forall s. Stream s Identity Char => ExpressionParser s
parseNewExpr forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"expression (3)"
  forall s.
Stream s Identity Char =>
Maybe ParsedExpression -> ExpressionParser s
parseSimpleExprForNew (forall a. a -> Maybe a
Just ParsedExpression
e)
    
--}}}

makeInfixExpr :: String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
str InfixOp
constr = forall s u (m :: * -> *) a.
ParsecT s u m (a -> a -> a) -> Assoc -> Operator s u m a
Infix forall s.
Stream s Identity Char =>
Parser s (ParsedExpression -> ParsedExpression -> ParsedExpression)
parser Assoc
AssocLeft where
  parser:: Stream s Identity Char
        => Parser s (Expression SourcePos -> Expression SourcePos -> Expression SourcePos)
  parser :: forall s.
Stream s Identity Char =>
Parser s (ParsedExpression -> ParsedExpression -> ParsedExpression)
parser = do
    SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
str
    forall (m :: * -> *) a. Monad m => a -> m a
return (forall a.
a -> InfixOp -> Expression a -> Expression a -> Expression a
InfixExpr SourcePos
pos InfixOp
constr)  -- points-free, returns a function


-- apparently, expression tables can't handle immediately-nested prefixes
parsePrefixedExpr :: Stream s Identity Char => ExpressionParser s
parsePrefixedExpr :: forall s. Stream s Identity Char => ExpressionParser s
parsePrefixedExpr = do
  SourcePos
pos <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  Maybe PrefixOp
op <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall a b. (a -> b) -> a -> b
$ (forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"!" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return PrefixOp
PrefixLNot) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> 
                      (forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"~" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return PrefixOp
PrefixBNot) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                      (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s a. Stream s Identity Char => Parser s a -> Parser s a
lexeme forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-')) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                       forall (m :: * -> *) a. Monad m => a -> m a
return PrefixOp
PrefixMinus) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                      (forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (forall s a. Stream s Identity Char => Parser s a -> Parser s a
lexeme forall a b. (a -> b) -> a -> b
$ forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'+' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'+')) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
                       forall (m :: * -> *) a. Monad m => a -> m a
return PrefixOp
PrefixPlus) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                      (forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"typeof" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return PrefixOp
PrefixTypeof) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                      (forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"void" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return PrefixOp
PrefixVoid) forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                      (forall s. Stream s Identity Char => String -> Parser s ()
reserved String
"delete" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return PrefixOp
PrefixDelete)
  case Maybe PrefixOp
op of
    Maybe PrefixOp
Nothing -> forall s. Stream s Identity Char => ExpressionParser s
unaryAssignExpr
    Just PrefixOp
op -> do
      ParsedExpression
innerExpr <- forall s. Stream s Identity Char => ExpressionParser s
parsePrefixedExpr
      forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> PrefixOp -> Expression a -> Expression a
PrefixExpr SourcePos
pos PrefixOp
op ParsedExpression
innerExpr)

exprTable:: Stream s Identity Char => [[Operator s ParserState Identity ParsedExpression]]
exprTable :: forall s.
Stream s Identity Char =>
[[Operator s ParserState Identity ParsedExpression]]
exprTable = 
  [ [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"*" InfixOp
OpMul
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"/" InfixOp
OpDiv
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"%" InfixOp
OpMod
    ]
  , [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"+" InfixOp
OpAdd
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"-" InfixOp
OpSub
    ]
  , [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"<<" InfixOp
OpLShift
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
">>" InfixOp
OpSpRShift
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
">>>" InfixOp
OpZfRShift
    ]
  , [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"<" InfixOp
OpLT
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"<=" InfixOp
OpLEq
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
">" InfixOp
OpGT
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
">=" InfixOp
OpGEq
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"instanceof" InfixOp
OpInstanceof
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"in" InfixOp
OpIn
    ]
  , [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"==" InfixOp
OpEq
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"!=" InfixOp
OpNEq
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"===" InfixOp
OpStrictEq
    , forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"!==" InfixOp
OpStrictNEq
    ]
  , [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"&" InfixOp
OpBAnd ]
  , [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"^" InfixOp
OpBXor ]
  , [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"|" InfixOp
OpBOr ]
  , [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"&&" InfixOp
OpLAnd ]
  , [ forall {s}.
Stream s Identity Char =>
String
-> InfixOp -> Operator s ParserState Identity ParsedExpression
makeInfixExpr String
"||" InfixOp
OpLOr ]
  ]

parseExpression' :: Stream s Identity Char => ExpressionParser s
parseExpression' :: forall s. Stream s Identity Char => ExpressionParser s
parseExpression' = 
  forall s (m :: * -> *) t u a.
Stream s m t =>
OperatorTable s u m a -> ParsecT s u m a -> ParsecT s u m a
buildExpressionParser forall s.
Stream s Identity Char =>
[[Operator s ParserState Identity ParsedExpression]]
exprTable forall s. Stream s Identity Char => ExpressionParser s
parsePrefixedExpr forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"simple expression"

asLValue :: Stream s Identity Char
         => SourcePos
         -> Expression SourcePos 
         -> Parser s (LValue SourcePos)
asLValue :: forall s.
Stream s Identity Char =>
SourcePos -> ParsedExpression -> Parser s (LValue SourcePos)
asLValue SourcePos
p' ParsedExpression
e = case ParsedExpression
e of
  VarRef SourcePos
p (Id SourcePos
_ String
x) -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> String -> LValue a
LVar SourcePos
p String
x)
  DotRef SourcePos
p ParsedExpression
e (Id SourcePos
_ String
x) -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a -> String -> LValue a
LDot SourcePos
p ParsedExpression
e String
x)
  BracketRef SourcePos
p ParsedExpression
e1 ParsedExpression
e2 -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Expression a -> Expression a -> LValue a
LBracket SourcePos
p ParsedExpression
e1 ParsedExpression
e2)
  ParsedExpression
otherwise -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"expected a left-value at " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show SourcePos
p'

lvalue :: Stream s Identity Char => Parser s (LValue SourcePos)
lvalue :: forall s. Stream s Identity Char => Parser s (LValue SourcePos)
lvalue = do
  SourcePos
p <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  ParsedExpression
e <- forall s.
Stream s Identity Char =>
Maybe ParsedExpression -> ExpressionParser s
parseSimpleExpr forall a. Maybe a
Nothing
  forall s.
Stream s Identity Char =>
SourcePos -> ParsedExpression -> Parser s (LValue SourcePos)
asLValue SourcePos
p ParsedExpression
e

unaryAssignExpr :: Stream s Identity Char => ExpressionParser s
unaryAssignExpr :: forall s. Stream s Identity Char => ExpressionParser s
unaryAssignExpr = do
  SourcePos
p <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  let prefixInc :: ExpressionParser s
prefixInc = do
        forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"++"
        forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall a. a -> UnaryAssignOp -> LValue a -> Expression a
UnaryAssignExpr SourcePos
p UnaryAssignOp
PrefixInc) forall s. Stream s Identity Char => Parser s (LValue SourcePos)
lvalue
  let prefixDec :: ExpressionParser s
prefixDec = do
        forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"--"
        forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall a. a -> UnaryAssignOp -> LValue a -> Expression a
UnaryAssignExpr SourcePos
p UnaryAssignOp
PrefixDec) forall s. Stream s Identity Char => Parser s (LValue SourcePos)
lvalue
  let postfixInc :: ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
postfixInc ParsedExpression
e = do
        forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"++"
        forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall a. a -> UnaryAssignOp -> LValue a -> Expression a
UnaryAssignExpr SourcePos
p UnaryAssignOp
PostfixInc) (forall s.
Stream s Identity Char =>
SourcePos -> ParsedExpression -> Parser s (LValue SourcePos)
asLValue SourcePos
p ParsedExpression
e)
  let postfixDec :: ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
postfixDec ParsedExpression
e = do
        forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"--"
        forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall a. a -> UnaryAssignOp -> LValue a -> Expression a
UnaryAssignExpr SourcePos
p UnaryAssignOp
PostfixDec) (forall s.
Stream s Identity Char =>
SourcePos -> ParsedExpression -> Parser s (LValue SourcePos)
asLValue SourcePos
p ParsedExpression
e)
  let other :: ExpressionParser s
other = do
        ParsedExpression
e <- forall s.
Stream s Identity Char =>
Maybe ParsedExpression -> ExpressionParser s
parseSimpleExpr forall a. Maybe a
Nothing
        forall {s}.
Stream s Identity Char =>
ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
postfixInc ParsedExpression
e forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall {s}.
Stream s Identity Char =>
ParsedExpression -> ParsecT s ParserState Identity ParsedExpression
postfixDec ParsedExpression
e forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return ParsedExpression
e
  ExpressionParser s
prefixInc forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ExpressionParser s
prefixDec forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ExpressionParser s
other

parseTernaryExpr':: Stream s Identity Char
                 => Parser s (ParsedExpression,ParsedExpression)
parseTernaryExpr' :: forall s.
Stream s Identity Char =>
Parser s (ParsedExpression, ParsedExpression)
parseTernaryExpr' = do
    forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"?"
    ParsedExpression
l <- forall s. Stream s Identity Char => ExpressionParser s
assignExpr
    forall s. Stream s Identity Char => Parser s String
colon
    ParsedExpression
r <- forall s. Stream s Identity Char => ExpressionParser s
assignExpr
    forall (m :: * -> *) a. Monad m => a -> m a
return (ParsedExpression
l,ParsedExpression
r)

parseTernaryExpr:: Stream s Identity Char => ExpressionParser s
parseTernaryExpr :: forall s. Stream s Identity Char => ExpressionParser s
parseTernaryExpr = do
  ParsedExpression
e <- forall s. Stream s Identity Char => ExpressionParser s
parseExpression'
  Maybe (ParsedExpression, ParsedExpression)
e' <- forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe forall s.
Stream s Identity Char =>
Parser s (ParsedExpression, ParsedExpression)
parseTernaryExpr'
  case Maybe (ParsedExpression, ParsedExpression)
e' of
    Maybe (ParsedExpression, ParsedExpression)
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ParsedExpression
e
    Just (ParsedExpression
l,ParsedExpression
r) -> do SourcePos
p <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                     forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a.
a -> Expression a -> Expression a -> Expression a -> Expression a
CondExpr SourcePos
p ParsedExpression
e ParsedExpression
l ParsedExpression
r

assignOp :: Stream s Identity Char => Parser s AssignOp
assignOp :: forall s. Stream s Identity Char => Parser s AssignOp
assignOp = (forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssign)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"+=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignAdd)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"-=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignSub)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"*=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignMul)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"/=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignDiv)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"%=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignMod)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"<<=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignLShift)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
">>=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignSpRShift)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
">>>=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignZfRShift)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"&=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignBAnd)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"^=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignBXor)
        forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>(forall s. Stream s Identity Char => String -> Parser s ()
reservedOp String
"|=" forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return AssignOp
OpAssignBOr)

assignExpr :: Stream s Identity Char => ExpressionParser s
assignExpr :: forall s. Stream s Identity Char => ExpressionParser s
assignExpr = do
  SourcePos
p <- forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  ParsedExpression
lhs <- forall s. Stream s Identity Char => ExpressionParser s
parseTernaryExpr
  let assign :: ExpressionParser s
assign = do
        AssignOp
op <- forall s. Stream s Identity Char => Parser s AssignOp
assignOp
        LValue SourcePos
lhs <- forall s.
Stream s Identity Char =>
SourcePos -> ParsedExpression -> Parser s (LValue SourcePos)
asLValue SourcePos
p ParsedExpression
lhs
        ParsedExpression
rhs <- forall s. Stream s Identity Char => ExpressionParser s
assignExpr
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> AssignOp -> LValue a -> Expression a -> Expression a
AssignExpr SourcePos
p AssignOp
op LValue SourcePos
lhs ParsedExpression
rhs)
  ExpressionParser s
assign forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> forall (m :: * -> *) a. Monad m => a -> m a
return ParsedExpression
lhs

parseExpression:: Stream s Identity Char => ExpressionParser s
parseExpression :: forall s. Stream s Identity Char => ExpressionParser s
parseExpression = forall s. Stream s Identity Char => ExpressionParser s
parseListExpr

-- | A parser that parses ECMAScript expressions
expression :: Stream s Identity Char => Parser s (Expression SourcePos)
expression :: forall s. Stream s Identity Char => ExpressionParser s
expression = forall s. Stream s Identity Char => ExpressionParser s
parseExpression

parseListExpr :: Stream s Identity Char => ExpressionParser s
parseListExpr :: forall s. Stream s Identity Char => ExpressionParser s
parseListExpr = forall s. Stream s Identity Char => ExpressionParser s
assignExpr 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]
`sepBy1` forall s. Stream s Identity Char => Parser s String
comma forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \[ParsedExpression]
exprs ->
  case [ParsedExpression]
exprs of
    [ParsedExpression
expr] -> forall (m :: * -> *) a. Monad m => a -> m a
return ParsedExpression
expr
    [ParsedExpression]
es     -> forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. a -> [Expression a] -> Expression a
ListExpr forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition (forall (m :: * -> *) a. Monad m => a -> m a
return [ParsedExpression]
es)

parseScript:: Stream s Identity Char => Parser s (JavaScript SourcePos)
parseScript :: forall s. Stream s Identity Char => Parser s (JavaScript SourcePos)
parseScript = do
  forall s. Stream s Identity Char => Parser s ()
whiteSpace
  forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 forall a. a -> [Statement a] -> JavaScript a
Script forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition (forall s. Stream s Identity Char => StatementParser s
parseStatement 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]
`sepBy` forall s. Stream s Identity Char => Parser s ()
whiteSpace)

-- | A parser that parses an ECMAScript program.
program :: Stream s Identity Char => Parser s (JavaScript SourcePos)
program :: forall s. Stream s Identity Char => Parser s (JavaScript SourcePos)
program = forall s. Stream s Identity Char => Parser s (JavaScript SourcePos)
parseScript
  
-- | Parse from a stream given a parser, same as 'Text.Parsec.parse'
-- in Parsec. We can use this to parse expressions or statements alone,
-- not just whole programs.
parse :: Stream s Identity Char
      => Parser s a -- ^ The parser to use
      -> SourceName -- ^ Name of the source file
      -> s -- ^ the stream to parse, usually a 'String'
      -> Either ParseError a
parse :: forall s a.
Stream s Identity Char =>
Parser s a -> String -> s -> Either ParseError a
parse Parser s a
p = forall s t u a.
Stream s Identity t =>
Parsec s u a -> u -> String -> s -> Either ParseError a
runParser Parser s a
p ParserState
initialParserState

-- | A convenience function that takes a 'String' and tries to parse
-- it as an ECMAScript program:
--
-- > parseFromString = parse program ""
parseFromString :: String -- ^ JavaScript source to parse
                  -> Either ParseError (JavaScript SourcePos)
parseFromString :: String -> Either ParseError (JavaScript SourcePos)
parseFromString = forall s a.
Stream s Identity Char =>
Parser s a -> String -> s -> Either ParseError a
parse forall s. Stream s Identity Char => Parser s (JavaScript SourcePos)
program String
""

-- | A convenience function that takes a filename and tries to parse
-- the file contents an ECMAScript program, it fails with an error
-- message if it can't.
parseFromFile :: (Error e, MonadIO m, MonadError e m) => String -- ^ file name
                -> m (JavaScript SourcePos)
parseFromFile :: forall e (m :: * -> *).
(Error e, MonadIO m, MonadError e m) =>
String -> m (JavaScript SourcePos)
parseFromFile String
fname =
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO String
readFile String
fname) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \String
source ->
  case forall s a.
Stream s Identity Char =>
Parser s a -> String -> s -> Either ParseError a
parse forall s. Stream s Identity Char => Parser s (JavaScript SourcePos)
program String
fname String
source of
    Left ParseError
err -> forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall a b. (a -> b) -> a -> b
$ forall a. Error a => String -> a
strMsg forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show ParseError
err
    Right JavaScript SourcePos
js -> forall (m :: * -> *) a. Monad m => a -> m a
return JavaScript SourcePos
js

-- | Read a JavaScript program from file an parse it into a list of
-- statements
parseJavaScriptFromFile :: MonadIO m => String -- ^ file name
                        -> m [Statement SourcePos]
parseJavaScriptFromFile :: forall (m :: * -> *). MonadIO m => String -> m [ParsedStatement]
parseJavaScriptFromFile String
filename = do
  String
chars <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ String -> IO String
readFile String
filename
  case forall s a.
Stream s Identity Char =>
Parser s a -> String -> s -> Either ParseError a
parse forall s. Stream s Identity Char => Parser s (JavaScript SourcePos)
parseScript String
filename String
chars of
    Left ParseError
err               -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall e a. Exception e => e -> IO a
throwIO forall a b. (a -> b) -> a -> b
$ String -> IOError
userError forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show ParseError
err
    Right (Script SourcePos
_ [ParsedStatement]
stmts) -> forall (m :: * -> *) a. Monad m => a -> m a
return [ParsedStatement]
stmts

-- | Parse a JavaScript program from a string
parseScriptFromString :: String -- ^ source file name
                      -> String -- ^ JavaScript source to parse
                      -> Either ParseError (JavaScript SourcePos)
parseScriptFromString :: String -> String -> Either ParseError (JavaScript SourcePos)
parseScriptFromString = forall s a.
Stream s Identity Char =>
Parser s a -> String -> s -> Either ParseError a
parse forall s. Stream s Identity Char => Parser s (JavaScript SourcePos)
parseScript

-- | Parse a JavaScript source string into a list of statements
parseString :: String -- ^ JavaScript source
            -> [Statement SourcePos]
parseString :: String -> [ParsedStatement]
parseString String
str = case forall s a.
Stream s Identity Char =>
Parser s a -> String -> s -> Either ParseError a
parse forall s. Stream s Identity Char => Parser s (JavaScript SourcePos)
parseScript String
"" String
str of
  Left ParseError
err -> forall a. HasCallStack => String -> a
error (forall a. Show a => a -> String
show ParseError
err)
  Right (Script SourcePos
_ [ParsedStatement]
stmts) -> [ParsedStatement]
stmts