Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- {-# LANGUAGE OverloadedStrings #-}
- module Electro where
- import Data.Text
- import Data.Void
- import Text.Megaparsec
- import Text.Megaparsec.Char
- import qualified Text.Megaparsec.Char.Lexer as L
- import Data.Foldable
- import Data.Functor.Identity
- import Data.Functor
- type Parser = Parsec Void Text
- lineComment :: Parser ()
- lineComment = L.skipLineComment "//"
- blockComment :: Parser ()
- blockComment = L.skipBlockComment "/*" "*/" <|> L.skipBlockCommentNested "" ""
- sc :: Parser ()
- sc = L.space (void $ takeWhile1P Nothing f) lineComment blockComment
- where
- f x = x == ' ' || x == '\t'
- lexeme :: Parser a -> Parser a
- lexeme = L.lexeme sc
- symbol :: Text -> Parser Text
- symbol = L.symbol sc
- charLiteral :: Parser Char
- charLiteral = between (char '\'') (char '\'') L.charLiteral
- stringLiteral :: Parser String
- stringLiteral = char '\"' *> manyTill L.charLiteral (char '\"')
- integer :: Parser Integer
- integer = lexeme L.decimal
- float :: Parser Double
- float = lexeme L.float
- signedInteger :: Parser Integer
- signedInteger = L.signed sc integer
- signedFloat :: Parser Double
- signedFloat = L.signed sc float
- rword :: Text -> Parser ()
- rword w = lexeme (string w *> notFollowedBy alphaNumChar)
- rws :: [String] -- list of reserved words
- rws = ["module", "import", "let", "if","then","else","while","do","skip","true","false","not","and","or"]
- semi :: Parser Text
- semi = symbol ";"
- word :: Parser Text
- word = (lexeme . try) (p >>= check <&> pack)
- where
- p = (:) <$> alphaNumChar <*> many alphaNumChar
- check x = if x `elem` rws
- then fail $ "keyword " ++ show x ++ " cannot be an word"
- else return x
- parens :: Parser a -> Parser a
- parens = between (symbol "(") (symbol ")")
- indentBlock :: Parser (L.IndentOpt Parser a b) -> Parser a
- indentBlock = L.indentBlock sc
- function :: Parser Expr
- function = indentBlock $ do
- rword "let"
- name <- word
- args <- many word
- char '='
- return (L.IndentMany Nothing (return . Function name args ) (try expr'))
- expr' :: Parser Expr
- expr' = try function <|> fail "Так получилось"
- data Expr = Module Text [Expr]
- | Function Text [Text] [Expr] deriving Show
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement