Skip to content

ATSCC2JS: representations of ATS terms in JS programs

Artyom Shalkhakov edited this page Sep 21, 2017 · 1 revision
  1. option_vt constructor in ATSCC2JS:

this:

//
extern
fun opti(bool): Option_vt(string) = "mac#"
//
implement
opti (x) = if x then Some_vt "hi" else None_vt()
//
extern
fun
hello(): void = "mac#"
implement
hello() = let
  val-~Some_vt(x) = opti(true)
  val () = print_string(x)
  val-~None_vt() = opti(false)
  val x = opti(true)
  val b = (case+ x of ~Some_vt(x) => true | ~None_vt () => false)
in
print("Hello, world!")
end
//

compiles to JS:

function
opti(arg0)
{
//
// knd = 0
  var tmpret0
  var tmplab, tmplab_js
//
  // __patsflab_opti
  if(arg0) {
    tmpret0 = ["hi"];
  } else {
    tmpret0 = null;
  } // end-of-if
  return tmpret0;
} // end-of-function

function
hello()
{
//
// knd = 0
  var tmp2
  var tmp3
  var tmp5
  var tmp6
  var tmp7
  var tmplab, tmplab_js
//
  // __patsflab_hello
  tmp2 = opti(true);
  if(ATSCKptrisnull(tmp2)) {
    ATSINScaseof_fail("/tmp/patsopt_ccats_wTjH9E: 521(line=38, offs=7) -- 545(line=38, offs=31)");
  } // ifthen
  tmp3 = tmp2[0];
  // ATSINSfreecon(tmp2);
  ats2jspre_print_string(tmp3);
  tmp5 = opti(false);
  if(ATSCKptriscons(tmp5)) {
    ATSINScaseof_fail("/tmp/patsopt_ccats_wTjH9E: 579(line=40, offs=7) -- 603(line=40, offs=31)");
  } // ifthen
  tmp6 = opti(true);
  // ATScaseofseq_beg
  tmplab_js = 1;
  while(true) {
    tmplab = tmplab_js; tmplab_js = 0;
    switch(tmplab) {
      // ATSbranchseq_beg
      case 1: // __atstmplab0
      if(ATSCKptrisnull(tmp6)) {
        { tmplab_js = 4; break; }
      } // ifthen
      case 2: // __atstmplab1
      // ATSINSfreecon(tmp6);
      tmp7 = true;
      break;
      // ATSbranchseq_end
      // ATSbranchseq_beg
      case 3: // __atstmplab2
      case 4: // __atstmplab3
      tmp7 = false;
      break;
      // ATSbranchseq_end
    } // end-of-switch
    if (tmplab_js === 0) break;
  } // endwhile
  // ATScaseofseq_end
  ats2jspre_print_string("Hello, world!");
  return/*_void*/;
} // end-of-function
  1. closure-function

this:

extern
fun funny(int, cfun(int,int)): int = "mac#"
//
implement
funny (x, f) = f(x)
//
extern
fun
hello(): void = "mac#"
implement
hello() = let
  val c = 10
  val x = funny(0, lam x =<cloref1> c + (x+1) * 2)
  val () = println!(x)
in
print("Hello, world!")
end

compiles to this JS:

function
__patsfun_2__closurerize(env0)
{
  return [function(cenv, arg0) { return __patsfun_2(cenv[1], arg0); }, env0];
}

function
funny(arg0, arg1)
{
//
// knd = 0
  var tmpret0
  var tmplab, tmplab_js
//
  // __patsflab_funny
  tmpret0 = arg1[0](arg1, arg0);
  return tmpret0;
} // end-of-function

function
hello()
{
//
// knd = 0
  var tmp2
  var tmplab, tmplab_js
//
  // __patsflab_hello
  tmp2 = funny(0, __patsfun_2__closurerize(10));
  ats2jspre_print_int(tmp2);
  ats2jspre_print_newline();
  ats2jspre_print_string("Hello, world!");
  return/*_void*/;
} // end-of-function

function
__patsfun_2(env0, arg0)
{
//
// knd = 0
  var tmpret3
  var tmp4
  var tmp5
  var tmplab, tmplab_js
//
  // __patsflab___patsfun_2
  tmp5 = ats2jspre_add_int0_int0(arg0, 1);
  tmp4 = ats2jspre_mul_int0_int0(tmp5, 2);
  tmpret3 = ats2jspre_add_int0_int0(env0, tmp4);
  return tmpret3;
} // end-of-function

So a ATS closure-function f is represented in JS as an array A. A[0] is the function that, when called with itself (that is, A), evaluates to a function that can be called as usual, by supplying any arguments it might need. The rest of the array contains variables captured by the closure f.

  • calling f in JS: f[0](f, a, ..., z)
  • where a,...,z are any additional arguments
Clone this wiki locally