diff --git a/.gitea/workflows/test-and-build.yml b/.gitea/workflows/test-and-build.yml index 95ebb58..7b8cc18 100644 --- a/.gitea/workflows/test-and-build.yml +++ b/.gitea/workflows/test-and-build.yml @@ -54,16 +54,12 @@ jobs: cp -L ./result/bin/tricu ./tricu chmod 755 ./tricu nix develop --command upx ./tricu - - - name: Setup go for release action - uses: actions/setup-go@v5 - with: - go-version: '>=1.20.1' - + - name: Release binary - uses: https://gitea.com/actions/release-action@main + uses: akkuman/gitea-release-action@v1 with: files: |- ./tricu - api_key: '${{ secrets.RELEASE_TOKEN }}' + token: '${{ secrets.RELEASE_TOKEN }}' + body: '${{ gitea.event.head_commit.message }}' pre_release: true diff --git a/README.md b/README.md index 12eb641..720326f 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ tricu eval [OPTIONS] -f --file=FILE Input file path(s) for evaluation. Defaults to stdin. - -t --form=FORM Optional output form: (tree|fsl|ast|ternary|ascii). + -t --form=FORM Optional output form: (tree|fsl|ast|ternary|ascii|decode). Defaults to tricu-compatible `t` tree form. tricu decode [OPTIONS] diff --git a/demos/equality.tri b/demos/equality.tri index efbfabe..f450afd 100644 --- a/demos/equality.tri +++ b/demos/equality.tri @@ -1,3 +1,5 @@ +main = lambdaEqualsTC + -- We represent `false` with a Leaf and `true` with a Stem Leaf demo_false = t demo_true = t t diff --git a/demos/levelOrderTraversal.tri b/demos/levelOrderTraversal.tri index ee46261..57c9c75 100644 --- a/demos/levelOrderTraversal.tri +++ b/demos/levelOrderTraversal.tri @@ -1,3 +1,4 @@ +main = exampleTwo -- Level Order Traversal of a labelled binary tree -- Objective: Print each "level" of the tree on a separate line -- @@ -58,5 +59,3 @@ exampleTwo = levelOrderTraversal [("1") [("2") [("4") [("8") t t] [("9") t t]] [("6") [("10") t t] [("12") t t]]] [("3") [("5") [("11") t t] t] [("7") t t]]] - -exampleTwo diff --git a/demos/size.tri b/demos/size.tri index 2efd2c1..74476cb 100644 --- a/demos/size.tri +++ b/demos/size.tri @@ -1,3 +1,5 @@ +main = size size + compose = \f g x : f (g x) succ = y (\self : @@ -17,5 +19,3 @@ size = (\x : self (\x y : compose (self x) (self y)) x)) x 0)) - -size size diff --git a/demos/toSource.tri b/demos/toSource.tri index e2fb054..f8419ea 100644 --- a/demos/toSource.tri +++ b/demos/toSource.tri @@ -1,3 +1,4 @@ +main = toSource not? -- Thanks to intensionality, we can inspect the structure of a given value -- even if it's a function. This includes lambdas which are eliminated to -- Tree Calculus (TC) terms during evaluation. diff --git a/src/Eval.hs b/src/Eval.hs index 51e9993..27dc436 100644 --- a/src/Eval.hs +++ b/src/Eval.hs @@ -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." diff --git a/src/FileEval.hs b/src/FileEval.hs index b453eed..40a14c4 100644 --- a/src/FileEval.hs +++ b/src/FileEval.hs @@ -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 diff --git a/src/Main.hs b/src/Main.hs index 2335a99..52016da 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -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 diff --git a/src/REPL.hs b/src/REPL.hs index 407b423..b725209 100644 --- a/src/REPL.hs +++ b/src/REPL.hs @@ -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 diff --git a/src/Research.hs b/src/Research.hs index f93bc24..c29f494 100644 --- a/src/Research.hs +++ b/src/Research.hs @@ -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 diff --git a/test/Spec.hs b/test/Spec.hs index a44d320..eb04e6f 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -488,8 +488,9 @@ fileEval = testGroup "File evaluation tests" res @?= Fork (Stem Leaf) Leaf , testCase "Mapping and Equality" $ do - res <- liftIO $ evaluateFileResult "./test/map.tri" - res @?= Stem Leaf + library <- liftIO $ evaluateFile "./lib/base.tri" + fEnv <- liftIO $ evaluateFileWithContext library "./test/map.tri" + (mainResult fEnv) @?= Stem Leaf , testCase "Eval and decoding string" $ do library <- liftIO $ evaluateFile "./lib/base.tri" diff --git a/test/comments-1.tri b/test/comments-1.tri index ee8de08..82ef6bd 100644 --- a/test/comments-1.tri +++ b/test/comments-1.tri @@ -2,7 +2,7 @@ -- t (t t) (t (t t t)) -- t (t t t) (t t) -- x = (\a : a) -t (t t) t -- Fork (Stem Leaf) Leaf +main = t (t t) t -- Fork (Stem Leaf) Leaf -- t t -- x -- x = (\a : a) diff --git a/test/fork.tri b/test/fork.tri index 66c0658..5b72b14 100644 --- a/test/fork.tri +++ b/test/fork.tri @@ -1 +1 @@ -t t t +main = t t t diff --git a/test/map.tri b/test/map.tri index f8c8f7a..b534482 100644 --- a/test/map.tri +++ b/test/map.tri @@ -1,24 +1,2 @@ -false = t -true = t t -_ = t -k = t t -i = t (t k) t -s = t (t (k t)) t -m = s i i -b = s (k s) k -c = s (s (k s) (s (k k) s)) (k k) -iC = (\a b c : s a (k c) b) -yi = (\i : b m (c b (i m))) -y = yi iC -triage = (\a b c : t (t a b) c) -pair = t -matchList = (\oe oc : triage oe _ oc) -lconcat = y (\self : matchList (\k : k) (\h r k : pair h (self r k))) -hmap = y (\self : matchList (\f : t) (\hd tl f : pair (f hd) (self tl f))) -map = (\f l : hmap l f) -lAnd = triage (\x : false) (\_ x : x) (\_ _ x : x) -lOr = triage (\x : x) (\_ _ : true) (\_ _ x : true) -equal = y (\self : triage (triage true (\z : false) (\y z : false)) (\ax : triage false (self ax) (\y z : false)) (\ax ay : triage false (\z : false) (\bx by : lAnd (self ax bx) (self ay by)))) - x = map (\i : lconcat "Successfully concatenated " i) [("two strings!")] -equal x [("Successfully concatenated two strings!")] +main = equal? x [("Successfully concatenated two strings!")] diff --git a/tricu.cabal b/tricu.cabal index de8367e..878e117 100644 --- a/tricu.cabal +++ b/tricu.cabal @@ -1,7 +1,7 @@ cabal-version: 1.12 name: tricu -version: 0.10.0 +version: 0.11.0 description: A micro-language for exploring Tree Calculus author: James Eversole maintainer: james@eversole.co