diff options
author | Marvin Borner | 2022-08-13 10:53:23 +0200 |
---|---|---|
committer | Marvin Borner | 2022-08-13 11:48:03 +0200 |
commit | cf76a2e33b708dd2bec72a782af214cbd792bb58 (patch) | |
tree | 754d02388abf1365c8282f46af2065095d43ae2f | |
parent | cbc9a382e356951896a21f80f52e0e5b3e8c4e1f (diff) |
Minor improvements
-rw-r--r-- | README.md | 58 | ||||
-rw-r--r-- | src/Eval.hs | 10 | ||||
-rw-r--r-- | src/Helper.hs | 9 | ||||
-rw-r--r-- | std/Church.bruijn | 14 |
4 files changed, 73 insertions, 18 deletions
@@ -115,7 +115,7 @@ You can try these by experimenting in the REPL or by running them as a file. Note, however, that you need an equal sign between the function name and its definition if you’re using the REPL. -Plain execution without any predefined functions: +#### Plain execution without any predefined functions # this is a comment # we now define a function returning a ternary 1 @@ -123,31 +123,61 @@ Plain execution without any predefined functions: # we can use the function in all functions below its definition get-one2 get-one - :test (get-one2 =? (+1)) (T) + + :test (get-one2) (+1) + + # indenting acts similar to Haskell's where statement + get-one3 foo + bar (+1) + foo bar # equivalent of λx.x id [0] - # equivalent of (λx.x) (λx.λy.x) = λx.λy.x + # testing equivalent of (λx.x) (λx.λy.x) = λx.λy.x :test (id [[1]]) ([[1]]) + # prefix function definition + !( [[1]] + + # use prefix function ! + :test (![0]) ([[0]]) + + # infix function definition + (<>) [[0 1]] + + # use infix function <> + :test ([[0]] <> [[1]]) ([[1]] [[0]]) + # multiple arguments - set-of-three [[[[0 1 2 3]]]] number-set set-of-three (+1) (+2) (+3) + set-of-three [[[[0 1 2 3]]]] + access-first [0 [[[0]]]] - :test ((access-first number-set) =? (+1)) (T) + :test (access-first number-set) (+1) # endless loop using omega combinator - om [0 0] - nom om main om nom + om [0 0] + nom om # you may have realized you can't easily operate with numbers # or anything else really without writing crazy functions # -> luckily the standard library defines many standard operations! -Using standard library: +#### Using standard library + +“Hello world” program using IO: + + :import std/List . + + main [("Hello " ++ 0) ++ "!\n"] + +You can then use `printf "world" | bruijn file.bruijn` to get “Hello +world!” + +Some other great functions: :import std/Logic . :import std/Combinator . @@ -156,11 +186,12 @@ Using standard library: :import std/Pair . # pairs with some values - me [[[1]]] - you [[[2]]] love pair me you - :test (fst love) (me) - :test (snd love) (you) + me [[[1]]] + you [[[2]]] + + :test (fst love) ([[[1]]]) + :test (snd love) ([[[2]]]) # options :test (map inc (some (+1))) (some (+2)) @@ -168,6 +199,7 @@ Using standard library: # numerical operations five --(((+8) + (-4)) - (-2)) + not-five? [if (0 =? (+5)) F T] :test (not-five? five) (F) @@ -179,7 +211,7 @@ Using standard library: :test (main) (F) - # read the files in std/ for an overview of all functions/libraries +Read the files in std/ for an overview of all functions/libraries. ### Compilation to BLC diff --git a/src/Eval.hs b/src/Eval.hs index 445e41d..4051643 100644 --- a/src/Eval.hs +++ b/src/Eval.hs @@ -41,7 +41,7 @@ loadFile path conf = do f <- try $ readFile path :: IO (Either IOError String) case f of Left exception -> - print (ContextualError (ImportError $ show (exception :: IOError)) (Context "" (nicePath conf))) >> pure (EnvState $ Environment []) + print (ContextualError (ImportError $ show (exception :: IOError)) (Context "" $ nicePath conf)) >> pure (EnvState $ Environment []) Right f' -> eval (filter (not . null) $ split "\n\n" f') (EnvState $ Environment []) (conf { isRepl = False, evalPaths = (path : (evalPaths conf)) }) @@ -117,7 +117,7 @@ evalInstruction (ContextualInstruction instr inp) s@(EnvState env) rec conf = ca let (res, env') = evalDefine name e subEnv `runState` env in case res of - Left err -> print (ContextualError err (Context inp (nicePath conf))) >> pure s -- don't continue + Left err -> print (ContextualError err $ Context inp $ nicePath conf) >> pure s -- don't continue Right _ -> if isRepl conf then (putStrLn $ name <> " = " <> show e) >> return (EnvState env') @@ -127,7 +127,7 @@ evalInstruction (ContextualInstruction instr inp) s@(EnvState env) rec conf = ca lib <- getDataFileName path -- TODO: Use actual lib directory exists <- doesFileExist lib actual <- pure $ if exists then lib else path - if (actual `elem` evalPaths conf) then (print (ContextualError (ImportError path) (Context inp (nicePath conf))) >> pure s) else do + if actual `elem` evalPaths conf then print (ContextualError (ImportError path) (Context inp $ nicePath conf)) >> pure s else do EnvState env' <- loadFile actual (conf { nicePath = path }) -- TODO: Fix wrong `within` in import error let prefix | null namespace = takeBaseName path ++ "." | namespace == "." = "" @@ -147,6 +147,8 @@ evalInstruction (ContextualInstruction instr inp) s@(EnvState env) rec conf = ca <> (show reduced) <> " " <> (humanifyExpression reduced) + <> " " + <> (matchingFunctions reduced env) where reduced = reduce e' ) >> rec s conf @@ -173,7 +175,7 @@ eval [""] s _ = return s eval (block : bs) s conf = handleInterrupt (putStrLn "<aborted>" >> return s) $ case parse blockParser "" block of - Left err -> print (ContextualError (SyntaxError $ printBundle err) (Context "" (nicePath conf))) >> eval bs s conf + Left err -> print (ContextualError (SyntaxError $ printBundle err) (Context "" $ nicePath conf)) >> eval bs s conf Right instr -> evalInstruction instr s (eval bs) conf where blockParser = if isRepl conf then parseReplLine else parseBlock 0 diff --git a/src/Helper.hs b/src/Helper.hs index eb41673..47c106d 100644 --- a/src/Helper.hs +++ b/src/Helper.hs @@ -178,6 +178,15 @@ decodeStdout e = do --- +lookupValues :: (Eq b) => b -> [(a, b)] -> [a] +lookupValues _ [] = [] +lookupValues key ((x, y) : xys) | key == y = x : lookupValues key xys + | otherwise = lookupValues key xys + +matchingFunctions :: Expression -> Environment -> String +matchingFunctions e (Environment env) = + intercalate ", " $ nub $ lookupValues e (map fst env) + -- TODO: Expression -> Maybe Char is missing maybeHumanifyExpression :: Expression -> Maybe String maybeHumanifyExpression e = ternaryToDecimal e <|> decodeStdout e diff --git a/std/Church.bruijn b/std/Church.bruijn index 412938a..bba2784 100644 --- a/std/Church.bruijn +++ b/std/Church.bruijn @@ -1,7 +1,19 @@ # MIT License, Copyright (c) 2022 Marvin Borner zero [[0]] -succ [[[1 (2 1 0)]]] + +inc [[[1 (2 1 0)]]] + +++( inc + add [[[[3 1 (2 1 0)]]]] + +(+) add + mul [[[2 (1 0)]]] + +(*) mul + exp [[0 1]] + +(^) exp |