# HG changeset patch
# User Adam Chlipala
# Date 1229880657 18000
# Node ID 57018f21cd5c04f8155dfd513fbb329fa220bade
# Parent 86d324061ddc3f9ffbc5bc917cadb4fcd265a915
Handling singnal bind
diff -r 86d324061ddc -r 57018f21cd5c jslib/urweb.js
--- a/jslib/urweb.js Sun Dec 21 12:01:00 2008 -0500
+++ b/jslib/urweb.js Sun Dec 21 12:30:57 2008 -0500
@@ -1,4 +1,5 @@
-function sreturn(v) { return {v : v} }
+function sr(v) { return {v : v} }
+function sb(x,y) { return {v : y(x.v).v} }
function dyn(s) {
var x = document.createElement("span");
diff -r 86d324061ddc -r 57018f21cd5c src/cjrize.sml
--- a/src/cjrize.sml Sun Dec 21 12:01:00 2008 -0500
+++ b/src/cjrize.sml Sun Dec 21 12:30:57 2008 -0500
@@ -423,6 +423,7 @@
| L.EJavaScript _ => raise Fail "Cjrize: EJavaScript remains"
| L.ESignalReturn _ => raise Fail "Cjrize: ESignalReturn remains"
+ | L.ESignalBind _ => raise Fail "Cjrize: ESignalBind remains"
fun cifyDecl ((d, loc), sm) =
case d of
diff -r 86d324061ddc -r 57018f21cd5c src/compiler.sig
--- a/src/compiler.sig Sun Dec 21 12:01:00 2008 -0500
+++ b/src/compiler.sig Sun Dec 21 12:30:57 2008 -0500
@@ -102,8 +102,9 @@
val toUntangle : (string, Mono.file) transform
val toMono_reduce : (string, Mono.file) transform
val toMono_shake : (string, Mono.file) transform
+ val toMono_opt2 : (string, Mono.file) transform
val toJscomp : (string, Mono.file) transform
- val toMono_opt2 : (string, Mono.file) transform
+ val toMono_opt3 : (string, Mono.file) transform
val toFuse : (string, Mono.file) transform
val toUntangle2 : (string, Mono.file) transform
val toMono_shake2 : (string, Mono.file) transform
diff -r 86d324061ddc -r 57018f21cd5c src/compiler.sml
--- a/src/compiler.sml Sun Dec 21 12:01:00 2008 -0500
+++ b/src/compiler.sml Sun Dec 21 12:30:57 2008 -0500
@@ -511,21 +511,23 @@
val toMono_shake = transform mono_shake "mono_shake1" o toMono_reduce
+val toMono_opt2 = transform mono_opt "mono_opt2" o toMono_shake
+
val jscomp = {
func = JsComp.process,
print = MonoPrint.p_file MonoEnv.empty
}
-val toJscomp = transform jscomp "jscomp" o toMono_reduce
+val toJscomp = transform jscomp "jscomp" o toMono_opt2
-val toMono_opt2 = transform mono_opt "mono_opt2" o toJscomp
+val toMono_opt3 = transform mono_opt "mono_opt3" o toJscomp
val fuse = {
func = Fuse.fuse,
print = MonoPrint.p_file MonoEnv.empty
}
-val toFuse = transform fuse "fuse" o toMono_opt2
+val toFuse = transform fuse "fuse" o toMono_opt3
val toUntangle2 = transform untangle "untangle2" o toFuse
diff -r 86d324061ddc -r 57018f21cd5c src/jscomp.sml
--- a/src/jscomp.sml Sun Dec 21 12:01:00 2008 -0500
+++ b/src/jscomp.sml Sun Dec 21 12:30:57 2008 -0500
@@ -33,6 +33,20 @@
structure E = MonoEnv
structure U = MonoUtil
+val funcs = [(("Basis", "alert"), "alert"),
+ (("Basis", "htmlifyString"), "escape")]
+
+structure FM = BinaryMapFn(struct
+ type ord_key = string * string
+ fun compare ((m1, x1), (m2, x2)) =
+ Order.join (String.compare (m1, m2),
+ fn () => String.compare (x1, x2))
+ end)
+
+val funcs = foldl (fn ((k, v), m) => FM.insert (m, k, v)) FM.empty funcs
+
+fun ffi k = FM.find (funcs, k)
+
type state = {
decls : decl list,
script : string
@@ -70,6 +84,7 @@
| EUnurlify _ => 0
| EJavaScript _ => 0
| ESignalReturn e => varDepth e
+ | ESignalBind (e1, e2) => Int.max (varDepth e1, varDepth e2)
fun strcat loc es =
case es of
@@ -150,33 +165,50 @@
e, st)
end
- | EFfi (_, s) => (str s, st)
- | EFfiApp (_, s, []) => (str (s ^ "()"), st)
- | EFfiApp (_, s, [e]) =>
+ | EFfi k =>
let
- val (e, st) = jsE inner (e, st)
-
+ val name = case ffi k of
+ NONE => (EM.errorAt loc "Unsupported FFI identifier in JavaScript";
+ "ERROR")
+ | SOME s => s
in
- (strcat [str (s ^ "("),
- e,
- str ")"], st)
+ (str name, st)
end
- | EFfiApp (_, s, e :: es) =>
+ | EFfiApp (m, x, args) =>
let
- val (e, st) = jsE inner (e, st)
- val (es, st) = ListUtil.foldlMapConcat
- (fn (e, st) =>
- let
- val (e, st) = jsE inner (e, st)
- in
- ([str ",", e], st)
- end)
- st es
+ val name = case ffi (m, x) of
+ NONE => (EM.errorAt loc "Unsupported FFI function in JavaScript";
+ "ERROR")
+ | SOME s => s
in
- (strcat (str (s ^ "(")
- :: e
- :: es
- @ [str ")"]), st)
+ case args of
+ [] => (str (name ^ "()"), st)
+ | [e] =>
+ let
+ val (e, st) = jsE inner (e, st)
+
+ in
+ (strcat [str (name ^ "("),
+ e,
+ str ")"], st)
+ end
+ | e :: es =>
+ let
+ val (e, st) = jsE inner (e, st)
+ val (es, st) = ListUtil.foldlMapConcat
+ (fn (e, st) =>
+ let
+ val (e, st) = jsE inner (e, st)
+ in
+ ([str ",", e], st)
+ end)
+ st es
+ in
+ (strcat (str (name ^ "(")
+ :: e
+ :: es
+ @ [str ")"]), st)
+ end
end
| EApp (e1, e2) =>
@@ -317,11 +349,23 @@
let
val (e, st) = jsE inner (e, st)
in
- (strcat [str "sreturn(",
+ (strcat [str "sr(",
e,
str ")"],
st)
end
+ | ESignalBind (e1, e2) =>
+ let
+ val (e1, st) = jsE inner (e1, st)
+ val (e2, st) = jsE inner (e2, st)
+ in
+ (strcat [str "sb(",
+ e1,
+ str ",",
+ e2,
+ str ")"],
+ st)
+ end
end
in
jsE
diff -r 86d324061ddc -r 57018f21cd5c src/mono.sml
--- a/src/mono.sml Sun Dec 21 12:01:00 2008 -0500
+++ b/src/mono.sml Sun Dec 21 12:30:57 2008 -0500
@@ -105,6 +105,7 @@
| EJavaScript of javascript_mode * exp
| ESignalReturn of exp
+ | ESignalBind of exp * exp
withtype exp = exp' located
diff -r 86d324061ddc -r 57018f21cd5c src/mono_opt.sml
--- a/src/mono_opt.sml Sun Dec 21 12:01:00 2008 -0500
+++ b/src/mono_opt.sml Sun Dec 21 12:30:57 2008 -0500
@@ -360,6 +360,9 @@
| EWrite (EPrim (Prim.String ""), loc) =>
ERecord []
+ | ESignalBind ((ESignalReturn e1, loc), e2) =>
+ optExp (EApp (e2, e1), loc)
+
| _ => e
and optExp e = #1 (U.Exp.map {typ = typ, exp = exp} e)
diff -r 86d324061ddc -r 57018f21cd5c src/mono_print.sml
--- a/src/mono_print.sml Sun Dec 21 12:01:00 2008 -0500
+++ b/src/mono_print.sml Sun Dec 21 12:30:57 2008 -0500
@@ -285,6 +285,12 @@
| ESignalReturn e => box [string "Return(",
p_exp env e,
string ")"]
+ | ESignalBind (e1, e2) => box [string "Return(",
+ p_exp env e1,
+ string ",",
+ space,
+ p_exp env e2,
+ string ")"]
and p_exp env = p_exp' false env
diff -r 86d324061ddc -r 57018f21cd5c src/mono_reduce.sml
--- a/src/mono_reduce.sml Sun Dec 21 12:01:00 2008 -0500
+++ b/src/mono_reduce.sml Sun Dec 21 12:30:57 2008 -0500
@@ -77,6 +77,7 @@
| EClosure (_, es) => List.exists impure es
| EJavaScript (_, e) => impure e
| ESignalReturn e => impure e
+ | ESignalBind (e1, e2) => impure e1 orelse impure e2
val liftExpInExp = Monoize.liftExpInExp
@@ -333,6 +334,7 @@
| EUnurlify (e, _) => summarize d e
| EJavaScript (_, e) => summarize d e
| ESignalReturn e => summarize d e
+ | ESignalBind (e1, e2) => summarize d e1 @ summarize d e2
fun exp env e =
@@ -478,6 +480,9 @@
| EStrcat ((EPrim (Prim.String s1), _), (EPrim (Prim.String s2), _)) =>
EPrim (Prim.String (s1 ^ s2))
+ | ESignalBind ((ESignalReturn e1, loc), e2) =>
+ #1 (reduceExp env (EApp (e2, e1), loc))
+
| _ => e
in
(*Print.prefaces "exp'" [("r", MonoPrint.p_exp env (r, ErrorMsg.dummySpan))];*)
diff -r 86d324061ddc -r 57018f21cd5c src/mono_util.sml
--- a/src/mono_util.sml Sun Dec 21 12:01:00 2008 -0500
+++ b/src/mono_util.sml Sun Dec 21 12:30:57 2008 -0500
@@ -328,6 +328,12 @@
S.map2 (mfe ctx e,
fn e' =>
(ESignalReturn e', loc))
+ | ESignalBind (e1, e2) =>
+ S.bind2 (mfe ctx e1,
+ fn e1' =>
+ S.map2 (mfe ctx e2,
+ fn e2' =>
+ (ESignalBind (e1', e2'), loc)))
in
mfe
end
diff -r 86d324061ddc -r 57018f21cd5c src/monoize.sml
--- a/src/monoize.sml Sun Dec 21 12:01:00 2008 -0500
+++ b/src/monoize.sml Sun Dec 21 12:30:57 2008 -0500
@@ -957,8 +957,8 @@
val mt1 = (L'.TFun (un, t1), loc)
val mt2 = (L'.TFun (un, t2), loc)
in
- ((L'.EAbs ("m1", mt1, (L'.TFun (mt1, (L'.TFun (mt2, (L'.TFun (un, un), loc)), loc)), loc),
- (L'.EAbs ("m2", mt2, (L'.TFun (un, un), loc),
+ ((L'.EAbs ("m1", mt1, (L'.TFun ((L'.TFun (t1, mt2), loc), (L'.TFun (un, un), loc)), loc),
+ (L'.EAbs ("m2", (L'.TFun (t1, mt2), loc), (L'.TFun (un, un), loc),
(L'.EAbs ("_", un, un,
(L'.ELet ("r", t1, (L'.EApp ((L'.ERel 2, loc),
(L'.ERecord [], loc)), loc),
@@ -989,6 +989,20 @@
(L'.ESignalReturn (L'.ERel 0, loc), loc)), loc),
fm)
end
+ | L.EApp ((L.ECApp ((L.ECApp ((L.ECApp ((L.EFfi ("Basis", "bind"), _), _), _), t1), _), t2), _),
+ (L.EFfi ("Basis", "signal_monad"), _)) =>
+ let
+ val t1 = monoType env t1
+ val t2 = monoType env t2
+ val un = (L'.TRecord [], loc)
+ val mt1 = (L'.TSignal t1, loc)
+ val mt2 = (L'.TSignal t2, loc)
+ in
+ ((L'.EAbs ("m1", mt1, (L'.TFun ((L'.TFun (t1, mt2), loc), mt2), loc),
+ (L'.EAbs ("m2", (L'.TFun (t1, mt2), loc), mt2,
+ (L'.ESignalBind ((L'.ERel 1, loc), (L'.ERel 0, loc)), loc)), loc)), loc),
+ fm)
+ end
| L.ECApp ((L.EFfi ("Basis", "getCookie"), _), t) =>
let
diff -r 86d324061ddc -r 57018f21cd5c tests/sbind.ur
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/sbind.ur Sun Dec 21 12:30:57 2008 -0500
@@ -0,0 +1,5 @@
+fun main () : transaction page = return
+ Before
+ {[s]}
}/>
+ After
+
diff -r 86d324061ddc -r 57018f21cd5c tests/sbind.urp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/sbind.urp Sun Dec 21 12:30:57 2008 -0500
@@ -0,0 +1,3 @@
+debug
+
+sbind