Advertisement
Guest User

Untitled

a guest
Jan 30th, 2015
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.49 KB | None | 0 0
  1. import Data.ByteString.Char8 (unpack,pack)
  2. import qualified Data.ByteString.Char8 as BS
  3. import Control.Applicative
  4. import Text.Trifecta
  5. import Text.Trifecta.Indentation as I
  6. import Text.Trifecta.Delta
  7. import Text.Parser.Token.Style
  8. import qualified Data.HashSet as HashSet
  9.  
  10. type EName = String
  11.  
  12. data Lit
  13. = LInt
  14. | LChar
  15. | LFloat
  16. deriving (Show,Eq,Ord)
  17.  
  18. data PrimFun
  19. = PAddI
  20. | PUpper
  21. | PMulF
  22. | PShow
  23. | PRead
  24. deriving (Show,Eq,Ord)
  25.  
  26. type Range = (Delta,Delta)
  27. data Exp
  28. = ELit Range Lit
  29. | EPrimFun Range PrimFun
  30. | EVar Range EName
  31. | EApp Range Exp Exp
  32. | ELam Range EName Exp
  33. | ELet Range EName Exp Exp
  34. -- | EFix EName Exp
  35. deriving (Show,Eq,Ord)
  36.  
  37.  
  38. type P a = IndentationParserT Char Parser a
  39.  
  40. lcIdents = emptyIdents { _styleReserved = HashSet.fromList reservedIdents }
  41. where
  42. reservedIdents =
  43. [ "let"
  44. , "upper"
  45. , "in"
  46. , "add"
  47. , "show"
  48. , "read"
  49. ]
  50.  
  51. kw w = reserve lcIdents w
  52.  
  53. op w = reserve haskellOps w
  54.  
  55. var :: P String
  56. var = ident lcIdents
  57.  
  58. lit :: P Lit
  59. lit = LFloat <$ try double <|> LInt <$ integer <|> LChar <$ charLiteral
  60.  
  61. letin :: P Exp
  62. letin = do
  63. localIndentation Ge $ do
  64. l <- kw "let" *> (localIndentation Gt $ some $ localAbsoluteIndentation $ def) -- WORKS
  65. a <- kw "in" *> (localIndentation Gt expr)
  66. return $ foldr ($) a l
  67.  
  68. def :: P (Exp -> Exp)
  69. def = (\p1 n d p2 e -> ELet (p1,p2) n d e) <$> position <*> var <* kw "=" <*> expr <*> position
  70.  
  71. expr :: P Exp
  72. expr = letin <|> lam <|> formula
  73.  
  74. formula = (\p1 l p2 -> foldl1 (EApp (p1,p2)) l) <$> position <*> some atom <*> position
  75.  
  76. atom =
  77. (\p1 f p2 -> EPrimFun (p1,p2) f) <$> position <*> primFun <*> position <|>
  78. (\p1 l p2 -> ELit (p1,p2) l) <$> position <*> lit <*> position <|>
  79. (\p1 v p2 -> EVar (p1,p2) v) <$> position <*> var <*> position <|>
  80. parens expr
  81.  
  82. primFun = PUpper <$ kw "upper" <|>
  83. PAddI <$ kw "add" <|>
  84. PShow <$ kw "show" <|>
  85. PRead <$ kw "read"
  86.  
  87. lam :: P Exp
  88. lam = (\p1 n e p2 -> ELam (p1,p2) n e) <$> position <* op "\\" <*> var <* op "->" <*> expr <*> position
  89.  
  90. indentState = mkIndentationState 1 infIndentation True Gt
  91.  
  92. src = pack $ unlines
  93. [ ""
  94. , ""
  95. , "let id = \\x -> x"
  96. , " c = ' '"
  97. , " i = 1"
  98. , " a = id c"
  99. , " b = id i"
  100. , " inc = \\x -> add 1 x"
  101. , "in id inc"
  102. , ""
  103. , ""
  104. ]
  105.  
  106. test :: IO ()
  107. test = do
  108. case parseByteString (evalIndentationParserT (kw "" *> expr <* eof) indentState) (Directed BS.empty 0 0 0 0) src of
  109. Failure m -> print m
  110. Success e -> return ()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement