Compare commits
3 Commits
e22ff06bfe
...
0048fed6b4
Author | SHA1 | Date | |
---|---|---|---|
0048fed6b4 | |||
476c3912a4 | |||
|
493ef51a6a |
34
README.md
34
README.md
@ -46,14 +46,42 @@ tricu < map (\i : listConcat i " is super cool!") [("Tree Calculus") ("Intension
|
||||
READ -: ["Tree Calculus is super cool!", "Intensionality is super cool!", "tricu is super cool!"]
|
||||
```
|
||||
|
||||
## Installation
|
||||
## Installation and Use
|
||||
|
||||
You can easily build and/or run this project using [Nix](https://nixos.org/download/).
|
||||
|
||||
- Run REPL immediately:
|
||||
- Quick Start (REPL):
|
||||
- `nix run git+https://git.eversole.co/James/tricu`
|
||||
- Build REPL executable in `./result/bin`:
|
||||
- Build executable in `./result/bin`:
|
||||
- `nix build git+https://git.eversole.co/James/tricu`
|
||||
- `./result/bin/tricu --help`
|
||||
|
||||
```
|
||||
tricu - compiler and repl
|
||||
|
||||
tricu [COMMAND] ... [OPTIONS]
|
||||
tricu: Exploring Tree Calculus
|
||||
|
||||
Common flags:
|
||||
-? --help Display help message
|
||||
-V --version Print version information
|
||||
|
||||
tricu [repl] [OPTIONS]
|
||||
Start interactive REPL
|
||||
|
||||
tricu compile [OPTIONS]
|
||||
Compile a file and return the result of the expression in the final line
|
||||
|
||||
-f --file=FILE Relative or absolute path to file input for compilation
|
||||
-o --output=OUTPUT Optional output file path for resulting output
|
||||
-t --form=FORM Output form: (tree|ast|ternary|ascii)
|
||||
|
||||
tricu decode [OPTIONS]
|
||||
Decode a Tree Calculus value into a string representation
|
||||
|
||||
-f --input=FILE Optional file path containing a Tree Calculus value.
|
||||
Defaults to stdin.
|
||||
```
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
@ -3,8 +3,7 @@ module Eval where
|
||||
import Parser
|
||||
import Research
|
||||
|
||||
import Data.Map (Map)
|
||||
import Data.List (foldl')
|
||||
import Data.Map (Map)
|
||||
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Set as Set
|
||||
@ -102,11 +101,6 @@ freeVars (SLambda vs b) = foldr Set.delete (freeVars b) vs
|
||||
isFree :: String -> TricuAST -> Bool
|
||||
isFree x = Set.member x . freeVars
|
||||
|
||||
toAST :: T -> TricuAST
|
||||
toAST Leaf = TLeaf
|
||||
toAST (Stem a) = TStem (toAST a)
|
||||
toAST (Fork a b) = TFork (toAST a) (toAST b)
|
||||
|
||||
-- We need the SKI operators in an unevaluated TricuAST tree form so that we
|
||||
-- can keep the evaluation functions straightforward
|
||||
tI :: TricuAST
|
||||
|
21
src/Lexer.hs
21
src/Lexer.hs
@ -1,32 +1,17 @@
|
||||
module Lexer where
|
||||
|
||||
import Research
|
||||
|
||||
import Control.Monad (void)
|
||||
import Data.Void
|
||||
import Text.Megaparsec
|
||||
import Text.Megaparsec.Char hiding (space)
|
||||
import Text.Megaparsec.Char.Lexer
|
||||
|
||||
import Control.Monad (void)
|
||||
import Data.Void
|
||||
|
||||
import qualified Data.Set as Set
|
||||
|
||||
type Lexer = Parsec Void String
|
||||
|
||||
data LToken
|
||||
= LKeywordT
|
||||
| LIdentifier String
|
||||
| LIntegerLiteral Int
|
||||
| LStringLiteral String
|
||||
| LAssign
|
||||
| LColon
|
||||
| LBackslash
|
||||
| LOpenParen
|
||||
| LCloseParen
|
||||
| LOpenBracket
|
||||
| LCloseBracket
|
||||
| LNewline
|
||||
deriving (Show, Eq, Ord)
|
||||
|
||||
keywordT :: Lexer LToken
|
||||
keywordT = string "t" *> notFollowedBy alphaNumChar *> pure LKeywordT
|
||||
|
||||
|
@ -4,10 +4,10 @@ import Eval
|
||||
import Parser
|
||||
import Research
|
||||
|
||||
import qualified Data.Map as Map
|
||||
import Data.Map (empty)
|
||||
|
||||
library :: Env
|
||||
library = evalTricu Map.empty $ parseTricu $ unlines
|
||||
library = evalTricu empty $ parseTricu $ unlines
|
||||
[ "false = t"
|
||||
, "true = t t"
|
||||
, "_ = t"
|
||||
|
21
src/Main.hs
21
src/Main.hs
@ -1,13 +1,13 @@
|
||||
module Main where
|
||||
|
||||
import Compiler
|
||||
import Eval (evalTricu, result, toAST)
|
||||
import Library (library)
|
||||
import Parser (parseTricu)
|
||||
import Eval (evalTricu, result)
|
||||
import Library (library)
|
||||
import Parser (parseTricu)
|
||||
import REPL
|
||||
import Research
|
||||
|
||||
import Text.Megaparsec (runParser)
|
||||
import Text.Megaparsec (runParser)
|
||||
import System.Console.CmdArgs
|
||||
|
||||
import qualified Data.Map as Map
|
||||
@ -18,9 +18,6 @@ data TricuArgs
|
||||
| Decode { input :: Maybe FilePath }
|
||||
deriving (Show, Data, Typeable)
|
||||
|
||||
data CompiledForm = TreeCalculus | AST | Ternary | Ascii
|
||||
deriving (Show, Data, Typeable)
|
||||
|
||||
replMode :: TricuArgs
|
||||
replMode = Repl
|
||||
&= help "Start interactive REPL"
|
||||
@ -33,8 +30,8 @@ compileMode = Compile
|
||||
&= help "Relative or absolute path to file input for compilation" &= name "f"
|
||||
, output = def &= typ "OUTPUT"
|
||||
&= help "Optional output file path for resulting output" &= name "o"
|
||||
, form = TreeCalculus &= typ "FORM"
|
||||
&= help "Output form: (tree|ast|ternary|ascii)"
|
||||
, form = FSL &= typ "FORM"
|
||||
&= help "Output form: (fsl|tree|ast|ternary|ascii)"
|
||||
&= name "t"
|
||||
}
|
||||
&= help "Compile a file and return the result of the expression in the final line"
|
||||
@ -75,9 +72,3 @@ main = do
|
||||
Just inputPath -> readFile inputPath
|
||||
Nothing -> getContents
|
||||
putStrLn $ decodeResult $ result $ evalTricu library $ parseTricu value
|
||||
|
||||
formatResult :: CompiledForm -> T -> String
|
||||
formatResult TreeCalculus = show
|
||||
formatResult AST = show . toAST
|
||||
formatResult Ternary = toTernaryString
|
||||
formatResult Ascii = toAscii
|
||||
|
@ -1,33 +1,19 @@
|
||||
module Parser where
|
||||
|
||||
import Lexer
|
||||
import Research hiding (toList)
|
||||
import Research hiding (toList)
|
||||
|
||||
import Data.List.NonEmpty (toList)
|
||||
import Data.List.NonEmpty (toList)
|
||||
import Data.Void (Void)
|
||||
import Text.Megaparsec
|
||||
import Text.Megaparsec.Char
|
||||
import Text.Megaparsec.Error (errorBundlePretty, ParseErrorBundle)
|
||||
import Text.Megaparsec.Error (ParseErrorBundle, errorBundlePretty)
|
||||
|
||||
import qualified Data.Set as Set
|
||||
|
||||
type Parser = Parsec Void [LToken]
|
||||
type AltParser = Parsec Void String
|
||||
|
||||
data TricuAST
|
||||
= SVar String
|
||||
| SInt Int
|
||||
| SStr String
|
||||
| SList [TricuAST]
|
||||
| SFunc String [String] TricuAST
|
||||
| SApp TricuAST TricuAST
|
||||
| TLeaf
|
||||
| TStem TricuAST
|
||||
| TFork TricuAST TricuAST
|
||||
| SLambda [String] TricuAST
|
||||
| SEmpty
|
||||
deriving (Show, Eq, Ord)
|
||||
|
||||
parseTricu :: String -> [TricuAST]
|
||||
parseTricu input
|
||||
| null tokens = []
|
||||
|
108
src/Research.hs
108
src/Research.hs
@ -1,14 +1,57 @@
|
||||
module Research where
|
||||
|
||||
import Control.Monad.State
|
||||
import Data.List (intercalate)
|
||||
import Data.Map (Map)
|
||||
import Data.List (intercalate)
|
||||
import Data.Map (Map)
|
||||
import Data.Text (Text, replace)
|
||||
import System.Console.CmdArgs (Data, Typeable)
|
||||
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Text as T
|
||||
|
||||
-- Tree Calculus Types
|
||||
data T = Leaf | Stem T | Fork T T
|
||||
deriving (Show, Eq, Ord)
|
||||
|
||||
-- Abstract Syntax Tree for tricu
|
||||
data TricuAST
|
||||
= SVar String
|
||||
| SInt Int
|
||||
| SStr String
|
||||
| SList [TricuAST]
|
||||
| SFunc String [String] TricuAST
|
||||
| SApp TricuAST TricuAST
|
||||
| TLeaf
|
||||
| TStem TricuAST
|
||||
| TFork TricuAST TricuAST
|
||||
| SLambda [String] TricuAST
|
||||
| SEmpty
|
||||
deriving (Show, Eq, Ord)
|
||||
|
||||
-- Tokens from Lexer
|
||||
data LToken
|
||||
= LKeywordT
|
||||
| LIdentifier String
|
||||
| LIntegerLiteral Int
|
||||
| LStringLiteral String
|
||||
| LAssign
|
||||
| LColon
|
||||
| LBackslash
|
||||
| LOpenParen
|
||||
| LCloseParen
|
||||
| LOpenBracket
|
||||
| LCloseBracket
|
||||
| LNewline
|
||||
deriving (Show, Eq, Ord)
|
||||
|
||||
-- Output formats
|
||||
data CompiledForm = TreeCalculus | FSL | AST | Ternary | Ascii
|
||||
deriving (Show, Data, Typeable)
|
||||
|
||||
-- Environment containing previously evaluated TC terms
|
||||
type Env = Map.Map String T
|
||||
|
||||
-- Tree Calculus Reduction
|
||||
apply :: T -> T -> T
|
||||
apply Leaf b = Stem b
|
||||
apply (Stem a) b = Fork a b
|
||||
@ -79,13 +122,29 @@ toList (Fork x rest) = case toList rest of
|
||||
toList _ = Left "Invalid Tree Calculus list"
|
||||
|
||||
-- Outputs
|
||||
formatResult :: CompiledForm -> T -> String
|
||||
formatResult TreeCalculus = toSimpleT . show
|
||||
formatResult FSL = show
|
||||
formatResult AST = show . toAST
|
||||
formatResult Ternary = toTernaryString
|
||||
formatResult Ascii = toAscii
|
||||
|
||||
toSimpleT :: String -> String
|
||||
toSimpleT s = T.unpack
|
||||
$ replace "Fork" "t"
|
||||
$ replace "Stem" "t"
|
||||
$ replace "Leaf" "t"
|
||||
$ (T.pack s)
|
||||
|
||||
toTernaryString :: T -> String
|
||||
toTernaryString Leaf = "0"
|
||||
toTernaryString (Stem t) = "1" ++ toTernaryString t
|
||||
toTernaryString (Fork t1 t2) = "2" ++ toTernaryString t1 ++ toTernaryString t2
|
||||
|
||||
-- Utility
|
||||
type Env = Map.Map String T
|
||||
toAST :: T -> TricuAST
|
||||
toAST Leaf = TLeaf
|
||||
toAST (Stem a) = TStem (toAST a)
|
||||
toAST (Fork a b) = TFork (toAST a) (toAST b)
|
||||
|
||||
toAscii :: T -> String
|
||||
toAscii tree = go tree "" True
|
||||
@ -101,41 +160,4 @@ toAscii tree = go tree "" True
|
||||
++ go left (prefix ++ (if isLast then " " else "| ")) False
|
||||
++ go right (prefix ++ (if isLast then " " else "| ")) True
|
||||
|
||||
rules :: IO ()
|
||||
rules = putStr $ header
|
||||
++ (unlines $ tcRules)
|
||||
++ (unlines $ haskellRules)
|
||||
++ footer
|
||||
where
|
||||
tcRules :: [String]
|
||||
tcRules =
|
||||
[ "| |"
|
||||
, "| ┌--------- | Tree Calculus | ---------┐ |"
|
||||
, "| | 1. t t a b -> a | |"
|
||||
, "| | 2. t (t a) b c -> a c (b c)| |"
|
||||
, "| | 3a. t (t a b) c t -> a | |"
|
||||
, "| | 3b. t (t a b) c (t u) -> b u | |"
|
||||
, "| | 3c. t (t a b) c (t u v) -> c u v | |"
|
||||
, "| └-------------------------------------┘ |"
|
||||
, "| |"
|
||||
]
|
||||
haskellRules :: [String]
|
||||
haskellRules =
|
||||
[ "| ┌------------------------------ | Haskell | --------------------------------┐ |"
|
||||
, "| | | |"
|
||||
, "| | data T = Leaf | Stem T | Fork TT | |"
|
||||
, "| | | |"
|
||||
, "| | apply :: T -> T -> T | |"
|
||||
, "| | apply Leaf b = Stem b | |"
|
||||
, "| | apply (Stem a) b = Fork a b | |"
|
||||
, "| | apply (Fork Leaf a) _ = a | |"
|
||||
, "| | apply (Fork (Stem a1) a2) b = apply (apply a1 b) (apply a2 b) | |"
|
||||
, "| | apply (Fork (Fork a1 a2) a3) Leaf = a1 | |"
|
||||
, "| | apply (Fork (Fork a1 a2) a3) (Stem u) = apply a2 u | |"
|
||||
, "| | apply (Fork (Fork a1 a2) a3) (Fork u v) = apply (apply a3 u) v | |"
|
||||
, "| └---------------------------------------------------------------------------┘ |"
|
||||
]
|
||||
header :: String
|
||||
header = "┌-------------------- | Rules for evaluating Tree Calculus | -------------------┐\n"
|
||||
footer :: String
|
||||
footer = "└-------------------- | Rules for evaluating Tree Calculus | -------------------┘\n"
|
||||
-- Utility
|
||||
|
@ -388,6 +388,9 @@ compilerTests = testGroup "Compiler tests"
|
||||
, testCase "Mapping and Equality" $ do
|
||||
res <- liftIO $ evaluateFile "./test/map.tri"
|
||||
res @?= Stem Leaf
|
||||
, testCase "Map evaluation to String -> compilation -> string decoding" $ do
|
||||
res <- liftIO $ evaluateFile "./test/string.tri"
|
||||
decodeResult res @?= "String test!"
|
||||
]
|
||||
|
||||
propertyTests :: TestTree
|
||||
|
1
test/string.tri
Normal file
1
test/string.tri
Normal file
@ -0,0 +1 @@
|
||||
head (map (\i : lconcat "String " i) [("test!")])
|
12
tricu.cabal
12
tricu.cabal
@ -17,15 +17,8 @@ executable tricu
|
||||
hs-source-dirs:
|
||||
src
|
||||
default-extensions:
|
||||
ConstraintKinds
|
||||
DataKinds
|
||||
DeriveDataTypeable
|
||||
DeriveGeneric
|
||||
FlexibleContexts
|
||||
FlexibleInstances
|
||||
GeneralizedNewtypeDeriving
|
||||
OverloadedStrings
|
||||
ScopedTypeVariables
|
||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N -optl-pthread -fPIC
|
||||
build-depends:
|
||||
base >=4.7
|
||||
@ -34,6 +27,7 @@ executable tricu
|
||||
, haskeline
|
||||
, megaparsec
|
||||
, mtl
|
||||
, text
|
||||
other-modules:
|
||||
Compiler
|
||||
Eval
|
||||
@ -48,6 +42,9 @@ test-suite tricu-tests
|
||||
type: exitcode-stdio-1.0
|
||||
main-is: Spec.hs
|
||||
hs-source-dirs: test, src
|
||||
default-extensions:
|
||||
DeriveDataTypeable
|
||||
OverloadedStrings
|
||||
build-depends:
|
||||
base
|
||||
, cmdargs
|
||||
@ -58,6 +55,7 @@ test-suite tricu-tests
|
||||
, tasty
|
||||
, tasty-hunit
|
||||
, tasty-quickcheck
|
||||
, text
|
||||
default-language: Haskell2010
|
||||
other-modules:
|
||||
Compiler
|
||||
|
Loading…
x
Reference in New Issue
Block a user