Caller-relative imports; smart deduping in imports
This commit is contained in:
parent
a16a24a808
commit
1a9a4494e0
@ -1,4 +1,5 @@
|
|||||||
!import "lib/base.tri" !Local
|
!import "../lib/base.tri" !Local
|
||||||
|
!import "../lib/list.tri" !Local
|
||||||
|
|
||||||
main = lambdaEqualsTC
|
main = lambdaEqualsTC
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
!import "lib/base.tri" !Local
|
!import "../lib/base.tri" Lib
|
||||||
|
!import "../lib/list.tri" !Local
|
||||||
|
|
||||||
main = exampleTwo
|
main = exampleTwo
|
||||||
-- Level Order Traversal of a labelled binary tree
|
-- Level Order Traversal of a labelled binary tree
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
!import "lib/base.tri" !Local
|
!import "../lib/base.tri" !Local
|
||||||
|
!import "../lib/list.tri" !Local
|
||||||
|
|
||||||
main = size size
|
main = size size
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
!import "lib/base.tri" !Local
|
!import "../lib/base.tri" !Local
|
||||||
|
!import "../lib/list.tri" !Local
|
||||||
|
|
||||||
main = toSource not?
|
main = toSource not?
|
||||||
-- Thanks to intensionality, we can inspect the structure of a given value
|
-- Thanks to intensionality, we can inspect the structure of a given value
|
||||||
|
115
lib/base.tri
115
lib/base.tri
@ -1,13 +1,8 @@
|
|||||||
false = t
|
false = t
|
||||||
_ = t
|
_ = t
|
||||||
true = t t
|
true = 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)
|
|
||||||
id = \a : a
|
id = \a : a
|
||||||
|
const = \a b : a
|
||||||
pair = t
|
pair = t
|
||||||
if = \cond then else : t (t else (t t then)) t cond
|
if = \cond then else : t (t else (t t then)) t cond
|
||||||
|
|
||||||
@ -26,33 +21,6 @@ matchBool = (\ot of : triage
|
|||||||
(\_ _ : ot)
|
(\_ _ : ot)
|
||||||
)
|
)
|
||||||
|
|
||||||
matchList = \a b : triage a _ b
|
|
||||||
|
|
||||||
matchPair = \a : triage _ _ a
|
|
||||||
|
|
||||||
not? = matchBool false true
|
|
||||||
and? = matchBool id (\_ : false)
|
|
||||||
emptyList? = matchList true (\_ _ : false)
|
|
||||||
|
|
||||||
head = matchList t (\head _ : head)
|
|
||||||
tail = matchList t (\_ tail : tail)
|
|
||||||
|
|
||||||
or? = (\x y :
|
|
||||||
matchBool
|
|
||||||
(matchBool (t t) (t t) y)
|
|
||||||
(matchBool (t t) t y)
|
|
||||||
x)
|
|
||||||
|
|
||||||
xor? = (\x y :
|
|
||||||
matchBool
|
|
||||||
(matchBool t (t t) y)
|
|
||||||
(matchBool (t t) t y)
|
|
||||||
x)
|
|
||||||
|
|
||||||
append = y (\self : matchList
|
|
||||||
(\k : k)
|
|
||||||
(\h r k : pair h (self r k)))
|
|
||||||
|
|
||||||
lAnd = (triage
|
lAnd = (triage
|
||||||
(\_ : false)
|
(\_ : false)
|
||||||
(\_ x : x)
|
(\_ x : x)
|
||||||
@ -63,11 +31,22 @@ lOr = (triage
|
|||||||
(\_ _ : true)
|
(\_ _ : true)
|
||||||
(\_ _ _ : true))
|
(\_ _ _ : true))
|
||||||
|
|
||||||
map_ = y (\self :
|
matchPair = \a : triage _ _ a
|
||||||
matchList
|
|
||||||
(\_ : t)
|
not? = matchBool false true
|
||||||
(\head tail f : pair (f head) (self tail f)))
|
and? = matchBool id (\_ : false)
|
||||||
map = \f l : map_ l f
|
|
||||||
|
or? = (\x z :
|
||||||
|
matchBool
|
||||||
|
(matchBool true true z)
|
||||||
|
(matchBool true false z)
|
||||||
|
x)
|
||||||
|
|
||||||
|
xor? = (\x z :
|
||||||
|
matchBool
|
||||||
|
(matchBool false true z)
|
||||||
|
(matchBool true false z)
|
||||||
|
x)
|
||||||
|
|
||||||
equal? = y (\self : triage
|
equal? = y (\self : triage
|
||||||
(triage
|
(triage
|
||||||
@ -85,21 +64,6 @@ equal? = y (\self : triage
|
|||||||
(\_ : false)
|
(\_ : false)
|
||||||
(\bx by : lAnd (self ax bx) (self ay by))))
|
(\bx by : lAnd (self ax bx) (self ay by))))
|
||||||
|
|
||||||
lExist? = y (\self x : matchList
|
|
||||||
false
|
|
||||||
(\h z : or? (equal? x h) (self x z)))
|
|
||||||
|
|
||||||
filter_ = y (\self : matchList
|
|
||||||
(\_ : t)
|
|
||||||
(\head tail f : matchBool (t head) i (f head) (self tail f)))
|
|
||||||
filter = \f l : filter_ l f
|
|
||||||
|
|
||||||
foldl_ = y (\self f l x : matchList (\acc : acc) (\head tail acc : self f tail (f acc head)) l x)
|
|
||||||
foldl = \f x l : foldl_ f l x
|
|
||||||
|
|
||||||
foldr_ = y (\self x f l : matchList x (\head tail : f (self x f tail) head) l)
|
|
||||||
foldr = \f x l : foldr_ x f l
|
|
||||||
|
|
||||||
succ = y (\self :
|
succ = y (\self :
|
||||||
triage
|
triage
|
||||||
1
|
1
|
||||||
@ -108,48 +72,3 @@ succ = y (\self :
|
|||||||
(t (t t))
|
(t (t t))
|
||||||
(\_ tail : t t (self tail))
|
(\_ tail : t t (self tail))
|
||||||
t))
|
t))
|
||||||
|
|
||||||
length = y (\self : matchList
|
|
||||||
0
|
|
||||||
(\_ tail : succ (self tail)))
|
|
||||||
|
|
||||||
reverse = y (\self : matchList
|
|
||||||
t
|
|
||||||
(\head tail : append (self tail) (pair head t)))
|
|
||||||
|
|
||||||
snoc = y (\self x : matchList
|
|
||||||
(pair x t)
|
|
||||||
(\h z : pair h (self x z)))
|
|
||||||
|
|
||||||
count = y (\self x : matchList
|
|
||||||
0
|
|
||||||
(\h z : matchBool
|
|
||||||
(succ (self x z))
|
|
||||||
(self x z)
|
|
||||||
(equal? x h)))
|
|
||||||
|
|
||||||
last = y (\self : matchList
|
|
||||||
t
|
|
||||||
(\hd tl : matchBool
|
|
||||||
hd
|
|
||||||
(self tl)
|
|
||||||
(emptyList? tl)))
|
|
||||||
|
|
||||||
all? = y (\self pred : matchList
|
|
||||||
true
|
|
||||||
(\h z : and? (pred h) (self pred z)))
|
|
||||||
|
|
||||||
any? = y (\self pred : matchList
|
|
||||||
false
|
|
||||||
(\h z : or? (pred h) (self pred z)))
|
|
||||||
|
|
||||||
unique_ = y (\self seen : matchList
|
|
||||||
t
|
|
||||||
(\head rest : matchBool
|
|
||||||
(self seen rest)
|
|
||||||
(pair head (self (pair head seen) rest))
|
|
||||||
(lExist? head seen)))
|
|
||||||
unique = \xs : unique_ t xs
|
|
||||||
|
|
||||||
intersect = \xs ys : filter (\x : lExist? x ys) xs
|
|
||||||
union = \xs ys : unique (append xs ys)
|
|
||||||
|
77
lib/list.tri
Normal file
77
lib/list.tri
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
!import "base.tri" !Local
|
||||||
|
|
||||||
|
matchList = \a b : triage a _ b
|
||||||
|
|
||||||
|
emptyList? = matchList true (\_ _ : false)
|
||||||
|
head = matchList t (\head _ : head)
|
||||||
|
tail = matchList t (\_ tail : tail)
|
||||||
|
|
||||||
|
append = y (\self : matchList
|
||||||
|
(\k : k)
|
||||||
|
(\h r k : pair h (self r k)))
|
||||||
|
|
||||||
|
lExist? = y (\self x : matchList
|
||||||
|
false
|
||||||
|
(\h z : or? (equal? x h) (self x z)))
|
||||||
|
|
||||||
|
map_ = y (\self :
|
||||||
|
matchList
|
||||||
|
(\_ : t)
|
||||||
|
(\head tail f : pair (f head) (self tail f)))
|
||||||
|
map = \f l : map_ l f
|
||||||
|
|
||||||
|
filter_ = y (\self : matchList
|
||||||
|
(\_ : t)
|
||||||
|
(\head tail f : matchBool (t head) id (f head) (self tail f)))
|
||||||
|
filter = \f l : filter_ l f
|
||||||
|
|
||||||
|
foldl_ = y (\self f l x : matchList (\acc : acc) (\head tail acc : self f tail (f acc head)) l x)
|
||||||
|
foldl = \f x l : foldl_ f l x
|
||||||
|
|
||||||
|
foldr_ = y (\self x f l : matchList x (\head tail : f (self x f tail) head) l)
|
||||||
|
foldr = \f x l : foldr_ x f l
|
||||||
|
|
||||||
|
length = y (\self : matchList
|
||||||
|
0
|
||||||
|
(\_ tail : succ (self tail)))
|
||||||
|
|
||||||
|
reverse = y (\self : matchList
|
||||||
|
t
|
||||||
|
(\head tail : append (self tail) (pair head t)))
|
||||||
|
|
||||||
|
snoc = y (\self x : matchList
|
||||||
|
(pair x t)
|
||||||
|
(\h z : pair h (self x z)))
|
||||||
|
|
||||||
|
count = y (\self x : matchList
|
||||||
|
0
|
||||||
|
(\h z : matchBool
|
||||||
|
(succ (self x z))
|
||||||
|
(self x z)
|
||||||
|
(equal? x h)))
|
||||||
|
|
||||||
|
last = y (\self : matchList
|
||||||
|
t
|
||||||
|
(\hd tl : matchBool
|
||||||
|
hd
|
||||||
|
(self tl)
|
||||||
|
(emptyList? tl)))
|
||||||
|
|
||||||
|
all? = y (\self pred : matchList
|
||||||
|
true
|
||||||
|
(\h z : and? (pred h) (self pred z)))
|
||||||
|
|
||||||
|
any? = y (\self pred : matchList
|
||||||
|
false
|
||||||
|
(\h z : or? (pred h) (self pred z)))
|
||||||
|
|
||||||
|
unique_ = y (\self seen : matchList
|
||||||
|
t
|
||||||
|
(\head rest : matchBool
|
||||||
|
(self seen rest)
|
||||||
|
(pair head (self (pair head seen) rest))
|
||||||
|
(lExist? head seen)))
|
||||||
|
unique = \xs : unique_ t xs
|
||||||
|
|
||||||
|
intersect = \xs ys : filter (\x : lExist? x ys) xs
|
||||||
|
union = \xs ys : unique (append xs ys)
|
17
src/Eval.hs
17
src/Eval.hs
@ -141,18 +141,23 @@ reorderDefs env defs
|
|||||||
|
|
||||||
buildDepGraph :: [TricuAST] -> Map.Map String (Set.Set String)
|
buildDepGraph :: [TricuAST] -> Map.Map String (Set.Set String)
|
||||||
buildDepGraph topDefs
|
buildDepGraph topDefs
|
||||||
| not (null duplicateNames) =
|
| not (null conflictingDefs) =
|
||||||
errorWithoutStackTrace $
|
errorWithoutStackTrace $
|
||||||
"Duplicate definitions detected: " ++ show duplicateNames
|
"Conflicting definitions detected: " ++ show conflictingDefs
|
||||||
| otherwise =
|
| otherwise =
|
||||||
Map.fromList
|
Map.fromList
|
||||||
[ (name, depends topDefs (SDef name [] body))
|
[ (name, depends topDefs (SDef name [] body))
|
||||||
| SDef name _ body <- topDefs]
|
| SDef name _ body <- topDefs]
|
||||||
where
|
where
|
||||||
names = [name | SDef name _ _ <- topDefs]
|
defsMap = Map.fromListWith (++)
|
||||||
duplicateNames =
|
[(name, [(name, body)]) | SDef name _ body <- topDefs]
|
||||||
[ name | (name, count) <- Map.toList (countOccurrences names) , count > 1]
|
|
||||||
countOccurrences = foldr (\x -> Map.insertWith (+) x 1) Map.empty
|
conflictingDefs =
|
||||||
|
[ name
|
||||||
|
| (name, defs) <- Map.toList defsMap
|
||||||
|
, let bodies = map snd defs
|
||||||
|
, not $ all (== head bodies) (tail bodies)
|
||||||
|
]
|
||||||
|
|
||||||
sortDeps :: Map.Map String (Set.Set String) -> [String]
|
sortDeps :: Map.Map String (Set.Set String) -> [String]
|
||||||
sortDeps graph = go [] Set.empty (Map.keys graph)
|
sortDeps graph = go [] Set.empty (Map.keys graph)
|
||||||
|
@ -8,6 +8,7 @@ import Research
|
|||||||
import Data.List (partition)
|
import Data.List (partition)
|
||||||
import Control.Monad (foldM)
|
import Control.Monad (foldM)
|
||||||
import System.IO
|
import System.IO
|
||||||
|
import System.FilePath (takeDirectory, normalise, (</>))
|
||||||
|
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
@ -46,38 +47,45 @@ evaluateFileWithContext env filePath = do
|
|||||||
pure $ evalTricu env ast
|
pure $ evalTricu env ast
|
||||||
|
|
||||||
preprocessFile :: FilePath -> IO [TricuAST]
|
preprocessFile :: FilePath -> IO [TricuAST]
|
||||||
preprocessFile = preprocessFile' Set.empty
|
preprocessFile p = preprocessFile' Set.empty p p
|
||||||
|
|
||||||
preprocessFile' :: Set.Set FilePath -> FilePath -> IO [TricuAST]
|
preprocessFile' :: Set.Set FilePath -> FilePath -> FilePath -> IO [TricuAST]
|
||||||
preprocessFile' inProgress filePath
|
preprocessFile' s b p
|
||||||
| filePath `Set.member` inProgress =
|
| p `Set.member` s =
|
||||||
errorWithoutStackTrace $ "Encountered cyclic import: " ++ filePath
|
errorWithoutStackTrace $ "Encountered cyclic import: " ++ p
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
contents <- readFile filePath
|
c <- readFile p
|
||||||
let tokens = lexTricu contents
|
let t = lexTricu c
|
||||||
case parseProgram tokens of
|
case parseProgram t of
|
||||||
Left err -> errorWithoutStackTrace (handleParseError err)
|
Left e -> errorWithoutStackTrace (handleParseError e)
|
||||||
Right asts -> do
|
Right a -> do
|
||||||
let (imports, nonImports) = partition isImport asts
|
let (i, n) = partition isImp a
|
||||||
let newInProgress = Set.insert filePath inProgress
|
let s' = Set.insert p s
|
||||||
importedASTs <- concat <$>
|
r <- concat <$>
|
||||||
mapM (processImport newInProgress "") imports
|
mapM (procImp s' "" p) i
|
||||||
pure $ importedASTs ++ nonImports
|
pure $ r ++ n
|
||||||
where
|
where
|
||||||
isImport :: TricuAST -> Bool
|
isImp :: TricuAST -> Bool
|
||||||
isImport (SImport _ _) = True
|
isImp (SImport _ _) = True
|
||||||
isImport _ = False
|
isImp _ = False
|
||||||
|
|
||||||
processImport :: Set.Set FilePath -> String -> TricuAST -> IO [TricuAST]
|
procImp :: Set.Set FilePath -> String -> FilePath -> TricuAST -> IO [TricuAST]
|
||||||
processImport prog currentModule (SImport path "!Local") = do
|
procImp s m f (SImport p "!Local") = do
|
||||||
ast <- preprocessFile' prog path
|
let ip = makeRelativeTo f p
|
||||||
let defs = filter (not . isImport) ast
|
a <- preprocessFile' s b ip
|
||||||
pure $ map (nsDefinition currentModule) defs
|
let d = filter (not . isImp) a
|
||||||
processImport prog _ (SImport path name) = do
|
pure $ map (nsDefinition m) d
|
||||||
ast <- preprocessFile' prog path
|
procImp s _ f (SImport p n) = do
|
||||||
let defs = filter (not . isImport) ast
|
let ip = makeRelativeTo f p
|
||||||
pure $ map (nsDefinition name) defs
|
a <- preprocessFile' s b ip
|
||||||
processImport _ _ _ = error "Unexpected non-import in processImport"
|
let d = filter (not . isImp) a
|
||||||
|
pure $ map (nsDefinition n) d
|
||||||
|
procImp _ _ _ _ = error "Unexpected non-import in processImport"
|
||||||
|
|
||||||
|
makeRelativeTo :: FilePath -> FilePath -> FilePath
|
||||||
|
makeRelativeTo f i =
|
||||||
|
let d = takeDirectory f
|
||||||
|
in normalise $ d </> i
|
||||||
|
|
||||||
nsDefinitions :: String -> [TricuAST] -> [TricuAST]
|
nsDefinitions :: String -> [TricuAST] -> [TricuAST]
|
||||||
nsDefinitions moduleName = map (nsDefinition moduleName)
|
nsDefinitions moduleName = map (nsDefinition moduleName)
|
||||||
|
80
test/Spec.hs
80
test/Spec.hs
@ -30,7 +30,7 @@ tests = testGroup "Tricu Tests"
|
|||||||
, parser
|
, parser
|
||||||
, simpleEvaluation
|
, simpleEvaluation
|
||||||
, lambdas
|
, lambdas
|
||||||
, baseLibrary
|
, providedLibraries
|
||||||
, fileEval
|
, fileEval
|
||||||
, modules
|
, modules
|
||||||
, demos
|
, demos
|
||||||
@ -343,137 +343,101 @@ lambdas = testGroup "Lambda Evaluation Tests"
|
|||||||
runTricu input @?= "Fork Leaf (Fork (Stem Leaf) Leaf)"
|
runTricu input @?= "Fork Leaf (Fork (Stem Leaf) Leaf)"
|
||||||
]
|
]
|
||||||
|
|
||||||
baseLibrary :: TestTree
|
providedLibraries :: TestTree
|
||||||
baseLibrary = testGroup "Library Tests"
|
providedLibraries = testGroup "Library Tests"
|
||||||
[ testCase "K combinator 1" $ do
|
[ testCase "Triage test Leaf" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "k (t) (t t)"
|
|
||||||
env = evalTricu library (parseTricu input)
|
|
||||||
result env @?= Leaf
|
|
||||||
|
|
||||||
, testCase "K combinator 2" $ do
|
|
||||||
library <- evaluateFile "./lib/base.tri"
|
|
||||||
let input = "k (t t) (t)"
|
|
||||||
env = evalTricu library (parseTricu input)
|
|
||||||
result env @?= Stem Leaf
|
|
||||||
|
|
||||||
, testCase "K combinator 3" $ do
|
|
||||||
library <- evaluateFile "./lib/base.tri"
|
|
||||||
let input = "k (t t t) (t)"
|
|
||||||
env = evalTricu library (parseTricu input)
|
|
||||||
result env @?= Fork Leaf Leaf
|
|
||||||
|
|
||||||
, testCase "S combinator" $ do
|
|
||||||
library <- evaluateFile "./lib/base.tri"
|
|
||||||
let input = "s (t) (t) (t)"
|
|
||||||
env = evalTricu library (parseTricu input)
|
|
||||||
result env @?= Fork Leaf (Stem Leaf)
|
|
||||||
|
|
||||||
, testCase "SKK == I (fully expanded)" $ do
|
|
||||||
library <- evaluateFile "./lib/base.tri"
|
|
||||||
let input = "s k k"
|
|
||||||
env = evalTricu library (parseTricu input)
|
|
||||||
result env @?= Fork (Stem (Stem Leaf)) (Stem Leaf)
|
|
||||||
|
|
||||||
, testCase "I combinator" $ do
|
|
||||||
library <- evaluateFile "./lib/base.tri"
|
|
||||||
let input = "i not?"
|
|
||||||
env = evalTricu library (parseTricu input)
|
|
||||||
result env @?= Fork (Fork (Stem Leaf) (Fork Leaf Leaf)) (Fork Leaf (Fork Leaf Leaf))
|
|
||||||
|
|
||||||
, testCase "Triage test Leaf" $ do
|
|
||||||
library <- evaluateFile "./lib/base.tri"
|
|
||||||
let input = "test t"
|
let input = "test t"
|
||||||
env = decodeResult $ result $ evalTricu library (parseTricu input)
|
env = decodeResult $ result $ evalTricu library (parseTricu input)
|
||||||
env @?= "\"Leaf\""
|
env @?= "\"Leaf\""
|
||||||
|
|
||||||
, testCase "Triage test (Stem Leaf)" $ do
|
, testCase "Triage test (Stem Leaf)" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "test (t t)"
|
let input = "test (t t)"
|
||||||
env = decodeResult $ result $ evalTricu library (parseTricu input)
|
env = decodeResult $ result $ evalTricu library (parseTricu input)
|
||||||
env @?= "\"Stem\""
|
env @?= "\"Stem\""
|
||||||
|
|
||||||
, testCase "Triage test (Fork Leaf Leaf)" $ do
|
, testCase "Triage test (Fork Leaf Leaf)" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "test (t t t)"
|
let input = "test (t t t)"
|
||||||
env = decodeResult $ result $ evalTricu library (parseTricu input)
|
env = decodeResult $ result $ evalTricu library (parseTricu input)
|
||||||
env @?= "\"Fork\""
|
env @?= "\"Fork\""
|
||||||
|
|
||||||
, testCase "Boolean NOT: true" $ do
|
, testCase "Boolean NOT: true" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "not? true"
|
let input = "not? true"
|
||||||
env = result $ evalTricu library (parseTricu input)
|
env = result $ evalTricu library (parseTricu input)
|
||||||
env @?= Leaf
|
env @?= Leaf
|
||||||
|
|
||||||
, testCase "Boolean NOT: false" $ do
|
, testCase "Boolean NOT: false" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "not? false"
|
let input = "not? false"
|
||||||
env = result $ evalTricu library (parseTricu input)
|
env = result $ evalTricu library (parseTricu input)
|
||||||
env @?= Stem Leaf
|
env @?= Stem Leaf
|
||||||
|
|
||||||
|
|
||||||
, testCase "Boolean AND TF" $ do
|
, testCase "Boolean AND TF" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "and? (t t) (t)"
|
let input = "and? (t t) (t)"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Leaf
|
result env @?= Leaf
|
||||||
|
|
||||||
, testCase "Boolean AND FT" $ do
|
, testCase "Boolean AND FT" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "and? (t) (t t)"
|
let input = "and? (t) (t t)"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Leaf
|
result env @?= Leaf
|
||||||
|
|
||||||
, testCase "Boolean AND FF" $ do
|
, testCase "Boolean AND FF" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "and? (t) (t)"
|
let input = "and? (t) (t)"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Leaf
|
result env @?= Leaf
|
||||||
|
|
||||||
, testCase "Boolean AND TT" $ do
|
, testCase "Boolean AND TT" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "and? (t t) (t t)"
|
let input = "and? (t t) (t t)"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Stem Leaf
|
result env @?= Stem Leaf
|
||||||
|
|
||||||
, testCase "List head" $ do
|
, testCase "List head" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "head [(t) (t t) (t t t)]"
|
let input = "head [(t) (t t) (t t t)]"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Leaf
|
result env @?= Leaf
|
||||||
|
|
||||||
, testCase "List tail" $ do
|
, testCase "List tail" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "head (tail (tail [(t) (t t) (t t t)]))"
|
let input = "head (tail (tail [(t) (t t) (t t t)]))"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Fork Leaf Leaf
|
result env @?= Fork Leaf Leaf
|
||||||
|
|
||||||
, testCase "List map" $ do
|
, testCase "List map" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "head (tail (map (\\a : (t t t)) [(t) (t) (t)]))"
|
let input = "head (tail (map (\\a : (t t t)) [(t) (t) (t)]))"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Fork Leaf Leaf
|
result env @?= Fork Leaf Leaf
|
||||||
|
|
||||||
, testCase "Empty list check" $ do
|
, testCase "Empty list check" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "emptyList? []"
|
let input = "emptyList? []"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Stem Leaf
|
result env @?= Stem Leaf
|
||||||
|
|
||||||
, testCase "Non-empty list check" $ do
|
, testCase "Non-empty list check" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "not? (emptyList? [(1) (2) (3)])"
|
let input = "not? (emptyList? [(1) (2) (3)])"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Stem Leaf
|
result env @?= Stem Leaf
|
||||||
|
|
||||||
, testCase "Concatenate strings" $ do
|
, testCase "Concatenate strings" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "append \"Hello, \" \"world!\""
|
let input = "append \"Hello, \" \"world!\""
|
||||||
env = decodeResult $ result $ evalTricu library (parseTricu input)
|
env = decodeResult $ result $ evalTricu library (parseTricu input)
|
||||||
env @?= "\"Hello, world!\""
|
env @?= "\"Hello, world!\""
|
||||||
|
|
||||||
, testCase "Verifying Equality" $ do
|
, testCase "Verifying Equality" $ do
|
||||||
library <- evaluateFile "./lib/base.tri"
|
library <- evaluateFile "./lib/list.tri"
|
||||||
let input = "equal? (t t t) (t t t)"
|
let input = "equal? (t t t) (t t t)"
|
||||||
env = evalTricu library (parseTricu input)
|
env = evalTricu library (parseTricu input)
|
||||||
result env @?= Stem Leaf
|
result env @?= Stem Leaf
|
||||||
@ -490,12 +454,12 @@ fileEval = testGroup "File evaluation tests"
|
|||||||
res @?= Fork (Stem Leaf) Leaf
|
res @?= Fork (Stem Leaf) Leaf
|
||||||
|
|
||||||
, testCase "Mapping and Equality" $ do
|
, testCase "Mapping and Equality" $ do
|
||||||
library <- liftIO $ evaluateFile "./lib/base.tri"
|
library <- liftIO $ evaluateFile "./lib/list.tri"
|
||||||
fEnv <- liftIO $ evaluateFileWithContext library "./test/map.tri"
|
fEnv <- liftIO $ evaluateFileWithContext library "./test/map.tri"
|
||||||
(mainResult fEnv) @?= Stem Leaf
|
(mainResult fEnv) @?= Stem Leaf
|
||||||
|
|
||||||
, testCase "Eval and decoding string" $ do
|
, testCase "Eval and decoding string" $ do
|
||||||
library <- liftIO $ evaluateFile "./lib/base.tri"
|
library <- liftIO $ evaluateFile "./lib/list.tri"
|
||||||
res <- liftIO $ evaluateFileWithContext library "./test/string.tri"
|
res <- liftIO $ evaluateFileWithContext library "./test/string.tri"
|
||||||
decodeResult (result res) @?= "\"String test!\""
|
decodeResult (result res) @?= "\"String test!\""
|
||||||
]
|
]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
!import "test/cycle-2.tri" Cycle2
|
!import "cycle-2.tri" Cycle2
|
||||||
|
|
||||||
cycle1 = t Cycle2.cycle2
|
cycle1 = t Cycle2.cycle2
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
!import "test/cycle-1.tri" Cycle1
|
!import "cycle-1.tri" Cycle1
|
||||||
|
|
||||||
cycle2 = t Cycle1.cycle1
|
cycle2 = t Cycle1.cycle1
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
!import "test/local-ns/2.tri" Two
|
!import "2.tri" Two
|
||||||
|
|
||||||
main = Two.x
|
main = Two.x
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
|
|
||||||
!import "test/local-ns/3.tri" !Local
|
!import "3.tri" !Local
|
||||||
|
@ -1,2 +1 @@
|
|||||||
|
|
||||||
x = 3
|
x = 3
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
!import "./test/multi-level-B.tri" B
|
!import "multi-level-B.tri" B
|
||||||
main = B.main
|
main = B.main
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
!import "./test/multi-level-C.tri" C
|
!import "multi-level-C.tri" C
|
||||||
main = C.val
|
main = C.val
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
!import "./test/namespace-B.tri" B
|
!import "namespace-B.tri" B
|
||||||
main = B.x
|
main = B.x
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
!import "./test/vars-B.tri" B
|
!import "vars-B.tri" B
|
||||||
|
|
||||||
!import "./test/vars-C.tri" C
|
!import "vars-C.tri" C
|
||||||
|
|
||||||
main = B.y (C.z)
|
main = B.y (C.z)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
cabal-version: 1.12
|
cabal-version: 1.12
|
||||||
|
|
||||||
name: tricu
|
name: tricu
|
||||||
version: 0.13.2
|
version: 0.14.0
|
||||||
description: A micro-language for exploring Tree Calculus
|
description: A micro-language for exploring Tree Calculus
|
||||||
author: James Eversole
|
author: James Eversole
|
||||||
maintainer: james@eversole.co
|
maintainer: james@eversole.co
|
||||||
@ -27,6 +27,7 @@ executable tricu
|
|||||||
, cmdargs
|
, cmdargs
|
||||||
, containers
|
, containers
|
||||||
, exceptions
|
, exceptions
|
||||||
|
, filepath
|
||||||
, haskeline
|
, haskeline
|
||||||
, megaparsec
|
, megaparsec
|
||||||
, mtl
|
, mtl
|
||||||
@ -54,6 +55,7 @@ test-suite tricu-tests
|
|||||||
, cmdargs
|
, cmdargs
|
||||||
, containers
|
, containers
|
||||||
, exceptions
|
, exceptions
|
||||||
|
, filepath
|
||||||
, haskeline
|
, haskeline
|
||||||
, megaparsec
|
, megaparsec
|
||||||
, mtl
|
, mtl
|
||||||
|
Loading…
x
Reference in New Issue
Block a user