You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.1 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. include import "./lang.ml"
  2. include import "./lexer.ml"
  3. open import "prelude.ml"
  4. let parse = lex
  5. let laid_out_block p = between obrace cbrace (sep_end_by_1 semi p)
  6. let rec atom : forall 'm. monad 'm => parser_t 'm expr =
  7. map Ref (try varid)
  8. <|> map Ref (try conid)
  9. <|> map Lit (try integer)
  10. <+> between (try oparen) cparen expr
  11. and fexp : forall 'm. monad 'm => parser_t 'm expr =
  12. let! a = atom
  13. let! ats = many atom
  14. pure (foldl (curry App) a ats)
  15. and expr : forall 'm. monad 'm => parser_t 'm expr =
  16. let lam =
  17. let! _ = back
  18. let! vs = many (try varid)
  19. let! _ = arrow
  20. let! b = expr
  21. pure (foldr ((Lam #) # curry id) b vs)
  22. let case =
  23. let! _ = keyword "case"
  24. let! e = fexp
  25. let! _ = keyword "of"
  26. let! arms =
  27. laid_out_block (
  28. let! c = conid
  29. let! vs = many (try varid)
  30. let! _ = arrow
  31. let! e = expr
  32. pure (c, vs, e)
  33. )
  34. pure (Case (e, arms))
  35. let hslet =
  36. let binding =
  37. let! c = varid
  38. let! vs = many (try varid)
  39. let! _ = equals
  40. let! e = expr
  41. pure (c, foldr ((Lam #) # curry id) e vs)
  42. let! _ = keyword "let"
  43. let! bs = laid_out_block binding
  44. let! _ = keyword "in"
  45. let! b = expr
  46. pure (Let (bs, b))
  47. let hsif =
  48. let! _ = keyword "if"
  49. let! c = fexp <* keyword "then"
  50. let! t = expr <* keyword "else"
  51. let! e = expr
  52. pure (If (c, t, e))
  53. try lam <|> try case <|> try hslet <|> try hsif <+> fexp
  54. let rec ty_atom : forall 'm. monad 'm => parser_t 'm hstype =
  55. map Tyvar (try varid)
  56. <|> map Tycon (try conid)
  57. <+> between (try oparen) cparen ty_tup
  58. and ty_fexp : forall 'm. monad 'm => parser_t 'm hstype =
  59. let! a = ty_atom
  60. let! ats = many ty_atom
  61. pure (foldl (curry Tyapp) a ats)
  62. and ty_exp : forall 'm. monad 'm => parser_t 'm hstype =
  63. chainr1 ty_fexp (map (const (curry Tyarr)) arrow)
  64. and ty_tup : forall 'm. monad 'm => parser_t 'm hstype =
  65. let tytup = function
  66. | [x] -> x
  67. | x -> Tytup x
  68. tytup <$> sep_by comma ty_exp
  69. let datadec : forall 'm. monad 'm => parser_t 'm decl =
  70. let! _ = try (keyword "data")
  71. let datacon =
  72. let! nm = conid
  73. let! args = many ty_atom
  74. pure (Constr (nm, args))
  75. let! nm = conid
  76. let! args = many (try varid)
  77. let! cs = optionally (
  78. let! _ = equals
  79. sep_by_1 pipe (try datacon)
  80. )
  81. pure (Data (nm, args, match cs with | Some cs -> cs | None -> []))
  82. let fdecl : forall 'm. monad 'm => parser_t 'm fdecl =
  83. let! _ = try (keyword "import")
  84. let! cc =
  85. ( (Lua <$ try (keyword "lua"))
  86. <|> (Prim <$ try (keyword "prim"))
  87. )
  88. let! fent = string
  89. let! var = varid
  90. let! _ = dcolon
  91. let! ftype = ty_exp
  92. pure (Fimport { cc, fent, var, ftype })
  93. let func : forall 'm. monad 'm => parser_t 'm decl =
  94. let! nm = varid
  95. let! args = many (try varid)
  96. let! _ = equals
  97. map (fun e -> Decl (nm, args, e)) expr
  98. let dec : forall 'm. monad 'm => parser_t 'm decl =
  99. let foreign =
  100. let! _ = try (keyword "foreign")
  101. map Foreign fdecl
  102. try datadec <|> try foreign <|> func
  103. let prog : forall 'm. monad 'm => parser_t 'm prog =
  104. sep_end_by_1 semi dec <* eof