Advertisement
Guest User

Untitled

a guest
Aug 9th, 2018
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- http://gilmi.xyz/blog/post/2016/10/14/lisp-to-js
  2.  
  3. module Parser where
  4.  
  5. import Prelude
  6.  
  7. import Control.Lazy (class Lazy)
  8. import Control.Monad.State (class MonadState, StateT, get, lift, put, runStateT)
  9. import Control.MonadZero (class Alt, class Alternative, class MonadZero, class Plus, guard)
  10. import Data.Array (many)
  11. import Data.Char.Unicode (isSpace)
  12. import Data.Maybe (Maybe(..))
  13. import Data.Newtype (class Newtype, unwrap)
  14. import Data.String.CodeUnits as S
  15. import Data.Traversable (elem, sequence, traverse)
  16. import Data.Tuple (Tuple)
  17. import Data.Unfoldable (replicate)
  18. import Effect (Effect)
  19. import Effect.Class.Console (logShow)
  20.  
  21. newtype Parser a = Parser (StateT String Maybe a)
  22.  
  23. derive instance newtypeParser :: Newtype (Parser a) _
  24.  
  25. derive newtype instance lazyParser :: Lazy (Parser a)
  26.  
  27. derive newtype instance functorParser :: Functor Parser
  28. derive newtype instance applyParser :: Apply Parser
  29. derive newtype instance applicativeParser :: Applicative Parser
  30. derive newtype instance bindParser :: Bind Parser
  31. derive newtype instance monadParser :: Monad Parser
  32.  
  33. derive newtype instance plusParser :: Plus Parser
  34. derive newtype instance altParser :: Alt Parser
  35. derive newtype instance alternativeParser :: Alternative Parser
  36. derive newtype instance monadZeroParser :: MonadZero Parser
  37.  
  38. derive newtype instance monadStateParser :: MonadState String Parser
  39.  
  40. anyChar :: Parser Char
  41. anyChar = Parser $ do
  42.   xs <- get
  43.   case S.uncons xs of
  44.     Just {head, tail} -> put tail *> pure head
  45.     Nothing -> lift Nothing
  46.  
  47. satisfy :: (Char -> Boolean) -> Parser Char
  48. satisfy pred = do
  49.     c <- anyChar
  50.     guard $ pred c
  51.     pure c
  52.  
  53. char :: Char -> Parser Char
  54. char = satisfy <<< (==)
  55.  
  56. string :: String -> Parser String
  57. string = map S.fromCharArray <$> traverse char <<< S.toCharArray
  58.  
  59. string2 :: String -> Parser String
  60. string2 s = case S.uncons s of
  61.   Just r -> do
  62.     c <- char r.head
  63.     cs <- string2 r.tail
  64.     pure $ S.singleton c <> cs
  65.   Nothing -> pure ""
  66.  
  67. count :: forall a. Int -> Parser a -> Parser (Array a)
  68. count n p = sequence (replicate n p)
  69.  
  70. oneOf :: Array Char -> Parser Char
  71. oneOf ss = satisfy (flip elem ss)
  72.  
  73. space :: Parser Char
  74. space = satisfy isSpace
  75.  
  76. spaces :: Parser String
  77. spaces = map S.fromCharArray $ many space
  78.  
  79. brackets :: forall a b. Parser a -> Parser a -> Parser b -> Parser b
  80. brackets o c p = o *> p <* c
  81.  
  82. withSpaces :: forall a. Parser a -> Parser a
  83. withSpaces = brackets spaces spaces
  84.  
  85. parens :: forall a. Parser a -> Parser a
  86. parens = brackets (withSpaces $ char '(') (withSpaces $ char ')')
  87.  
  88. runParser :: forall a. Parser a -> String -> Maybe (Tuple a String)
  89. runParser = runStateT <<< unwrap
  90.  
  91.  
  92. -- Show
  93. -- Eq
  94. -- Ord
  95. data Expr
  96.   = Var Int
  97.   | Add Expr Expr
  98.   | Mul Expr Expr
  99.  
  100. interpreter :: Expr -> Int
  101. interpreter = case _ of
  102.   Var a -> a
  103.   Add a b -> interpreter a + interpreter b
  104.   Mul a b -> interpreter a * interpreter b
  105.  
  106. main :: Effect Unit
  107. main = do
  108.   logShow $
  109.     runParser (true <$ (parens $ string "test")) """(              test)             """
  110.   logShow $ runParser (count 4 $ char 'a') "aaaaa"
  111.   logShow $ interpreter $ Add (Mul (Var 10) (Var 40)) (Var 20)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement