1{-# LANGUAGE OverloadedStrings #-}
3-- simple parser for a Lisp-like syntax I wrote some time ago
8import qualified Data.Text as T
10import Text.Megaparsec.Char
11import Text.Megaparsec.Error (errorBundlePretty)
12import Text.Megaparsec hiding (State)
13import qualified Text.Megaparsec.Char.Lexer as L
25type Parser = Parsec Void Text
27readStr :: Text -> Either String [LispVal]
29 case parse pLisp "f" t of
30 Right parsed -> Right parsed
31 Left err -> Left $ errorBundlePretty err
32{-# INLINABLE readStr #-}
35sc = L.space space1 (L.skipLineComment ";") empty
38lexeme :: Parser a -> Parser a
42symbol :: Text -> Parser Text
46symbol' :: Text -> Parser Text
51pNil = symbol' "nil" >> return Nil
54integer :: Parser Integer
55integer = lexeme L.decimal
58lispSymbols :: Parser Char
59lispSymbols = oneOf ("#$%&|*+-/:<=>?@^_~" :: String)
60{-# INLINE lispSymbols #-}
62pLispVal :: Parser LispVal
63pLispVal = choice [pList, pNumber, pSymbol, pNil, pString]
64{-# INLINE pLispVal #-}
66pSymbol :: Parser LispVal
67pSymbol = (Symbol . T.pack <$> lexeme (some (letterChar <|> lispSymbols)))
68{-# INLINABLE pSymbol #-}
70pList :: Parser LispVal
71pList = List <$> between (symbol "(") (symbol ")") (many pLispVal)
72{-# INLINABLE pList #-}
74pLisp :: Parser [LispVal]
78pNumber :: Parser LispVal
79pNumber = Number <$> integer
82pString :: Parser LispVal
84 str <- char '\"' *> manyTill L.charLiteral (char '\"')
85 return $ String (T.pack str)
86{-# INLINABLE pString #-}
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list