2024-12-18 18:55:51 -06:00
|
|
|
module Main where
|
|
|
|
|
2024-12-31 10:00:52 -06:00
|
|
|
import Eval (evalTricu, result)
|
2025-01-01 08:17:05 -06:00
|
|
|
import FileEval
|
2024-12-31 10:00:52 -06:00
|
|
|
import Parser (parseTricu)
|
2024-12-30 14:19:43 -06:00
|
|
|
import REPL
|
|
|
|
import Research
|
2024-12-18 18:55:51 -06:00
|
|
|
|
2025-01-01 19:27:04 -06:00
|
|
|
import Control.Monad (foldM)
|
2025-01-01 18:53:56 -06:00
|
|
|
import Control.Monad.IO.Class (liftIO)
|
2024-12-31 10:00:52 -06:00
|
|
|
import Text.Megaparsec (runParser)
|
2024-12-29 21:49:57 -06:00
|
|
|
import System.Console.CmdArgs
|
2024-12-18 18:55:51 -06:00
|
|
|
|
2024-12-29 20:29:41 -06:00
|
|
|
import qualified Data.Map as Map
|
|
|
|
|
2024-12-29 21:49:57 -06:00
|
|
|
data TricuArgs
|
|
|
|
= Repl
|
2025-01-01 19:27:04 -06:00
|
|
|
| Evaluate { file :: [FilePath], form :: EvaluatedForm }
|
|
|
|
| Decode { file :: [FilePath] }
|
2024-12-30 14:19:43 -06:00
|
|
|
deriving (Show, Data, Typeable)
|
|
|
|
|
2024-12-29 21:49:57 -06:00
|
|
|
replMode :: TricuArgs
|
|
|
|
replMode = Repl
|
|
|
|
&= help "Start interactive REPL"
|
|
|
|
&= auto
|
|
|
|
&= name "repl"
|
|
|
|
|
2025-01-01 08:17:05 -06:00
|
|
|
evaluateMode :: TricuArgs
|
2025-01-01 19:27:04 -06:00
|
|
|
evaluateMode = Evaluate
|
|
|
|
{ file = def &= help "Input file path(s) for evaluation.\n \
|
|
|
|
\ Defaults to stdin."
|
2025-01-01 19:32:41 -06:00
|
|
|
&= name "f" &= typ "FILE"
|
2025-01-01 19:27:04 -06:00
|
|
|
, form = FSL &= typ "FORM"
|
2025-01-01 08:34:17 -06:00
|
|
|
&= help "Optional output form: (fsl|tree|ast|ternary|ascii).\n \
|
2025-01-01 19:27:04 -06:00
|
|
|
\ Defaults to fsl \"Fork Stem Leaf\" form."
|
2024-12-30 14:19:43 -06:00
|
|
|
&= name "t"
|
|
|
|
}
|
2025-01-01 19:27:04 -06:00
|
|
|
&= help "Evaluate tricu and return the result of the final expression."
|
2024-12-29 21:49:57 -06:00
|
|
|
&= explicit
|
2025-01-01 08:17:05 -06:00
|
|
|
&= name "eval"
|
2024-12-29 21:49:57 -06:00
|
|
|
|
2024-12-30 14:19:43 -06:00
|
|
|
decodeMode :: TricuArgs
|
|
|
|
decodeMode = Decode
|
2025-01-01 19:27:04 -06:00
|
|
|
{ file = def
|
2025-01-01 19:32:41 -06:00
|
|
|
&= help "Optional input file path to attempt decoding.\n \
|
2025-01-01 19:27:04 -06:00
|
|
|
\ Defaults to stdin."
|
2025-01-01 19:32:41 -06:00
|
|
|
&= name "f" &= typ "FILE"
|
2024-12-30 14:19:43 -06:00
|
|
|
}
|
2025-01-01 19:27:04 -06:00
|
|
|
&= help "Decode a Tree Calculus value into a string representation."
|
2024-12-30 14:19:43 -06:00
|
|
|
&= explicit
|
|
|
|
&= name "decode"
|
|
|
|
|
2024-12-18 18:55:51 -06:00
|
|
|
main :: IO ()
|
2024-12-27 19:27:04 -06:00
|
|
|
main = do
|
2025-01-01 08:17:05 -06:00
|
|
|
args <- cmdArgs $ modes [replMode, evaluateMode, decodeMode]
|
2024-12-29 21:49:57 -06:00
|
|
|
&= help "tricu: Exploring Tree Calculus"
|
|
|
|
&= program "tricu"
|
2025-01-01 08:17:05 -06:00
|
|
|
&= summary "tricu Evaluator and REPL"
|
2024-12-29 21:49:57 -06:00
|
|
|
case args of
|
|
|
|
Repl -> do
|
|
|
|
putStrLn "Welcome to the tricu REPL"
|
|
|
|
putStrLn "You can exit with `CTRL+D` or the `:_exit` command.`"
|
2025-01-01 18:53:56 -06:00
|
|
|
library <- liftIO $ evaluateFile "./lib/base.tri"
|
2024-12-30 08:30:40 -06:00
|
|
|
repl library
|
2025-01-01 19:27:04 -06:00
|
|
|
Evaluate { file = filePaths, form = form } -> do
|
|
|
|
result <- case filePaths of
|
|
|
|
[] -> do
|
2025-01-01 08:17:05 -06:00
|
|
|
t <- getContents
|
|
|
|
pure $ runTricu t
|
2025-01-01 19:27:04 -06:00
|
|
|
(filePath:restFilePaths) -> do
|
|
|
|
initialEnv <- evaluateFile filePath
|
|
|
|
finalEnv <- foldM evaluateFileWithContext initialEnv restFilePaths
|
|
|
|
pure $ result finalEnv
|
2024-12-30 14:19:43 -06:00
|
|
|
let fRes = formatResult form result
|
2025-01-01 19:27:04 -06:00
|
|
|
putStr fRes
|
|
|
|
Decode { file = filePaths } -> do
|
|
|
|
value <- case filePaths of
|
|
|
|
[] -> getContents
|
|
|
|
(filePath:_) -> readFile filePath
|
2025-01-01 18:53:56 -06:00
|
|
|
library <- liftIO $ evaluateFile "./lib/base.tri"
|
2024-12-30 14:19:43 -06:00
|
|
|
putStrLn $ decodeResult $ result $ evalTricu library $ parseTricu value
|
2025-01-01 08:17:05 -06:00
|
|
|
|
|
|
|
runTricu :: String -> T
|
|
|
|
runTricu = result . evalTricu Map.empty . parseTricu
|