41 lines
1.0 KiB
Haskell
41 lines
1.0 KiB
Haskell
module Parser where
|
|
|
|
import Text.ParserCombinators.Parsec
|
|
import Data.Char
|
|
|
|
import Expression
|
|
|
|
-- Receives a string, parses it, and returns an expression
|
|
parseExpression :: String -> Either ParseError Expression
|
|
parseExpression s = do
|
|
e <- parse anyExpressionParser "" s
|
|
return e
|
|
|
|
-- Parser any possible expression
|
|
anyExpressionParser :: GenParser Char st Expression
|
|
anyExpressionParser = numberParser <|> symbolParser <|> sexprParser
|
|
|
|
-- Parses an S-expr
|
|
sexprParser :: GenParser Char st Expression
|
|
sexprParser = do
|
|
_ <- spaces
|
|
_ <- char '('
|
|
es <- many1 (try $ spaces >> anyExpressionParser)
|
|
_ <- spaces
|
|
_ <- char ')' >> spaces
|
|
return $ SExpr es
|
|
|
|
-- Parses a symbol
|
|
symbolParser :: GenParser Char st Expression
|
|
symbolParser = Symbol <$> do
|
|
c <- symbolChar
|
|
cs <- many (symbolChar <|> digit)
|
|
return $ c:cs
|
|
where symbolChar = letter <|> oneOf "!#$%&*+-/:<=>?@\\^_`~"
|
|
|
|
-- Parses a number
|
|
numberParser :: GenParser Char st Expression
|
|
numberParser = do
|
|
num <- read <$> many1 digit
|
|
return $ Number num
|