module Micro.Lexer where import Data.Char (digitToInt) import Text.Parsec import Text.Parsec.Language (emptyDef) import Text.Parsec.String (Parser) import qualified Text.Parsec.Token as T scanner :: T.TokenParser () scanner = T.makeTokenParser style where ops = ["+", "*", "-", ";", "="] names = ["module", "private", "var", "def", "return", "->", "true", "false"] style = emptyDef { T.commentLine = "#", T.reservedOpNames = ops, T.reservedNames = names } binNum :: Parser Integer binNum = do _ <- char '0' _ <- oneOf "bB" digits <- many1 $ oneOf "01" let n = foldl (\x d -> 2 * x + toInteger (digitToInt d)) 0 digits seq n $ return n integer :: Parser Integer integer = try binNum <|> T.integer scanner parens :: Parser a -> Parser a parens = T.parens scanner braces :: Parser a -> Parser a braces = T.braces scanner commaSep :: Parser a -> Parser [a] commaSep = T.commaSep scanner colonSep :: Parser String colonSep = T.colon scanner identifier :: Parser String identifier = T.identifier scanner reserved :: String -> Parser () reserved = T.reserved scanner reservedOp :: String -> Parser () reservedOp = T.reservedOp scanner scan :: Parser a -> Parser a scan p = do T.whiteSpace scanner r <- p eof return r