diff options
author | Marvin Borner | 2022-08-20 22:30:31 +0200 |
---|---|---|
committer | Marvin Borner | 2022-08-20 22:30:31 +0200 |
commit | b68307db49807c83860f4303a05d08f25dbf6375 (patch) | |
tree | 240891b0fd979016502a1e1ec0f207d432936a3e | |
parent | 7e5cae744c3943eae7806c533f65acc5ff8fbe8a (diff) |
Parser shenanigans
-rw-r--r-- | src/Eval.hs | 55 | ||||
-rw-r--r-- | src/Helper.hs | 38 | ||||
-rw-r--r-- | src/Parser.hs | 52 | ||||
-rw-r--r-- | std/Combinator.bruijn | 330 | ||||
-rw-r--r-- | std/List.bruijn | 46 | ||||
-rw-r--r-- | std/Logic.bruijn | 4 | ||||
-rw-r--r-- | std/Pair.bruijn | 23 |
7 files changed, 290 insertions, 258 deletions
diff --git a/src/Eval.hs b/src/Eval.hs index fdaa2cb..eea56a8 100644 --- a/src/Eval.hs +++ b/src/Eval.hs @@ -55,14 +55,17 @@ loadFile path conf = do (conf { isRepl = False, evalPaths = (path : (evalPaths conf)) }) ) -evalVar :: String -> Environment -> Program (Failable Expression) -evalVar var (Environment sub) = state $ \env@(Environment e) -> +evalIdent :: String -> Environment -> Program (Failable Expression) +evalIdent ident (Environment sub) = state $ \env@(Environment e) -> let lookup' name env' = case lookup name env' of - Nothing -> Left $ UndeclaredFunction var + Nothing -> Left $ UndeclaredIdentifier name Just x -> Right x - in case lookup' var (map fst sub) of -- search in sub env + in case lookup' ident (map fst sub) of -- search in sub env s@(Right _) -> (s, env) - _ -> (lookup' var (map fst e), env) -- search in global env + _ -> (lookup' ident (map fst e), env) -- search in global env + +evalFun :: Identifier -> Environment -> Program (Failable Expression) +evalFun = evalIdent . functionName evalAbs :: Expression -> Environment -> Program (Failable Expression) evalAbs e sub = evalExp e sub >>= pure . fmap Abstraction @@ -78,28 +81,27 @@ evalApp f g sub = evalInfix :: Expression - -> String + -> Identifier -> Expression -> Environment -> Program (Failable Expression) -evalInfix le i re = - evalExp $ Application (Application (Variable $ "(" ++ i ++ ")") le) re +evalInfix le i re = evalExp $ Application (Application (Function i) le) re evalPrefix - :: String -> Expression -> Environment -> Program (Failable Expression) -evalPrefix p e = evalExp $ Application (Variable $ p ++ "(") e + :: Identifier -> Expression -> Environment -> Program (Failable Expression) +evalPrefix p e = evalExp $ Application (Function p) e evalExp :: Expression -> Environment -> Program (Failable Expression) evalExp idx@(Bruijn _ ) = const $ pure $ Right idx -evalExp ( Variable var) = evalVar var +evalExp ( Function fun) = evalFun fun evalExp ( Abstraction e ) = evalAbs e evalExp ( Application f g) = evalApp f g evalExp ( Infix le i re ) = evalInfix le i re evalExp ( Prefix p e ) = evalPrefix p e evalDefine - :: String -> Expression -> Environment -> Program (Failable Expression) -evalDefine name e sub = + :: Identifier -> Expression -> Environment -> Program (Failable Expression) +evalDefine i e sub = evalExp e sub >>= (\case Left e' -> pure $ Left e' @@ -110,6 +112,7 @@ evalDefine name e sub = ) >> pure (Right f) ) + where name = functionName i evalTest :: Expression -> Expression -> Environment -> Program (Failable Instruction) @@ -136,14 +139,14 @@ evalInstruction :: Instruction -> EnvState -> (EnvState -> IO EnvState) -> IO EnvState evalInstruction (ContextualInstruction instr inp) s@(EnvState env conf) rec = case instr of - Define name e sub -> do + Define i e sub -> do EnvState subEnv _ <- evalSubEnv sub s - (res, env') <- pure $ evalDefine name e subEnv `runState` env + (res, env') <- pure $ evalDefine i e subEnv `runState` env case res of Left err -> print (ContextualError err $ Context inp $ nicePath conf) >> pure s -- don't continue Right _ - | isRepl conf -> (putStrLn $ name <> " = " <> show e) + | isRepl conf -> (putStrLn $ show i <> " = " <> show e) >> return (EnvState env' conf) | otherwise -> rec $ EnvState env' conf Input path -> do @@ -186,9 +189,9 @@ evalInstruction (ContextualInstruction instr inp) s@(EnvState env conf) rec = <> (show e') <> "\n*> " <> (show reduced) - <> " " + <> "\n?> " <> (humanifyExpression reduced) - <> " " + <> "\n#> " <> (matchingFunctions reduced env) where reduced = reduce e' ) @@ -242,7 +245,7 @@ evalFileConf path wr conv conf = do arg <- encodeStdin case evalMainFunc env arg of Nothing -> - print $ ContextualError (UndeclaredFunction "main") (Context "" path) + print $ ContextualError (UndeclaredIdentifier "main") (Context "" path) Just e -> wr $ conv e defaultConf :: String -> EvalConf @@ -253,12 +256,12 @@ defaultConf path = EvalConf { isRepl = False , evalPaths = [] } -reduceFile :: String -> (a -> IO ()) -> (Expression -> a) -> IO () -reduceFile path wr conv = do +dumpFile :: String -> (a -> IO ()) -> (Expression -> a) -> IO () +dumpFile path wr conv = do EnvState (Environment env) _ <- loadFile path (defaultConf path) case lookup "main" (map fst env) of Nothing -> - print $ ContextualError (UndeclaredFunction "main") (Context "" path) + print $ ContextualError (UndeclaredIdentifier "main") (Context "" path) Just e -> wr $ conv e evalFile :: String -> (a -> IO ()) -> (Expression -> a) -> IO () @@ -345,10 +348,10 @@ evalMain = do args <- getArgs case args of [] -> runRepl - ["-b", path] -> reduceFile path - (Byte.putStr . Bit.realizeBitStringStrict) - (toBitString . toBinary) - ["-B", path] -> reduceFile path putStrLn toBinary + ["-b", path] -> dumpFile path + (Byte.putStr . Bit.realizeBitStringStrict) + (toBitString . toBinary) + ["-B", path] -> dumpFile path putStrLn toBinary ["-e", path] -> exec path (try . Byte.readFile) (fromBitString . Bit.bitString) ["-E", path] -> exec path (try . readFile) id diff --git a/src/Helper.hs b/src/Helper.hs index 418735e..d7064c1 100644 --- a/src/Helper.hs +++ b/src/Helper.hs @@ -34,13 +34,13 @@ printContext (Context inp path) = p $ lines inp errPrefix :: String errPrefix = "\ESC[41mERROR\ESC[0m " -data Error = SyntaxError String | UndeclaredFunction String | InvalidIndex Int | FailedTest Expression Expression Expression Expression | ContextualError Error Context | ImportError String +data Error = SyntaxError String | UndeclaredIdentifier String | InvalidIndex Int | FailedTest Expression Expression Expression Expression | ContextualError Error Context | ImportError String instance Show Error where show (ContextualError err ctx) = show err <> "\n" <> (printContext ctx) show (SyntaxError err) = errPrefix <> "invalid syntax\n\ESC[45mnear\ESC[0m " <> err - show (UndeclaredFunction func) = - errPrefix <> "undeclared function " <> show func + show (UndeclaredIdentifier ident) = + errPrefix <> "undeclared identifier " <> ident show (InvalidIndex err) = errPrefix <> "invalid index " <> show err show (FailedTest exp1 exp2 red1 red2) = errPrefix @@ -89,19 +89,35 @@ printBundle ParseErrorBundle {..} = <> pointer <> "\n" -data Expression = Bruijn Int | Variable String | Abstraction Expression | Application Expression Expression | Infix Expression String Expression | Prefix String Expression +data Identifier = NormalFunction String | InfixFunction String | PrefixFunction String | NamespacedFunction String Identifier deriving (Ord, Eq) -data Instruction = Define String Expression [Instruction] | Evaluate Expression | Comment | Input String | Import String String | Test Expression Expression | ContextualInstruction Instruction String +functionName :: Identifier -> String +functionName = \case + NormalFunction f -> f + InfixFunction i -> "(" <> i <> ")" + PrefixFunction p -> p <> "(" + NamespacedFunction n f -> n <> functionName f +instance Show Identifier where + show ident = "\ESC[95m" <> functionName ident <> "\ESC[0m" +data Expression = Bruijn Int | Function Identifier | Abstraction Expression | Application Expression Expression | Infix Expression Identifier Expression | Prefix Identifier Expression + deriving (Ord, Eq) +data Instruction = Define Identifier Expression [Instruction] | Evaluate Expression | Comment | Input String | Import String String | Test Expression Expression | ContextualInstruction Instruction String deriving (Show) instance Show Expression where - show (Bruijn x ) = "\ESC[91m" <> show x <> "\ESC[0m" - show (Variable var) = "\ESC[95m" <> var <> "\ESC[0m" - show (Abstraction e ) = "\ESC[36m[\ESC[0m" <> show e <> "\ESC[36m]\ESC[0m" + show (Bruijn x ) = "\ESC[91m" <> show x <> "\ESC[0m" + show (Function ident) = "\ESC[95m" <> show ident <> "\ESC[0m" + show (Abstraction e ) = "\ESC[36m[\ESC[0m" <> show e <> "\ESC[36m]\ESC[0m" show (Application exp1 exp2) = "\ESC[33m(\ESC[0m" <> show exp1 <> " " <> show exp2 <> "\ESC[33m)\ESC[0m" show (Infix le i re) = - show le <> " \ESC[95m(" <> i <> ")" <> "\ESC[0m " <> show re - show (Prefix p e) = "\ESC[95m" <> p <> show e <> "\ESC[0m" + "\ESC[33m(\ESC[0m" + <> show i + <> " " + <> show le + <> " " + <> show re + <> "\ESC[33m)\ESC[0m" + show (Prefix p e) = show p <> " " <> show e type EnvDef = (String, Expression) data EvalConf = EvalConf @@ -193,7 +209,7 @@ maybeHumanifyExpression e = ternaryToDecimal e <|> decodeStdout e humanifyExpression :: Expression -> String humanifyExpression e = case maybeHumanifyExpression e of - Nothing -> "" + Nothing -> show e Just h -> h --- diff --git a/src/Parser.hs b/src/Parser.hs index c23130d..a27c6a2 100644 --- a/src/Parser.hs +++ b/src/Parser.hs @@ -17,36 +17,44 @@ type Parser = Parsec Void String sc :: Parser () sc = void $ char ' ' +-- "'" can't be in special chars because of 'c' char notation and prefixation specialChar :: Parser Char specialChar = oneOf "!?*@.:;+-_#$%^&<>/\\|~=" +-- lower or upper +greekLetter :: Parser Char +greekLetter = satisfy isGreek + where isGreek c = ('Α' <= c && c <= 'Ω') || ('α' <= c && c <= 'ω') + infixOperator :: Parser String -infixOperator = some specialChar +infixOperator = + some specialChar <|> ((++) <$> dottedNamespace <*> infixOperator) prefixOperator :: Parser String -prefixOperator = some specialChar +prefixOperator = infixOperator --- def identifier disallows the import prefix dots -defIdentifier :: Parser String +defIdentifier :: Parser Identifier defIdentifier = - ((:) <$> letterChar <*> many (alphaNumChar <|> specialChar <|> char '\'')) - <|> ((\l i r -> [l] ++ i ++ [r]) <$> char '(' <*> infixOperator <*> char ')' + ( NormalFunction + <$> ((:) <$> (lowerChar <|> greekLetter) <*> many + (alphaNumChar <|> specialChar <|> char '\'') ) - <|> ((\p i -> p ++ [i]) <$> prefixOperator <*> char '(') + ) + <|> (InfixFunction <$> (char '(' *> infixOperator <* char ')')) + <|> (PrefixFunction <$> (prefixOperator <* char '(')) <?> "defining identifier" --- TODO: write as extension to defIdentifier -identifier :: Parser String +identifier :: Parser Identifier identifier = - ((:) <$> letterChar <*> many (alphaNumChar <|> specialChar <|> oneOf ".\'")) - <|> ((\l i r -> [l] ++ i ++ [r]) <$> char '(' <*> infixOperator <*> char ')' - ) - <|> ((\p i -> p ++ [i]) <$> prefixOperator <*> char '(') + try (NamespacedFunction <$> dottedNamespace <*> defIdentifier) + <|> defIdentifier <?> "identifier" namespace :: Parser String -namespace = - ((:) <$> upperChar <*> many letterChar) <|> string "." <?> "namespace" +namespace = (:) <$> upperChar <*> many letterChar <?> "namespace" + +dottedNamespace :: Parser String +dottedNamespace = (\n d -> n ++ [d]) <$> namespace <*> char '.' parens :: Parser a -> Parser a parens = between (string "(") (string ")") @@ -107,10 +115,10 @@ parseChar = do <?> "quoted char" pure $ charToExpression ch -parseVariable :: Parser Expression -parseVariable = do +parseFunction :: Parser Expression +parseFunction = do var <- identifier - pure $ Variable var + pure $ Function var parseInfix :: Parser Expression parseInfix = do @@ -119,13 +127,13 @@ parseInfix = do i <- infixOperator sc e2 <- parseSingleton - pure $ Infix e1 i e2 + pure $ Infix e1 (InfixFunction i) e2 parsePrefix :: Parser Expression parsePrefix = do p <- prefixOperator e <- parseSingleton - pure $ Prefix p e + pure $ Prefix (PrefixFunction p) e parseSingleton :: Parser Expression parseSingleton = @@ -134,7 +142,7 @@ parseSingleton = <|> parseString <|> parseChar <|> parseAbstraction - <|> try parseVariable + <|> try parseFunction <|> try (parens parseInfix <?> "enclosed infix expr") <|> (parens parseApplication <?> "enclosed application") <|> parsePrefix @@ -180,7 +188,7 @@ parseImport = do inp <- getInput _ <- string ":import " <?> "import instruction" path <- importPath - ns <- (try $ sc *> namespace) <|> (eof >> return "") + ns <- (try $ (sc *> (namespace <|> string "."))) <|> (eof >> return "") pure $ ContextualInstruction (Import (path ++ ".bruijn") ns) inp parseInput :: Parser Instruction diff --git a/std/Combinator.bruijn b/std/Combinator.bruijn index 115ea93..6b0eaed 100644 --- a/std/Combinator.bruijn +++ b/std/Combinator.bruijn @@ -2,238 +2,238 @@ # Inspired by Raymond Smullyan: To Mock a Mockingbird # -> bird monickered combinators (they're still quite useful though!) -# Apply combinator -A [[1 0]] +# apply combinator +a [[1 0]] -($) A +($) a -# Bluebird combinator: 1 <- 1 composition -B [[[2 (1 0)]]] +# bluebird combinator: 1 <- 1 composition +b [[[2 (1 0)]]] -(.) B +(.) b -# Blackbird combinator -B' [[[[3 (2 1 0)]]]] +# blackbird combinator +b' [[[[3 (2 1 0)]]]] -(..) B' +(..) b' -# Bunting combinator -B'' [[[[[4 (3 2 1 0)]]]]] +# bunting combinator +b'' [[[[[4 (3 2 1 0)]]]]] -(...) B'' +(...) b'' -# Becard combinator -B''' [[[[3 (2 (1 0))]]]] +# becard combinator +b''' [[[[3 (2 (1 0))]]]] -# Cardinal combinator: Reverse arguments -C [[[2 0 1]]] +# cardinal combinator: reverse arguments +c [[[2 0 1]]] -\( C +\( c -# Cardinal once removed combinator -C* [[[[3 2 0 1]]]] +# cardinal once removed combinator +c* [[[[3 2 0 1]]]] -# Cardinal twice removed combinator -C** [[[[[4 3 2 0 1]]]]] +# cardinal twice removed combinator +c** [[[[[4 3 2 0 1]]]]] -# Dove combinator -D [[[[3 2 (1 0)]]]] +# dove combinator +d [[[[3 2 (1 0)]]]] -# Dickcissel combinator -D' [[[[[4 3 2 (1 0)]]]]] +# dickcissel combinator +d' [[[[[4 3 2 (1 0)]]]]] -# Dovekies combinator -D'' [[[[[4 (3 2) (1 0)]]]]] +# dovekies combinator +d'' [[[[[4 (3 2) (1 0)]]]]] -# Eagle combinator -E [[[[[4 3 (2 1 0)]]]]] +# eagle combinator +e [[[[[4 3 (2 1 0)]]]]] -# Bald eagle combinator -E' [[[[[[[6 (5 4 3) (2 1 0)]]]]]]] +# bald eagle combinator +e' [[[[[[[6 (5 4 3) (2 1 0)]]]]]]] -# Finch combinator -F [[[0 1 2]]] +# finch combinator +f [[[0 1 2]]] -# Finch once removed combinator -F* [[[[3 0 1 2]]]] +# finch once removed combinator +f* [[[[3 0 1 2]]]] -# Finch twice removed combinator -F** [[[[[4 3 0 1 2]]]]] +# finch twice removed combinator +f** [[[[[4 3 0 1 2]]]]] -# Goldfinch combinator -G [[[[3 0 (2 1)]]]] +# goldfinch combinator +g [[[[3 0 (2 1)]]]] -# Hummingbird combinator -H [[[2 1 0 1]]] +# hummingbird combinator +h [[[2 1 0 1]]] -# Idiot combinator: Identity -I [0] +# idiot combinator: identity +i [0] -# Idiot once removed combinator -I* [[1 0]] +# idiot once removed combinator +i* [[1 0]] -# Idiot twice removed combinator -I** [[[2 1 0]]] +# idiot twice removed combinator +i** [[[2 1 0]]] -# Jay combinator -J [[[[3 2 (3 0 1)]]]] +# jay combinator +j [[[[3 2 (3 0 1)]]]] -# Kestrel combinator: Const, True -K [[1]] +# kestrel combinator: const, true +k [[1]] -# Kite combinator: Const id, False -KI [[0]] +# kite combinator: const id, false +ki [[0]] -# Konstant mocker combinator -KM [[0 0]] +# konstant mocker combinator +km [[0 0]] -# Crossed konstant mocker combinator -KM' [[1 1]] +# crossed konstant mocker combinator +km' [[1 1]] -# Lark combinator -L [[1 (0 0)]] +# lark combinator +l [[1 (0 0)]] -# Mockingbird/omega combinator -M [0 0] +# mockingbird/omega combinator +m [0 0] -ω M +ω m -# Double mockingbird combinator -M' [[1 0 (1 0)]] +# double mockingbird combinator +m' [[1 0 (1 0)]] -# Owl combinator -O [[0 (1 0)]] +# owl combinator +o [[0 (1 0)]] -# Omega combinator +# omega combinator Ω ω ω -# Phoenix combinator -Φ [[[[3 (2 0) (1 0)]]]] +# phoenix combinator +φ [[[[3 (2 0) (1 0)]]]] -# Psi combinator: On -Ψ [[[[3 (2 1) (2 0)]]]] +# psi combinator: on +ψ [[[[3 (2 1) (2 0)]]]] -# Queer combinator -Q [[[1 (2 0)]]] +# queer combinator +q [[[1 (2 0)]]] -(>>>) Q +(>>>) q -# Quixotic bird combinator -Q' [[[2 (0 1)]]] +# quixotic bird combinator +q' [[[2 (0 1)]]] -# Quizzical bird combinator -Q'' [[[1 (0 2)]]] +# quizzical bird combinator +q'' [[[1 (0 2)]]] -# Quirky bird combinator -Q''' [[[0 (2 1)]]] +# quirky bird combinator +q''' [[[0 (2 1)]]] -# Quacky bird combinator -Q'''' [[[0 (1 2)]]] +# quacky bird combinator +q'''' [[[0 (1 2)]]] -# Robin combinator -R [[[1 0 2]]] +# robin combinator +r [[[1 0 2]]] -# Robin once removed combinator -R* [[[[3 1 0 2]]]] +# robin once removed combinator +r* [[[[3 1 0 2]]]] -# Robin twice removed combinator -R** [[[[[4 3 1 0 2]]]]] +# robin twice removed combinator +r** [[[[[4 3 1 0 2]]]]] -# Starling combinator: <*> -S [[[2 0 (1 0)]]] +# starling combinator: <*> +s [[[2 0 (1 0)]]] -# Thrush combinator: Flipped $ -T [[0 1]] +# thrush combinator: flipped $ +t [[0 1]] -(&) T +(&) t -# Turing combinator -U [[0 (1 1 0)]] +# turing combinator +u [[0 (1 1 0)]] -# Vireo combinator -V [[[0 2 1]]] +# vireo combinator +v [[[0 2 1]]] -# Vireo once removed combinator -V* [[[[3 0 2 1]]]] +# vireo once removed combinator +v* [[[[3 0 2 1]]]] -# Vireo twice removed combinator -V** [[[[[4 3 0 2 1]]]]] +# vireo twice removed combinator +v** [[[[[4 3 0 2 1]]]]] -# Warbler combinator -W [[1 0 0]] +# warbler combinator +w [[1 0 0]] -# Warbler once removed combinator -W* [[[2 1 0 0]]] +# warbler once removed combinator +w* [[[2 1 0 0]]] -# Warbler twice removed combinator -W** [[[[3 2 1 0 0]]]] +# warbler twice removed combinator +w** [[[[3 2 1 0 0]]]] -# Converse warbler combinator -W' [[0 1 1]] +# converse warbler combinator +w' [[0 1 1]] -# Sage bird combinator -Y [[1 (0 0)] [1 (0 0)]] +# sage bird combinator +y [[1 (0 0)] [1 (0 0)]] -# Z fixed point combinator -Z [[1 [1 1 0]] [1 [1 1 0]]] +# z fixed point combinator +z [[1 [1 1 0]] [1 [1 1 0]]] -# Theta combinator -Θ [[0 (1 1 0)]] [[0 (1 1 0)]] +# theta combinator +θ [[0 (1 1 0)]] [[0 (1 1 0)]] # iota combinator -i [0 S K] +ι [0 s k] # -- combinator equivalency tests -- -:test (A) (S (S K)) -:test (B) (S (K S) K) -:test (B') (B B B) -:test (B'') (B (B B B) B) -:test (B''') (B (B B) B) -:test (C) (S (B B S) (K K)) -:test (C*) (B C) -:test (C**) (B C*) -:test (D) (B B) -:test (D') (B (B B)) -:test (D'') (B B (B B)) -:test (E) (B (B B B)) -:test (E') (B (B B B) (B (B B B))) -:test (F) (E T T E T) -:test (F*) (B C* R*) -:test (F**) (B F*) -:test (G) (B B C) -:test (H) (B W (B C)) -:test (I) (S K K) -:test (I*) (S (S K)) -:test (J) (B (B C) (W (B C E))) -:test (KI) (K I) -:test (L) (C B M) -:test (M) (S I I) -:test (M') (B M) -:test (O) (S I) -:test (Q) (C B) -:test (Q') (B C B) -:test (Q'') (C (B C B)) -:test (Q''') (B T) -:test (Q'''') (F* B) -:test (R) (B B T) -:test (R*) (C* C*) -:test (R**) (B R*) -:test (T) (C I) -:test (U) (L O) -:test (V) (B C T) -:test (V*) (C* F*) -:test (V**) (B V*) -:test (W) (C (B M R)) -:test (W*) (B W) -:test (W**) (B (B W)) -:test (W') (C W) +:test (a) (s (s k)) +:test (b) (s (k s) k) +:test (b') (b b b) +:test (b'') (b (b b b) b) +:test (b''') (b (b b) b) +:test (c) (s (b b s) (k k)) +:test (c*) (b c) +:test (c**) (b c*) +:test (d) (b b) +:test (d') (b (b b)) +:test (d'') (b b (b b)) +:test (e) (b (b b b)) +:test (e') (b (b b b) (b (b b b))) +:test (f) (e t t e t) +:test (f*) (b c* r*) +:test (f**) (b f*) +:test (g) (b b c) +:test (h) (b w (b c)) +:test (i) (s k k) +:test (i*) (s (s k)) +:test (j) (b (b c) (w (b c e))) +:test (ki) (k i) +:test (l) (c b m) +:test (m) (s i i) +:test (m') (b m) +:test (o) (s i) +:test (q) (c b) +:test (q') (b c b) +:test (q'') (c (b c b)) +:test (q''') (b t) +:test (q'''') (f* b) +:test (r) (b b t) +:test (r*) (c* c*) +:test (r**) (b r*) +:test (t) (c i) +:test (u) (l o) +:test (v) (b c t) +:test (v*) (c* f*) +:test (v**) (b v*) +:test (w) (c (b m r)) +:test (w*) (b w) +:test (w**) (b (b w)) +:test (w') (c w) # -- iota and SKI tests -- -:test (I) (i i) -:test (K) (i (i (i i))) -:test (S) (i (i (i (i i)))) -:test (B) (S (K S) K) -:test (C) (S (S (K (S (K S) K)) S) (K K)) -:test (W) (S S (S K)) +:test (i) (ι ι) +:test (k) (ι (ι (ι ι))) +:test (s) (ι (ι (ι (ι ι)))) +:test (b) (s (k s) k) +:test (c) (s (s (k (s (k s) k)) s) (k k)) +:test (w) (s s (s k)) diff --git a/std/List.bruijn b/std/List.bruijn index b84f5d0..891dc7c 100644 --- a/std/List.bruijn +++ b/std/List.bruijn @@ -42,7 +42,7 @@ tail P.snd :test (~((+1) : ((+2) : empty))) ((+2) : empty) # returns the length of a list in balanced ternary -length Z [[[rec]]] (+0) +length z [[[rec]]] (+0) rec <>?0 case-end case-inc case-inc 2 ++1 ~0 case-end 1 @@ -53,7 +53,7 @@ length Z [[[rec]]] (+0) :test (#empty) ((+0)) # returns the element at index in list -index Z [[[rec]]] +index z [[[rec]]] rec <>?0 case-end case-index case-index =?1 ^0 (2 --1 ~0) case-end empty @@ -66,7 +66,7 @@ index Z [[[rec]]] :test (((+1) : ((+2) : ((+3) : empty))) !! (+3)) (empty) # applies a left fold on a list -foldl Z [[[[rec]]]] +foldl z [[[[rec]]]] rec <>?0 case-end case-fold case-fold 3 2 (2 1 ^0) ~0 case-end 1 @@ -78,7 +78,7 @@ foldl Z [[[[rec]]]] foldl1 [[foldl 1 ^0 ~0]] # applies a right fold on a list -foldr [[[Z [[rec]] 0]]] +foldr [[[z [[rec]] 0]]] rec <>?0 case-end case-fold case-fold 4 ^0 (1 ~0) case-end 3 @@ -143,7 +143,7 @@ reverse foldl \cons empty list [0 [[[2 (0 : 1)]]] reverse empty] # appends two lists -append Z [[[rec]]] +append z [[[rec]]] rec <>?1 case-end case-merge case-merge ^1 : (2 ~1 0) case-end 0 @@ -161,7 +161,7 @@ snoc [[1 ++ (0 : empty)]] :test (((+1) : empty) ; (+2)) ((+1) : ((+2) : empty)) # maps each element to a function -map Z [[[rec]]] +map z [[[rec]]] rec <>?0 case-end case-map case-map (1 ^0) : (2 1 ~0) case-end empty @@ -171,9 +171,9 @@ map Z [[[rec]]] :test (inc <$> ((+1) : ((+2) : ((+3) : empty)))) ((+2) : ((+3) : ((+4) : empty))) # filters a list based on a predicate -filter Z [[[rec]]] +filter z [[[rec]]] rec <>?0 case-end case-filter - case-filter 1 ^0 (cons ^0) I (2 1 ~0) + case-filter 1 ^0 (cons ^0) i (2 1 ~0) case-end empty (<#>) \filter @@ -181,7 +181,7 @@ filter Z [[[rec]]] :test (((+1) : ((+0) : ((+3) : empty))) <#> zero?) ((+0) : empty) # returns the last element of a list -last Z [[rec]] +last z [[rec]] rec <>?0 case-end case-last case-last <>?(~0) ^0 (1 ~0) case-end empty @@ -191,7 +191,7 @@ _( last :test (last ((+1) : ((+2) : ((+3) : empty)))) ((+3)) # returns everything but the last element of a list -init Z [[rec]] +init z [[rec]] rec <>?0 case-end case-init case-init <>?(~0) empty (^0 : (1 ~0)) case-end empty @@ -211,7 +211,7 @@ concat-map [foldr (append . 0) empty] :test (concat-map [-0 : (0 : empty)] ((+1) : ((+2) : empty))) ((-1) : ((+1) : ((-2) : ((+2) : empty)))) # zips two lists discarding excess elements -zip Z [[[rec]]] +zip z [[[rec]]] rec <>?1 case-end case-zip case-zip <>?0 empty ((^1 : ^0) : (2 ~1 ~0)) case-end empty @@ -219,7 +219,7 @@ zip Z [[[rec]]] :test (zip ((+1) : ((+2) : empty)) ((+2) : ((+1) : empty))) (((+1) : (+2)) : (((+2) : (+1)) : empty)) # applies pairs of the zipped list as arguments to a function -zip-with Z [[[[rec]]]] +zip-with z [[[[rec]]]] rec <>?1 case-end case-zip case-zip <>?0 empty ((2 ^1 ^0) : (3 2 ~1 ~0)) case-end empty @@ -227,7 +227,7 @@ zip-with Z [[[[rec]]]] :test (zip-with (+) ((+1) : ((+2) : empty)) ((+2) : ((+1) : empty))) ((+3) : ((+3) : empty)) # returns first n elements of a list -take Z [[[rec]]] +take z [[[rec]]] rec <>?0 case-end case-take case-take =?1 empty (^0 : (2 --1 ~0)) case-end empty @@ -235,7 +235,7 @@ take Z [[[rec]]] :test (take (+2) ((+1) : ((+2) : ((+3) : empty)))) ((+1) : ((+2) : empty)) # takes elements while a predicate is satisfied -take-while Z [[[rec]]] +take-while z [[[rec]]] rec <>?0 case-end case-take case-take 1 ^0 (^0 : (2 1 ~0)) empty case-end empty @@ -243,7 +243,7 @@ take-while Z [[[rec]]] :test (take-while zero? ((+0) : ((+0) : ((+1) : empty)))) ((+0) : ((+0) : empty)) # removes first n elements of a list -drop Z [[[rec]]] +drop z [[[rec]]] rec <>?0 case-end case-drop case-drop =?1 0 (2 --1 ~0) case-end empty @@ -251,7 +251,7 @@ drop Z [[[rec]]] :test (drop (+2) ((+1) : ((+2) : ((+3) : empty)))) ((+3) : empty) # removes elements from list while a predicate is satisfied -drop-while Z [[[rec]]] +drop-while z [[[rec]]] rec <>?0 case-end case-drop case-drop 1 ^0 (2 1 ~0) 0 case-end empty @@ -259,7 +259,7 @@ drop-while Z [[[rec]]] :test (drop-while zero? ((+0) : ((+0) : ((+1) : empty)))) ((+1) : empty) # returns pair of take-while and drop-while -span Z [[[rec]]] +span z [[[rec]]] rec <>?0 case-end case-drop case-drop 1 ^0 ((^0 : ^recced) : ~recced) (empty : 0) recced 2 1 ~0 @@ -298,7 +298,7 @@ eq? &&( ... zip-with :test (eq? (=?) empty empty) (true) # removes first element that match an eq predicate -remove Z [[[[rec]]]] +remove z [[[[rec]]]] rec <>?0 case-end case-remove case-remove (2 ^0 1) ~0 (^0 : (3 2 1 ~0)) case-end empty @@ -306,7 +306,7 @@ remove Z [[[[rec]]]] :test (remove (=?) (+2) ((+1) : ((+2) : ((+3) : ((+2) : empty))))) ((+1) : ((+3) : ((+2) : empty))) # removes duplicates from list based on eq predicate (keeps first occurrence) -nub Z [[[rec]]] +nub z [[[rec]]] rec <>?0 case-end case-nub case-nub ^0 : (2 1 (~0 <#> [!(2 0 ^1)])) case-end empty @@ -315,7 +315,7 @@ nub Z [[[rec]]] :test (nub (=?) ((+1) : ((+2) : ((+1) : empty)))) (((+1) : ((+2) : empty))) # returns a list with infinite-times a element -repeat Z [[rec]] +repeat z [[rec]] rec 0 : (1 0) :test (take (+3) (repeat (+4))) ((+4) : ((+4) : ((+4) : empty))) @@ -326,16 +326,16 @@ replicate [[take 1 (repeat 0)]] :test (replicate (+3) (+4)) ((+4) : ((+4) : ((+4) : empty))) # returns an infinite list repeating a finite list -cycle Z [[rec]] +cycle z [[rec]] rec 0 ++ (1 0) :test (take (+6) (cycle "ab")) ("ababab") # returns a list with infinite-times previous (or start) value applied to a function -iterate Z [[[rec]]] +iterate z [[[rec]]] rec 0 : (2 1 (1 0)) :test (take (+5) (iterate inc (+0))) (((+0) : ((+1) : ((+2) : ((+3) : ((+4) : empty)))))) :test (take (+2) (iterate dec (+5))) (((+5) : ((+4) : empty))) -:test (take (+5) (iterate I (+4))) (repeat (+5) (+4)) +:test (take (+5) (iterate i (+4))) (repeat (+5) (+4)) :test (take (+0) (iterate inc (+0))) (empty) diff --git a/std/Logic.bruijn b/std/Logic.bruijn index 94e737d..0e7c1ba 100644 --- a/std/Logic.bruijn +++ b/std/Logic.bruijn @@ -3,10 +3,10 @@ :import std/Combinator . # true -true K +true k # false -false KI +false ki # inverts boolean value not! [0 false true] diff --git a/std/Pair.bruijn b/std/Pair.bruijn index b21d193..8dffe7d 100644 --- a/std/Pair.bruijn +++ b/std/Pair.bruijn @@ -8,35 +8,40 @@ pair [[[0 2 1]]] (:) pair # extracts first expression from pair -fst [0 K] +fst [0 k] ^( fst -# test fst with example pair of [[0]] and [[1]] :test (^([[0]] : [[1]])) ([[0]]) # extracts second expression from pair -snd [0 KI] +snd [0 ki] ~( snd -# test snd with example pair of [[0]] and [[1]] :test (~([[0]] : [[1]])) ([[1]]) # applies both elements of a pair to a function uncurry [[1 ^0 ~0]] -# test uncurry with example pair of [[0]] and [[1]] and some combinator -:test (uncurry W ([[0]] : [[1]])) ([[1]]) +:test (uncurry w ([[0]] : [[1]])) ([[1]]) # applies a function to the pair of two values curry [[[2 (1 : 0)]]] -# test curry with example pair of [[0]] and [[1]] and fst :test (curry fst [[0]] [[1]]) ([[0]]) -# swaps the values of a pair +# zips two pairs (basically rotating the elements) +zip [[(^1 : ^0) : (~1 : ~0)]] + +:test (zip ([[0]] : [[[0]]]) ([[1]] : [[[1]]])) (([[0]] : [[1]]) : ([[[0]]] : [[[1]]])) + +# applies pairs of two pairs as arguments to a function +zip-with [[[(2 ^1 ^0) : (2 ~1 ~0)]]] + +:test (zip-with w ([[0]] : [[[0]]]) ([[1]] : [[[1]]])) ([[1]] : [0]) + +# swaps the elements of a pair swap [~0 : ^0] -# test swap with example pair of [[0]] and [[1]] :test (swap ([[0]] : [[1]])) ([[1]] : [[0]]) |