Mercurial > urweb
changeset 815:493f44759879
Redo Jscomp
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sun, 17 May 2009 18:41:43 -0400 |
parents | 3f3b211f9bca |
children | 26e911ee924c |
files | src/cjrize.sml src/jscomp.sml src/mono.sml src/mono_opt.sml src/mono_print.sml src/mono_reduce.sml src/mono_util.sml src/monoize.sml |
diffstat | 8 files changed, 305 insertions(+), 126 deletions(-) [+] |
line wrap: on
line diff
--- a/src/cjrize.sml Sun May 17 14:36:55 2009 -0400 +++ b/src/cjrize.sml Sun May 17 18:41:43 2009 -0400 @@ -235,7 +235,6 @@ ((L'.PSome (t, p), loc), sm) end - fun cifyExp (eAll as (e, loc), sm) = case e of L.EPrim p => ((L'.EPrim p, loc), sm) @@ -470,7 +469,6 @@ ((L'.EUnurlify (e, t), loc), sm) end - | L.EJavaScript (_, _, SOME e) => cifyExp (e, sm) | L.EJavaScript _ => raise Fail "Cjrize: EJavaScript remains" | L.ESignalReturn _ => raise Fail "Cjrize: ESignalReturn remains"
--- a/src/jscomp.sml Sun May 17 14:36:55 2009 -0400 +++ b/src/jscomp.sml Sun May 17 18:41:43 2009 -0400 @@ -126,7 +126,7 @@ | EDml e => cu inner e | ENextval e => cu inner e | EUnurlify (e, _) => cu inner e - | EJavaScript (_, e, _) => cu inner e + | EJavaScript (_, e) => cu inner e | ESignalReturn e => cu inner e | ESignalBind (e1, e2) => cu inner e1 andalso cu inner e2 | ESignalSource e => cu inner e @@ -169,21 +169,8 @@ U.Exp.RelE _ => inner+1 | _ => inner} -val desourceify' = - U.Exp.map {typ = fn t => t, - exp = fn e => - case e of - EJavaScript (_, e, _) => #1 e - | _ => e} - -val desourceify = - U.File.map {typ = fn t => t, - exp = fn e => - case e of - EJavaScript (m, e, eo) => EJavaScript (m, desourceify' e, eo) - | _ => e, - decl = fn d => d} - +exception CantEmbed of typ + fun process file = let val (someTs, nameds) = @@ -387,9 +374,10 @@ ((EApp ((ENamed n', loc), e), loc), st) end) - | _ => (EM.errorAt loc "Don't know how to embed type in JavaScript"; + | _ => raise CantEmbed t + (*(EM.errorAt loc "Don't know how to embed type in JavaScript"; Print.prefaces "Can't embed" [("t", MonoPrint.p_typ MonoEnv.empty t)]; - (str loc "ERROR", st)) + (str loc "ERROR", st))*) fun unurlifyExp loc (t : typ, st) = case #1 t of @@ -773,14 +761,6 @@ end | EFfiApp (m, x, args) => let - val args = - case (m, x, args) of - ("Basis", "new_client_source", [(EJavaScript (_, e, _), _)]) => - (foundJavaScript := true; [e]) - | ("Basis", "set_client_source", [e1, (EJavaScript (_, e2, _), _)]) => - (foundJavaScript := true; [e1, e2]) - | _ => args - val name = case Settings.jsFunc (m, x) of NONE => (EM.errorAt loc ("Unsupported FFI function " ^ x ^ " in JavaScript"); @@ -985,15 +965,19 @@ str ")"], st) end - | EJavaScript (Source _, _, SOME _) => + | EJavaScript (Source _, e) => (foundJavaScript := true; - (e, st)) - | EJavaScript (_, _, SOME e) => - (foundJavaScript := true; - (strcat [str "cs(function(){return ", - compact inner e, - str "})"], - st)) + jsE inner (e, st)) + | EJavaScript (_, e) => + let + val (e, st) = jsE inner (e, st) + in + foundJavaScript := true; + (strcat [str "cs(function(){return ", + compact inner e, + str "})"], + st) + end | EClosure _ => unsupported "EClosure" | EQuery _ => unsupported "Query" @@ -1001,16 +985,6 @@ | ENextval _ => unsupported "Nextval" | EUnurlify _ => unsupported "EUnurlify" | EReturnBlob _ => unsupported "EUnurlify" - | EJavaScript (_, e, _) => - let - val (e, st) = jsE inner (e, st) - in - foundJavaScript := true; - (strcat [str "cs(function(){return ", - e, - str "})"], - st) - end | ESignalReturn e => let @@ -1094,56 +1068,274 @@ jsE end - val decl : state -> decl -> decl * state = - U.Decl.foldMapB {typ = fn x => x, - exp = fn (env, e, st) => - let - fun doCode m env e = - let - val len = length env - fun str s = (EPrim (Prim.String s), #2 e) - val locals = List.tabulate - (varDepth e, - fn i => str ("var _" ^ Int.toString (len + i) ^ ";")) - val old = e - val (e, st) = jsExp m env 0 (e, st) - val e = - case locals of - [] => e - | _ => - strcat (#2 e) (str "(function(){" - :: locals - @ [str "return ", - e, - str "}())"]) - in - (*Print.prefaces "jsify" [("old", MonoPrint.p_exp MonoEnv.empty old), - ("new", MonoPrint.p_exp MonoEnv.empty e)];*) - (EJavaScript (m, old, SOME e), st) - end - in - case e of - (*EJavaScript (m as Source t, orig, NONE) => - let - val loc = #2 orig - val (e, st) = doCode m (t :: env) (ERel 0, loc) - in - (ELet ("x", t, orig, (e, loc)), st) - end - |*) EJavaScript (m, orig, NONE) => - (foundJavaScript := true; - doCode m env orig) - | _ => (e, st) - end, - decl = fn (_, e, st) => (e, st), - bind = fn (env, U.Decl.RelE (_, t)) => t :: env - | (env, _) => env} - [] + fun patBinds ((p, _), env) = + case p of + PWild => env + | PVar (_, t) => t :: env + | PPrim _ => env + | PCon (_, _, NONE) => env + | PCon (_, _, SOME p) => patBinds (p, env) + | PRecord xpts => foldl (fn ((_, p, _), env) => patBinds (p, env)) env xpts + | PNone _ => env + | PSome (_, p) => patBinds (p, env) + + fun exp outer (e as (_, loc), st) = + ((*Print.preface ("exp", MonoPrint.p_exp MonoEnv.empty e);*) + case #1 e of + EPrim _ => (e, st) + | ERel _ => (e, st) + | ENamed _ => (e, st) + | ECon (_, _, NONE) => (e, st) + | ECon (dk, pc, SOME e) => + let + val (e, st) = exp outer (e, st) + in + ((ECon (dk, pc, SOME e), loc), st) + end + | ENone _ => (e, st) + | ESome (t, e) => + let + val (e, st) = exp outer (e, st) + in + ((ESome (t, e), loc), st) + end + | EFfi _ => (e, st) + | EFfiApp (m, x, es) => + let + val (es, st) = ListUtil.foldlMap (exp outer) st es + in + ((EFfiApp (m, x, es), loc), st) + end + | EApp (e1, e2) => + let + val (e1, st) = exp outer (e1, st) + val (e2, st) = exp outer (e2, st) + in + ((EApp (e1, e2), loc), st) + end + | EAbs (x, dom, ran, e) => + let + val (e, st) = exp (dom :: outer) (e, st) + in + ((EAbs (x, dom, ran, e), loc), st) + end + + | EUnop (s, e) => + let + val (e, st) = exp outer (e, st) + in + ((EUnop (s, e), loc), st) + end + | EBinop (s, e1, e2) => + let + val (e1, st) = exp outer (e1, st) + val (e2, st) = exp outer (e2, st) + in + ((EBinop (s, e1, e2), loc), st) + end + + | ERecord xets => + let + val (xets, st) = ListUtil.foldlMap (fn ((x, e, t), st) => + let + val (e, st) = exp outer (e, st) + in + ((x, e, t), st) + end) st xets + in + ((ERecord xets, loc), st) + end + | EField (e, s) => + let + val (e, st) = exp outer (e, st) + in + ((EField (e, s), loc), st) + end + + | ECase (e, pes, ts) => + let + val (e, st) = exp outer (e, st) + val (pes, st) = ListUtil.foldlMap (fn ((p, e), st) => + let + val (e, st) = exp (patBinds (p, outer)) (e, st) + in + ((p, e), st) + end) st pes + in + ((ECase (e, pes, ts), loc), st) + end + + | EStrcat (e1, e2) => + let + val (e1, st) = exp outer (e1, st) + val (e2, st) = exp outer (e2, st) + in + ((EStrcat (e1, e2), loc), st) + end + + | EError (e, t) => + let + val (e, st) = exp outer (e, st) + in + ((EError (e, t), loc), st) + end + | EReturnBlob {blob, mimeType, t} => + let + val (blob, st) = exp outer (blob, st) + val (mimeType, st) = exp outer (mimeType, st) + in + ((EReturnBlob {blob = blob, mimeType = mimeType, t = t}, loc), st) + end + + | EWrite e => + let + val (e, st) = exp outer (e, st) + in + ((EWrite e, loc), st) + end + | ESeq (e1, e2) => + let + val (e1, st) = exp outer (e1, st) + val (e2, st) = exp outer (e2, st) + in + ((ESeq (e1, e2), loc), st) + end + | ELet (x, t, e1, e2) => + let + val (e1, st) = exp outer (e1, st) + val (e2, st) = exp (t :: outer) (e2, st) + in + ((ELet (x, t, e1, e2), loc), st) + end + + | EClosure (n, es) => + let + val (es, st) = ListUtil.foldlMap (exp outer) st es + in + ((EClosure (n, es), loc), st) + end + + | EQuery {exps, tables, state, query, body, initial} => + let + val (query, st) = exp outer (query, st) + val (body, st) = exp outer (body, st) + val (initial, st) = exp outer (initial, st) + in + ((EQuery {exps = exps, tables = tables, state = state, + query = query, body = body, initial = initial}, loc), st) + end + | EDml e => + let + val (e, st) = exp outer (e, st) + in + ((EDml e, loc), st) + end + | ENextval e => + let + val (e, st) = exp outer (e, st) + in + ((ENextval e, loc), st) + end + + | EUnurlify (e, t) => + let + val (e, st) = exp outer (e, st) + in + ((EUnurlify (e, t), loc), st) + end + + | EJavaScript (m, e') => + (let + val len = length outer + fun str s = (EPrim (Prim.String s), #2 e') + + val locals = List.tabulate + (varDepth e', + fn i => str ("var _" ^ Int.toString (len + i) ^ ";")) + + val (e', st) = jsExp m outer 0 (e', st) + + val e' = + case locals of + [] => e' + | _ => + strcat (#2 e') (str "(function(){" + :: locals + @ [str "return ", + e', + str "}())"]) + in + (e', st) + end handle CantEmbed _ => (e, st)) + + | ESignalReturn e => + let + val (e, st) = exp outer (e, st) + in + ((ESignalReturn e, loc), st) + end + | ESignalBind (e1, e2) => + let + val (e1, st) = exp outer (e1, st) + val (e2, st) = exp outer (e2, st) + in + ((ESignalBind (e1, e2), loc), st) + end + | ESignalSource e => + let + val (e, st) = exp outer (e, st) + in + ((ESignalSource e, loc), st) + end + + | EServerCall (e1, e2, t, ef) => + let + val (e1, st) = exp outer (e1, st) + val (e2, st) = exp outer (e2, st) + in + ((EServerCall (e1, e2, t, ef), loc), st) + end + | ERecv (e1, e2, t) => + let + val (e1, st) = exp outer (e1, st) + val (e2, st) = exp outer (e2, st) + in + ((ERecv (e1, e2, t), loc), st) + end + | ESleep (e1, e2) => + let + val (e1, st) = exp outer (e1, st) + val (e2, st) = exp outer (e2, st) + in + ((ESleep (e1, e2), loc), st) + end) + + fun decl (d as (_, loc), st) = + case #1 d of + DVal (x, n, t, e, s) => + let + val (e, st) = exp [] (e, st) + in + ((DVal (x, n, t, e, s), loc), st) + end + | DValRec vis => + let + val (vis, st) = ListUtil.foldlMap (fn ((x, n, t, e, s), st) => + let + val (e, st) = exp [] (e, st) + in + ((x, n, t, e, s), st) + end) st vis + in + ((DValRec vis, loc), st) + end + | _ => (d, st) fun doDecl (d, st) = let - val (d, st) = decl st d + (*val () = Print.preface ("doDecl", MonoPrint.p_decl MonoEnv.empty d)*) + val (d, st) = decl (d, st) in (List.revAppend (#decls st, [d]), {decls = [], @@ -1163,7 +1355,7 @@ listInjectors = TM.empty, decoders = IM.empty, maxName = U.File.maxName file + 1} - (desourceify file) + file val inf = TextIO.openIn (OS.Path.joinDirFile {dir = Config.libJs, file = "urweb.js"}) fun lines acc =
--- a/src/mono.sml Sun May 17 14:36:55 2009 -0400 +++ b/src/mono.sml Sun May 17 18:41:43 2009 -0400 @@ -108,7 +108,7 @@ | EUnurlify of exp * typ - | EJavaScript of javascript_mode * exp * exp option + | EJavaScript of javascript_mode * exp | ESignalReturn of exp | ESignalBind of exp * exp
--- a/src/mono_opt.sml Sun May 17 14:36:55 2009 -0400 +++ b/src/mono_opt.sml Sun May 17 18:41:43 2009 -0400 @@ -376,8 +376,6 @@ | ESignalBind ((ESignalReturn e1, loc), e2) => optExp (EApp (e2, e1), loc) - | EJavaScript (_, _, SOME (e, _)) => e - | EFfiApp ("Basis", "bless", [(se as EPrim (Prim.String s), loc)]) => (if Settings.checkUrl s then ()
--- a/src/mono_print.sml Sun May 17 14:36:55 2009 -0400 +++ b/src/mono_print.sml Sun May 17 18:41:43 2009 -0400 @@ -310,13 +310,12 @@ | EUnurlify (e, _) => box [string "unurlify(", p_exp env e, string ")"] - | EJavaScript (m, e, NONE) => box [string "JavaScript(", - p_mode env m, - string ",", - space, - p_exp env e, - string ")"] - | EJavaScript (_, _, SOME e) => p_exp env e + | EJavaScript (m, e) => box [string "JavaScript(", + p_mode env m, + string ",", + space, + p_exp env e, + string ")"] | ESignalReturn e => box [string "Return(", p_exp env e,
--- a/src/mono_reduce.sml Sun May 17 14:36:55 2009 -0400 +++ b/src/mono_reduce.sml Sun May 17 18:41:43 2009 -0400 @@ -74,7 +74,7 @@ | ELet (_, _, e1, e2) => impure e1 orelse impure e2 | EClosure (_, es) => List.exists impure es - | EJavaScript (_, e, _) => impure e + | EJavaScript (_, e) => impure e | ESignalReturn e => impure e | ESignalBind (e1, e2) => impure e1 orelse impure e2 | ESignalSource e => impure e @@ -344,7 +344,7 @@ | EDml e => summarize d e @ [WriteDb] | ENextval e => summarize d e @ [WriteDb] | EUnurlify (e, _) => summarize d e - | EJavaScript (_, e, _) => summarize d e + | EJavaScript (_, e) => summarize d e | ESignalReturn e => summarize d e | ESignalBind (e1, e2) => summarize d e1 @ summarize d e2 | ESignalSource e => summarize d e
--- a/src/mono_util.sml Sun May 17 14:36:55 2009 -0400 +++ b/src/mono_util.sml Sun May 17 18:41:43 2009 -0400 @@ -340,20 +340,12 @@ S.map2 (mft t, fn t' => (EUnurlify (e', t'), loc))) - | EJavaScript (m, e, NONE) => + | EJavaScript (m, e) => S.bind2 (mfmode ctx m, fn m' => S.map2 (mfe ctx e, fn e' => - (EJavaScript (m', e', NONE), loc))) - | EJavaScript (m, e, SOME e2) => - S.bind2 (mfmode ctx m, - fn m' => - S.bind2 (mfe ctx e, - fn e' => - S.map2 (mfe ctx e2, - fn e2' => - (EJavaScript (m, e', SOME e2'), loc)))) + (EJavaScript (m', e'), loc))) | ESignalReturn e => S.map2 (mfe ctx e,
--- a/src/monoize.sml Sun May 17 14:36:55 2009 -0400 +++ b/src/monoize.sml Sun May 17 18:41:43 2009 -0400 @@ -1173,7 +1173,7 @@ ((L'.EAbs ("x", t, (L'.TFun ((L'.TRecord [], loc), (L'.TSource, loc)), loc), (L'.EAbs ("_", (L'.TRecord [], loc), (L'.TSource, loc), (L'.EFfiApp ("Basis", "new_client_source", - [(L'.EJavaScript (L'.Source t, (L'.ERel 1, loc), NONE), loc)]), + [(L'.EJavaScript (L'.Source t, (L'.ERel 1, loc)), loc)]), loc)), loc)), loc), fm) @@ -1189,7 +1189,7 @@ (L'.EFfiApp ("Basis", "set_client_source", [(L'.ERel 2, loc), (L'.EJavaScript (L'.Source t, - (L'.ERel 1, loc), NONE), loc)]), + (L'.ERel 1, loc)), loc)]), loc)), loc)), loc)), loc), fm) end @@ -2410,7 +2410,7 @@ (L'.EStrcat ( (L'.EPrim (Prim.String s'), loc), (L'.EStrcat ( - (L'.EJavaScript (L'.Attribute, e, NONE), loc), + (L'.EJavaScript (L'.Attribute, e), loc), (L'.EPrim (Prim.String "'"), loc)), loc)), loc)), loc), fm) @@ -2500,11 +2500,11 @@ (fn ("Source", _, _) => NONE | ("Onchange", e, _) => SOME (strcat [str "addOnChange(d,", - (L'.EJavaScript (L'.Script, e, NONE), loc), + (L'.EJavaScript (L'.Script, e), loc), str ")"]) | (x, e, _) => SOME (strcat [str ("d." ^ lowercaseFirst x ^ "="), - (L'.EJavaScript (L'.Script, e, NONE), loc), + (L'.EJavaScript (L'.Script, e), loc), str ";"])) attrs in @@ -2524,7 +2524,7 @@ let val e = (L'.EApp (e, (L'.ERecord [], loc)), loc) in - (L'.EJavaScript (L'.Attribute, e, NONE), loc) + (L'.EJavaScript (L'.Attribute, e), loc) end in normal ("body", @@ -2543,7 +2543,7 @@ |*) [("Signal", e, _)] => ((L'.EStrcat ((L'.EPrim (Prim.String "<span><script type=\"text/javascript\">dyn("), loc), - (L'.EStrcat ((L'.EJavaScript (L'.Script, e, NONE), loc), + (L'.EStrcat ((L'.EJavaScript (L'.Script, e), loc), (L'.EPrim (Prim.String ")</script></span>"), loc)), loc)), loc), fm) | _ => raise Fail "Monoize: Bad dyn attributes") @@ -2566,7 +2566,7 @@ end | SOME (_, src, _) => (strcat [str "<span><script type=\"text/javascript\">inp(\"input\",", - (L'.EJavaScript (L'.Script, src, NONE), loc), + (L'.EJavaScript (L'.Script, src), loc), str ",\"\")</script></span>"], fm)) | _ => (Print.prefaces "Targs" (map (fn t => ("T", CorePrint.p_con env t)) targs); @@ -2638,7 +2638,7 @@ | SOME (_, src, _) => let val sc = strcat [str "inp(\"input\",", - (L'.EJavaScript (L'.Script, src, NONE), loc), + (L'.EJavaScript (L'.Script, src), loc), str ",\"\")"] val sc = setAttrs sc in @@ -2663,9 +2663,9 @@ val (xml, fm) = monoExp (env, st, fm) xml val sc = strcat [str "inp(\"select\",", - (L'.EJavaScript (L'.Script, src, NONE), loc), + (L'.EJavaScript (L'.Script, src), loc), str ",", - (L'.EJavaScript (L'.Script, xml, NONE), loc), + (L'.EJavaScript (L'.Script, xml), loc), str ")"] val sc = setAttrs sc in