Advertisement
Guest User

Untitled

a guest
Apr 1st, 2021
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Electro where
  3. import Data.Text
  4. import Data.Void
  5. import Text.Megaparsec
  6. import Text.Megaparsec.Char
  7. import qualified Text.Megaparsec.Char.Lexer as L
  8. import Data.Foldable
  9. import Data.Functor.Identity
  10. import Data.Functor
  11.  
  12. type Parser = Parsec Void Text
  13.  
  14. lineComment :: Parser ()
  15. lineComment = L.skipLineComment "//"
  16.  
  17. blockComment :: Parser ()
  18. blockComment = L.skipBlockComment "/*" "*/" <|> L.skipBlockCommentNested "" ""
  19.  
  20. sc :: Parser ()
  21. sc = L.space (void $ takeWhile1P Nothing f) lineComment blockComment
  22.   where
  23.    f x = x == ' ' || x == '\t'
  24.  
  25. lexeme :: Parser a -> Parser a
  26. lexeme = L.lexeme sc
  27.  
  28. symbol :: Text -> Parser Text
  29. symbol = L.symbol sc
  30.  
  31. charLiteral :: Parser Char
  32. charLiteral = between (char '\'') (char '\'') L.charLiteral
  33.  
  34. stringLiteral :: Parser String
  35. stringLiteral = char '\"' *> manyTill L.charLiteral (char '\"')
  36.  
  37. integer :: Parser Integer
  38. integer = lexeme L.decimal
  39.  
  40. float :: Parser Double
  41. float = lexeme L.float
  42.  
  43. signedInteger :: Parser Integer
  44. signedInteger = L.signed sc integer
  45.  
  46. signedFloat :: Parser Double
  47. signedFloat = L.signed sc float
  48.  
  49. rword :: Text -> Parser ()
  50. rword w = lexeme (string w *> notFollowedBy alphaNumChar)
  51.  
  52. rws :: [String] -- list of reserved words
  53. rws = ["module", "import",  "let", "if","then","else","while","do","skip","true","false","not","and","or"]
  54.  
  55. semi :: Parser Text
  56. semi = symbol ";"
  57.  
  58. word :: Parser Text
  59. word = (lexeme . try) (p >>= check <&> pack)
  60.   where
  61.     p       = (:) <$> alphaNumChar <*> many alphaNumChar
  62.     check x = if x `elem` rws
  63.                 then fail $ "keyword " ++ show x ++ " cannot be an word"
  64.                 else return x
  65.  
  66. parens :: Parser a -> Parser a
  67. parens = between (symbol "(") (symbol ")")
  68.  
  69. indentBlock :: Parser (L.IndentOpt Parser a b) -> Parser a
  70. indentBlock = L.indentBlock sc
  71.  
  72. function :: Parser Expr
  73. function = indentBlock $ do
  74.   rword "let"
  75.   name <- word
  76.   args <- many word
  77.   char '='
  78.   return (L.IndentMany Nothing (return . Function name args ) (try expr'))
  79.  
  80. expr' :: Parser Expr
  81. expr' = try function <|> fail "Так получилось"
  82.  
  83. data Expr = Module Text [Expr]
  84.          | Function Text [Text] [Expr] deriving Show
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement