diff options
author | Marvin Borner | 2022-04-12 00:09:35 +0200 |
---|---|---|
committer | Marvin Borner | 2022-04-12 00:09:35 +0200 |
commit | 32515bf8bf04958f22ce2cfe98edebc7b892774c (patch) | |
tree | 9432af890bb7d863e185fe3e2ae47bfa3e69dc52 /src/Parser.hs |
Initial commit
Diffstat (limited to 'src/Parser.hs')
-rw-r--r-- | src/Parser.hs | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/Parser.hs b/src/Parser.hs new file mode 100644 index 0000000..611261f --- /dev/null +++ b/src/Parser.hs @@ -0,0 +1,66 @@ +module Parser where + +import Data.Functor.Identity +import Text.Parsec +import Text.Parsec.Language +import qualified Text.Parsec.Token as Token + +languageDef :: GenLanguageDef String u Identity +languageDef = emptyDef { Token.commentLine = "#" + , Token.identStart = letter + , Token.identLetter = alphaNum <|> char '_' + , Token.reservedOpNames = ["[", "]"] + } + +type Parser = Parsec String () + +lexer :: Token.GenTokenParser String u Identity +lexer = Token.makeTokenParser languageDef + +identifier :: Parser String +identifier = Token.identifier lexer + +reservedOp :: String -> Parser () +reservedOp = Token.reservedOp lexer + +parens :: Parser a -> Parser a +parens = Token.parens lexer + +data Expression = Index Int | Abstraction Int Expression | Application Expression Expression + deriving (Ord, Eq) +data Instruction = Define String Expression | Evaluate Expression | Comment String + +parseAbstraction :: Parser Expression +parseAbstraction = do + reservedOp "[" + idc <- endBy1 digit spaces + build idc <$> parseExpression + where + build (idx : idc) body = + Abstraction ((read . pure :: Char -> Int) idx) $ build idc body + curry [] body = body + +parseApplication :: Parser Expression +parseApplication = do + s <- sepBy1 parseSingleton spaces + pure $ foldl1 Application s + +parseSingleton :: Parser Expression +parseSingleton = parseAbstraction <|> parens parseApplication + +parseExpression :: Parser Expression +parseExpression = do + expr <- parseApplication <|> parseSingleton + pure expr + +parseDefine :: Parser Instruction +parseDefine = do + var <- identifier + space + Define var <$> parseExpression + +parseLine :: Parser Instruction +parseLine = try parseDefine + +parseReplLine :: Parser Expression +parseReplLine = try parseExpression |