tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

commit cf0e2378e717d23f37844536e72306532ae029e9
parent d55ac43d6531a8a550e69c21124b122d3048622a
Author: James Eversole <james@eversole.co>
Date:   Thu, 22 May 2025 16:52:37 -0500

Update README and !help; fix list and name lookups

Diffstat:
MREADME.md | 23++++++++++++++---------
Msrc/ContentStore.hs | 8+++++---
Msrc/Eval.hs | 19++++++++++++++-----
Msrc/Main.hs | 1-
Msrc/REPL.hs | 9++++-----
5 files changed, 37 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md @@ -32,15 +32,20 @@ tricu < -- or calculate its size (/demos/size.tri) tricu < size not? tricu > 12 -tricu < -- REPL Commands: -tricu < !definitions -- Lists all available definitions -tricu < !output -- Change output format (Tree, FSL, AST, etc.) -tricu < !import -- Import definitions from a file -tricu < !exit -- Exit the REPL -tricu < !clear -- ANSI screen clear -tricu < !save -- Save all REPL definitions to a file that you can !import -tricu < !reset -- Clear all REPL definitions -tricu < !version -- Print tricu version +tricu < !help +tricu version 0.20.0 +Available commands: + !exit - Exit the REPL + !clear - Clear the screen + !reset - Reset preferences for selected versions + !help - Show tricu version and available commands + !output - Change output format (tree|fsl|ast|ternary|ascii|decode) + !definitions - List all defined terms in the content store + !import - Import definitions from file (definitions are stored) + !watch - Watch a file for changes (definitions are stored) + !versions - Show all versions of a term by name + !select - Select a specific version of a term for subsequent lookups + !tag - Add or update a tag for a term by hash or name ``` ## Content Store diff --git a/src/ContentStore.hs b/src/ContentStore.hs @@ -127,7 +127,9 @@ hashToTerm conn hashText = nameToTerm :: Connection -> Text -> IO (Maybe StoredTerm) nameToTerm conn nameText = - queryMaybeOne conn (selectStoredTermFields <> " WHERE names LIKE ? ORDER BY created_at DESC LIMIT 1") (Only $ "%" <> nameText <> "%") + queryMaybeOne conn + (selectStoredTermFields <> " WHERE (names = ? OR names LIKE ? OR names LIKE ? OR names LIKE ?) ORDER BY created_at DESC LIMIT 1") + (nameText, nameText <> T.pack ",%", T.pack "%," <> nameText <> T.pack ",%", T.pack "%," <> nameText) listStoredTerms :: Connection -> IO [StoredTerm] listStoredTerms conn = @@ -172,8 +174,8 @@ termVersions :: Connection -> String -> IO [(Text, T, Integer)] termVersions conn name = do let nameText = T.pack name results <- query conn - "SELECT hash, term_data, created_at FROM terms WHERE names LIKE ? ORDER BY created_at DESC" - (Only $ "%" <> nameText <> "%") + ("SELECT hash, term_data, created_at FROM terms WHERE (names = ? OR names LIKE ? OR names LIKE ? OR names LIKE ?) ORDER BY created_at DESC") + (nameText, nameText <> T.pack ",%", T.pack "%," <> nameText <> T.pack ",%", T.pack "%," <> nameText) catMaybes <$> mapM (\(hashVal, termDataVal, timestamp) -> do maybeT <- tryDeserializeTerm termDataVal diff --git a/src/Eval.hs b/src/Eval.hs @@ -137,6 +137,7 @@ elimLambda = go | lambdaList term = elimLambda $ lambdaListResult term | nestedLambda term = nestedLambdaResult term | application term = applicationResult term + | isSList term = slistTransform term | otherwise = term etaReduction (SLambda [v] (SApp f (SVar x Nothing))) = v == x && not (isFree v f) @@ -157,18 +158,26 @@ elimLambda = go nestedLambda (SLambda (_:_) _) = True nestedLambda _ = False nestedLambdaResult (SLambda (v:vs) body) - | null vs = toSKI v (elimLambda body) - | otherwise = elimLambda (SLambda [v] (SLambda vs body)) + | null vs = toSKI v (go body) -- Changed elimLambda to go + | otherwise = go (SLambda [v] (SLambda vs body)) -- Changed elimLambda to go application (SApp _ _) = True application _ = False - applicationResult (SApp f g) = SApp (elimLambda f) (elimLambda g) + applicationResult (SApp f g) = SApp (go f) (go g) -- Changed elimLambda to go + + isSList (SList _) = True + isSList _ = False + + slistTransform :: TricuAST -> TricuAST + slistTransform (SList xs) = foldr (\m r -> SApp (SApp TLeaf (go m)) r) TLeaf xs + slistTransform ast = ast -- Should not be reached if isSList is the guard toSKI x (SVar y Nothing) | x == y = _I | otherwise = SApp _K (SVar y Nothing) toSKI x (SApp m n) = SApp (SApp _S (toSKI x m)) (toSKI x n) - toSKI x (SLambda [y] body) = toSKI x (toSKI y body) + toSKI x (SLambda [y] body) = toSKI x (toSKI y body) -- This should ideally not happen if lambdas are fully eliminated first + toSKI _ sl@(SList _) = SApp _K (go sl) -- Ensure SList itself is transformed if somehow passed to toSKI directly toSKI _ term = SApp _K term _S = parseSingle "t (t (t t t)) t" @@ -178,7 +187,7 @@ elimLambda = go _TRI = parseSingle "t (t (t t (t (t (t t t))))) t" triageBody a b c = SApp (SApp TLeaf (SApp (SApp TLeaf (SVar a Nothing)) (SVar b Nothing))) (SVar c Nothing) - composeBody f g x = SApp (SVar f Nothing) (SVar g Nothing) + composeBody f g x = SApp (SVar f Nothing) (SVar g Nothing) -- Note: This might not be the standard B combinator body f(g x) isFree :: String -> TricuAST -> Bool isFree x = Set.member x . freeVars diff --git a/src/Main.hs b/src/Main.hs @@ -65,7 +65,6 @@ main = do Repl -> do putStrLn "Welcome to the tricu REPL" putStrLn "You may exit with `CTRL+D` or the `!exit` command." - putStrLn "Try typing `!` with tab completion for more commands." repl Evaluate { file = filePaths, form = form } -> do result <- case filePaths of diff --git a/src/REPL.hs b/src/REPL.hs @@ -101,16 +101,15 @@ repl = do outputStrLn "Available commands:" outputStrLn " !exit - Exit the REPL" outputStrLn " !clear - Clear the screen" - outputStrLn " !reset - Reset selected versions (for lookups)" + outputStrLn " !reset - Reset preferences for selected versions" outputStrLn " !help - Show tricu version and available commands" outputStrLn " !output - Change output format (tree|fsl|ast|ternary|ascii|decode)" outputStrLn " !definitions - List all defined terms in the content store" - outputStrLn " !import - Import definitions from file (definitions are stored)" - outputStrLn " !watch - Watch a file for changes (definitions are stored)" - outputStrLn " !refresh - (Currently no-op, definitions are live)" + outputStrLn " !import - Import definitions from file to the content store" + outputStrLn " !watch - Watch a file for changes, evaluate terms, and store them" outputStrLn " !versions - Show all versions of a term by name" outputStrLn " !select - Select a specific version of a term for subsequent lookups" - outputStrLn " !tag - Add or update a tag for a term (by hash or name)" + outputStrLn " !tag - Add or update a tag for a term by hash or name" loop state | strip s == "!output" -> handleOutput state | strip s == "!definitions" -> handleDefinitions state