0.1.0 base collection of features
Implemented evaluation of tree calculus terms alongside referentially transparent variable identifiers. Implemented evaluation of defined functions into tree calculus.
This commit is contained in:
@ -20,11 +20,9 @@ data SaplingAST
|
||||
deriving (Show, Eq, Ord)
|
||||
|
||||
parseSapling :: String -> SaplingAST
|
||||
parseSapling input = case runParser saplingLexer "" input of
|
||||
Left err -> error "RIP"
|
||||
Right tokens -> case runParser parseExpression "" tokens of
|
||||
Left err -> error "RIP"
|
||||
Right ast -> ast
|
||||
parseSapling input = case runParser parseExpression "" (lexSapling input) of
|
||||
Left err -> error "Failed to parse input"
|
||||
Right ast -> ast
|
||||
|
||||
scnParser :: Parser ()
|
||||
scnParser = skipMany (satisfy isNewline)
|
||||
@ -48,9 +46,26 @@ parseFunction = do
|
||||
|
||||
parseApplication :: Parser SaplingAST
|
||||
parseApplication = do
|
||||
func <- parseAtomic
|
||||
func <- parseAtomicBase
|
||||
args <- many parseAtomic
|
||||
return (SApp func args)
|
||||
case func of
|
||||
TLeaf | not (null args) && all isTreeTerm args -> fail "Not an application, defer to Tree Calculus"
|
||||
_ -> return (SApp func args)
|
||||
|
||||
isTreeTerm :: SaplingAST -> Bool
|
||||
isTreeTerm TLeaf = True
|
||||
isTreeTerm (TStem _) = True
|
||||
isTreeTerm (TFork _ _) = True
|
||||
isTreeTerm _ = False
|
||||
|
||||
parseAtomicBase :: Parser SaplingAST
|
||||
parseAtomicBase = choice
|
||||
[ parseVar
|
||||
, parseTreeLeaf
|
||||
]
|
||||
|
||||
parseTreeLeaf :: Parser SaplingAST
|
||||
parseTreeLeaf = satisfy isKeywordT *> pure TLeaf
|
||||
|
||||
getIdentifier :: LToken -> String
|
||||
getIdentifier (LIdentifier name) = name
|
||||
@ -81,6 +96,7 @@ foldTree (x:y:rest) = TFork x (foldTree (y:rest))
|
||||
parseAtomic :: Parser SaplingAST
|
||||
parseAtomic = choice
|
||||
[ parseVar
|
||||
, parseTreeLeafOrParenthesized
|
||||
, parseLiteral
|
||||
, parseListLiteral
|
||||
, between (satisfy (== LOpenParen)) (satisfy (== LCloseParen)) parseExpression
|
||||
@ -92,13 +108,43 @@ parseLiteral = choice
|
||||
, parseStrLiteral
|
||||
]
|
||||
|
||||
parens :: Parser SaplingAST -> Parser SaplingAST
|
||||
parens p = do
|
||||
satisfy (== LOpenParen)
|
||||
result <- p
|
||||
satisfy (== LCloseParen)
|
||||
return result
|
||||
|
||||
parseListLiteral :: Parser SaplingAST
|
||||
parseListLiteral = do
|
||||
satisfy (== LOpenBracket)
|
||||
elements <- sepEndBy parseExpression scnParser
|
||||
satisfy (== LOpenBracket)
|
||||
elements <- many parseListItem
|
||||
satisfy (== LCloseBracket)
|
||||
return (SList elements)
|
||||
|
||||
parseListItem :: Parser SaplingAST
|
||||
parseListItem = parseGroupedItem <|> parseSingleItem
|
||||
|
||||
parseGroupedItem :: Parser SaplingAST
|
||||
parseGroupedItem = do
|
||||
satisfy (== LOpenParen)
|
||||
inner <- parseExpression
|
||||
satisfy (== LCloseParen)
|
||||
return inner
|
||||
|
||||
parseSingleItem :: Parser SaplingAST
|
||||
parseSingleItem = do
|
||||
token <- satisfy isListItem
|
||||
case token of
|
||||
LIdentifier name -> return (SVar name)
|
||||
LKeywordT -> return TLeaf
|
||||
_ -> fail "Unexpected token in list item"
|
||||
|
||||
isListItem :: LToken -> Bool
|
||||
isListItem (LIdentifier _) = True
|
||||
isListItem LKeywordT = True
|
||||
isListItem _ = False
|
||||
|
||||
parseVar :: Parser SaplingAST
|
||||
parseVar = do
|
||||
LIdentifier name <- satisfy isIdentifier
|
||||
@ -114,6 +160,12 @@ parseStrLiteral = do
|
||||
LStringLiteral value <- satisfy isStringLiteral
|
||||
return (SStr value)
|
||||
|
||||
parseMulti :: String -> [SaplingAST]
|
||||
parseMulti input =
|
||||
let nonEmptyLines = filter (not . null) (lines input)
|
||||
in map parseSapling nonEmptyLines
|
||||
|
||||
-- Boolean Helpers
|
||||
isKeywordT (LKeywordT) = True
|
||||
isKeywordT _ = False
|
||||
|
||||
@ -128,4 +180,3 @@ isStringLiteral _ = False
|
||||
|
||||
isNewline (LNewline) = True
|
||||
isNewline _ = False
|
||||
|
||||
|
Reference in New Issue
Block a user