diff options
Diffstat (limited to 'Biz/Language/Bs/Parser.hs')
-rw-r--r-- | Biz/Language/Bs/Parser.hs | 84 |
1 files changed, 46 insertions, 38 deletions
diff --git a/Biz/Language/Bs/Parser.hs b/Biz/Language/Bs/Parser.hs index 3044a60..574536d 100644 --- a/Biz/Language/Bs/Parser.hs +++ b/Biz/Language/Bs/Parser.hs @@ -1,10 +1,12 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude #-} -module Language.Bs.Parser ( - readExpr -, readExprFile -) where + +module Language.Bs.Parser + ( readExpr, + readExprFile, + ) +where import Control.Monad (fail) import Control.Monad (mzero) @@ -23,15 +25,16 @@ lexer :: Tok.GenTokenParser T.Text () Identity lexer = Tok.makeTokenParser style style :: Tok.GenLanguageDef T.Text () Identity -style = Lang.emptyDef { - Tok.commentStart = "#|" - , Tok.commentEnd = "|#" - , Tok.commentLine = ";" - , Tok.opStart = mzero - , Tok.opLetter = mzero - , Tok.identStart = letter <|> oneOf "!$%&*/:<=>?^_~" - , Tok.identLetter = digit <|> letter <|> oneOf "!$%&*/:<=>?^_~+-.@" - } +style = + Lang.emptyDef + { Tok.commentStart = "#|", + Tok.commentEnd = "|#", + Tok.commentLine = ";", + Tok.opStart = mzero, + Tok.opLetter = mzero, + Tok.identStart = letter <|> oneOf "!$%&*/:<=>?^_~", + Tok.identLetter = digit <|> letter <|> oneOf "!$%&*/:<=>?^_~+-.@" + } parens :: Parser a -> Parser a parens = Tok.parens lexer @@ -48,9 +51,10 @@ quoted p = try (char '\'') *> p identifier :: Parser T.Text identifier = T.pack <$> (Tok.identifier lexer <|> specialIdentifier) <?> "identifier" where - specialIdentifier :: Parser String - specialIdentifier = lexeme $ try $ - string "-" <|> string "+" <|> string "..." + specialIdentifier :: Parser String + specialIdentifier = + lexeme $ try $ + string "-" <|> string "+" <|> string "..." -- | The @Radix@ type consists of a base integer (e.g. @10@) and a parser for -- digits in that base (e.g. @digit@). @@ -61,7 +65,7 @@ type Radix = (Integer, Parser Char) numberWithRadix :: Radix -> Parser Integer numberWithRadix (base, baseDigit) = do digits <- many1 baseDigit - let n = foldl (\x d -> base*x + toInteger (digitToInt d)) 0 digits + let n = foldl (\x d -> base * x + toInteger (digitToInt d)) 0 digits seq n (return n) decimal :: Parser Integer @@ -70,9 +74,10 @@ decimal = Tok.decimal lexer -- | Parse a sign, return either @id@ or @negate@ based on the sign parsed. -- Copied from Text.Parsec.Token sign :: Parser (Integer -> Integer) -sign = char '-' *> return negate - <|> char '+' *> return identity - <|> return identity +sign = + char '-' *> return negate + <|> char '+' *> return identity + <|> return identity intRadix :: Radix -> Parser Integer intRadix r = sign <*> numberWithRadix r @@ -84,26 +89,29 @@ nil :: Parser () nil = try ((char '\'') *> string "()") *> return () <?> "nil" hashVal :: Parser Expr -hashVal = lexeme $ char '#' - *> (char 't' *> return (Bool True) - <|> char 'f' *> return (Bool False) - <|> char 'b' *> (Numb <$> intRadix (2, oneOf "01")) - <|> char 'o' *> (Numb <$> intRadix (8, octDigit)) - <|> char 'd' *> (Numb <$> intRadix (10, digit)) - <|> char 'x' *> (Numb <$> intRadix (16, hexDigit)) - <|> oneOf "ei" *> fail "Unsupported: exactness" - <|> char '(' *> fail "Unsupported: vector" - <|> char '\\' *> fail "Unsupported: char") - +hashVal = + lexeme $ + char '#' + *> ( char 't' *> return (Bool True) + <|> char 'f' *> return (Bool False) + <|> char 'b' *> (Numb <$> intRadix (2, oneOf "01")) + <|> char 'o' *> (Numb <$> intRadix (8, octDigit)) + <|> char 'd' *> (Numb <$> intRadix (10, digit)) + <|> char 'x' *> (Numb <$> intRadix (16, hexDigit)) + <|> oneOf "ei" *> fail "Unsupported: exactness" + <|> char '(' *> fail "Unsupported: vector" + <|> char '\\' *> fail "Unsupported: char" + ) lispVal :: Parser Expr -lispVal = hashVal - <|> Nil <$ nil - <|> Numb <$> try (sign <*> decimal) - <|> Atom <$> identifier - <|> Tape <$> textLiteral - <|> _Quote <$> quoted lispVal - <|> List <$> parens manyExpr +lispVal = + hashVal + <|> Nil <$ nil + <|> Numb <$> try (sign <*> decimal) + <|> Atom <$> identifier + <|> Tape <$> textLiteral + <|> _Quote <$> quoted lispVal + <|> List <$> parens manyExpr manyExpr :: Parser [Expr] manyExpr = lispVal `sepBy` whitespace |