Guest User

Untitled

a guest
Jun 21st, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.62 KB | None | 0 0
  1. {-# LANGUAGE TypeOperators #-}
  2.  
  3. import Web.Zwaluw
  4. import Prelude hiding (id, (.))
  5. import Control.Category
  6. import Data.Char
  7.  
  8.  
  9. data Expr
  10. = Variable String
  11. | Literal Int
  12. | BinOp Expr Op Expr
  13. | IfZero Expr Expr Expr
  14. deriving (Eq, Show)
  15.  
  16. data Op
  17. = AddOp
  18. | MulOp
  19. deriving (Eq, Show)
  20.  
  21. variable :: Router r (Expr :- r)
  22. variable = (constr1 Variable $ \a -> do Variable v <- a; return v) . somer (consP . satisfy (\c -> c >= 'a' && c <= 'z')) . nilP
  23.  
  24. literal :: Router r (Expr :- r)
  25. literal = (constr1 Literal $ \a -> do Literal i <- a; return i) . int
  26.  
  27. binOp :: Router (Expr :- Op :- Expr :- r) (Expr :- r)
  28. binOp = constr3 BinOp $ \a -> do BinOp e1 o e2 <- a; return (e1, o, e2)
  29.  
  30. ifZero :: Router (Expr :- Expr :- Expr :- r) (Expr :- r)
  31. ifZero = constr3 IfZero $ \a -> do IfZero i t e <- a; return (i, t, e)
  32.  
  33. addOp, mulOp :: Router r (Op :- r)
  34. addOp = constr0 AddOp $ \a -> do AddOp <- a; return ()
  35. mulOp = constr0 MulOp $ \a -> do MulOp <- a; return ()
  36.  
  37. skipSpace, optSpace, sepSpace :: Router r r
  38. skipSpace = lit " " <> lit ""
  39. optSpace = lit "" <> lit " "
  40. sepSpace = somer (lit " ")
  41.  
  42. keywords = ["ifzero", "else"]
  43.  
  44. letter = satisfy isLetter
  45. digit = satisfy isDigit
  46.  
  47. identifier = (consP . letter . listP (letter <> digit)) `having` (`notElem` keywords)
  48.  
  49. parens p = lit "(" . p . lit ")"
  50.  
  51. ifz = ifZero . lit "ifzero" . optSpace . parens expr . optSpace . parens expr . optSpace . lit "else" . optSpace . parens expr
  52. atoms = parens (skipSpace . expr . skipSpace) <> literal <> variable <> ifz
  53. op s r = binOp . duck r . optSpace . lit s . optSpace
  54.  
  55. expr :: Router r (Expr :- r)
  56. expr = atoms `chainl1` op "*" mulOp `chainl1` op "+" addOp
Add Comment
Please, Sign In to add comment