ExpandCollapse

+ 1 Control Synopsis

share/lib/std/control/__init__.flx

  // stream is part of datatype, included in std/datatype/__init__
  include "std/control/svc";
  include "std/control/control";
  include "std/control/unique";
  include "std/control/iterator";
  include "std/control/schannels";
  include "std/control/fibres";
  include "std/control/spipes";
  include "std/control/chips";
  
  //include "std/control/mux";
  

+ 2 Misc Control Flow

share/lib/std/control/control.flx

  open class Control
  {
    open C_hack;
  
    // FIXPOINT OPERATOR
    fun fix[D,C] (f:(D->C)->D->C) (x:D) : C => f (fix f) x;
  
    /* Example use: factorial function
    fun flat_fact (g:int->int) (x:int):int =>
      if x == 0 then 1 
      else x * g (x - 1)
    ;
    var fact = fix flat_fact;
    println$ fact 5;
    */
  
    proc _swap[t] (a:&t,b:&t) =
    {
      var tmp = *a;
      a <- *b;
      b <- tmp;
    }
    proc swap[t] (a:&t,b:&t) => _swap(a,b);
  
    infinite loop
    proc forever (bdy:unit->void)
    {
      rpeat:>
        bdy();
        goto rpeat;
      dummy:> // fool reachability checker
    }
  
    publish "do nothing [the name pass comes from Python]"
    proc pass(){}
  
    C style for loop
    proc for_each
      (init:unit->void)
      (cond:unit->bool)
      (incr:unit->void)
      (bdy:unit->void)
    {
      init();
      rpeat:>
        if not (cond()) goto finish;
        bdy();
        incr();
        goto rpeat;
      finish:>
    }
  
    proc branch-and-link (target:&LABEL, save:&LABEL)
    {
       save <- next;
       goto *target;
       next:>
    }
  
    throw[ret, exn] throw exception of type exn
    in a context expecting type ret. 
    gen throw[ret,exn] : exn -> ret = "(throw $1,*(?1*)0)";
    proc raise[exn] : exn = "(throw $1);";
    proc proc_fail:string = 'throw ::std::runtime_error($1);' 
      requires Cxx_headers::stdexcept;
  
    // Note: must be a fun not a gen to avoid lifting.
    fun fun_fail[ret]:string -> ret = '(throw ::std::runtime_error($1),*(?1*)0)' 
      requires Cxx_headers::stdexcept;
  
    This is the type of a Felix procedural
    continuations in C++ lifted into Felix.
    Do not confuse this with the Felix type of the procedure.
    _gc_pointer type cont = "::flx::rtl::con_t*";
  
    fun entry_label : cont -> LABEL = "::flx::rtl::jump_address_t($1)";
    fun current_position : cont -> LABEL = "::flx::rtl::jump_address_t($1,$1->pc)";
    fun entry_label[T] (p:T->0):LABEL => entry_label (C_hack::cast[cont] p);
  
    This is a hack to get the procedural continuation
    currently executing, it is just the procedures
    C++ this pointer.
    fun current_continuation: unit -> cont = "this";
  
    The type of a Felix fthread or fibre, which is
    a container which holds a procedural continuation.
    _gc_pointer type fthread = "::flx::rtl::fthread_t*";
  
  
     Throw a continuation. This is unsafe. It should
     work from a top level procedure, or any function
     called by such a procedure, but may fail
     if thrown from a procedure called by a function.
     The library run and driver will catch the
     continuation and execute it instead of the
     current continuation. If the library run is used
     and the continuation being executed is down the
     C stack, the C stack will not have been correctly
     popped. Crudely, nested drivers should rethrow
     the exception until the C stack is in the correct
     state to execute the continuation, but there is no
     way to determine that at the moment.
      //$  Compiler generated runs ignore the exception,
     the library run catches it. Exceptions typically
     use a non-local goto, and they cannot pass across
     a function boundary.
  
    proc throw_continuation(x: unit->void) { _throw (C_hack::cast[cont] x); }
    private proc _throw: cont = "throw $1;";
  
   }