-- | Interface to the Futhark parser.
module Language.Futhark.Parser
  ( parseFuthark,
    parseFutharkWithComments,
    parseExp,
    parseModExp,
    parseType,
    parseDecOrExp,
    SyntaxError (..),
    Comment (..),
  )
where

import Data.Text qualified as T
import Language.Futhark.Parser.Parser
import Language.Futhark.Prop
import Language.Futhark.Syntax

-- | Parse an entire Futhark program from the given 'T.Text', using
-- the 'FilePath' as the source name for error messages.
parseFuthark ::
  FilePath ->
  T.Text ->
  Either SyntaxError UncheckedProg
parseFuthark :: FilePath -> Text -> Either SyntaxError UncheckedProg
parseFuthark = ParserMonad UncheckedProg
-> FilePath -> Text -> Either SyntaxError UncheckedProg
forall a. ParserMonad a -> FilePath -> Text -> Either SyntaxError a
parse ParserMonad UncheckedProg
prog

-- | Parse an entire Futhark program from the given 'T.Text', using
-- the 'FilePath' as the source name for error messages.  Also returns
-- the comments encountered.
parseFutharkWithComments ::
  FilePath ->
  T.Text ->
  Either SyntaxError (UncheckedProg, [Comment])
parseFutharkWithComments :: FilePath -> Text -> Either SyntaxError (UncheckedProg, [Comment])
parseFutharkWithComments = ParserMonad UncheckedProg
-> FilePath
-> Text
-> Either SyntaxError (UncheckedProg, [Comment])
forall a.
ParserMonad a
-> FilePath -> Text -> Either SyntaxError (a, [Comment])
parseWithComments ParserMonad UncheckedProg
prog

-- | Parse an Futhark expression from the given 'String', using the
-- 'FilePath' as the source name for error messages.
parseExp ::
  FilePath ->
  T.Text ->
  Either SyntaxError UncheckedExp
parseExp :: FilePath -> Text -> Either SyntaxError UncheckedExp
parseExp = ParserMonad UncheckedExp
-> FilePath -> Text -> Either SyntaxError UncheckedExp
forall a. ParserMonad a -> FilePath -> Text -> Either SyntaxError a
parse ParserMonad UncheckedExp
expression

-- | Parse a Futhark module expression from the given 'String', using the
-- 'FilePath' as the source name for error messages.
parseModExp ::
  FilePath ->
  T.Text ->
  Either SyntaxError (ModExpBase NoInfo Name)
parseModExp :: FilePath -> Text -> Either SyntaxError (ModExpBase NoInfo Name)
parseModExp = ParserMonad (ModExpBase NoInfo Name)
-> FilePath -> Text -> Either SyntaxError (ModExpBase NoInfo Name)
forall a. ParserMonad a -> FilePath -> Text -> Either SyntaxError a
parse ParserMonad (ModExpBase NoInfo Name)
modExpression

-- | Parse an Futhark type from the given 'String', using the
-- 'FilePath' as the source name for error messages.
parseType ::
  FilePath ->
  T.Text ->
  Either SyntaxError UncheckedTypeExp
parseType :: FilePath -> Text -> Either SyntaxError UncheckedTypeExp
parseType = ParserMonad UncheckedTypeExp
-> FilePath -> Text -> Either SyntaxError UncheckedTypeExp
forall a. ParserMonad a -> FilePath -> Text -> Either SyntaxError a
parse ParserMonad UncheckedTypeExp
futharkType

-- | Parse either an expression or a declaration; favouring
-- declarations in case of ambiguity.
parseDecOrExp ::
  FilePath ->
  T.Text ->
  Either SyntaxError (Either UncheckedDec UncheckedExp)
parseDecOrExp :: FilePath
-> Text -> Either SyntaxError (Either UncheckedDec UncheckedExp)
parseDecOrExp FilePath
file Text
input =
  case ParserMonad UncheckedDec
-> FilePath -> Text -> Either SyntaxError UncheckedDec
forall a. ParserMonad a -> FilePath -> Text -> Either SyntaxError a
parse ParserMonad UncheckedDec
declaration FilePath
file Text
input of
    Left {} -> UncheckedExp -> Either UncheckedDec UncheckedExp
forall a b. b -> Either a b
Right (UncheckedExp -> Either UncheckedDec UncheckedExp)
-> Either SyntaxError UncheckedExp
-> Either SyntaxError (Either UncheckedDec UncheckedExp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> Text -> Either SyntaxError UncheckedExp
parseExp FilePath
file Text
input
    Right UncheckedDec
d -> Either UncheckedDec UncheckedExp
-> Either SyntaxError (Either UncheckedDec UncheckedExp)
forall a b. b -> Either a b
Right (Either UncheckedDec UncheckedExp
 -> Either SyntaxError (Either UncheckedDec UncheckedExp))
-> Either UncheckedDec UncheckedExp
-> Either SyntaxError (Either UncheckedDec UncheckedExp)
forall a b. (a -> b) -> a -> b
$ UncheckedDec -> Either UncheckedDec UncheckedExp
forall a b. a -> Either a b
Left UncheckedDec
d