module Unison.Parsers where

import Data.Text qualified as Text
import Unison.Builtin qualified as Builtin
import Unison.Parser.Ann (Ann)
import Unison.Prelude
import Unison.PrintError (defaultWidth, prettyParseError)
import Unison.Symbol (Symbol)
import Unison.Syntax.FileParser qualified as FileParser
import Unison.Syntax.Parser qualified as Parser
import Unison.Syntax.TermParser qualified as TermParser
import Unison.Syntax.TypeParser qualified as TypeParser
import Unison.Term (Term)
import Unison.Type (Type)
import Unison.UnisonFile (UnisonFile)
import Unison.Util.Pretty qualified as Pr
import Unison.Var (Var)

unsafeGetRightFrom :: (Var v, Show v) => String -> Either (Parser.Err v) a -> a
unsafeGetRightFrom :: forall v a. (Var v, Show v) => String -> Either (Err v) a -> a
unsafeGetRightFrom String
src =
  (Err v -> a) -> (a -> a) -> Either (Err v) a -> a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> (Err v -> String) -> Err v -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Width -> Pretty ColorText -> String
Pr.toANSI Width
defaultWidth (Pretty ColorText -> String)
-> (Err v -> Pretty ColorText) -> Err v -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Err v -> Pretty ColorText
forall v. Var v => String -> Err v -> Pretty ColorText
prettyParseError String
src) a -> a
forall a. a -> a
id

parse ::
  (Monad m, Var v) =>
  Parser.P v m a ->
  String ->
  Parser.ParsingEnv m ->
  m (Either (Parser.Err v) a)
parse :: forall (m :: * -> *) v a.
(Monad m, Var v) =>
P v m a -> String -> ParsingEnv m -> m (Either (Err v) a)
parse P v m a
p = P v m a -> String -> ParsingEnv m -> m (Either (Err v) a)
forall (m :: * -> *) v a.
(Monad m, Ord v) =>
P v m a -> String -> ParsingEnv m -> m (Either (Err v) a)
Parser.run (P v m a -> P v m a
forall v (m :: * -> *) a. Ord v => P v m a -> P v m a
Parser.root P v m a
p)

parseTerm ::
  (Monad m, Var v) =>
  String ->
  Parser.ParsingEnv m ->
  m (Either (Parser.Err v) (Term v Ann))
parseTerm :: forall (m :: * -> *) v.
(Monad m, Var v) =>
String -> ParsingEnv m -> m (Either (Err v) (Term v Ann))
parseTerm = P v m (Term v Ann)
-> String -> ParsingEnv m -> m (Either (Err v) (Term v Ann))
forall (m :: * -> *) v a.
(Monad m, Var v) =>
P v m a -> String -> ParsingEnv m -> m (Either (Err v) a)
parse P v m (Term v Ann)
forall (m :: * -> *) v. (Monad m, Var v) => TermP v m
TermParser.term

parseType ::
  (Monad m, Var v) =>
  String ->
  Parser.ParsingEnv m ->
  m (Either (Parser.Err v) (Type v Ann))
parseType :: forall (m :: * -> *) v.
(Monad m, Var v) =>
String -> ParsingEnv m -> m (Either (Err v) (Type v Ann))
parseType = P v m (Type v Ann)
-> String -> ParsingEnv m -> m (Either (Err v) (Type v Ann))
forall (m :: * -> *) v a.
(Monad m, Ord v) =>
P v m a -> String -> ParsingEnv m -> m (Either (Err v) a)
Parser.run (P v m (Type v Ann) -> P v m (Type v Ann)
forall v (m :: * -> *) a. Ord v => P v m a -> P v m a
Parser.root P v m (Type v Ann)
forall (m :: * -> *) v. (Monad m, Var v) => TypeP v m
TypeParser.valueType)

parseFile ::
  (Monad m, Var v) =>
  FilePath ->
  String ->
  Parser.ParsingEnv m ->
  m (Either (Parser.Err v) (UnisonFile v Ann))
parseFile :: forall (m :: * -> *) v.
(Monad m, Var v) =>
String
-> String -> ParsingEnv m -> m (Either (Err v) (UnisonFile v Ann))
parseFile String
filename String
s = P v m (UnisonFile v Ann)
-> String
-> String
-> ParsingEnv m
-> m (Either (Err v) (UnisonFile v Ann))
forall (m :: * -> *) v a.
(Monad m, Ord v) =>
P v m a -> String -> String -> ParsingEnv m -> m (Either (Err v) a)
Parser.run' (P v m (UnisonFile v Ann) -> P v m (UnisonFile v Ann)
forall v (m :: * -> *) a. Ord v => P v m a -> P v m a
Parser.rootFile P v m (UnisonFile v Ann)
forall (m :: * -> *) v.
(Monad m, Var v) =>
P v m (UnisonFile v Ann)
FileParser.file) String
s String
filename

readAndParseFile ::
  (MonadIO m, Var v) =>
  Parser.ParsingEnv m ->
  FilePath ->
  m (Either (Parser.Err v) (UnisonFile v Ann))
readAndParseFile :: forall (m :: * -> *) v.
(MonadIO m, Var v) =>
ParsingEnv m -> String -> m (Either (Err v) (UnisonFile v Ann))
readAndParseFile ParsingEnv m
penv String
fileName = do
  Text
txt <- IO Text -> m Text
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (String -> IO Text
readUtf8 String
fileName)
  let src :: String
src = Text -> String
Text.unpack Text
txt
  String
-> String -> ParsingEnv m -> m (Either (Err v) (UnisonFile v Ann))
forall (m :: * -> *) v.
(Monad m, Var v) =>
String
-> String -> ParsingEnv m -> m (Either (Err v) (UnisonFile v Ann))
parseFile String
fileName String
src ParsingEnv m
penv

unsafeParseTerm :: (Monad m, Var v) => String -> Parser.ParsingEnv m -> m (Term v Ann)
unsafeParseTerm :: forall (m :: * -> *) v.
(Monad m, Var v) =>
String -> ParsingEnv m -> m (Term v Ann)
unsafeParseTerm String
s ParsingEnv m
env =
  String -> Either (Err v) (Term v Ann) -> Term v Ann
forall v a. (Var v, Show v) => String -> Either (Err v) a -> a
unsafeGetRightFrom String
s (Either (Err v) (Term v Ann) -> Term v Ann)
-> m (Either (Err v) (Term v Ann)) -> m (Term v Ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsingEnv m -> m (Either (Err v) (Term v Ann))
forall (m :: * -> *) v.
(Monad m, Var v) =>
String -> ParsingEnv m -> m (Either (Err v) (Term v Ann))
parseTerm String
s ParsingEnv m
env

unsafeReadAndParseFile ::
  Parser.ParsingEnv IO -> FilePath -> IO (UnisonFile Symbol Ann)
unsafeReadAndParseFile :: ParsingEnv IO -> String -> IO (UnisonFile Symbol Ann)
unsafeReadAndParseFile ParsingEnv IO
penv String
fileName = do
  Text
txt <- String -> IO Text
readUtf8 String
fileName
  let str :: String
str = Text -> String
Text.unpack Text
txt
  String
-> Either (Err Symbol) (UnisonFile Symbol Ann)
-> UnisonFile Symbol Ann
forall v a. (Var v, Show v) => String -> Either (Err v) a -> a
unsafeGetRightFrom String
str (Either (Err Symbol) (UnisonFile Symbol Ann)
 -> UnisonFile Symbol Ann)
-> IO (Either (Err Symbol) (UnisonFile Symbol Ann))
-> IO (UnisonFile Symbol Ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> String
-> ParsingEnv IO
-> IO (Either (Err Symbol) (UnisonFile Symbol Ann))
forall (m :: * -> *) v.
(Monad m, Var v) =>
String
-> String -> ParsingEnv m -> m (Either (Err v) (UnisonFile v Ann))
parseFile String
fileName String
str ParsingEnv IO
penv

unsafeParseFileBuiltinsOnly ::
  FilePath -> IO (UnisonFile Symbol Ann)
unsafeParseFileBuiltinsOnly :: String -> IO (UnisonFile Symbol Ann)
unsafeParseFileBuiltinsOnly =
  ParsingEnv IO -> String -> IO (UnisonFile Symbol Ann)
unsafeReadAndParseFile (ParsingEnv IO -> String -> IO (UnisonFile Symbol Ann))
-> ParsingEnv IO -> String -> IO (UnisonFile Symbol Ann)
forall a b. (a -> b) -> a -> b
$
    Parser.ParsingEnv
      { $sel:uniqueNames:ParsingEnv :: UniqueName
uniqueNames = UniqueName
forall a. Monoid a => a
mempty,
        $sel:uniqueTypeGuid:ParsingEnv :: Name -> IO (Maybe Text)
uniqueTypeGuid = \Name
_ -> Maybe Text -> IO (Maybe Text)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Text
forall a. Maybe a
Nothing,
        $sel:names:ParsingEnv :: Names
names = Names
Builtin.names,
        $sel:maybeNamespace:ParsingEnv :: Maybe Name
maybeNamespace = Maybe Name
forall a. Maybe a
Nothing,
        $sel:localNamespacePrefixedTypesAndConstructors:ParsingEnv :: Names
localNamespacePrefixedTypesAndConstructors = Names
forall a. Monoid a => a
mempty
      }

unsafeParseFile :: (Monad m) => String -> Parser.ParsingEnv m -> m (UnisonFile Symbol Ann)
unsafeParseFile :: forall (m :: * -> *).
Monad m =>
String -> ParsingEnv m -> m (UnisonFile Symbol Ann)
unsafeParseFile String
s ParsingEnv m
pEnv = String
-> Either (Err Symbol) (UnisonFile Symbol Ann)
-> UnisonFile Symbol Ann
forall v a. (Var v, Show v) => String -> Either (Err v) a -> a
unsafeGetRightFrom String
s (Either (Err Symbol) (UnisonFile Symbol Ann)
 -> UnisonFile Symbol Ann)
-> m (Either (Err Symbol) (UnisonFile Symbol Ann))
-> m (UnisonFile Symbol Ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> String
-> ParsingEnv m
-> m (Either (Err Symbol) (UnisonFile Symbol Ann))
forall (m :: * -> *) v.
(Monad m, Var v) =>
String
-> String -> ParsingEnv m -> m (Either (Err v) (UnisonFile v Ann))
parseFile String
"" String
s ParsingEnv m
pEnv