module Ast.Parser where

import qualified Ast.Parser.Program as PP
import qualified Ast.Parser.State as PS
import qualified Ast.Types as AT
import qualified Control.Monad.State as S
import qualified Text.Megaparsec as M

-- | Parses a string into an abstract syntax tree (AST).
-- The `parse` function takes a filename `String`, and an input `String` as a parameter and returns either an AST or an error message.
parse :: String -> String -> IO (Either String AT.Program)
parse :: String -> String -> IO (Either String Program)
parse String
sourceFile String
input = do
  (Either (ParseErrorBundle String ParseErrorCustom) Program
result, ParserState
_) <- StateT
  ParserState
  IO
  (Either (ParseErrorBundle String ParseErrorCustom) Program)
-> ParserState
-> IO
     (Either (ParseErrorBundle String ParseErrorCustom) Program,
      ParserState)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
S.runStateT (ParsecT ParseErrorCustom String (StateT ParserState IO) Program
-> String
-> String
-> StateT
     ParserState
     IO
     (Either (ParseErrorBundle String ParseErrorCustom) Program)
forall (m :: * -> *) e s a.
Monad m =>
ParsecT e s m a
-> String -> s -> m (Either (ParseErrorBundle s e) a)
M.runParserT (String
-> ParsecT ParseErrorCustom String (StateT ParserState IO) Program
PP.parseProgram String
sourceFile) String
sourceFile String
input) ParserState
PS.parserState
  case Either (ParseErrorBundle String ParseErrorCustom) Program
result of
    (Left ParseErrorBundle String ParseErrorCustom
err) -> Either String Program -> IO (Either String Program)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String Program -> IO (Either String Program))
-> Either String Program -> IO (Either String Program)
forall a b. (a -> b) -> a -> b
$ String -> Either String Program
forall a b. a -> Either a b
Left (ParseErrorBundle String ParseErrorCustom -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
M.errorBundlePretty ParseErrorBundle String ParseErrorCustom
err)
    (Right Program
program) -> Either String Program -> IO (Either String Program)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String Program -> IO (Either String Program))
-> Either String Program -> IO (Either String Program)
forall a b. (a -> b) -> a -> b
$ Program -> Either String Program
forall a b. b -> Either a b
Right Program
program