let rec step_expr (ctx: context) (b: b) (e: inner expr)
: b * inner expr * output_event list * task list =
let step = step_expr ctx in
begin match e with
| Eval(X(R(Error(s))))
| Apply(X(R(Error(s))), _)
| Prim1(_, X(R(Error(s))))
| Prim2(_, X(R(Error(s))), _)
| Alert(X(R(Error(s))))
| If(X(R(Error(s))), _, _)
| Set_var(_, X(R(Error(s))))
| Seq(X(R(Error(s))), _)
| Get_cookie(X(R(Error(s))), _)
| Set_cookie(X(R(Error(s))), _, _)
| Xhr(X(R(Error(s))), _, _)
| Named_win(X(R(Error(s))))
| Open_win(X(R(Error(s))))
| Open_named_win(X(R(Error(s))), _)
| Close_win(X(R(Error(s))))
| Navigate_win(X(R(Error(s))), _)
| Is_win_closed(X(R(Error(s))))
| Get_win_opener(X(R(Error(s))))
| Get_win_location(X(R(Error(s))))
| Get_win_name(X(R(Error(s))))
| Set_win_name(X(R(Error(s))), _)
| Get_win_root_node(X(R(Error(s))))
| Set_win_root_node(X(R(Error(s))), _)
| Get_win_var(X(R(Error(s))), _)
| Set_win_var(X(R(Error(s))), _, _)
| New_node(X(R(Error(s))))
| Get_node_type(X(R(Error(s))))
| Get_node_contents(X(R(Error(s))))
| Set_node_contents(X(R(Error(s))), _)
| Get_node_attr(X(R(Error(s))), _)
| Set_node_attr(X(R(Error(s))), _, _)
| Remove_handlers(X(R(Error(s))))
| Add_handler(X(R(Error(s))), _)
| Get_parent(X(R(Error(s))))
| Get_child(X(R(Error(s))), _)
| Insert_node(X(R(Error(s))), _, _)
| Remove_node(X(R(Error(s)))) ->
(b, X(R(Error(s))), [], [])
| Apply(X(R(_)), X(R(Error(s))))
| Prim2(_, X(R(_)), X(R(Error(s))))
| Get_cookie(X(R(_)), X(R(Error(s))))
| Set_cookie(X(R(_)), X(R(Error(s))), _)
| Open_named_win(X(R(_)), X(R(Error(s))))
| Navigate_win(X(R(_)), X(R(Error(s))))
| Set_node_contents(X(R(_)), X(R(Error(s))))
| Get_node_attr(X(R(_)), X(R(Error(s))))
| Set_node_attr(X(R(_)), X(R(Error(s))), _)
| Set_win_name(X(R(_)), X(R(Error(s))))
| Set_win_root_node(X(R(_)), X(R(Error(s))))
| Set_win_var(X(R(_)), _, X(R(Error(s))))
| Add_handler(X(R(_)), X(R(Error(s))))
| Get_child(X(R(_)), X(R(Error(s))))
| Insert_node(X(R(_)), X(R(Error(s))), _)
| Xhr(X(R(_)), X(R(Error(s))), _) ->
(b, X(R(Error(s))), [], [])
| Set_cookie(X(R(_)), X(R(_)), X(R(Error(s))))
| Xhr(X(R(_)), X(R(_)), X(R(Error(s))))
| Set_node_attr(X(R(_)), X(R(_)), X(R(Error(s))))
| Insert_node(X(R(_)), X(R(_)), X(R(Error(s)))) ->
(b, X(R(Error(s))), [], [])
| X(R(_)) ->
let err = "run-time type error" in
(b, X(R(Error(err))), [], [])
| X(Scoped_expr(_, X(R(r1)))) ->
(b, X(R(r1)), [], [])
| X(Scoped_expr(ctx', e1)) ->
let (b', e1', oes, ts) = step_expr ctx' b e1 in
(b', X(Scoped_expr(ctx', e1')), oes, ts)
| Null ->
(b, X(R(Null_value)), [], [])
| Bool(bl) ->
(b, X(R(Bool_value(bl))), [], [])
| Int(n) ->
(b, X(R(Int_value(n))), [], [])
| String(s) ->
(b, X(R(String_value(s))), [], [])
| Url(u) ->
(b, X(R(Url_value(u))), [], [])
| Type(t) ->
(b, X(R(Type_value(t))), [], [])
| Code(e) ->
(b, X(R(Code_value(e))), [], [])
| Eval(X(R(Code_value(e1)))) ->
(b, to_inner_expr e1, [], [])
| Var(x) ->
begin match get_var x ctx.context_act b with
| None ->
let err = Printf.sprintf "variable %S not found" x.var_name in
(b, X(R(Error(err))), [], [])
| Some(r) ->
(b, X(R(r)), [], [])
end
| Function(x, locals, e1) ->
(b, X(R(Closure(ctx, x, locals, e1))), [], [])
| Apply(X(R(Closure(ctx1, x, locals, e1))), X(R(r2))) ->
let bot_null x = (x, Null_value) in
let act = {
act_parent = Some(ctx1.context_act);
act_vars = (x, r2) :: List.map bot_null locals;
} in
let (ar', b') = act_new act b in
let ctx2 = { ctx1 with context_act = ar' } in
(b', X(Scoped_expr(ctx2, e1)), [], [])
| Prim1(prim, X(R(r))) ->
(b, X(R(prim1 prim r)), [], [])
| Prim2(prim, X(R(r1)), X(R(r2))) ->
(b, X(R(prim2 prim r1 r2)), [], [])
| Alert(X(R(Null_value))) ->
(b, X(R(Null_value)), [ UI_alert("null") ], [])
| Alert(X(R(Bool_value(bl)))) ->
(b, X(R(Null_value)), [ UI_alert(Printf.sprintf "%B" bl) ], [])
| Alert(X(R(Int_value(n)))) ->
(b, X(R(Null_value)), [ UI_alert(Printf.sprintf "%N" n) ], [])
| Alert(X(R(String_value(s)))) ->
(b, X(R(Null_value)), [ UI_alert(s) ], [])
| Alert(X(R(Url_value(_)))) ->
(b, X(R(Null_value)), [ UI_alert("<URL>") ], [])
| Alert(X(R(Code_value(_)))) ->
(b, X(R(Null_value)), [ UI_alert("<code>") ], [])
| Alert(X(R(Win_value(_)))) ->
(b, X(R(Null_value)), [ UI_alert("<window>") ], [])
| Alert(X(R(Node_value(_)))) ->
(b, X(R(Null_value)), [ UI_alert("<node>") ], [])
| Alert(X(R(Closure(_, _, _, _)))) ->
(b, X(R(Null_value)), [ UI_alert("<function>") ], [])
| Set_var(x, X(R(r1))) ->
(set_var x r1 ctx.context_act b, X(R(r1)), [], [])
| If(X(R(Bool_value(true))), e2, e3) ->
(b, e2, [], [])
| If(X(R(Bool_value(false))), e2, e3) ->
(b, e3, [], [])
| While(e1, e2) ->
(b, If(e1, Seq(e2, While(e1, e2)), Null), [], [])
| Seq(X(R(_)), e2) ->
(b, e2, [], [])
| Get_cookie(X(R(Url_value(Http_url(d, uri)))), X(R(String_value(ck)))) ->
let cs = get_site_cookies d uri.req_uri_path b in
begin try
(b, X(R(String_value(List.assoc ck cs))), [], [])
with
| Not_found -> (b, X(R(Null_value)), [], [])
end
| Set_cookie(
X(R(Url_value(Http_url(d, uri)))),
X(R(String_value(ck))),
X(R(Null_value))) ->
let b' = del_site_cookie d uri.req_uri_path ck b in
(b', X(R(Null_value)), [], [])
| Set_cookie(
X(R(Url_value(Http_url(d, uri)))),
X(R(String_value(ck))),
X(R(String_value(cv)))) ->
let b' = set_site_cookie d uri.req_uri_path (ck, cv) b in
(b', X(R(Null_value)), [], [])
| Xhr(X(R(Url_value(Blank_url))), X(R(_)), X(R(_))) ->
(b, X(R(Null_value)), [], [])
| Xhr(X(R(Url_value(Http_url(d, uri)))),
X(R(String_value(msg))), X(R(Closure(_, _, _, _) as handler))) ->
begin if not (win_valid ctx.context_win b) then
let err = "window was closed---cannot make AJAX request" in
(b, X(R(Error(err))), [], [])
else
let w = win_assoc_valid ctx.context_win b in
let dst = Xhr_dst(w.win_page, handler) in
let (b', oe) = http_send d uri msg dst b in
(b', X(R(Null_value)), [ oe ], [])
end
| Self_win ->
(b, X(R(Win_value(ctx.context_win))), [], [])
| Named_win(X(R(String_value(wn)))) ->
begin match win_from_win_name wn b with
| None -> (b, X(R(Null_value)), [], [])
| Some(wr) -> (b, X(R(Win_value(wr))), [], [])
end
| Open_win(X(R(Url_value(u)))) ->
let wo = Win_opener(ctx.context_win) in
let (wr, b', oes) = open_win No_name u wo b in
(b', X(R(Win_value(wr))), oes, [])
| Open_named_win(X(R(Url_value(u))), X(R(String_value(str)))) ->
begin match win_from_win_name str b with
| None ->
let wo = Win_opener(ctx.context_win) in
let (wr, b', oes) = open_win (Str_name(str)) u wo b in
(b', X(R(Win_value(wr))), oes, [])
| Some(wr) ->
let (b', oes) = direct_win wr u b in
(b', X(R(Win_value(wr))), oes, [])
end
| Close_win(X(R(Win_value(wr)))) ->
let oes =
if win_valid wr b then [ UI_win_closed_event(win_to_user_window wr b) ]
else []
in
(win_remove wr b, X(R(Null_value)), oes, [])
| Navigate_win(
X(R(Win_value(wr))),
X(R(Url_value(url)))) ->
begin if win_valid wr b then
let (b', oes) = direct_win wr (url) b in
(b', X(R(Null_value)), oes, [])
else
let err = "window was closed---cannot set location" in
(b, X(R(Error(err))), [], [])
end
| Is_win_closed(X(R(Win_value(wr)))) ->
(b, X(R(Bool_value(not (win_valid wr b)))), [], [])
| Get_win_opener(X(R(Win_value(wr)))) ->
begin match win_assoc wr b with
| None ->
let err = "window was closed---cannot get opener" in
(b, X(R(Error(err))), [], [])
| Some(w) ->
begin match w.win_opener with
| No_opener -> (b, X(R(Null_value)), [], [])
| Win_opener(wr') -> (b, X(R(Win_value(wr))), [], [])
end
end
| Get_win_location(X(R(Win_value(wr)))) ->
begin match win_assoc wr b with
| None ->
let err = "window was closed---cannot get location" in
(b, X(R(Error(err))), [], [])
| Some(w) ->
let u =
(page_assoc_valid w.win_page b).page_location
in
(b, X(R(Url_value(u))), [], [])
end
| Get_win_name(X(R(Win_value(wr)))) ->
begin match win_assoc wr b with
| None ->
let err = "window was closed---cannot get name" in
(b, X(R(Error(err))), [], [])
| Some(w) ->
begin match w.win_name with
| No_name ->
(b, X(R(Null_value)), [], [])
| Str_name(str) ->
(b, X(R(String_value(str))), [], [])
end
end
| Set_win_name(X(R(Win_value(wr))), X(R(Null_value))) ->
begin match win_assoc wr b with
| None ->
let err = "window was closed---cannot unset name" in
(b, X(R(Error(err))), [], [])
| Some(w) ->
let w' = { w with win_name = No_name } in
let b' = win_update wr w' b in
(b', X(R(Null_value)), [], [])
end
| Set_win_name(X(R(Win_value(wr))), X(R(String_value(str)))) ->
begin match win_assoc wr b with
| None ->
let err = "window was closed---cannot set name" in
(b, X(R(Error(err))), [], [])
| Some(w) ->
let w' = { w with win_name = Str_name(str) } in
let b' = win_update wr w' b in
(b', X(R(Null_value)), [], [])
end
| Get_win_root_node(X(R(Win_value(wr)))) ->
begin match win_assoc wr b with
| None ->
let err = "window was closed---cannot get root node" in
(b, X(R(Error(err))), [], [])
| Some(w) ->
begin match (page_assoc_valid w.win_page b).page_document with
| None ->
(b, X(R(Null_value)), [], [])
| Some(dr) ->
(b, X(R(Node_value(dr))), [], [])
end
end
| Set_win_root_node(
X(R(Win_value(wr))),
X(R(Node_value(dr)))) ->
begin match win_assoc wr b with
| None ->
let err = "window was closed---cannot set root node" in
(b, X(R(Error(err))), [], [])
| Some(w) ->
let (b', oes1) = node_remove dr b in
let p = page_assoc_valid w.win_page b in
let p' = { p with page_document = Some(dr) } in
let b'' = page_update w.win_page p' b' in
let (b''', oes2, ts) = process_node_scripts w.win_page dr b'' in
let oes = oes1 @ [ page_update_event w.win_page b''' ] @ oes2 in
(b''', X(R(Null_value)), oes, ts)
end
| Get_win_var(X(R(Win_value(wr))), x) ->
begin match win_assoc wr b with
| None ->
let err =
Printf.sprintf "window was closed---cannot get variable %S"
x.var_name
in
(b, X(R(Error(err))), [], [])
| Some(w) ->
let ar = (page_assoc_valid w.win_page b).page_environment in
begin match get_var x ar b with
| None ->
let err =
Printf.sprintf "window variable %S not found" x.var_name
in
(b, X(R(Error(err))), [], [])
| Some(r) ->
(b, X(R(r)), [], [])
end
end
| Set_win_var(X(R(Win_value(wr))), x, X(R(r2))) ->
begin match win_assoc wr b with
| None ->
let err =
Printf.sprintf "window was closed---cannot set variable %s"
x.var_name
in
(b, X(R(Error(err))), [], [])
| Some(w) ->
let ar = (page_assoc_valid w.win_page b).page_environment in
let b' = set_var x r2 ar b in
(b', X(R(Null_value)), [], [])
end
| New_node(X(R(String_value("para")))) ->
let (dr, b') = node_new (Para_node(None, "")) b in
(b', X(R(Node_value(dr))), [], [])
| New_node(X(R(String_value("link")))) ->
let (dr, b') = node_new (Link_node(None, Blank_url, "")) b in
(b', X(R(Node_value(dr))), [], [])
| New_node(X(R(String_value("textbox")))) ->
let (dr, b') = node_new (Textbox_node(None, "", [])) b in
(b', X(R(Node_value(dr))), [], [])
| New_node(X(R(String_value("button")))) ->
let (dr, b') = node_new (Button_node(None, "", [])) b in
(b', X(R(Node_value(dr))), [], [])
| New_node(X(R(String_value("inl_script")))) ->
let (dr, b') = node_new (Inl_script_node(None, Null, false)) b in
(b', X(R(Node_value(dr))), [], [])
| New_node(X(R(String_value("rem_script")))) ->
let (dr, b') = node_new (Rem_script_node(None, Blank_url, false)) b in
(b', X(R(Node_value(dr))), [], [])
| New_node(X(R(String_value("div")))) ->
let (dr, b') = node_new (Div_node(None, [])) b in
(b', X(R(Node_value(dr))), [], [])
| New_node(X(R(String_value(_)))) ->
let err = "expected valid node type string" in
(b, X(R(Error(err))), [], [])
| Get_node_type(X(R(Node_value(dr)))) ->
begin match node_assoc_valid dr b with
| Para_node(_, _) ->
(b, X(R(String_value("para"))), [], [])
| Link_node(_, _, _) ->
(b, X(R(String_value("link"))), [], [])
| Textbox_node(_, _, _) ->
(b, X(R(String_value("textbox"))), [], [])
| Button_node(_, _, _) ->
(b, X(R(String_value("button"))), [], [])
| Inl_script_node(_, _, _) ->
(b, X(R(String_value("inl_script"))), [], [])
| Rem_script_node(_, _, _) ->
(b, X(R(String_value("rem_script"))), [], [])
| Div_node(_, _) ->
(b, X(R(String_value("div"))), [], [])
end
| Get_node_contents(X(R(Node_value(dr)))) ->
begin match node_assoc_valid dr b with
| Para_node(_, txt) ->
(b, X(R(String_value(txt))), [], [])
| Link_node(_, _, txt) ->
(b, X(R(String_value(txt))), [], [])
| Button_node(_, txt, _) ->
(b, X(R(String_value(txt))), [], [])
| Inl_script_node(_, e, _) ->
(b, X(R(Code_value(e))), [], [])
| _ ->
let err = "node has no contents" in
(b, X(R(Error(err))), [], [])
end
| Set_node_contents(X(R(Node_value(dr))), X(R(String_value(s)))) ->
begin match node_assoc_valid dr b with
| Para_node(oeid, _) ->
let b' = node_update dr (Para_node(oeid, s)) b in
(b', X(R(String_value(s))), [], [])
| Link_node(oeid, u, _) ->
let b' = node_update dr (Link_node(oeid, u, s)) b in
(b', X(R(String_value(s))), [], [])
| Button_node(oeid, _, hs) ->
let b' = node_update dr (Button_node(oeid, s, hs)) b in
(b', X(R(String_value(s))), [], [])
| _ ->
let err = "node has no string contents" in
(b, X(R(Error(err))), [], [])
end
| Set_node_contents(X(R(Node_value(dr))), X(R(Code_value(e)))) ->
begin match node_assoc_valid dr b with
| Inl_script_node(oeid, _, flag) ->
let b' = node_update dr (Inl_script_node(oeid, e, flag)) b in
(b', X(R(Code_value(e))), [], [])
| _ ->
let err = "node has no script contents" in
(b, X(R(Error(err))), [], [])
end
| Get_node_attr(X(R(Node_value(dr))), X(R(String_value("id")))) ->
begin match node_assoc_valid dr b with
| Para_node(Some({ elt_id_value = id }), _)
| Link_node(Some({ elt_id_value = id }), _, _)
| Textbox_node(Some({ elt_id_value = id }), _, _)
| Button_node(Some({ elt_id_value = id }), _, _)
| Inl_script_node(Some({ elt_id_value = id }), _, _)
| Rem_script_node(Some({ elt_id_value = id }), _, _)
| Div_node(Some({ elt_id_value = id }), _) ->
(b, X(R(String_value(id))), [], [])
| _ ->
(b, X(R(Null_value)), [], [])
end
| Set_node_attr(
X(R(Node_value(dr))),
X(R(String_value("id"))),
X(R(Null_value))) ->
begin match node_assoc_valid dr b with
| Para_node(_, text) ->
let b' = node_update dr (Para_node(None, text)) b in
(b', X(R(Null_value)), [], [])
| Link_node(_, u, text) ->
let b' = node_update dr (Link_node(None, u, text)) b in
(b', X(R(Null_value)), [], [])
| Textbox_node(_, s, hs) ->
let b' = node_update dr (Textbox_node(None, s, hs)) b in
(b', X(R(Null_value)), [], [])
| Button_node(_, s, hs) ->
let b' = node_update dr (Button_node(None, s, hs)) b in
(b', X(R(Null_value)), [], [])
| Inl_script_node(_, e, flag) ->
let b' = node_update dr (Inl_script_node(None, e, flag)) b in
(b', X(R(Null_value)), [], [])
| Rem_script_node(_, u, flag) ->
let b' = node_update dr (Rem_script_node(None, u, flag)) b in
(b', X(R(Null_value)), [], [])
| Div_node(_, ns) ->
let b' = node_update dr (Div_node(None, ns)) b in
(b', X(R(Null_value)), [], [])
end
| Set_node_attr(
X(R(Node_value(dr))),
X(R(String_value("id"))),
X(R(String_value(s)))) ->
let oeid = Some({ elt_id_value = s }) in
begin match node_assoc_valid dr b with
| Para_node(_, text) ->
let b' = node_update dr (Para_node(oeid, text)) b in
(b', X(R(Null_value)), [], [])
| Link_node(_, u, text) ->
let b' = node_update dr (Link_node(oeid, u, text)) b in
(b', X(R(Null_value)), [], [])
| Textbox_node(_, s, hs) ->
let b' = node_update dr (Textbox_node(oeid, s, hs)) b in
(b', X(R(Null_value)), [], [])
| Button_node(_, s, hs) ->
let b' = node_update dr (Button_node(oeid, s, hs)) b in
(b', X(R(Null_value)), [], [])
| Inl_script_node(_, e, flag) ->
let b' = node_update dr (Inl_script_node(oeid, e, flag)) b in
(b', X(R(Null_value)), [], [])
| Rem_script_node(_, u, flag) ->
let b' = node_update dr (Rem_script_node(oeid, u, flag)) b in
(b', X(R(Null_value)), [], [])
| Div_node(_, ns) ->
let b' = node_update dr (Div_node(oeid, ns)) b in
(b', X(R(Null_value)), [], [])
end
| Get_node_attr(X(R(Node_value(dr))), X(R(String_value("href")))) ->
begin match node_assoc_valid dr b with
| Link_node(_, u, _) ->
(b, X(R(Url_value(u))), [], [])
| _ ->
let err = "node has no 'href' attribute" in
(b, X(R(Error(err))), [], [])
end
| Set_node_attr(
X(R(Node_value(dr))),
X(R(String_value("href"))),
X(R(Url_value(u)))) ->
begin match node_assoc_valid dr b with
| Link_node(oeid, _, text) ->
let b' = node_update dr (Link_node(oeid, u, text)) b in
let oes =
begin match node_page dr b' with
| None -> []
| Some(pr) -> [ page_update_event pr b' ]
end
in
(b', X(R(Url_value(u))), oes, [])
| _ ->
let err = "node has no 'href' attribute" in
(b, X(R(Error(err))), [], [])
end
| Get_node_attr(X(R(Node_value(dr))), X(R(String_value("value")))) ->
begin match node_assoc_valid dr b with
| Textbox_node(_, s, _) ->
(b, X(R(String_value(s))), [], [])
| _ ->
let err = "node has no 'value' attribute" in
(b, X(R(Error(err))), [], [])
end
| Set_node_attr(
X(R(Node_value(dr))),
X(R(String_value("value"))),
X(R(String_value(s)))) ->
begin match node_assoc_valid dr b with
| Textbox_node(oeid, _, handlers) ->
let b' = node_update dr (Textbox_node(oeid, s, handlers)) b in
let oes =
begin match node_page dr b' with
| None -> []
| Some(pr) -> [ page_update_event pr b' ]
end
in
(b', X(R(String_value(s))), oes, [])
| _ ->
let err = "node has no 'value' attribute" in
(b, X(R(Error(err))), [], [])
end
| Get_node_attr(X(R(Node_value(dr))), X(R(String_value("src")))) ->
begin match node_assoc_valid dr b with
| Rem_script_node(_, u, _) ->
(b, X(R(Url_value(u))), [], [])
| _ ->
let err = "node has no 'src' attribute" in
(b, X(R(Error(err))), [], [])
end
| Set_node_attr(
X(R(Node_value(dr))),
X(R(String_value("src"))),
X(R(Url_value(u)))) ->
begin match node_assoc_valid dr b with
| Rem_script_node(oeid, _, flag) ->
let b' = node_update dr (Rem_script_node(oeid, u, flag)) b in
(b', X(R(Url_value(u))), [], [])
| _ ->
let err = "node has no 'src' attribute" in
(b, X(R(Error(err))), [], [])
end
| Remove_handlers(X(R(Node_value(dr)))) ->
begin match node_assoc_valid dr b with
| Textbox_node(id, s, _) ->
let dn' = Textbox_node(id, s, []) in
let b' = node_update dr dn' b in
(b', X(R(Null_value)), [], [])
| Button_node(id, s, _) ->
let dn' = Button_node(id, s, []) in
let b' = node_update dr dn' b in
(b', X(R(Null_value)), [], [])
| _ ->
let err = "expected textbox or button node" in
(b, X(R(Error(err))), [], [])
end
| Add_handler(X(R(Node_value(dr))), X(R(Closure(_, _, _, _) as r2))) ->
begin match node_assoc_valid dr b with
| Textbox_node(oeid, str, hs) ->
let b' = node_update dr (Textbox_node(oeid, str, r2 :: hs)) b in
(b', X(R(Null_value)), [], [])
| Button_node(oeid, str, hs) ->
let b' = node_update dr (Button_node(oeid, str, r2 :: hs)) b in
(b', X(R(Null_value)), [], [])
| _ ->
let err = "expected textbox or button node" in
(b, X(R(Error(err))), [], [])
end
| Get_parent(X(R(Node_value(dr)))) ->
begin match node_parent dr b with
| Parent_node(parent) ->
(b, X(R(Node_value(parent))), [], [])
| _ ->
(b, X(R(Null_value)), [], [])
end
| Get_child(X(R(Node_value(dr))), X(R(Int_value(i)))) ->
begin match node_assoc_valid dr b with
| Div_node(_, drs) ->
begin if List.length drs <= i then
(b, X(R(Null_value)), [], [])
else
(b, X(R(Node_value(List.nth drs i))), [], [])
end
| _ ->
let err = "expected div node" in
(b, X(R(Error(err))), [], [])
end
| Insert_node(
X(R(Node_value(dr1))),
X(R(Node_value(dr2))),
X(R(Int_value(k)))) ->
begin try
let (b', oes, ts) = node_insert dr1 dr2 k b in
(b', X(R(Null_value)), oes, ts)
with
| Failure("node_insert") ->
let err = "parent node not a div node or a descendant of child" in
(b, X(R(Error(err))), [], [])
| Failure("insert_in_list") ->
(b, X(R(Error("div node has too few children"))), [], [])
end
| Remove_node(X(R(Node_value(dr)))) ->
let (b', oes) = node_remove dr b in
(b', X(R(Null_value)), oes, [])
| Eval(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b, Eval(e1'), oes, ts)
| Apply(X(R(_)) as e1, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Apply(e1, e2'), oes, ts)
| Apply(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Apply(e1', e2), oes, ts)
| Prim1(prim, e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Prim1(prim, e1'), oes, ts)
| Prim2(prim, (X(R(_)) as e1), e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Prim2(prim, e1, e2'), oes, ts)
| Prim2(prim, e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Prim2(prim, e1', e2), oes, ts)
| Alert(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Alert(e1'), oes, ts)
| If(e1, e2, e3) ->
let (b', e1', oes, ts) = step b e1 in
(b', If(e1', e2, e3), oes, ts)
| Set_var(x, e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Set_var(x, e1'), oes, ts)
| Seq(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Seq(e1', e2), oes, ts)
| Get_cookie(X(R(_)) as e1, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Get_cookie(e1, e2'), oes, ts)
| Get_cookie(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_cookie(e1', e2), oes, ts)
| Set_cookie((X(R(_)) as e1), (X(R(_)) as e2), e3) ->
let (b', e3', oes, ts) = step b e3 in
(b', Set_cookie(e1, e2, e3'), oes, ts)
| Set_cookie((X(R(_)) as e1), e2, e3) ->
let (b', e2', oes, ts) = step b e2 in
(b', Set_cookie(e1, e2', e3), oes, ts)
| Set_cookie(e1, e2, e3) ->
let (b', e1', oes, ts) = step b e1 in
(b', Set_cookie(e1', e2, e3), oes, ts)
| Xhr((X(R(_)) as e1), (X(R(_)) as e2), e3) ->
let (b', e3', oes, ts) = step b e3 in
(b', Xhr(e1, e2, e3'), oes, ts)
| Xhr((X(R(_)) as e1), e2, e3) ->
let (b', e2', oes, ts) = step b e2 in
(b', Xhr(e1, e2', e3), oes, ts)
| Xhr(e1, e2, e3) ->
let (b', e1', oes, ts) = step b e1 in
(b', Xhr(e1', e2, e3), oes, ts)
| Named_win(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Named_win(e1'), oes, ts)
| Open_win(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Open_win(e1'), oes, ts)
| Open_named_win(X(R(_)) as e1, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Open_named_win(e1, e2'), oes, ts)
| Open_named_win(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Open_named_win(e1', e2), oes, ts)
| Close_win(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Close_win(e1'), oes, ts)
| Navigate_win(X(R(_)) as e1, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Navigate_win(e1, e2'), oes, ts)
| Navigate_win(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Navigate_win(e1', e2), oes, ts)
| Is_win_closed(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Is_win_closed(e1'), oes, ts)
| Get_win_opener(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_win_opener(e1'), oes, ts)
| Get_win_location(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_win_location(e1'), oes, ts)
| Get_win_name(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_win_name(e1'), oes, ts)
| Set_win_name(X(R(_)) as e1, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Set_win_name(e1, e2'), oes, ts)
| Set_win_name(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Set_win_name(e1', e2), oes, ts)
| Get_win_root_node(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_win_root_node(e1'), oes, ts)
| Set_win_root_node(X(R(_)) as e1, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Set_win_root_node(e1, e2'), oes, ts)
| Set_win_root_node(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Set_win_root_node(e1', e2), oes, ts)
| Get_win_var(e1, x) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_win_var(e1', x), oes, ts)
| Set_win_var(X(R(_)) as e1, x, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Set_win_var(e1, x, e2'), oes, ts)
| Set_win_var(e1, x, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Set_win_var(e1', x, e2), oes, ts)
| New_node(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', New_node(e1'), oes, ts)
| Get_node_type(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_node_type(e1'), oes, ts)
| Get_node_contents(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_node_contents(e1'), oes, ts)
| Set_node_contents(X(R(_)) as e1, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Set_node_contents(e1, e2'), oes, ts)
| Set_node_contents(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Set_node_contents(e1', e2), oes, ts)
| Get_node_attr(X(R(_)) as e1, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Get_node_attr(e1, e2'), oes, ts)
| Get_node_attr(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_node_attr(e1', e2), oes, ts)
| Set_node_attr((X(R(_)) as e1), (X(R(_)) as e2), e3) ->
let (b', e3', oes, ts) = step b e3 in
(b', Set_node_attr(e1, e2, e3'), oes, ts)
| Set_node_attr((X(R(_)) as e1), e2, e3) ->
let (b', e2', oes, ts) = step b e2 in
(b', Set_node_attr(e1, e2', e3), oes, ts)
| Set_node_attr(e1, e2, e3) ->
let (b', e1', oes, ts) = step b e1 in
(b', Set_node_attr(e1', e2, e3), oes, ts)
| Remove_handlers(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Remove_handlers(e1'), oes, ts)
| Add_handler((X(R(_)) as e1), e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Add_handler(e1, e2'), oes, ts)
| Add_handler(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Add_handler(e1', e2), oes, ts)
| Get_child(X(R(_)) as e1, e2) ->
let (b', e2', oes, ts) = step b e2 in
(b', Get_child(e1, e2'), oes, ts)
| Get_parent(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_parent(e1'), oes, ts)
| Get_child(e1, e2) ->
let (b', e1', oes, ts) = step b e1 in
(b', Get_child(e1', e2), oes, ts)
| Insert_node((X(R(_)) as e1), (X(R(_)) as e2), e3) ->
let (b', e3', oes, ts) = step b e3 in
(b', Insert_node(e1, e2, e3'), oes, ts)
| Insert_node((X(R(_)) as e1), e2, e3) ->
let (b', e2', oes, ts) = step b e2 in
(b', Insert_node(e1, e2', e3), oes, ts)
| Insert_node(e1, e2, e3) ->
let (b', e1', oes, ts) = step b e1 in
(b', Insert_node(e1', e2, e3), oes, ts)
| Remove_node(e1) ->
let (b', e1', oes, ts) = step b e1 in
(b', Remove_node(e1'), oes, ts)
end