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.

69 lines
1.8 KiB

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. <+> between (try oparen) cparen expr
  10. and fexp : forall 'm. monad 'm => parser_t 'm expr =
  11. let! a = atom
  12. let! ats = many atom
  13. pure (foldl (curry App) a ats)
  14. and expr : forall 'm. monad 'm => parser_t 'm expr =
  15. let lam =
  16. let! _ = back
  17. let! vs = many (try varid)
  18. let! _ = arrow
  19. let! b = expr
  20. pure (foldr ((Lam #) # curry id) b vs)
  21. let case =
  22. let! _ = keyword "case"
  23. let! e = fexp
  24. let! _ = keyword "of"
  25. let! arms =
  26. laid_out_block (
  27. let! c = conid
  28. let! vs = many (try varid)
  29. let! _ = arrow
  30. let! e = expr
  31. pure (c, foldr ((Lam #) # curry id) e vs)
  32. )
  33. pure (Case (e, arms))
  34. try lam <|> try case <+> fexp
  35. let rec ty_atom : forall 'm. monad 'm => parser_t 'm hstype =
  36. map Tyvar (try varid)
  37. <|> map Tycon (try conid)
  38. <+> between (try oparen) cparen ty_exp
  39. and ty_exp : forall 'm. monad 'm => parser_t 'm hstype =
  40. let! a = ty_atom
  41. let! ats = many ty_atom
  42. pure (foldl (curry Tyapp) a ats)
  43. let datadec : forall 'm. monad 'm => parser_t 'm decl =
  44. let! _ = keyword "data"
  45. let datacon =
  46. let! nm = conid
  47. let! args = many ty_atom
  48. pure (Constr (nm, args))
  49. let! nm = conid
  50. let! args = many (try varid)
  51. let! _ = equals
  52. let! c = sep_by_1 pipe (try datacon)
  53. pure (Data (nm, args, c))
  54. let dec : forall 'm. monad 'm => parser_t 'm decl =
  55. let func =
  56. let! nm = varid
  57. let! args = many (try varid)
  58. let! _ = equals
  59. map (fun e -> Decl (nm, args, e)) expr
  60. try datadec <|> func
  61. let prog : forall 'm. monad 'm => parser_t 'm prog =
  62. sep_end_by_1 semi dec <* eof