diff --git a/app/Main.hs b/app/Main.hs index 3a1ea88a7fdc2851d3221d8506f11527eca88310..fd999a1a2adaea68a2b5efb5424e7577e5736f51 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -8,55 +8,64 @@ import System.Console.Shell import System.Console.Shell.ShellMonad import System.Console.Shell.Backend.Haskeline (haskelineBackend) +import qualified Data.Map as Map import qualified Paths_lambda_calculator as P -import Language.Lambda import Language.Lambda.Util.PrettyPrint -import Language.SystemF + +import qualified Language.Lambda as Lambda +import qualified Language.SystemF as SystemF main :: IO () main = execParser opts >>= runShell' where opts = info (helper <*> cliParser) (briefDesc <> progDesc "A Lambda Calculus Interpreter") --- Option Parsing +-- | Option Parsing data CliOptions = CliOptions { language :: Eval Language, version :: Bool - } +} --- Supported Languages: +-- | Supported Languages: -- --- * Untyped Lambda Calculus --- * System F +-- * Untyped Lambda Calculus +-- * System F data Language = Untyped | SystemF --- The result of an evaluation -type Result a = Either a -- An error - a -- The result +-- | Globals are Maps that map names to expressions. +data Globals n t + = GlobalsUntyped (Map.Map n (Lambda.LambdaExpr n)) + | GlobalsSystemF (Map.Map n (SystemF.SystemFExpr n t)) + +-- | The result of an evaluation +type Result a state = Either a -- ^ An error + (a, state) -- ^ The result along with its state --- Represent a language together with its evaluation function -data Eval a = Eval a (String -> Result String) +-- | Represent a language together with its evaluation function +data Eval a = Eval a (String -> Result String (Globals String String)) -untyped :: Eval Language +untyped :: Eval Language untyped = Eval Untyped eval - where eval = fromEvalString Language.Lambda.evalString + where eval = fromEvalString Lambda.evalString systemf :: Eval Language systemf = Eval SystemF eval - where eval = fromEvalString Language.SystemF.evalString + where eval = fromEvalString SystemF.evalString --- Take a typed evaluation function and return a function that returns a result +-- | Take a typed evaluation function and return a function that returns a result -- --- For example: --- (String -> Either ParseError (LambdaExpr String)) -> (String -> Result String) --- (String -> Either ParseError (SystemFExpr String String)) -> (String -> Result String) +-- For example: +-- (String -> Either ParseError (LambdaExpr String)) -> (String -> Result String) +-- (String -> Either ParseError (SystemFExpr String String)) -> (String -> Result String) fromEvalString :: (Show s, PrettyPrint p) => (String -> Either s p) - -> (String -> Result String) -fromEvalString f = either (Left . show) (Right . prettyPrint) . f + -> (String -> Result String (Globals String String)) +fromEvalString f = either (Left . show) (Right . toResult) . f + -- TODO[sgillespie]: Remove placeholder below + where toResult expr = (prettyPrint expr, GlobalsUntyped Map.empty) cliParser :: Parser CliOptions cliParser = CliOptions @@ -69,14 +78,14 @@ cliParser = CliOptions short 'v' <> help "Print the version") --- Interactive Shell +-- | Interactive Shell runShell' :: CliOptions -> IO () runShell' CliOptions{version=True} = putStrLn version' runShell' CliOptions{language=Eval lang eval} = runShell (mkShellDesc lang eval) haskelineBackend () mkShellDesc :: Language - -> (String -> Result String) + -> (String -> Result String (Globals String String)) -> ShellDescription () mkShellDesc language f = shellDesc' $ mkShellDescription commands (eval f) where shellDesc' d = d { @@ -98,10 +107,10 @@ commands = [ helpCommand "h" ] -eval :: (String -> Result String) -> String -> Sh s' () -eval f = either shellPutErrLn shellPutStrLn . f +eval :: (String -> Result String (Globals String String)) -> String -> Sh s' () +eval f = either shellPutErrLn shellPutStrLn . fmap fst . f --- Get the current version +-- | Get the current version version' :: String version' = showVersion P.version diff --git a/lambda-calculator.cabal b/lambda-calculator.cabal index 21391ff0018cd4fe65134eb4c520f42eaf0a96f6..760dba5cb729b034e5f46f0afc883b2267f7d085 100644 --- a/lambda-calculator.cabal +++ b/lambda-calculator.cabal @@ -2,7 +2,7 @@ -- -- see: https://github.com/sol/hpack -- --- hash: 797b677552c81b80399ac8b69e2e398479887a332862d9878a7c508a259975ee +-- hash: f7f43eaf08f4a2a78ad4d303404ea19c729aa53a0afa30fd0f99d8eb505b8306 name: lambda-calculator version: 2.0.0 @@ -55,6 +55,7 @@ executable lambda-calculator Shellac , Shellac-haskeline , base >=4.9 && <5 + , containers , lambda-calculator , optparse-applicative >=0.13 default-language: Haskell2010 diff --git a/package.yaml b/package.yaml index f935f548c941d0013be5ca8b5dfb72f2ad3a9955..925444faec887cbeccdf2e25884633653f338c83 100644 --- a/package.yaml +++ b/package.yaml @@ -37,6 +37,7 @@ executables: - -rtsopts - -with-rtsopts=-N dependencies: + - containers - lambda-calculator - optparse-applicative >=0.13 - Shellac