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.

90 lines
2.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
  1. open import "prelude.ml"
  2. module S = import "data/set.ml"
  3. module M = import "data/map.ml"
  4. type expr =
  5. | Ref of string
  6. | App of expr * expr
  7. | Lam of string * expr
  8. | Case of expr * list (string * expr)
  9. | Lit of int
  10. let app = curry App
  11. let lam = curry Lam
  12. let rec free_vars = function
  13. | Ref v -> S.singleton v
  14. | App (f, x) -> S.union (free_vars f) (free_vars x)
  15. | Lam (v, x) -> v `S.delete` free_vars x
  16. | Case (e, bs) ->
  17. bs
  18. |> map (fun (_, e) -> free_vars e)
  19. |> foldl S.union S.empty
  20. |> S.union (free_vars e)
  21. | Lit _ -> S.empty
  22. let rec subst m = function
  23. | Ref v ->
  24. match M.lookup v m with
  25. | Some s -> s
  26. | None -> Ref v
  27. | App (f, x) -> App (subst m f, subst m x)
  28. | Lam (v, x) -> Lam (v, subst (M.delete v m) x)
  29. | Case (e, xs) -> Case (subst m e, map (second (subst m)) xs)
  30. | Lit x -> Lit x
  31. type hstype =
  32. | Tycon of string
  33. | Tyvar of string
  34. | Tyapp of hstype * hstype
  35. | Tyarr of hstype * hstype
  36. | Tytup of list hstype
  37. let rec arity = function
  38. | Tyarr (_, i) -> 1 + arity i
  39. | _ -> 0
  40. type constr = Constr of string * list hstype
  41. type call_conv = Lua | Prim
  42. type fdecl =
  43. Fimport of {
  44. cc : call_conv,
  45. fent : string,
  46. ftype : hstype,
  47. var : string
  48. }
  49. type decl =
  50. | Decl of string * list string * expr
  51. | Data of string * list string * list constr
  52. | Foreign of fdecl
  53. type prog <- list decl
  54. let rec xs !! i =
  55. match xs, i with
  56. | Cons (x, _), 0 -> x
  57. | Cons (_, xs), i when i > 0 -> xs !! (i - 1)
  58. | _, _ -> error "empty list and/or negative index"
  59. let ds_data (_, _, cs) =
  60. let ncons = length cs
  61. let alts = map (("c" ^) # show) [1..ncons]
  62. let ds_con i (Constr (n, args)) =
  63. let arity = length args
  64. let alt = alts !! i
  65. let args = map (("x" ^) # show) [1..arity]
  66. Decl (n, args, foldr lam (foldl app (Ref alt) (map Ref args)) alts)
  67. let rec go i = function
  68. | [] -> []
  69. | Cons (x, xs) -> ds_con i x :: go (i + 1) xs
  70. go 0 cs
  71. let ds_prog prog =
  72. let! c = prog
  73. match c with
  74. | Data c -> ds_data c
  75. | Decl (n, args, e) -> [Decl (n, args, e)]
  76. | Foreign d -> [Foreign d]