tricu/src/Main.hs

82 lines
2.5 KiB
Haskell
Raw Normal View History

module Main where
import Eval (evalTricu, result)
import FileEval
import Library (library)
import Parser (parseTricu)
import REPL
import Research
import Text.Megaparsec (runParser)
import System.Console.CmdArgs
2024-12-29 20:29:41 -06:00
import qualified Data.Map as Map
data TricuArgs
= Repl
| Evaluate { file :: Maybe FilePath, output :: Maybe FilePath, form :: EvaluatedForm }
| Decode { input :: Maybe FilePath }
deriving (Show, Data, Typeable)
replMode :: TricuArgs
replMode = Repl
&= help "Start interactive REPL"
&= auto
&= name "repl"
evaluateMode :: TricuArgs
evaluateMode = Evaluate
{ file = def &= typ "FILE"
&= help "Optional input file path for evaluation.\nDefaults to stdin." &= name "f"
, output = def &= typ "OUTPUT"
&= help "Optional output file path for resulting output.\nDefaults to stdout." &= name "o"
, form = FSL &= typ "FORM"
&= help "Optional output form: (fsl|tree|ast|ternary|ascii).\nDefaults to fsl."
&= name "t"
}
&= help "Evaluate a file and return the result of the expression in the final line"
&= explicit
&= name "eval"
decodeMode :: TricuArgs
decodeMode = Decode
{ input = def &= typ "FILE"
&= help "Optional file path to attempt decoding.\nDefaults to stdin." &= name "f"
}
&= help "Decode a Tree Calculus value into a string representation"
&= explicit
&= name "decode"
main :: IO ()
main = do
args <- cmdArgs $ modes [replMode, evaluateMode, decodeMode]
&= help "tricu: Exploring Tree Calculus"
&= program "tricu"
&= summary "tricu Evaluator and REPL"
case args of
Repl -> do
putStrLn "Welcome to the tricu REPL"
putStrLn "You can exit with `CTRL+D` or the `:_exit` command.`"
repl library
Evaluate { file = maybeFilePath, output = maybeOutputPath, form = form } -> do
result <- case maybeFilePath of
Just filePath -> evaluateFile filePath
Nothing -> do
t <- getContents
pure $ runTricu t
let fRes = formatResult form result
case maybeOutputPath of
Just outputPath -> do
writeFile outputPath fRes
putStrLn $ "Output to: " ++ outputPath
Nothing -> putStr fRes
Decode { input = maybeInputPath } -> do
value <- case maybeInputPath of
Just inputPath -> readFile inputPath
Nothing -> getContents
putStrLn $ decodeResult $ result $ evalTricu library $ parseTricu value
runTricu :: String -> T
runTricu = result . evalTricu Map.empty . parseTricu