|
|
- open import "prelude.ml"
- module S = import "data/set.ml"
- module M = import "data/map.ml"
-
- type expr =
- | Ref of string
- | App of expr * expr
- | Lam of string * expr
- | Case of expr * list (string * expr)
- | Lit of int
-
- let app = curry App
- let lam = curry Lam
-
- let rec free_vars = function
- | Ref v -> S.singleton v
- | App (f, x) -> S.union (free_vars f) (free_vars x)
- | Lam (v, x) -> v `S.delete` free_vars x
- | Case (e, bs) ->
- bs
- |> map (fun (_, e) -> free_vars e)
- |> foldl S.union S.empty
- |> S.union (free_vars e)
- | Lit _ -> S.empty
-
- let rec subst m = function
- | Ref v ->
- match M.lookup v m with
- | Some s -> s
- | None -> Ref v
- | App (f, x) -> App (subst m f, subst m x)
- | Lam (v, x) -> Lam (v, subst (M.delete v m) x)
- | Case (e, xs) -> Case (subst m e, map (second (subst m)) xs)
- | Lit x -> Lit x
-
- type hstype =
- | Tycon of string
- | Tyvar of string
- | Tyapp of hstype * hstype
- | Tyarr of hstype * hstype
- | Tytup of list hstype
-
- let rec arity = function
- | Tyarr (_, i) -> 1 + arity i
- | _ -> 0
-
- type constr = Constr of string * list hstype
-
- type call_conv = Lua | Prim
-
- type fdecl =
- Fimport of {
- cc : call_conv,
- fent : string,
- ftype : hstype,
- var : string
- }
-
- type decl =
- | Decl of string * list string * expr
- | Data of string * list string * list constr
- | Foreign of fdecl
-
- type prog <- list decl
-
- let rec xs !! i =
- match xs, i with
- | Cons (x, _), 0 -> x
- | Cons (_, xs), i when i > 0 -> xs !! (i - 1)
- | _, _ -> error "empty list and/or negative index"
-
- let ds_data (_, _, cs) =
- let ncons = length cs
- let alts = map (("c" ^) # show) [1..ncons]
- let ds_con i (Constr (n, args)) =
- let arity = length args
- let alt = alts !! i
- let args = map (("x" ^) # show) [1..arity]
- Decl (n, args, foldr lam (foldl app (Ref alt) (map Ref args)) alts)
- let rec go i = function
- | [] -> []
- | Cons (x, xs) -> ds_con i x :: go (i + 1) xs
- go 0 cs
-
- let ds_prog prog =
- let! c = prog
- match c with
- | Data c -> ds_data c
- | Decl (n, args, e) -> [Decl (n, args, e)]
- | Foreign d -> [Foreign d]
|