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 import qualified Data.Map as Map data TricuArgs = Repl | Evaluate { file :: Maybe FilePath , output :: Maybe FilePath , form :: EvaluatedForm } | Decode { file :: 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.\n \ \ Defaults to stdin." &= name "f" , output = def &= typ "OUTPUT" &= help "Optional output file path for resulting output.\n \ \ Defaults to stdout." &= name "o" , form = FSL &= typ "FORM" &= help "Optional output form: (fsl|tree|ast|ternary|ascii).\n \ \ Defaults to fsl \"Fork Stem Leaf\" form." &= name "t" } &= help "Evaluate tricu and return the result of the expression in the final line" &= explicit &= name "eval" decodeMode :: TricuArgs decodeMode = Decode { file = def &= help "Optional input file path to attempt decoding.\n \ \ Defaults to stdin." &= name "f" &= typ "FILE" } &= 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 { file = maybeFilePath } -> do value <- case maybeFilePath of Just filePath -> readFile filePath Nothing -> getContents putStrLn $ decodeResult $ result $ evalTricu library $ parseTricu value runTricu :: String -> T runTricu = result . evalTricu Map.empty . parseTricu