# File eval mode now relies on main function
All checks were successful
Test, Build, and Release / test (push) Successful in 1m26s
Test, Build, and Release / build (push) Successful in 1m15s

To encourage organizing code in a way that helps in understanding, I
have implemented the common idiom of requiring a `main` function. In
tricu and other functional languages, it is usually placed near the top
of the module. The evaluator gracefully handles the situation of passing
multiple files where the intermediary "library" files do not have main functions.
This commit is contained in:
James Eversole
2025-01-26 15:33:12 -06:00
parent a64b3f0829
commit 918d929c09
16 changed files with 39 additions and 58 deletions

View File

@ -179,3 +179,8 @@ result :: Env -> T
result r = case Map.lookup "__result" r of
Just a -> a
Nothing -> errorWithoutStackTrace "No __result field found in provided env"
mainResult :: Env -> T
mainResult r = case Map.lookup "main" r of
Just a -> a
Nothing -> errorWithoutStackTrace "No valid definition for `main` found."

View File

@ -13,9 +13,9 @@ evaluateFileResult filePath = do
contents <- readFile filePath
let asts = parseTricu contents
let finalEnv = evalTricu Map.empty asts
case Map.lookup "__result" finalEnv of
case Map.lookup "main" finalEnv of
Just finalResult -> return finalResult
Nothing -> errorWithoutStackTrace "No expressions to evaluate found"
Nothing -> errorWithoutStackTrace "No `main` function detected"
evaluateFile :: FilePath -> IO Env
evaluateFile filePath = do

View File

@ -1,6 +1,6 @@
module Main where
import Eval (evalTricu, result)
import Eval (evalTricu, mainResult, result)
import FileEval
import Parser (parseTricu)
import REPL
@ -16,7 +16,7 @@ import qualified Data.Map as Map
data TricuArgs
= Repl
| Evaluate { file :: [FilePath], form :: EvaluatedForm }
| Decode { file :: [FilePath] }
| TDecode { file :: [FilePath] }
deriving (Show, Data, Typeable)
replMode :: TricuArgs
@ -31,7 +31,7 @@ evaluateMode = Evaluate
\ Defaults to stdin."
&= name "f" &= typ "FILE"
, form = TreeCalculus &= typ "FORM"
&= help "Optional output form: (tree|fsl|ast|ternary|ascii).\n \
&= help "Optional output form: (tree|fsl|ast|ternary|ascii|decode).\n \
\ Defaults to tricu-compatible `t` tree form."
&= name "t"
}
@ -40,7 +40,7 @@ evaluateMode = Evaluate
&= name "eval"
decodeMode :: TricuArgs
decodeMode = Decode
decodeMode = TDecode
{ file = def
&= help "Optional input file path to attempt decoding.\n \
\ Defaults to stdin."
@ -70,10 +70,10 @@ main = do
(filePath:restFilePaths) -> do
initialEnv <- evaluateFile filePath
finalEnv <- foldM evaluateFileWithContext initialEnv restFilePaths
pure $ result finalEnv
pure $ mainResult finalEnv
let fRes = formatResult form result
putStr fRes
Decode { file = filePaths } -> do
TDecode { file = filePaths } -> do
value <- case filePaths of
[] -> getContents
(filePath:_) -> readFile filePath

View File

@ -59,10 +59,3 @@ repl env = runInputT defaultSettings (loop env)
strip :: String -> String
strip = dropWhileEnd isSpace . dropWhile isSpace
decodeResult :: T -> String
decodeResult tc
| Right num <- toNumber tc = show num
| Right str <- toString tc = "\"" ++ str ++ "\""
| Right list <- toList tc = "[" ++ intercalate ", " (map decodeResult list) ++ "]"
| otherwise = formatResult TreeCalculus tc

View File

@ -45,7 +45,7 @@ data LToken
deriving (Show, Eq, Ord)
-- Output formats
data EvaluatedForm = TreeCalculus | FSL | AST | Ternary | Ascii
data EvaluatedForm = TreeCalculus | FSL | AST | Ternary | Ascii | Decode
deriving (Show, Data, Typeable)
-- Environment containing previously evaluated TC terms
@ -115,6 +115,7 @@ formatResult FSL = show
formatResult AST = show . toAST
formatResult Ternary = toTernaryString
formatResult Ascii = toAscii
formatResult Decode = decodeResult
toSimpleT :: String -> String
toSimpleT s = T.unpack
@ -147,4 +148,9 @@ toAscii tree = go tree "" True
++ go left (prefix ++ (if isLast then " " else "| ")) False
++ go right (prefix ++ (if isLast then " " else "| ")) True
-- Utility
decodeResult :: T -> String
decodeResult tc
| Right num <- toNumber tc = show num
| Right str <- toString tc = "\"" ++ str ++ "\""
| Right list <- toList tc = "[" ++ intercalate ", " (map decodeResult list) ++ "]"
| otherwise = formatResult TreeCalculus tc