commit ec0a6b7b1673453ca0ad45266728e2d6dce55281
parent eeaf9e0289fa74e0ac0a57a7c037b4bb8e7e5ac0
Author: James Eversole <james@eversole.co>
Date: Mon, 20 Jan 2025 19:20:29 -0600
Allow multiline expressions
Diffstat:
7 files changed, 345 insertions(+), 271 deletions(-)
diff --git a/lib/base.tri b/lib/base.tri
@@ -17,25 +17,77 @@ yD = yi iE
id = (\a : a)
triage = (\a b c : t (t a b) c)
pair = t
-matchBool = (\ot of : triage of (\_ : ot) (\_ _ : ot))
-matchList = (\oe oc : triage oe _ oc)
-matchPair = (\op : triage _ _ op)
+
+matchBool = (\ot of : triage
+ of
+ (\_ : ot)
+ (\_ _ : ot)
+)
+
+matchList = (\oe oc : triage
+ oe
+ _
+ oc
+)
+
+matchPair = (\op : triage
+ _
+ _
+ op
+)
+
not = matchBool false true
and = matchBool id (\z : false)
if = (\cond then else : t (t else (t t then)) t cond)
test = triage "Leaf" (\z : "Stem") (\a b : "Fork")
+
emptyList = matchList true (\y z : false)
head = matchList t (\hd tl : hd)
tail = matchList t (\hd tl : tl)
-lconcat = y (\self : matchList (\k : k) (\h r k : pair h (self r k)))
-lAnd = triage (\x : false) (\_ x : x) (\_ _ x : x)
-lOr = triage (\x : x) (\_ _ : true) (\_ _ x : true)
-hmap = y (\self : matchList (\f : t) (\hd tl f : pair (f hd) (self tl f)))
+
+lconcat = y (\self : matchList
+ (\k : k)
+ (\h r k : pair h (self r k)))
+
+lAnd = (triage
+ (\x : false)
+ (\_ x : x)
+ (\_ _ x : x)
+)
+
+lOr = (triage
+ (\x : x)
+ (\_ _ : true)
+ (\_ _ x : true)
+)
+
+hmap = y (\self :
+ matchList
+ (\f : t)
+ (\hd tl f : pair
+ (f hd)
+ (self tl f)))
map = (\f l : hmap l f)
-equal = y (\self : triage (triage true (\z : false) (\y z : false)) (\ax : triage false (self ax) (\y z : false)) (\ax ay : triage false (\z : false) (\bx by : lAnd (self ax bx) (self ay by))))
+
+equal = y (\self : triage
+ (triage
+ true
+ (\z : false)
+ (\y z : false))
+ (\ax : triage
+ false
+ (self ax)
+ (\y z : false))
+ (\ax ay : triage
+ false
+ (\z : false)
+ (\bx by : lAnd (self ax bx) (self ay by))))
+
hfilter = y (\self : matchList (\f : t) (\hd tl f : matchBool (t hd) i (f hd) (self tl f)))
-filter = (\f l : hfilter l f)
-hfoldl = y (\self f l x : matchList (\acc : acc) (\hd tl acc : self f tl (f acc hd)) l x)
-foldl = (\f x l : hfoldl f l x)
-hfoldr = y (\self x f l : matchList x (\hd tl : f (self x f tl) hd) l)
-foldr = (\f x l : hfoldr x f l)
+filter = (\f l : hfilter l f)
+
+hfoldl = y (\self f l x : matchList (\acc : acc) (\hd tl acc : self f tl (f acc hd)) l x)
+foldl = (\f x l : hfoldl f l x)
+
+hfoldr = y (\self x f l : matchList x (\hd tl : f (self x f tl) hd) l)
+foldr = (\f x l : hfoldr x f l)
diff --git a/src/Eval.hs b/src/Eval.hs
@@ -13,22 +13,23 @@ evalSingle env term
| SFunc name [] body <- term =
let res = evalAST env body
in Map.insert "__result" res (Map.insert name res env)
- | SApp func arg <- term = Map.insert "__result"
- (apply (evalAST env func) (evalAST env arg)) env
- | SVar name <- term = case Map.lookup name env of
- Just v -> Map.insert "__result" v env
- Nothing -> errorWithoutStackTrace $ "Variable " ++ name ++ " not defined"
- | otherwise = Map.insert "__result" (evalAST env term) env
+ | SApp func arg <- term =
+ let res = apply (evalAST env func) (evalAST env arg)
+ in Map.insert "__result" res env
+ | SVar name <- term =
+ case Map.lookup name env of
+ Just v -> Map.insert "__result" v env
+ Nothing -> errorWithoutStackTrace $ "Variable " ++ name ++ " not defined"
+ | otherwise =
+ Map.insert "__result" (evalAST env term) env
evalTricu :: Env -> [TricuAST] -> Env
-evalTricu env list = evalTricu' env (filter (/= SEmpty) list)
- where
- evalTricu' :: Env -> [TricuAST] -> Env
- evalTricu' env [] = env
- evalTricu' env [s] =
- let updatedEnv = evalSingle env s
- in Map.insert "__result" (result updatedEnv) updatedEnv
- evalTricu' env (x:xs) = evalTricu (evalSingle env x) xs
+evalTricu env [] = env
+evalTricu env [x] =
+ let updatedEnv = evalSingle env x
+ in Map.insert "__result" (result updatedEnv) updatedEnv
+evalTricu env (x:xs) =
+ evalTricu (evalSingle env x) xs
evalAST :: Env -> TricuAST -> T
evalAST env term
diff --git a/src/Lexer.hs b/src/Lexer.hs
@@ -61,7 +61,10 @@ lnewline :: Lexer LToken
lnewline = char '\n' *> pure LNewline
sc :: Lexer ()
-sc = space space1 (skipLineComment "--") (skipBlockComment "|-" "-|")
+sc = space
+ (void $ takeWhile1P (Just "space") (\c -> c == ' ' || c == '\t'))
+ (skipLineComment "--")
+ (skipBlockComment "|-" "-|")
tricuLexer :: Lexer [LToken]
tricuLexer = do
@@ -75,7 +78,8 @@ tricuLexer = do
pure tokens
where
tricuLexer' =
- [ try identifier
+ [ try lnewline
+ , try identifier
, try keywordT
, try integerLiteral
, try stringLiteral
diff --git a/src/Main.hs b/src/Main.hs
@@ -81,4 +81,7 @@ main = do
putStrLn $ decodeResult $ result $ evalTricu library $ parseTricu value
runTricu :: String -> T
-runTricu = result . evalTricu Map.empty . parseTricu
+runTricu input =
+ let asts = parseTricu input
+ finalEnv = evalTricu Map.empty asts
+ in result finalEnv
diff --git a/src/Parser.hs b/src/Parser.hs
@@ -1,281 +1,299 @@
module Parser where
import Lexer
-import Research hiding (toList)
+import Research
-import Data.List.NonEmpty (toList)
+import Control.Monad (void)
+import Control.Monad.State
+import Data.List.NonEmpty (toList)
import Data.Void (Void)
import Text.Megaparsec
-import Text.Megaparsec.Char
import Text.Megaparsec.Error (ParseErrorBundle, errorBundlePretty)
-
import qualified Data.Set as Set
-type Parser = Parsec Void [LToken]
-type AltParser = Parsec Void String
+data PState = PState
+ { depth :: Int
+ } deriving (Show)
+
+type ParserM = StateT PState (Parsec Void [LToken])
+
+satisfyM :: (LToken -> Bool) -> ParserM LToken
+satisfyM f = do
+ token <- lift (satisfy f)
+ modify' (updateDepth token)
+ return token
+
+updateDepth :: LToken -> PState -> PState
+updateDepth LOpenParen st = st { depth = depth st + 1 }
+updateDepth LCloseParen st = st { depth = max 0 (depth st - 1) }
+updateDepth _ st = st
+
+topLevelNewline :: ParserM ()
+topLevelNewline = do
+ st <- get
+ if depth st == 0
+ then void (satisfyM (== LNewline))
+ else fail "Top-level exit in paren context"
+
+parseProgram :: [LToken] -> Either (ParseErrorBundle [LToken] Void) [TricuAST]
+parseProgram tokens =
+ runParser (evalStateT parseProgramM (PState 0)) "" tokens
+
+parseSingleExpr :: [LToken] -> Either (ParseErrorBundle [LToken] Void) TricuAST
+parseSingleExpr tokens =
+ runParser (evalStateT (scnParserM *> parseExpressionM <* eofM) (PState 0)) "" tokens
parseTricu :: String -> [TricuAST]
-parseTricu input
- | null tokens = []
- | otherwise = map parseSingle tokens
- where
- tokens
- | null (lexTricu input) = []
- | otherwise = lines input
+parseTricu input =
+ case lexTricu input of
+ [] -> []
+ toks ->
+ case parseProgram toks of
+ Left err -> error (handleParseError err)
+ Right asts -> asts
parseSingle :: String -> TricuAST
-parseSingle input
- | null tokens = SEmpty
- | Left err <- parsed = error $ handleParseError err
- | Right ast <- parsed = ast
- where
- tokens = lexTricu input
- parsed = runParser parseExpression "" tokens
-
-parseExpression :: Parser TricuAST
-parseExpression = choice
- [ try parseFunction
- , try parseLambda
- , try parseLambdaExpression
- , try parseListLiteral
- , try parseApplication
- , try parseTreeTerm
- , parseLiteral
+parseSingle input =
+ case lexTricu input of
+ [] -> SEmpty
+ toks ->
+ case parseSingleExpr toks of
+ Left err -> error (handleParseError err)
+ Right ast -> ast
+
+parseProgramM :: ParserM [TricuAST]
+parseProgramM = do
+ skipMany topLevelNewline
+ exprs <- sepEndBy parseOneExpression (some topLevelNewline)
+ skipMany topLevelNewline
+ return exprs
+
+parseOneExpression :: ParserM TricuAST
+parseOneExpression = scnParserM *> parseExpressionM
+
+scnParserM :: ParserM ()
+scnParserM = skipMany $ do
+ t <- lookAhead anySingle
+ st <- get
+ if depth st > 0 && isNewline t
+ then void (satisfyM isNewline)
+ else
+ fail "In paren context or no space token" <|> empty
+
+eofM :: ParserM ()
+eofM = lift eof
+
+parseExpressionM :: ParserM TricuAST
+parseExpressionM = choice
+ [ try parseFunctionM
+ , try parseLambdaM
+ , try parseLambdaExpressionM
+ , try parseListLiteralM
+ , try parseApplicationM
+ , try parseTreeTermM
+ , parseLiteralM
]
-scnParser :: Parser ()
-scnParser = skipMany (satisfy isNewline)
-
-parseFunction :: Parser TricuAST
-parseFunction = do
- LIdentifier name <- satisfy isIdentifier
- args <- many (satisfy isIdentifier)
- satisfy (== LAssign)
- body <- parseExpression
- return (SFunc name (map getIdentifier args) body)
-
-parseAtomicBase :: Parser TricuAST
-parseAtomicBase = choice
- [ parseTreeLeaf
- , parseGrouped
- ]
-
-parseLambda :: Parser TricuAST
-parseLambda = between (satisfy (== LOpenParen)) (satisfy (== LCloseParen)) $ do
- satisfy (== LBackslash)
- param <- satisfy isIdentifier
- rest <- many (satisfy isIdentifier)
- satisfy (== LColon)
- body <- parseLambdaExpression
- let nestedLambda = foldr (\v acc -> SLambda [v] acc) body (map getIdentifier rest)
- return (SLambda [getIdentifier param] nestedLambda)
-
-parseLambdaExpression :: Parser TricuAST
-parseLambdaExpression = choice
- [ try parseLambdaApplication
- , parseAtomicLambda
+parseFunctionM :: ParserM TricuAST
+parseFunctionM = do
+ LIdentifier name <- satisfyM isIdentifier
+ args <- many (satisfyM isIdentifier)
+ _ <- satisfyM (== LAssign)
+ scnParserM
+ body <- parseExpressionM
+ pure (SFunc name (map getIdentifier args) body)
+
+parseLambdaM :: ParserM TricuAST
+parseLambdaM = between (satisfyM (== LOpenParen)) (satisfyM (== LCloseParen)) $ do
+ _ <- satisfyM (== LBackslash)
+ param <- satisfyM isIdentifier
+ rest <- many (satisfyM isIdentifier)
+ _ <- satisfyM (== LColon)
+ scnParserM
+ body <- parseLambdaExpressionM
+ let nested = foldr (\v acc -> SLambda [getIdentifier v] acc) body rest
+ pure (SLambda [getIdentifier param] nested)
+
+parseLambdaExpressionM :: ParserM TricuAST
+parseLambdaExpressionM = choice
+ [ try parseLambdaApplicationM
+ , parseAtomicLambdaM
]
-parseAtomicLambda :: Parser TricuAST
-parseAtomicLambda = choice
- [ parseVar
- , parseTreeLeaf
- , parseLiteral
- , parseListLiteral
- , try parseLambda
- , between (satisfy (== LOpenParen)) (satisfy (== LCloseParen)) parseLambdaExpression
+parseAtomicLambdaM :: ParserM TricuAST
+parseAtomicLambdaM = choice
+ [ parseVarM
+ , parseTreeLeafM
+ , parseLiteralM
+ , parseListLiteralM
+ , try parseLambdaM
+ , between (satisfyM (== LOpenParen)) (satisfyM (== LCloseParen)) parseLambdaExpressionM
]
-parseApplication :: Parser TricuAST
-parseApplication = do
- func <- parseAtomicBase
- args <- many parseAtomic
- return $ foldl (\acc arg -> SApp acc arg) func args
-
-parseLambdaApplication :: Parser TricuAST
-parseLambdaApplication = do
- func <- parseAtomicLambda
- args <- many parseAtomicLambda
- return $ foldl (\acc arg -> SApp acc arg) func args
-
-isTreeTerm :: TricuAST -> Bool
-isTreeTerm TLeaf = True
-isTreeTerm (TStem _) = True
-isTreeTerm (TFork _ _) = True
-isTreeTerm _ = False
-
-parseTreeLeaf :: Parser TricuAST
-parseTreeLeaf = satisfy isKeywordT *> notFollowedBy (satisfy (== LAssign)) *> pure TLeaf
-
-getIdentifier :: LToken -> String
-getIdentifier (LIdentifier name) = name
-getIdentifier _ = error "Expected identifier"
+parseApplicationM :: ParserM TricuAST
+parseApplicationM = do
+ func <- parseAtomicBaseM
+ scnParserM
+ args <- many $ do
+ scnParserM
+ arg <- parseAtomicM
+ return arg
+ return $ foldl SApp func args
+
+parseLambdaApplicationM :: ParserM TricuAST
+parseLambdaApplicationM = do
+ func <- parseAtomicLambdaM
+ scnParserM
+ args <- many $ do
+ arg <- parseAtomicLambdaM
+ scnParserM
+ pure arg
+ pure $ foldl SApp func args
+
+parseAtomicBaseM :: ParserM TricuAST
+parseAtomicBaseM = choice
+ [ parseTreeLeafM
+ , parseGroupedM
+ ]
-parseTreeTerm :: Parser TricuAST
-parseTreeTerm = do
- base <- parseTreeLeafOrParenthesized
- rest <- many parseTreeLeafOrParenthesized
- pure $ foldl combine base rest
+parseTreeLeafM :: ParserM TricuAST
+parseTreeLeafM = do
+ _ <- satisfyM isKeywordT
+ notFollowedBy (lift (satisfy (== LAssign)))
+ pure TLeaf
+
+parseTreeTermM :: ParserM TricuAST
+parseTreeTermM = do
+ base <- parseTreeLeafOrParenthesizedM
+ rest <- many parseTreeLeafOrParenthesizedM
+ pure (foldl combine base rest)
where
combine acc next
| TLeaf <- acc = TStem next
| TStem t <- acc = TFork t next
| TFork _ _ <- acc = TFork acc next
-parseTreeLeafOrParenthesized :: Parser TricuAST
-parseTreeLeafOrParenthesized = choice
- [ between (satisfy (== LOpenParen)) (satisfy (== LCloseParen)) parseTreeTerm
- , parseTreeLeaf
+parseTreeLeafOrParenthesizedM :: ParserM TricuAST
+parseTreeLeafOrParenthesizedM = choice
+ [ between (satisfyM (== LOpenParen)) (satisfyM (== LCloseParen)) parseTreeTermM
+ , parseTreeLeafM
]
-foldTree :: [TricuAST] -> TricuAST
-foldTree [] = TLeaf
-foldTree [x] = x
-foldTree (x:y:rest) = TFork x (foldTree (y:rest))
-
-parseAtomic :: Parser TricuAST
-parseAtomic = choice
- [ parseVar
- , parseTreeLeaf
- , parseListLiteral
- , parseGrouped
- , parseLiteral
+parseAtomicM :: ParserM TricuAST
+parseAtomicM = choice
+ [ parseVarM
+ , parseTreeLeafM
+ , parseListLiteralM
+ , parseGroupedM
+ , parseLiteralM
]
-parseGrouped :: Parser TricuAST
-parseGrouped = between (satisfy (== LOpenParen)) (satisfy (== LCloseParen)) parseExpression
+parseGroupedM :: ParserM TricuAST
+parseGroupedM = between (satisfyM (== LOpenParen)) (satisfyM (== LCloseParen)) $
+ scnParserM *> parseExpressionM <* scnParserM
-parseLiteral :: Parser TricuAST
-parseLiteral = choice
- [ parseIntLiteral
- , parseStrLiteral
+parseLiteralM :: ParserM TricuAST
+parseLiteralM = choice
+ [ parseIntLiteralM
+ , parseStrLiteralM
]
-parens :: Parser TricuAST -> Parser TricuAST
-parens p = do
- satisfy (== LOpenParen)
- result <- p
- satisfy (== LCloseParen)
- return result
-
-parseListLiteral :: Parser TricuAST
-parseListLiteral = do
- satisfy (== LOpenBracket)
- elements <- many parseListItem
- satisfy (== LCloseBracket)
- return (SList elements)
-
-parseListItem :: Parser TricuAST
-parseListItem = choice
- [ parseGroupedItem
- , parseListLiteral
- , parseSingleItem
+parseListLiteralM :: ParserM TricuAST
+parseListLiteralM = do
+ _ <- satisfyM (== LOpenBracket)
+ elements <- many parseListItemM
+ _ <- satisfyM (== LCloseBracket)
+ pure (SList elements)
+
+parseListItemM :: ParserM TricuAST
+parseListItemM = choice
+ [ parseGroupedItemM
+ , parseListLiteralM
+ , parseSingleItemM
]
-parseGroupedItem :: Parser TricuAST
-parseGroupedItem = do
- satisfy (== LOpenParen)
- inner <- parseExpression
- satisfy (== LCloseParen)
- return inner
+parseGroupedItemM :: ParserM TricuAST
+parseGroupedItemM = do
+ _ <- satisfyM (== LOpenParen)
+ inner <- parseExpressionM
+ _ <- satisfyM (== LCloseParen)
+ pure inner
-parseSingleItem :: Parser TricuAST
-parseSingleItem = do
- token <- satisfy isListItem
+parseSingleItemM :: ParserM TricuAST
+parseSingleItemM = do
+ token <- satisfyM isListItem
case token of
- _ | LIdentifier name <- token -> return (SVar name)
- | LKeywordT <- token -> return TLeaf
- | otherwise -> fail "Unexpected token in list item"
-
-isListItem :: LToken -> Bool
-isListItem (LIdentifier _) = True
-isListItem LKeywordT = True
-isListItem _ = False
-
-parseVar :: Parser TricuAST
-parseVar = do
- LIdentifier name <- satisfy isIdentifier
- if (name == "t" || name == "__result")
- then fail $ "Reserved keyword: " ++ name ++ " cannot be assigned."
- else return (SVar name)
-
-parseIntLiteral :: Parser TricuAST
-parseIntLiteral = do
- LIntegerLiteral value <- satisfy isIntegerLiteral
- return (SInt value)
-
-parseStrLiteral :: Parser TricuAST
-parseStrLiteral = do
- LStringLiteral value <- satisfy isStringLiteral
- return (SStr value)
-
--- Boolean Helpers
-isKeywordT (LKeywordT) = True
-isKeywordT _ = False
+ LIdentifier name -> pure (SVar name)
+ LKeywordT -> pure TLeaf
+ _ -> fail "Unexpected token in list item"
+
+parseVarM :: ParserM TricuAST
+parseVarM = do
+ LIdentifier name <- satisfyM isIdentifier
+ if name == "t" || name == "__result"
+ then fail ("Reserved keyword: " ++ name ++ " cannot be assigned.")
+ else pure (SVar name)
+
+parseIntLiteralM :: ParserM TricuAST
+parseIntLiteralM = do
+ LIntegerLiteral value <- satisfyM isIntegerLiteral
+ pure (SInt value)
+
+parseStrLiteralM :: ParserM TricuAST
+parseStrLiteralM = do
+ LStringLiteral value <- satisfyM isStringLiteral
+ pure (SStr value)
+
+isKeywordT :: LToken -> Bool
+isKeywordT LKeywordT = True
+isKeywordT _ = False
+
+isIdentifier :: LToken -> Bool
isIdentifier (LIdentifier _) = True
-isIdentifier _ = False
+isIdentifier _ = False
+
+isIntegerLiteral :: LToken -> Bool
isIntegerLiteral (LIntegerLiteral _) = True
-isIntegerLiteral _ = False
-isStringLiteral (LStringLiteral _) = True
-isStringLiteral _ = False
+isIntegerLiteral _ = False
+
+isStringLiteral :: LToken -> Bool
+isStringLiteral (LStringLiteral _) = True
+isStringLiteral _ = False
+
+isLiteral :: LToken -> Bool
isLiteral (LIntegerLiteral _) = True
-isLiteral (LStringLiteral _) = True
-isLiteral _ = False
-isNewline (LNewline) = True
-isNewline _ = False
-
--- Alternative parsers
-altSC :: AltParser ()
-altSC = skipMany (char ' ' <|> char '\t' <|> char '\n')
-
-parseTernaryTerm :: AltParser TricuAST
-parseTernaryTerm = do
- altSC
- term <- choice parseTernaryTerm'
- altSC
- pure term
- where
- parseTernaryTerm' =
- [ try (between (char '(') (char ')') parseTernaryTerm)
- , try parseTernaryLeaf
- , try parseTernaryStem
- , try parseTernaryFork
- ]
-
-parseTernaryLeaf :: AltParser TricuAST
-parseTernaryLeaf = char '0' *> pure TLeaf
-
-parseTernaryStem :: AltParser TricuAST
-parseTernaryStem = char '1' *> (TStem <$> parseTernaryTerm)
-
-parseTernaryFork :: AltParser TricuAST
-parseTernaryFork = do
- char '2'
- term1 <- parseTernaryTerm
- term2 <- parseTernaryTerm
- pure $ TFork term1 term2
-
-parseTernary :: String -> Either String TricuAST
-parseTernary input
- | Left err <- result = Left (errorBundlePretty err)
- | Right ast <- result = Right ast
- where
- result = runParser (parseTernaryTerm <* eof) "" input
+isLiteral (LStringLiteral _) = True
+isLiteral _ = False
+
+isListItem :: LToken -> Bool
+isListItem (LIdentifier _) = True
+isListItem LKeywordT = True
+isListItem _ = False
+
+isNewline :: LToken -> Bool
+isNewline LNewline = True
+isNewline _ = False
+
+getIdentifier :: LToken -> String
+getIdentifier (LIdentifier name) = name
+getIdentifier _ = error "Expected identifier"
--- Error Handling
handleParseError :: ParseErrorBundle [LToken] Void -> String
handleParseError bundle =
- let errors = bundleErrors bundle
- errorList = toList errors
- formattedErrors = map showError errorList
- in unlines ("Parse error(s) encountered:" : formattedErrors)
+ let errors = bundleErrors bundle
+ errorList = Data.List.NonEmpty.toList errors
+ formattedErrs = map showError errorList
+ in unlines ("Parse error(s) encountered:" : formattedErrs)
showError :: ParseError [LToken] Void -> String
showError (TrivialError offset (Just (Tokens tokenStream)) expected) =
- "Parse error at offset " ++ show offset ++ ": unexpected token "
- ++ show tokenStream ++ ", expected one of " ++ show (Set.toList expected)
+ "Parse error at offset " ++ show offset
+ ++ ": unexpected token " ++ show tokenStream
+ ++ ", expected one of " ++ show (Set.toList expected)
showError (FancyError offset fancy) =
- "Parse error at offset " ++ show offset ++ ":\n " ++ unlines (map show (Set.toList fancy))
+ "Parse error at offset " ++ show offset ++ ":\n "
+ ++ unlines (map show (Set.toList fancy))
showError (TrivialError offset Nothing expected) =
- "Parse error at offset " ++ show offset ++ ": expected one of "
- ++ show (Set.toList expected)
+ "Parse error at offset " ++ show offset
+ ++ ": expected one of " ++ show (Set.toList expected)
+
diff --git a/test/Spec.hs b/test/Spec.hs
@@ -71,9 +71,9 @@ lexerTests = testGroup "Lexer Tests"
parserTests :: TestTree
parserTests = testGroup "Parser Tests"
[ testCase "Error when assigning a value to T" $ do
- let input = lexTricu "t = x"
- case (runParser parseExpression "" input) of
- Left _ -> return ()
+ let tokens = lexTricu "t = x"
+ case parseSingleExpr tokens of
+ Left _ -> return ()
Right _ -> assertFailure "Expected failure when trying to assign the value of T"
, testCase "Parse function definitions" $ do
let input = "x = (\\a b c : a)"
@@ -149,10 +149,6 @@ parserTests = testGroup "Parser Tests"
let input = "(t) -- (t) -- (t)"
expect = [TLeaf]
parseTricu input @?= expect
- , testCase "Comments with no terms" $ do
- let input = unlines ["-- (t)", "(t t)"]
- expect = [SEmpty,SApp TLeaf TLeaf]
- parseTricu input @?= expect
]
evaluationTests :: TestTree
diff --git a/tricu.cabal b/tricu.cabal
@@ -1,7 +1,7 @@
cabal-version: 1.12
name: tricu
-version: 0.5.0
+version: 0.6.0
description: A micro-language for exploring Tree Calculus
author: James Eversole
maintainer: james@eversole.co