module Language.JavaScript.Parser.Parser (
   -- * Parsing
     parse
   , parseModule
   , readJs
   , readJsModule
   -- , readJsKeepComments
   , parseFile
   , parseFileUtf8
   -- * Parsing expressions
   -- parseExpr
   , parseUsing
   , showStripped
   , showStrippedMaybe
   ) where

import qualified Language.JavaScript.Parser.Grammar7 as P
import Language.JavaScript.Parser.Lexer
import qualified Language.JavaScript.Parser.AST as AST
import System.IO

-- | Parse JavaScript Program (Script)
-- Parse one compound statement, or a sequence of simple statements.
-- Generally used for interactive input, such as from the command line of an interpreter.
-- Return comments in addition to the parsed statements.
parse :: String -- ^ The input stream (Javascript source code).
      -> String -- ^ The name of the Javascript source (filename or input device).
      -> Either String AST.JSAST
         -- ^ An error or maybe the abstract syntax tree (AST) of zero
         -- or more Javascript statements, plus comments.
parse :: String -> String -> Either String JSAST
parse = Alex JSAST -> String -> String -> Either String JSAST
parseUsing Alex JSAST
P.parseProgram

-- | Parse JavaScript module
parseModule :: String -- ^ The input stream (JavaScript source code).
            -> String -- ^ The name of the JavaScript source (filename or input device).
            -> Either String AST.JSAST
            -- ^ An error or maybe the abstract syntax tree (AST) of zero
            -- or more JavaScript statements, plus comments.
parseModule :: String -> String -> Either String JSAST
parseModule = Alex JSAST -> String -> String -> Either String JSAST
parseUsing Alex JSAST
P.parseModule

readJsWith :: (String -> String -> Either String AST.JSAST)
           -> String
           -> AST.JSAST
readJsWith :: (String -> String -> Either String JSAST) -> String -> JSAST
readJsWith String -> String -> Either String JSAST
f String
input =
  case String -> String -> Either String JSAST
f String
input String
"src" of
    Left String
msg -> String -> JSAST
forall a. HasCallStack => String -> a
error (String -> String
forall a. Show a => a -> String
show String
msg)
    Right JSAST
p -> JSAST
p

readJs :: String -> AST.JSAST
readJs :: String -> JSAST
readJs = (String -> String -> Either String JSAST) -> String -> JSAST
readJsWith String -> String -> Either String JSAST
parse

readJsModule :: String -> AST.JSAST
readJsModule :: String -> JSAST
readJsModule = (String -> String -> Either String JSAST) -> String -> JSAST
readJsWith String -> String -> Either String JSAST
parseModule

-- | Parse the given file.
-- For UTF-8 support, make sure your locale is set such that
-- "System.IO.localeEncoding" returns "utf8"
parseFile :: FilePath -> IO AST.JSAST
parseFile :: String -> IO JSAST
parseFile String
filename =
  do
     x <- String -> IO String
readFile String
filename
     return $ readJs x

-- | Parse the given file, explicitly setting the encoding to UTF8
-- when reading it
parseFileUtf8 :: FilePath -> IO AST.JSAST
parseFileUtf8 :: String -> IO JSAST
parseFileUtf8 String
filename =
  do
     h <- String -> IOMode -> IO Handle
openFile String
filename IOMode
ReadMode
     hSetEncoding h utf8
     x <- hGetContents h
     return $ readJs x

showStripped :: AST.JSAST -> String
showStripped :: JSAST -> String
showStripped = JSAST -> String
AST.showStripped

showStrippedMaybe :: Show a => Either a AST.JSAST -> String
showStrippedMaybe :: forall a. Show a => Either a JSAST -> String
showStrippedMaybe Either a JSAST
maybeAst =
  case Either a JSAST
maybeAst of
    Left a
msg -> String
"Left (" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
msg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
    Right JSAST
p -> String
"Right (" String -> String -> String
forall a. [a] -> [a] -> [a]
++ JSAST -> String
AST.showStripped JSAST
p String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"

-- | Parse one compound statement, or a sequence of simple statements.
-- Generally used for interactive input, such as from the command line of an interpreter.
-- Return comments in addition to the parsed statements.
parseUsing ::
      Alex AST.JSAST -- ^ The parser to be used
      -> String -- ^ The input stream (Javascript source code).
      -> String -- ^ The name of the Javascript source (filename or input device).
      -> Either String AST.JSAST
         -- ^ An error or maybe the abstract syntax tree (AST) of zero
         -- or more Javascript statements, plus comments.

parseUsing :: Alex JSAST -> String -> String -> Either String JSAST
parseUsing Alex JSAST
p String
input String
_srcName = String -> Alex JSAST -> Either String JSAST
forall a. String -> Alex a -> Either String a
runAlex String
input Alex JSAST
p