summaryrefslogtreecommitdiff
path: root/src/monoize.sml
diff options
context:
space:
mode:
Diffstat (limited to 'src/monoize.sml')
-rw-r--r--src/monoize.sml346
1 files changed, 32 insertions, 314 deletions
diff --git a/src/monoize.sml b/src/monoize.sml
index 8934db2c..2e87a70b 100644
--- a/src/monoize.sml
+++ b/src/monoize.sml
@@ -50,9 +50,9 @@ structure RM = BinaryMapFn(struct
(L'.TRecord r2, E.dummySpan))
end)
-val nextPvar = ref 0
+val nextPvar = MonoFooify.nextPvar
val pvars = ref (RM.empty : (int * (string * int * L'.typ) list) RM.map)
-val pvarDefs = ref ([] : (string * int * (string * int * L'.typ option) list) list)
+val pvarDefs = MonoFooify.pvarDefs
val pvarOldDefs = ref ([] : (int * (string * int * L.con option) list) list)
fun choosePvar () =
@@ -374,311 +374,26 @@ fun monoType env =
val dummyExp = (L'.EPrim (Prim.Int 0), E.dummySpan)
-structure IM = IntBinaryMap
-
-datatype foo_kind =
- Attr
- | Url
-
-fun fk2s fk =
- case fk of
- Attr => "attr"
- | Url => "url"
-
-type vr = string * int * L'.typ * L'.exp * string
-
-structure Fm :> sig
- type t
-
- val empty : int -> t
-
- val lookup : t -> foo_kind -> int -> (int -> t -> vr * t) -> t * int
- val lookupList : t -> foo_kind -> L'.typ -> (int -> t -> vr * t) -> t * int
- val enter : t -> t
- val decls : t -> L'.decl list
-
- val freshName : t -> int * t
-end = struct
-
-structure M = BinaryMapFn(struct
- type ord_key = foo_kind
- fun compare x =
- case x of
- (Attr, Attr) => EQUAL
- | (Attr, _) => LESS
- | (_, Attr) => GREATER
-
- | (Url, Url) => EQUAL
- end)
-
-structure TM = BinaryMapFn(struct
- type ord_key = L'.typ
- val compare = MonoUtil.Typ.compare
- end)
-
-type t = {
- count : int,
- map : int IM.map M.map,
- listMap : int TM.map M.map,
- decls : vr list
-}
-
-fun empty count = {
- count = count,
- map = M.empty,
- listMap = M.empty,
- decls = []
-}
-
-fun chooseNext count =
- let
- val n = !nextPvar
- in
- if count < n then
- (count, count+1)
- else
- (nextPvar := n + 1;
- (n, n+1))
- end
-
-fun enter ({count, map, listMap, ...} : t) = {count = count, map = map, listMap = listMap, decls = []}
-fun freshName {count, map, listMap, decls} =
- let
- val (next, count) = chooseNext count
- in
- (next, {count = count , map = map, listMap = listMap, decls = decls})
- end
-fun decls ({decls, ...} : t) =
- case decls of
- [] => []
- | _ => [(L'.DValRec decls, ErrorMsg.dummySpan)]
-
-fun lookup (t as {count, map, listMap, decls}) k n thunk =
- let
- val im = Option.getOpt (M.find (map, k), IM.empty)
- in
- case IM.find (im, n) of
- NONE =>
- let
- val n' = count
- val (d, {count, map, listMap, decls}) =
- thunk count {count = count + 1,
- map = M.insert (map, k, IM.insert (im, n, n')),
- listMap = listMap,
- decls = decls}
- in
- ({count = count,
- map = map,
- listMap = listMap,
- decls = d :: decls}, n')
- end
- | SOME n' => (t, n')
- end
-
-fun lookupList (t as {count, map, listMap, decls}) k tp thunk =
- let
- val tm = Option.getOpt (M.find (listMap, k), TM.empty)
- in
- case TM.find (tm, tp) of
- NONE =>
- let
- val n' = count
- val (d, {count, map, listMap, decls}) =
- thunk count {count = count + 1,
- map = map,
- listMap = M.insert (listMap, k, TM.insert (tm, tp, n')),
- decls = decls}
- in
- ({count = count,
- map = map,
- listMap = listMap,
- decls = d :: decls}, n')
- end
- | SOME n' => (t, n')
- end
-
-end
-
-
-fun capitalize s =
- if s = "" then
- s
- else
- str (Char.toUpper (String.sub (s, 0))) ^ String.extract (s, 1, NONE)
+structure Fm = MonoFooify.Fm
fun fooifyExp fk env =
- let
- fun fooify fm (e, tAll as (t, loc)) =
- case #1 e of
- L'.EClosure (fnam, [(L'.ERecord [], _)]) =>
- let
- val (_, _, _, s) = Env.lookupENamed env fnam
- in
- ((L'.EPrim (Prim.String (Prim.Normal, Settings.getUrlPrefix () ^ s)), loc), fm)
- end
- | L'.EClosure (fnam, args) =>
- let
- val (_, ft, _, s) = Env.lookupENamed env fnam
- val ft = monoType env ft
-
- fun attrify (args, ft, e, fm) =
- case (args, ft) of
- ([], _) => (e, fm)
- | (arg :: args, (L'.TFun (t, ft), _)) =>
- let
- val (arg', fm) = fooify fm (arg, t)
- in
- attrify (args, ft,
- (L'.EStrcat (e,
- (L'.EStrcat ((L'.EPrim (Prim.String (Prim.Normal, "/")), loc),
- arg'), loc)), loc),
- fm)
- end
- | _ => (E.errorAt loc "Type mismatch encoding attribute";
- (e, fm))
- in
- attrify (args, ft, (L'.EPrim (Prim.String (Prim.Normal, Settings.getUrlPrefix () ^ s)), loc), fm)
- end
- | _ =>
- case t of
- L'.TFfi ("Basis", "unit") => ((L'.EPrim (Prim.String (Prim.Normal, "")), loc), fm)
- | L'.TFfi (m, x) => ((L'.EFfiApp (m, fk2s fk ^ "ify" ^ capitalize x, [(e, tAll)]), loc), fm)
-
- | L'.TRecord [] => ((L'.EPrim (Prim.String (Prim.Normal, "")), loc), fm)
- | L'.TRecord ((x, t) :: xts) =>
- let
- val (se, fm) = fooify fm ((L'.EField (e, x), loc), t)
- in
- foldl (fn ((x, t), (se, fm)) =>
- let
- val (se', fm) = fooify fm ((L'.EField (e, x), loc), t)
- in
- ((L'.EStrcat (se,
- (L'.EStrcat ((L'.EPrim (Prim.String (Prim.Normal, "/")), loc),
- se'), loc)), loc),
- fm)
- end) (se, fm) xts
- end
-
- | L'.TDatatype (i, ref (dk, _)) =>
- let
- fun makeDecl n fm =
- let
- val (x, xncs) =
- case ListUtil.search (fn (x, i', xncs) =>
- if i' = i then
- SOME (x, xncs)
- else
- NONE) (!pvarDefs) of
- NONE =>
- let
- val (x, _, xncs) = Env.lookupDatatype env i
- in
- (x, map (fn (x, n, c) => (x, n, Option.map (monoType env) c)) xncs)
- end
- | SOME v => v
-
- val (branches, fm) =
- ListUtil.foldlMap
- (fn ((x, n, to), fm) =>
- case to of
- NONE =>
- (((L'.PCon (dk, L'.PConVar n, NONE), loc),
- (L'.EPrim (Prim.String (Prim.Normal, x)), loc)),
- fm)
- | SOME t =>
- let
- val (arg, fm) = fooify fm ((L'.ERel 0, loc), t)
- in
- (((L'.PCon (dk, L'.PConVar n, SOME (L'.PVar ("a", t), loc)), loc),
- (L'.EStrcat ((L'.EPrim (Prim.String (Prim.Normal, x ^ "/")), loc),
- arg), loc)),
- fm)
- end)
- fm xncs
-
- val dom = tAll
- val ran = (L'.TFfi ("Basis", "string"), loc)
- in
- ((fk2s fk ^ "ify_" ^ x,
- n,
- (L'.TFun (dom, ran), loc),
- (L'.EAbs ("x",
- dom,
- ran,
- (L'.ECase ((L'.ERel 0, loc),
- branches,
- {disc = dom,
- result = ran}), loc)), loc),
- ""),
- fm)
- end
-
- val (fm, n) = Fm.lookup fm fk i makeDecl
- in
- ((L'.EApp ((L'.ENamed n, loc), e), loc), fm)
- end
-
- | L'.TOption t =>
- let
- val (body, fm) = fooify fm ((L'.ERel 0, loc), t)
- in
- ((L'.ECase (e,
- [((L'.PNone t, loc),
- (L'.EPrim (Prim.String (Prim.Normal, "None")), loc)),
-
- ((L'.PSome (t, (L'.PVar ("x", t), loc)), loc),
- (L'.EStrcat ((L'.EPrim (Prim.String (Prim.Normal, "Some/")), loc),
- body), loc))],
- {disc = tAll,
- result = (L'.TFfi ("Basis", "string"), loc)}), loc),
- fm)
- end
-
- | L'.TList t =>
- let
- fun makeDecl n fm =
- let
- val rt = (L'.TRecord [("1", t), ("2", (L'.TList t, loc))], loc)
- val (arg, fm) = fooify fm ((L'.ERel 0, loc), rt)
-
- val branches = [((L'.PNone rt, loc),
- (L'.EPrim (Prim.String (Prim.Normal, "Nil")), loc)),
- ((L'.PSome (rt, (L'.PVar ("a", rt), loc)), loc),
- (L'.EStrcat ((L'.EPrim (Prim.String (Prim.Normal, "Cons/")), loc),
- arg), loc))]
-
- val dom = tAll
- val ran = (L'.TFfi ("Basis", "string"), loc)
- in
- ((fk2s fk ^ "ify_list",
- n,
- (L'.TFun (dom, ran), loc),
- (L'.EAbs ("x",
- dom,
- ran,
- (L'.ECase ((L'.ERel 0, loc),
- branches,
- {disc = dom,
- result = ran}), loc)), loc),
- ""),
- fm)
- end
-
- val (fm, n) = Fm.lookupList fm fk t makeDecl
- in
- ((L'.EApp ((L'.ENamed n, loc), e), loc), fm)
- end
-
- | _ => (E.errorAt loc "Don't know how to encode attribute/URL type";
- Print.eprefaces' [("Type", MonoPrint.p_typ MonoEnv.empty tAll)];
- (dummyExp, fm))
- in
- fooify
- end
+ MonoFooify.fooifyExp
+ fk
+ (fn n =>
+ let
+ val (_, t, _, s) = Env.lookupENamed env n
+ in
+ (monoType env t, s)
+ end)
+ (fn n =>
+ let
+ val (x, _, xncs) = Env.lookupDatatype env n
+ in
+ (x, map (fn (x, n, c) => (x, n, Option.map (monoType env) c)) xncs)
+ end)
-val attrifyExp = fooifyExp Attr
-val urlifyExp = fooifyExp Url
+val attrifyExp = fooifyExp MonoFooify.Attr
+val urlifyExp = fooifyExp MonoFooify.Url
datatype 'a failable_search =
Found of 'a
@@ -1962,7 +1677,6 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L'.ERel 1, loc)), loc),
(L'.ERel 0, loc)), loc),
(L'.ERecord [], loc)), loc)
-
val body = (L'.EQuery {exps = exps,
tables = tables,
state = state,
@@ -4630,12 +4344,14 @@ fun monoize env file =
val (nullable, notNullable) = calcClientish xts
fun cond (x, v) =
- (L'.EStrcat (str (Settings.mangleSql x
- ^ (case v of
- Client => ""
- | Channel => " >> 32")
- ^ " = "),
- target), loc)
+ (L'.EStrcat ((L'.EStrcat (str ("(("
+ ^ Settings.mangleSql x
+ ^ (case v of
+ Client => ""
+ | Channel => " >> 32")
+ ^ ") = "),
+ target), loc),
+ str ")"), loc)
val e =
foldl (fn ((x, v), e) =>
@@ -4727,7 +4443,7 @@ fun monoize env file =
val mname = CoreUtil.File.maxName file + 1
val () = nextPvar := mname
- val (_, _, ds) = List.foldl (fn (d, (env, fm, ds)) =>
+ val (_, fm, ds) = List.foldl (fn (d, (env, fm, ds)) =>
case #1 d of
L.DDatabase s =>
let
@@ -4770,12 +4486,14 @@ fun monoize env file =
(L'.DDatatype (dts @ !pvarDefs), loc) :: Fm.decls fm @ ds
| _ =>
ds' @ Fm.decls fm @ (L'.DDatatype (!pvarDefs), loc) :: ds)))
- (env, Fm.empty mname, []) file
+ (env, Fm.empty mname, []) file
+ val monoFile = (rev ds, [])
in
pvars := RM.empty;
pvarDefs := [];
pvarOldDefs := [];
- (rev ds, [])
+ MonoFooify.canonicalFm := Fm.empty (MonoUtil.File.maxName monoFile + 1);
+ monoFile
end
end