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 :: [Char] -> [Char] -> Either [Char] JSAST
parse = Alex JSAST -> [Char] -> [Char] -> Either [Char] 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 :: [Char] -> [Char] -> Either [Char] JSAST
parseModule = Alex JSAST -> [Char] -> [Char] -> Either [Char] JSAST
parseUsing Alex JSAST
P.parseModule

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

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

readJsModule :: String -> AST.JSAST
readJsModule :: [Char] -> JSAST
readJsModule = ([Char] -> [Char] -> Either [Char] JSAST) -> [Char] -> JSAST
readJsWith [Char] -> [Char] -> Either [Char] 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 :: [Char] -> IO JSAST
parseFile [Char]
filename =
  do
     x <- [Char] -> IO [Char]
readFile [Char]
filename
     return $ readJs x

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

showStripped :: AST.JSAST -> String
showStripped :: JSAST -> [Char]
showStripped = JSAST -> [Char]
AST.showStripped

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

-- | 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 -> [Char] -> [Char] -> Either [Char] JSAST
parseUsing Alex JSAST
p [Char]
input [Char]
_srcName = [Char] -> Alex JSAST -> Either [Char] JSAST
forall a. [Char] -> Alex a -> Either [Char] a
runAlex [Char]
input Alex JSAST
p