cherry-lisp/src/Parser.hs

126 lines
3.1 KiB
Haskell
Raw Normal View History

2021-01-29 23:11:03 +00:00
module Parser where
2021-01-28 01:16:30 +00:00
2021-01-30 21:38:44 +00:00
import Text.Parsec hiding (tokens)
2021-01-28 01:16:30 +00:00
import Text.Parsec.String
2021-01-30 21:38:44 +00:00
import Lexer (tokens)
import Token
import Expression
2021-01-28 01:16:30 +00:00
parseExpression :: String -> Either ParseError Expr
parseExpression s = do
2021-01-30 21:38:44 +00:00
tokns <- parse tokens "lexical error" s
expr <- parse anyExpressionEOF "parsing error" tokns
2021-01-29 00:16:15 +00:00
return expr
2021-01-30 21:38:44 +00:00
anyExpressionEOF :: GenParser Token st Expr
anyExpressionEOF = do
expr <- anyExpression
2021-01-29 00:16:15 +00:00
_ <- eof
2021-01-28 01:16:30 +00:00
return expr
2021-01-30 21:38:44 +00:00
anyExpression :: GenParser Token st Expr
anyExpression = do
2021-01-30 19:47:05 +00:00
expr <- intE <|> quotedE <|> try setE <|> try nilE <|> try consE <|> try lambdaE <|> varE <|> listE
2021-01-28 23:47:53 +00:00
return expr
2021-01-28 01:16:30 +00:00
2021-01-30 21:38:44 +00:00
------------------------------------------------------------
listE :: GenParser Token st Expr
listE = do
_ <- parseLeftParenT
2021-01-30 21:38:44 +00:00
exprs <- many anyExpression
_ <- parseRightParenT
return $ toCons exprs
where toCons [] = NilE
toCons (x:xs) = ConsE x (toCons xs)
2021-01-28 01:16:30 +00:00
intE :: GenParser Token st Expr
intE = do
(IntT num) <- parseIntT
return $ IntE num
2021-01-30 14:28:30 +00:00
quotedE :: GenParser Token st Expr
quotedE = do
_ <- parseApostropheT
2021-01-30 21:38:44 +00:00
expr <- anyExpression
2021-01-30 14:28:30 +00:00
return $ QuotedE expr
2021-01-30 13:55:22 +00:00
consE :: GenParser Token st Expr
consE = do
_ <- parseLeftParenT
_ <- parseConsT
2021-01-30 21:38:44 +00:00
expr1 <- anyExpression
expr2 <- anyExpression
2021-01-30 13:55:22 +00:00
_ <- parseRightParenT
return $ ConsE expr1 expr2
2021-01-28 01:16:30 +00:00
varE :: GenParser Token st Expr
varE = do
(SymbolT var) <- parseSymbolT
2021-01-28 01:16:30 +00:00
return $ VarE var
nilE :: GenParser Token st Expr
nilE = do
_ <- parseNilT
return NilE
setE :: GenParser Token st Expr
setE = do
2021-01-28 01:16:30 +00:00
_ <- parseLeftParenT
_ <- parseSetT
(SymbolT var) <- parseSymbolT
2021-01-30 21:38:44 +00:00
expr <- anyExpression
2021-01-28 01:16:30 +00:00
_ <- parseRightParenT
return $ SetE var expr
2021-01-28 01:16:30 +00:00
2021-01-30 19:47:05 +00:00
lambdaE :: GenParser Token st Expr
lambdaE = do
_ <- parseBackslashT
(SymbolT arg) <- parseSymbolT
2021-01-30 21:38:44 +00:00
body <- anyExpression
2021-01-30 19:47:05 +00:00
return $ LambdaE arg body
2021-01-28 01:16:30 +00:00
------------------------------------------------------------
satisfyT :: (Stream s m a, Show a) => (a -> Bool) -> ParsecT s u m a
satisfyT f = tokenPrim show
(\pos _ _ -> incSourceColumn pos 1)
(\t -> if f t then Just t else Nothing)
2021-01-30 19:47:05 +00:00
parseBackslashT :: GenParser Token st Token
parseBackslashT = satisfyT (== BackslashT)
2021-01-28 01:16:30 +00:00
parseLeftParenT :: GenParser Token st Token
parseLeftParenT = satisfyT (== LeftParenT)
parseRightParenT :: GenParser Token st Token
parseRightParenT = satisfyT (== RightParenT)
2021-01-30 14:28:30 +00:00
parseApostropheT :: GenParser Token st Token
parseApostropheT = satisfyT (== ApostropheT)
parseSetT :: GenParser Token st Token
parseSetT = satisfyT isSetT
where isSetT (SymbolT "set!") = True
isSetT _ = False
2021-01-28 01:16:30 +00:00
parseNilT :: GenParser Token st Token
parseNilT = satisfyT isNilT
where isNilT (SymbolT "nil") = True
isNilT _ = False
2021-01-30 13:55:22 +00:00
parseConsT :: GenParser Token st Token
parseConsT = satisfyT isConsT
where isConsT (SymbolT "cons") = True
isConsT _ = False
parseSymbolT :: GenParser Token st Token
parseSymbolT = satisfyT isSymbolT
where isSymbolT (SymbolT _) = True
isSymbolT _ = False
2021-01-28 01:16:30 +00:00
parseIntT :: GenParser Token st Token
parseIntT = satisfyT isIntT
where isIntT (IntT _) = True
isIntT _ = False