(*
** For writing ATS code
** that translates into JavaScript
*)
(* ****** ****** *)
(*
** Permission to use, copy, modify, and distribute this software for any
** purpose with or without fee is hereby granted, provided that the above
** copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
** WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
** ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
** WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
** ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
** OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
(* ****** ****** *)
(*
** Author: Hongwei Xi
** Authoremail: gmhwxi AT gmail DOT com
** Start Time: October, 2015
*)
(* ****** ****** *)
//
staload
"./../../basics_js.sats"
//
(* ****** ****** *)
//
staload
UN = "prelude/SATS/unsafe.sats"
//
(* ****** ****** *)
staload "./../../SATS/Worker/channel.sats"
(* ****** ****** *)
%{^
//
var
theWorker_cont;
//
self.onmessage =
function(event)
{
var k0 = theWorker_cont;
return ats2jspre_cloref2_app(k0, 0, event.data);
}
//
function
ats2js_worker_chanpos0_recv
(chp, k0)
{
theWorker_cont = k0; return;
}
function
ats2js_worker_chanpos0_send
(chp, x0, k0)
{
postMessage(x0); return ats2jspre_cloref1_app(k0, 0);
}
//
function
ats2js_worker_chanpos1_recv
(chp, k0)
{
return ats2js_worker_chanpos0_recv(chp, k0);
}
function
ats2js_worker_chanpos1_send
(chp, x0, k0)
{
return ats2js_worker_chanpos0_send(chp, x0, k0);
}
//
%} // end of [%{^]
(* ****** ****** *)
//
%{^
//
function
ats2js_worker_chanpos0_close(chp) { return self.close(); }
function
ats2js_worker_chanpos1_close(chp) { return self.close(); }
//
%} // end of [%{^]
//
(* ****** ****** *)
//
implement
{a}{b}
rpc_server
(chp, fopr) = let
//
(*
val () = println! ("rpc_server")
*)
//
in
//
chanpos0_recv{a}
( chp
, lam(chp, e) =>
chanpos0_send{b}
( chp
, fopr(chmsg_parse(e))
, lam(chp) => rpc_server_cont(chp, fopr)
)
)
//
end (* end of [rpc_server] *)
(* ****** ****** *)
//
// HX: looping
//
implement
{a}{b}
rpc_server_cont = rpc_server
//
(*
//
// HX: one-time service
//
implement
{a}{b}
rpc_server_cont(chp, fopr) = chanpos0_close(chp)
*)
//
(* ****** ****** *)
//
(*
fun{}
chanpos1_append
{ss1,ss2:type}
(
chanpos(ssappend(ss1,ss2)), k0: chpcont0_nil
, fserv1: chanpos_nullify(ss1), fserv2: chanpos_nullify(ss2)
) : void // end of [chanpos1_append]
*)
//
implement
{}(*tmp*)
chanpos1_append
{ss1,ss2}
(
chp, k0, fserv1, fserv2
) = (
//
fserv1
(
$UN.castvwtp0{chanpos(ss1)}(chp)
, $UN.castvwtp0{chpcont0_nil}(lam(chp:chanpos(ss2)) = fserv2(chp, k0))
) (* end of [fserv1] *)
//
) (* end of [chanpos1_append] *)
//
(* ****** ****** *)
//
implement
{}(*tmp*)
chanpos1_choose_conj
{ss0,ss1}
(chp, k0, fserv0, fserv1) = let
//
val chp0 = $UN.castvwtp0{chanpos()}(chp)
//
in
//
chanpos0_recv
{int}
(
chp0
, lam(chp0, tag0) => let
val tag0 =
chmsg_parse(tag0)
// end of [val]
val ((*void*)) =
chanpos1_choose_conj$fwork_tag(tag0)
// end of [val]
in
case+ tag0 of
| 0 => fserv0($UN.castvwtp0(chp0), k0)
| _ => fserv1($UN.castvwtp0(chp0), k0)
end // end of [lam]
) (* end of [chanpos0_recv] *)
//
end // end of [chanpos1_choose_conj]
//
(* ****** ****** *)
//
implement
{}(*tmp*)
chanpos1_choose_disj
{ss0,ss1}
(chp, k0, fserv0, fserv1) = let
//
val chp0 = $UN.castvwtp0{chanpos()}(chp)
val tag0 = chanpos1_choose_disj$choose()
val ((*void*)) = chanpos1_choose_disj$fwork_tag(tag0)
//
in
//
case+
tag0 of
| 0 =>
chanpos0_send{int}
(
chp0, tag0, lam(chp0) => fserv0($UN.castvwtp0(chp0), k0)
) (* end of [0] *)
| _ =>
chanpos0_send{int}
(
chp0, tag0, lam(chp0) => fserv1($UN.castvwtp0(chp0), k0)
) (* end of [1] *)
//
end // end of [chanpos1_choose_disj]]
//
(* ****** ****** *)
(*
fun{}
chanpos1_option_conj
{ss:type}
(
chanpos(ssconj(ssoption(ss)))
, k0: chpcont0_nil, fserv: chanpos_nullify(ss)
) : void // end of [chanpos1_option_conj]
*)
//
implement
{}(*tmp*)
chanpos1_option_conj
{ss}(chp, k0, fserv) = let
//
val chp0 = $UN.castvwtp0{chanpos()}(chp)
//
in
//
chanpos0_recv
{int}
(
chp0
, lam(chp0, tag0) => let
val tag0 =
chmsg_parse(tag0)
// end of [val]
val ((*void*)) =
chanpos1_option_conj$fwork_tag(tag0)
// end of [val]
in
case+ tag0 of
| 0 => k0($UN.castvwtp0(chp0))
| _ => fserv($UN.castvwtp0(chp0), k0)
end // end of [lam]
) (* end of [chanpos0_recv] *)
//
end // end of [chanpos1_option_conj]
//
(* ****** ****** *)
//
(*
fun{}
chanpos1_option_disj
{ss:type}
(
chanpos(ssdisj(ssoption(ss)))
, k0: chpcont0_nil, fserv: chanpos_nullify(ss)
) : void // end of [chanpos1_option_disj]
*)
//
implement
{}(*tmp*)
chanpos1_option_disj
{ss}(chp, k0, fserv) = let
//
val chp0 = $UN.castvwtp0{chanpos()}(chp)
val tag0 = chanpos1_option_disj$choose()
val ((*void*)) = chanpos1_option_disj$fwork_tag(tag0)
//
in
//
case+
tag0 of
| 0 =>
chanpos0_send{int}(chp0, tag0, $UN.cast{chpcont0()}(k0))
| _ =>
chanpos0_send{int}
(
chp0, tag0, lam(chp0) => fserv($UN.castvwtp0(chp0), k0)
) (* end of [1] *)
//
end // end of [chanpos1_option_disj]]
//
(* ****** ****** *)
//
implement
{}(*tmp*)
chanpos1_option_conj$fwork_tag(tag) = () // nothing is done by default
//
implement
{}(*tmp*)
chanpos1_option_disj$fwork_tag(tag) = () // nothing is done by default
//
(* ****** ****** *)
(*
fun{}
chanpos1_repeat_conj
{ss:type}
(
chanpos(ssconj(ssrepeat(ss)))
, k0: chpcont0_nil, fserv: chanpos_nullify(ss)
) : void // end of [chanpos1_repeat_conj]
*)
//
implement
{}(*tmp*)
chanpos1_repeat_conj
{ss}(chp, k0, fserv) = let
//
typedef
loop =
$d2ctype
(chanpos1_repeat_conj<>)
//
fun
loop: loop =
lam(chp, k0, fserv) => let
val chp0 =
$UN.castvwtp0{chanpos()}(chp)
// end of [val]
in
//
chanpos0_recv
{int}
(
chp0
, lam(chp0, tag0) => let
val tag0 =
chmsg_parse(tag0)
// end of [val]
val ((*void*)) =
chanpos1_repeat_conj$fwork_tag(tag0)
// end of [val]
in
case+ tag0 of
| 0 => k0($UN.castvwtp0(chp0))
| _ => fserv($UN.castvwtp0(chp0), lam(chp) => loop($UN.castvwtp0(chp), k0, fserv))
end // end of [lam]
) (* end of [chanpos0_recv] *)
//
end // end of [loop]
//
val () = chanpos1_repeat_conj$init<>()
//
in
loop(chp, k0, fserv)
end // end of [chanpos1_repeat_conj]
//
(* ****** ****** *)
(*
//
fun{}
chanpos1_repeat_disj
{ss:type}
(
chanpos(ssrepeat(ss))
, k0: chpcont0_nil, fserv: chanpos_nullify(ss)
) : void // end of [chanpos1_repeat_disj]
//
*)
//
implement
{}(*tmp*)
chanpos1_repeat_disj
{ss}(chp, k0, fserv) = let
//
typedef
loop =
$d2ctype
(chanpos1_repeat_disj<>)
//
fun
loop: loop =
lam(chp, k0, fserv) => let
val chp0 =
$UN.castvwtp0{chanpos()}(chp)
val tag0 =
chanpos1_repeat_disj$choose()
// end of [val]
(*
val () = console_log
(
"chanpos1_repeat_disj: loop: tag0 = " + String(tag0)
)
*)
val ((*void*)) =
chanpos1_repeat_disj$fwork_tag(tag0)
// end of [val]
in
//
case+
tag0 of
| 0 =>
chanpos0_send{int}(chp0, tag0, $UN.cast{chpcont0()}(k0))
| _ =>
chanpos0_send{int}
(
chp0, tag0
, lam(chp0) =>
fserv($UN.castvwtp0(chp0), lam(chp) => loop($UN.castvwtp0(chp), k0, fserv))
// end of [lam]
) (* end of [1] *)
//
end // end of [loop]
//
val () = chanpos1_repeat_disj$init<>()
//
in
loop(chp, k0, fserv)
end // end of [chanpos1_repeat_disj]]
//
(* ****** ****** *)
//
implement
{}(*tmp*)
chanpos1_repeat_conj$init() = () // nothing is done by default
//
implement
{}(*tmp*)
chanpos1_repeat_disj$init() = () // nothing is done by default
//
implement
{}(*tmp*)
chanpos1_repeat_conj$fwork_tag(tag) = () // nothing is done by default
//
implement
{}(*tmp*)
chanpos1_repeat_disj$fwork_tag(tag) = () // nothing is done by default
//
(* ****** ****** *)
(* end of [chanpos.dats] *)