diff options
author | Adam Chlipala <adamc@hcoop.net> | 2009-08-09 16:13:27 -0400 |
---|---|---|
committer | Adam Chlipala <adamc@hcoop.net> | 2009-08-09 16:13:27 -0400 |
commit | 9f1c85cf0ef4be94bf189dea486806298f09ab51 (patch) | |
tree | 007835aa119d7ec7cae1d7de078850147ab9ca13 /src | |
parent | c79947821b62c16f0a5a21fb5ec935c1dba00aae (diff) |
Library improvements; proper list [un]urlification; remove server-side ServerCalls; eta reduction in type inference
Diffstat (limited to 'src')
-rw-r--r-- | src/cjr_print.sml | 89 | ||||
-rw-r--r-- | src/cjrize.sml | 1 | ||||
-rw-r--r-- | src/compiler.sml | 9 | ||||
-rw-r--r-- | src/elab_ops.sml | 22 | ||||
-rw-r--r-- | src/jscomp.sml | 18 | ||||
-rw-r--r-- | src/mono.sml | 2 | ||||
-rw-r--r-- | src/mono_opt.sig | 2 | ||||
-rw-r--r-- | src/mono_opt.sml | 8 | ||||
-rw-r--r-- | src/mono_print.sml | 10 | ||||
-rw-r--r-- | src/mono_reduce.sml | 2 | ||||
-rw-r--r-- | src/mono_util.sml | 8 | ||||
-rw-r--r-- | src/monoize.sml | 19 |
12 files changed, 160 insertions, 30 deletions
diff --git a/src/cjr_print.sml b/src/cjr_print.sml index 83b49719..0fd6339d 100644 --- a/src/cjr_print.sml +++ b/src/cjr_print.sml @@ -962,9 +962,11 @@ fun unurlify env (t, loc) = unurlify' IS.empty t end +val urlify1 = ref 0 + fun urlify env t = let - fun urlify' rf level (t as (_, loc)) = + fun urlify' rf rfl level (t as (_, loc)) = case #1 t of TFfi ("Basis", "unit") => box [] | TFfi (m, t) => box [string ("uw_" ^ ident m ^ "_urlify" ^ capitalize t @@ -1007,7 +1009,7 @@ fun urlify env t = newline] else []), - urlify' rf (level + 1) t, + urlify' rf rfl (level + 1) t, string "}", newline] :: blocks, true) @@ -1079,8 +1081,9 @@ fun urlify env t = string "it0) {", newline, box [string "if (it0) {", + newline, if isUnboxable t then - urlify' rf 0 t + urlify' rf rfl 0 t else box [p_typ env t, space, @@ -1094,11 +1097,12 @@ fun urlify env t = string has_arg, string "/\");", newline, - urlify' rf 1 t, + urlify' rf rfl 1 t, string ";", newline], string "} else {", - box [string "uw_write(ctx, \"", + box [newline, + string "uw_write(ctx, \"", string no_arg, string "\");", newline], @@ -1165,7 +1169,7 @@ fun urlify env t = string x', string ";", newline, - urlify' rf 1 t, + urlify' rf rfl 1 t, newline], string "} else {", newline, @@ -1208,7 +1212,7 @@ fun urlify env t = if isUnboxable t then box [string "uw_write(ctx, \"Some/\");", newline, - urlify' rf level t] + urlify' rf rfl level t] else box [p_typ env t, space, @@ -1223,19 +1227,84 @@ fun urlify env t = newline, string "uw_write(ctx, \"Some/\");", newline, - urlify' rf (level + 1) t, + urlify' rf rfl (level + 1) t, string ";", newline], string "} else {", - box [string "uw_write(ctx, \"None\");", + box [newline, + string "uw_write(ctx, \"None\");", newline], string "}", newline] + | TList (t, i) => + if IS.member (rfl, i) then + box [string "urlifyl_", + string (Int.toString i), + string "(it", + string (Int.toString level), + string ");", + newline] + else + let + val rfl = IS.add (rfl, i) + in + box [string "({", + space, + string "void", + space, + string "urlifyl_", + string (Int.toString i), + string "(struct __uws_", + string (Int.toString i), + space, + string "*it0) {", + newline, + box [string "if (it0) {", + newline, + p_typ env t, + space, + string "it1", + space, + string "=", + space, + string "it0->__uwf_1;", + newline, + string "uw_write(ctx, \"Cons/\");", + newline, + urlify' rf rfl 1 t, + string ";", + newline, + string "uw_write(ctx, \"/\");", + newline, + string "urlifyl_", + string (Int.toString i), + string "(it0->__uwf_2);", + newline, + string "} else {", + newline, + box [string "uw_write(ctx, \"Nil\");", + newline], + string "}", + newline], + string "}", + newline, + newline, + + string "urlifyl_", + string (Int.toString i), + string "(it", + string (Int.toString level), + string ");", + newline, + string "});", + newline] + end + | _ => (ErrorMsg.errorAt loc "Unable to choose a URL encoding function"; space) in - urlify' IS.empty 0 t + urlify' IS.empty IS.empty 0 t end fun sql_type_in env (tAll as (t, loc)) = diff --git a/src/cjrize.sml b/src/cjrize.sml index 5f3ea5a8..6a79b4e6 100644 --- a/src/cjrize.sml +++ b/src/cjrize.sml @@ -112,6 +112,7 @@ fun cifyTyp x = end | L.TRecord xts => let + val xts = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) xts val old_xts = xts val (xts, sm) = ListUtil.foldlMap (fn ((x, t), sm) => let diff --git a/src/compiler.sml b/src/compiler.sml index c99c0eeb..13bb77f9 100644 --- a/src/compiler.sml +++ b/src/compiler.sml @@ -805,7 +805,7 @@ val monoize = { val toMonoize = transform monoize "monoize" o toEffectize val mono_opt = { - func = MonoOpt.optimize, + func = (fn x => (MonoOpt.removeServerCalls := false; MonoOpt.optimize x)), print = MonoPrint.p_file MonoEnv.empty } @@ -841,7 +841,12 @@ val jscomp = { val toJscomp = transform jscomp "jscomp" o toMono_opt2 -val toMono_opt3 = transform mono_opt "mono_opt3" o toJscomp +val mono_opt' = { + func = (fn x => (MonoOpt.removeServerCalls := true; MonoOpt.optimize x)), + print = MonoPrint.p_file MonoEnv.empty +} + +val toMono_opt3 = transform mono_opt' "mono_opt3" o toJscomp val fuse = { func = Fuse.fuse, diff --git a/src/elab_ops.sml b/src/elab_ops.sml index a26ba17d..b5292e9b 100644 --- a/src/elab_ops.sml +++ b/src/elab_ops.sml @@ -131,6 +131,18 @@ fun subStrInSgn (m1, m2) = sgn_item = fn sgi => sgi, sgn = fn sgn => sgn} +val occurs = + U.Con.existsB {kind = fn _ => false, + con = fn (n, c) => + case c of + CRel n' => n' = n + | _ => false, + bind = fn (n, b) => + case b of + U.Con.RelC _ => n + 1 + | _ => n} + 0 + fun hnormCon env (cAll as (c, loc)) = case c of @@ -156,6 +168,16 @@ fun hnormCon env (cAll as (c, loc)) = | SOME (_, SOME c) => hnormCon env c end + (* Eta reduction *) + | CAbs (x, k, b) => + (case #1 (hnormCon (E.pushCRel env x k) b) of + CApp (f, (CRel 0, _)) => + if occurs f then + cAll + else + hnormCon env (subConInCon (0, (CUnit, loc)) f) + | _ => cAll) + | CApp (c1, c2) => (case #1 (hnormCon env c1) of CAbs (x, k, cb) => diff --git a/src/jscomp.sml b/src/jscomp.sml index 63f3d883..d42c659e 100644 --- a/src/jscomp.sml +++ b/src/jscomp.sml @@ -86,7 +86,7 @@ fun varDepth (e, _) = | ESignalReturn e => varDepth e | ESignalBind (e1, e2) => Int.max (varDepth e1, varDepth e2) | ESignalSource e => varDepth e - | EServerCall (e, ek, _, _) => Int.max (varDepth e, varDepth ek) + | EServerCall (e, ek, _, _, _) => Int.max (varDepth e, varDepth ek) | ERecv (e, ek, _) => Int.max (varDepth e, varDepth ek) | ESleep (e, ek) => Int.max (varDepth e, varDepth ek) @@ -130,7 +130,7 @@ fun closedUpto d = | ESignalReturn e => cu inner e | ESignalBind (e1, e2) => cu inner e1 andalso cu inner e2 | ESignalSource e => cu inner e - | EServerCall (e, ek, _, _) => cu inner e andalso cu inner ek + | EServerCall (e, ek, _, _, _) => cu inner e andalso cu inner ek | ERecv (e, ek, _) => cu inner e andalso cu inner ek | ESleep (e, ek) => cu inner e andalso cu inner ek in @@ -434,6 +434,13 @@ fun process file = ("(t[i++]==\"Some\"?" ^ e ^ ":null)", st) end + | TList t => + let + val (e, st) = unurlifyExp loc (t, st) + in + ("uul(function(){return t[i++];},function(){return " ^ e ^ "})", st) + end + | TDatatype (n, ref (dk, cs)) => (case IM.find (#decoders st, n) of SOME n' => ("(tmp=_n" ^ Int.toString n' ^ "(t,i),i=tmp._1,tmp._2)", st) @@ -1034,7 +1041,7 @@ fun process file = st) end - | EServerCall (e, ek, t, eff) => + | EServerCall (e, ek, t, eff, _) => let val (e, st) = jsE inner (e, st) val (ek, st) = jsE inner (ek, st) @@ -1313,12 +1320,13 @@ fun process file = ((ESignalSource e, loc), st) end - | EServerCall (e1, e2, t, ef) => + | EServerCall (e1, e2, t, ef, ue) => let val (e1, st) = exp outer (e1, st) val (e2, st) = exp outer (e2, st) + val (ue, st) = exp outer (ue, st) in - ((EServerCall (e1, e2, t, ef), loc), st) + ((EServerCall (e1, e2, t, ef, ue), loc), st) end | ERecv (e1, e2, t) => let diff --git a/src/mono.sml b/src/mono.sml index 64ed448c..2d29af48 100644 --- a/src/mono.sml +++ b/src/mono.sml @@ -114,7 +114,7 @@ datatype exp' = | ESignalBind of exp * exp | ESignalSource of exp - | EServerCall of exp * exp * typ * effect + | EServerCall of exp * exp * typ * effect * exp | ERecv of exp * exp * typ | ESleep of exp * exp diff --git a/src/mono_opt.sig b/src/mono_opt.sig index d0268087..7368f684 100644 --- a/src/mono_opt.sig +++ b/src/mono_opt.sig @@ -30,4 +30,6 @@ signature MONO_OPT = sig val optimize : Mono.file -> Mono.file val optExp : Mono.exp -> Mono.exp + val removeServerCalls : bool ref + end diff --git a/src/mono_opt.sml b/src/mono_opt.sml index bf39b311..7bfce88b 100644 --- a/src/mono_opt.sml +++ b/src/mono_opt.sml @@ -30,6 +30,8 @@ structure MonoOpt :> MONO_OPT = struct open Mono structure U = MonoUtil +val removeServerCalls = ref false + fun typ t = t fun decl d = d @@ -480,6 +482,12 @@ fun exp e = | [] => raise Fail "MonoOpt impossible nil") | NONE => e end + + | EServerCall (_, _, _, _, ue) => + if !removeServerCalls then + optExp ue + else + e | _ => e diff --git a/src/mono_print.sml b/src/mono_print.sml index 71bc734a..ed63b2a0 100644 --- a/src/mono_print.sml +++ b/src/mono_print.sml @@ -335,11 +335,11 @@ fun p_exp' par env (e, _) = p_exp env e, string ")"] - | EServerCall (n, e, _, _) => box [string "Server(", - p_exp env n, - string ")[", - p_exp env e, - string "]"] + | EServerCall (n, e, _, _, _) => box [string "Server(", + p_exp env n, + string ")[", + p_exp env e, + string "]"] | ERecv (n, e, _) => box [string "Recv(", p_exp env n, string ")[", diff --git a/src/mono_reduce.sml b/src/mono_reduce.sml index 4bbb430d..62368f9b 100644 --- a/src/mono_reduce.sml +++ b/src/mono_reduce.sml @@ -354,7 +354,7 @@ fun reduce file = | ESignalBind (e1, e2) => summarize d e1 @ summarize d e2 | ESignalSource e => summarize d e - | EServerCall (e, ek, _, _) => summarize d e @ summarize d ek @ [Unsure] + | EServerCall (e, ek, _, _, _) => summarize d e @ summarize d ek @ [Unsure] | ERecv (e, ek, _) => summarize d e @ summarize d ek @ [Unsure] | ESleep (e, ek) => summarize d e @ summarize d ek @ [Unsure] in diff --git a/src/mono_util.sml b/src/mono_util.sml index e2bed8eb..0a4bb048 100644 --- a/src/mono_util.sml +++ b/src/mono_util.sml @@ -362,14 +362,16 @@ fun mapfoldB {typ = fc, exp = fe, bind} = fn e' => (ESignalSource e', loc)) - | EServerCall (s, ek, t, eff) => + | EServerCall (s, ek, t, eff, ue) => S.bind2 (mfe ctx s, fn s' => S.bind2 (mfe ctx ek, fn ek' => - S.map2 (mft t, + S.bind2 (mft t, fn t' => - (EServerCall (s', ek', t', eff), loc)))) + S.map2 (mfe ctx ue, + fn ue' => + (EServerCall (s', ek', t', eff, ue'), loc))))) | ERecv (s, ek, t) => S.bind2 (mfe ctx s, fn s' => diff --git a/src/monoize.sml b/src/monoize.sml index d774c697..c0351756 100644 --- a/src/monoize.sml +++ b/src/monoize.sml @@ -93,7 +93,12 @@ fun monoType env = L.TFun (c1, c2) => (L'.TFun (mt env dtmap c1, mt env dtmap c2), loc) | L.TCFun _ => poly () | L.TRecord (L.CRecord ((L.KType, _), xcs), _) => - (L'.TRecord (map (fn (x, t) => (monoName env x, mt env dtmap t)) xcs), loc) + let + val xcs = map (fn (x, t) => (monoName env x, mt env dtmap t)) xcs + val xcs = ListMergeSort.sort (fn ((x, _), (y, _)) => String.compare (x, y) = GREATER) xcs + in + (L'.TRecord xcs, loc) + end | L.TRecord _ => poly () | L.CApp ((L.CFfi ("Basis", "option"), _), t) => @@ -3076,6 +3081,8 @@ fun monoExp (env, st, fm) (all as (e, loc)) = e, monoType env t), fm) end) fm xes + + val xes = ListMergeSort.sort (fn ((x, _, _), (y, _, _)) => String.compare (x, y) = GREATER) xes in ((L'.ERecord xes, loc), fm) end @@ -3154,6 +3161,12 @@ fun monoExp (env, st, fm) (all as (e, loc)) = val (ek, fm) = monoExp (env, st, fm) ek + val unRpced = foldl (fn (e1, e2) => (L'.EApp (e2, e1), loc)) (L'.ENamed n, loc) es + val unRpced = (L'.EApp (unRpced, (L'.ERecord [], loc)), loc) + val unRpced = (L'.EApp (ek, unRpced), loc) + val unRpced = (L'.EApp (unRpced, (L'.ERecord [], loc)), loc) + val unit = (L'.TRecord [], loc) + val ekf = (L'.EAbs ("f", (L'.TFun (t, (L'.TFun ((L'.TRecord [], loc), @@ -3171,9 +3184,9 @@ fun monoExp (env, st, fm) (all as (e, loc)) = L'.ReadCookieWrite else L'.ReadOnly - val e = (L'.EServerCall (call, ek, t, eff), loc) + + val e = (L'.EServerCall (call, ek, t, eff, unRpced), loc) val e = liftExpInExp 0 e - val unit = (L'.TRecord [], loc) val e = (L'.EAbs ("_", unit, unit, e), loc) in (e, fm) |