From 8230355e5e6b2693b0d792e0116f9a18b9fcc853 Mon Sep 17 00:00:00 2001
From: Erwan Jahier <jahier@imag.fr>
Date: Mon, 9 Feb 2015 15:48:26 +0100
Subject: [PATCH] Add a --2c-stack option that uses the stack instead of the
 heap to transfer I/O when calling soc.

Do not work all the times (eg, with arrays it generates C code that
does not compile). cf next changes.
---
 _oasis                   |   2 +-
 src/filenameExtras.ml    |   3 +-
 src/lic2soc.ml           |  15 +-
 src/lv6MainArgs.ml       |  31 +++-
 src/lv6MainArgs.mli      |  10 +-
 src/soc.ml               |   2 +-
 src/soc2c.ml             | 197 +++++++++++++------------
 src/soc2cDep.ml          |  59 ++++++--
 src/soc2cDep.mli         |  17 ++-
 src/soc2cExtern.ml       |   7 +-
 src/soc2cHeap.ml         |  41 +++++-
 src/soc2cHeap.mli        |   6 +-
 src/soc2cIdent.ml        |   2 +-
 src/soc2cStack.ml        | 194 +++++++++++++++++++++++++
 src/soc2cStack.mli       |  41 ++++++
 src/soc2cUtil.ml         |   9 +-
 src/soc2cUtil.mli        |   4 +-
 src/socPredef2cHeap.ml   |   3 +-
 src/socPredef2cStack.ml  | 300 +++++++++++++++++++++++++++++++++++++++
 src/socPredef2cStack.mli |  15 ++
 src/socUtils.ml          |  28 +++-
 src/socUtils.mli         |  18 ++-
 test/Makefile            |   8 +-
 test/lus2lic.sum         |  26 ++--
 test/lus2lic.time        |  16 +--
 test/should_work/ex.lus  |   4 +-
 26 files changed, 883 insertions(+), 175 deletions(-)
 create mode 100644 src/soc2cStack.ml
 create mode 100644 src/soc2cStack.mli
 create mode 100644 src/socPredef2cStack.ml
 create mode 100644 src/socPredef2cStack.mli

diff --git a/_oasis b/_oasis
index 7b440b47..b00cf5db 100644
--- a/_oasis
+++ b/_oasis
@@ -37,5 +37,5 @@ Library "lustre-v6"
   Install:true
   XMETAEnable: true
   XMETADescription: an API to call the Lustre v6 interpreter from ocaml
-  InternalModules: SocExecValue,SocUtils,Lv6util,Lv6version,Lv6errors,Lxm,Lv6MainArgs,Verbose,Soc,SocPredef,Ident,SocExec,SocExecEvalPredef,Compile,AstTab,AstTabSymbol,AstInstanciateModel,Lv6parserUtils,AstV6,FilenameExtras,LicTab,LicDump,AstPredef,Lic,AstCore,LicName,IdSolver,EvalConst,LicEvalConst,LicEvalType,UnifyType,Ast2lic,AstV6Dump,EvalClock,UnifyClock,LicEvalClock,EvalType,LicPrg,LicMetaOp,L2lCheckOutputs,Misc,L2lRmPoly,L2lExpandMetaOp,L2lSplit,L2lExpandNodes,L2lExpandArrays,L2lCheckLoops,Lv6lexer,Lv6parser,AstRecognizePredef,Lic2soc,ActionsDeps,SocVar,Lus2licRun,SortActions
+  InternalModules: SocExecValue,SocUtils,Lv6util,Lv6version,Lv6errors,Lxm,Lv6MainArgs,Verbose,Soc,SocPredef,Ident,SocExec,SocExecEvalPredef,Compile,AstTab,AstTabSymbol,AstInstanciateModel,Lv6parserUtils,AstV6,FilenameExtras,LicTab,LicDump,AstPredef,Lic,AstCore,LicName,IdSolver,EvalConst,LicEvalConst,LicEvalType,UnifyType,Ast2lic,AstV6Dump,EvalClock,UnifyClock,LicEvalClock,EvalType,LicPrg,LicMetaOp,L2lCheckOutputs,Misc,L2lRmPoly,L2lExpandMetaOp,L2lSplit,L2lExpandNodes,L2lExpandArrays,L2lCheckLoops,L2lCheckMemSafe,L2lOptimIte,Lv6lexer,Lv6parser,AstRecognizePredef,Lic2soc,Action,ActionsDeps,SocVar,Lus2licRun,SortActions
 # Comment se passer de cette liste à la Prevert ?
diff --git a/src/filenameExtras.ml b/src/filenameExtras.ml
index 3efdb568..d0f8fcbc 100644
--- a/src/filenameExtras.ml
+++ b/src/filenameExtras.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 11/12/2012 (at 15:29) by Erwan Jahier> *)
+(* Time-stamp: <modified the 05/02/2015 (at 17:31) by Erwan Jahier> *)
 
 
 let (to_list : string -> string list) =
@@ -62,3 +62,4 @@ let _ =
   assert(simplify "/home/./name/././././dir/.././../file" = "/home/file");
   assert(simplify "" = "./."); (* hum, that one is not simpler... *)
   assert(simplify "./a/b/../../../x" = "./../x")
+    
diff --git a/src/lic2soc.ml b/src/lic2soc.ml
index 6051eddf..814b81cd 100644
--- a/src/lic2soc.ml
+++ b/src/lic2soc.ml
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 19/01/2015 (at 14:13) by Erwan Jahier> *)
+(** Time-stamp: <modified the 06/02/2015 (at 14:28) by Erwan Jahier> *)
 
 (* XXX ce module est mal écrit. A reprendre. (R1) *)
  
@@ -424,17 +424,8 @@ let soc_step_to_operation:
 let (action_of_step : Lxm.t -> Soc.t -> Lic.clock -> Soc.var_expr list -> 
       Soc.var_expr list -> Soc.instance option -> Soc.step_method -> action) =
   fun lxm c clk il ol mem step ->
-    let local_nth i l = 
-      try List.nth l i 
-      with _ -> 
-        print_string (
-          "\n*** Cannot get the " ^ (string_of_int (i+1)) ^ 
-            "th element of a list of size " ^ (string_of_int (List.length l))^"\n");
-        flush stdout;
-        assert false 
-    in
-    let inputs  = List.map (fun i -> local_nth i il) step.Soc.idx_ins  in
-    let outputs = List.map (fun i -> local_nth i ol) step.Soc.idx_outs in
+    let inputs  = SocUtils.filter_step_params step.Soc.idx_ins  il in
+    let outputs = SocUtils.filter_step_params step.Soc.idx_outs ol in
     let call_action = soc_step_to_operation step.Soc.name c mem in
       (clk, inputs, outputs, call_action, step.Soc.lxm)
 
diff --git a/src/lv6MainArgs.ml b/src/lv6MainArgs.ml
index 545b55e4..89badcc6 100644
--- a/src/lv6MainArgs.ml
+++ b/src/lv6MainArgs.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 22/01/2015 (at 11:10) by Erwan Jahier> *)
+(* Time-stamp: <modified the 09/02/2015 (at 16:10) by Erwan Jahier> *)
 (*
 Le manager d'argument adapté de celui de lutin, plus joli
 N.B. solution un peu batarde : les options sont stockées, comme avant, dans Global,
@@ -11,8 +11,9 @@ open Arg
 let tool_name = Lv6version.tool
 let usage_msg =  "usage: "^tool_name^" [options] <file> | "^tool_name^" -help"
 
-type c_code_gen_kind = Heap
 type enum_mode = AsInt | AsConst | AsEnum
+type io_transmit_mode = Stack | Heap | HeapStack
+
 type t = {
   mutable opts : (string * Arg.spec * string) list; (* classical Arg option tab used by Arg.parse *)
   mutable user_man  : (string * string list) list; (* ad hoc tab for pretty prtting usage *)
@@ -54,8 +55,8 @@ type global_opt = {
   mutable current_file :  string;
   mutable line_num : int;
   mutable line_start_pos : int;
-  mutable c_code_gen : c_code_gen_kind;
   mutable soc2c_no_switch : bool;
+  mutable io_transmit_mode : io_transmit_mode;
 }
 let (global_opt:global_opt) =
   {
@@ -69,8 +70,8 @@ let (global_opt:global_opt) =
     line_start_pos = 0;
     current_file =  "";
     expand_enums =  AsInt;
-    c_code_gen = Heap;
-    soc2c_no_switch = false
+    soc2c_no_switch = false;
+    io_transmit_mode = Heap;
   }
 let (make_opt : unit -> t) = 
   fun () -> 
@@ -358,9 +359,25 @@ let mkoptab (opt:t) : unit = (
     *)
     mkopt opt ~hide:true
       ["-cc"]
-      (Arg.Unit (fun i -> opt.launch_cc <- true))
-      ["Try to compile the generated C files (requires -2c)"]
+      (Arg.Unit (fun i -> opt.gen_c <- true; opt.launch_cc <- true))
+      ["Try to compile the generated C files (forces -2c)"]
+    ;
+    mkopt opt ~hide:true
+      ["-2cs";"--2c-stack"]
+      (Arg.Unit (fun i -> opt.gen_c <- true; global_opt.io_transmit_mode <- Stack))
+      ["Soc I/O are transmitted as params of the step functions (forces -2c)"]
+    ;
+    mkopt opt ~hide:true
+      ["--2c-heap"]
+      (Arg.Unit (fun i -> opt.gen_c <- true; global_opt.io_transmit_mode <- Heap))
+      ["Soc I/O are transmitted via a ctx structure in the heap (forces -2c)"]
+    ;
+    mkopt opt ~hide:true
+      ["-2chs";"--2c-heap-and-stack"]
+      (Arg.Unit (fun i -> opt.gen_c <- true; global_opt.io_transmit_mode <- HeapStack))
+      ["I/O of memoryless soc are transmitted via the stack, and the heap otherwise (forces -2c)"]
     ;
+
     mkopt opt ~hide:true
       ["--2c-no-switch"]
       (Arg.Unit (fun () -> global_opt.soc2c_no_switch <-true))
diff --git a/src/lv6MainArgs.mli b/src/lv6MainArgs.mli
index 3da308ad..c9911ca7 100644
--- a/src/lv6MainArgs.mli
+++ b/src/lv6MainArgs.mli
@@ -9,8 +9,12 @@ type enum_mode =
    les options dans des var. globales ! (cf Global
 *)
 
-type c_code_gen_kind = Heap
-
+type io_transmit_mode =
+  | Stack (* All I/O are are passed as arguments of the step functions *)
+  | Heap  (* All I/O are in a ctx structure; ctx of memoryless soc are global *)
+  | HeapStack  (* I/O of memoryful soc are in a ctx structure; memoryless soc uses step arg *)
+(* *)
+      
 type t = {
   mutable opts : (string * Arg.spec * string) list; (* classical Arg option tab used by Arg.parse *)
   mutable user_man  : (string * string list) list; (* ad hoc tab for pretty prtting usage *)
@@ -51,8 +55,8 @@ type global_opt = {
   mutable current_file :  string;
   mutable line_num : int;
   mutable line_start_pos : int;
-  mutable c_code_gen : c_code_gen_kind;
   mutable soc2c_no_switch : bool;
+  mutable io_transmit_mode : io_transmit_mode;
 }
 val paranoid : Verbose.flag 
 
diff --git a/src/soc.ml b/src/soc.ml
index 641d2b5a..ade7eea1 100644
--- a/src/soc.ml
+++ b/src/soc.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 06/01/2015 (at 11:35) by Erwan Jahier> *)
+(* Time-stamp: <modified the 28/01/2015 (at 15:22) by Erwan Jahier> *)
 
 (** Synchronous Object Component *)
 
diff --git a/src/soc2c.ml b/src/soc2c.ml
index f79d653f..973fe52c 100644
--- a/src/soc2c.ml
+++ b/src/soc2c.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 21/01/2015 (at 17:50) by Erwan Jahier> *)
+(* Time-stamp: <modified the 09/02/2015 (at 15:08) by Erwan Jahier> *)
 
 
 (* let put (os: out_channel) (fmt:('a, unit, string, unit) format4) : 'a = *)
@@ -41,11 +41,6 @@ type 'a soc_pp = {
 let (string_of_soc_key : Soc.key -> string) =
   fun (name,_,_) ->  (id2s name)
 
-let string_of_flow_decl (id, t) = 
-  Printf.sprintf "   %s;\n" (Soc2cUtil.type_to_string t (id2s id)) 
-
-
-let (is_memory_less : Soc.t -> bool) = SocUtils.is_memory_less
 
 let string_of_var_expr = Soc2cDep.string_of_var_expr
 open Soc
@@ -69,7 +64,8 @@ let (gao2c : Soc.tbl -> 'a soc_pp -> Soc.gao -> unit) =
           let ctx_opt = 
             let il,ol = sp.soc.profile in
             if List.mem_assoc id il || List.mem_assoc id ol then
-              (if SocUtils.is_memory_less sp.soc then Soc2cUtil.ML_IO sp.soc.key 
+              (if SocUtils.ctx_is_global sp.soc 
+               then Soc2cUtil.ML_IO sp.soc.key 
                else Soc2cUtil.M_IO)
             else Soc2cUtil.Local 
           in
@@ -109,20 +105,15 @@ let (step2c : Soc.tbl -> 'a soc_pp -> Soc.step_method -> unit) =
     if inlined_soc sp.soc then () (* don't generate code if inlined *) else
     (*     let sname = Soc2cDep.step_name sp.soc.key sm.name in *)
       let sname = Soc2cDep.step_name sp.soc.key sm.name in
-      let ctx = if is_memory_less sp.soc then "" else
-          Printf.sprintf "%s_type* ctx" (get_ctx_name sp.soc.key)
-      in
-      let ctx_decl = if is_memory_less sp.soc then "" else
-          Printf.sprintf "%s_type*" (get_ctx_name sp.soc.key)
-      in
       if sm.impl<>Extern then (
-        sp.hput (Printf.sprintf "void %s(%s);\n" sname ctx_decl);
-        sp.cput (Printf.sprintf "void %s(%s){\n" sname ctx);
+        let decl, def = Soc2cDep.get_step_prototype sm sp.soc in
+        sp.hput (Printf.sprintf "%s\n" decl);
+        sp.cput (Printf.sprintf "%s\n" def);
         (match sm.impl with
           | Extern -> ()
           | Predef -> sp.cput (Soc2cDep.get_predef_op sp.soc.key)
           | Gaol(vl, gaol) -> (
-            List.iter (fun v -> sp.cput (string_of_flow_decl v)) vl ; 
+            List.iter (fun v -> sp.cput (Soc2cUtil.string_of_flow_decl v)) vl ; 
             sp.cput "\n"; 
             List.iter (gao2c stbl sp) gaol
           )
@@ -153,9 +144,9 @@ let (soc2c: int -> out_channel -> out_channel -> Soc.tbl -> Soc.t -> unit) =
     let ctx_name_type = ctx_name^"_type" in    
     if pass=1 then (
        (* Only for ctx of memoryless nodes + main node *)
-      if is_memory_less soc then cfmt "%s %s;\n" ctx_name_type ctx_name;
+      if SocUtils.ctx_is_global soc then cfmt "%s %s;\n" ctx_name_type ctx_name;
     ) else (
-      if is_memory_less soc then () else (
+      if SocUtils.is_memory_less soc then () else (
         cfmt "// Memory initialisation for %s\n" ctx_name;
         hfmt "void %s_reset(%s_type* ctx);\n" ctx_name ctx_name;
         cfmt "void %s_reset(%s_type* ctx){" ctx_name ctx_name;
@@ -171,16 +162,20 @@ let (soc2c: int -> out_channel -> out_channel -> Soc.tbl -> Soc.t -> unit) =
         cfmt "
 }
 ";      
-        cfmt "// Memory allocation for %s\n" ctx_name;
-        hfmt "%s_type* %s_new_ctx();\n" ctx_name ctx_name;
-        cfmt "%s_type* %s_new_ctx(){" ctx_name ctx_name;
-        cfmt "
+        if
+          SocUtils.is_memory_less soc
+        then () (*no ctx at all in this case ! *) else (
+          cfmt "// Memory allocation for %s\n" ctx_name;
+          hfmt "%s_type* %s_new_ctx();\n" ctx_name ctx_name;
+          cfmt "%s_type* %s_new_ctx(){" ctx_name ctx_name;
+          cfmt "
    %s_type* ctx = (%s_type*)calloc(1, sizeof(%s_type));
    // ctx->client_data = cdata;
    %s_reset(ctx);
    return ctx;
 }
-" ctx_name ctx_name ctx_name ctx_name) ;
+" ctx_name ctx_name ctx_name ctx_name) 
+      );
       cfmt "// Step function(s) for %s\n" ctx_name;
       List.iter (step2c stbl sp) soc.step;
       ()
@@ -202,31 +197,6 @@ let (type_to_format_string : Data.t -> string) =
 
 (****************************************************************************)
 
-let (typedef_of_soc : Soc.t -> string) =
-  fun soc -> 
-    if inlined_soc soc then ""  (* don't generate code if inlined *) else
-    let ctx_name = get_ctx_name soc.key in
-    let ctx_name_type = ctx_name^"_type" in    
-    let il,ol = soc.profile in
-    let str = Printf.sprintf  "/* %s */\ntypedef struct {\n   /*INPUTS*/\n" ctx_name in
-    let str = List.fold_left (fun acc v -> acc^ (string_of_flow_decl v)) str il in
-    let str = str ^ "   /*OUTPUTS*/\n" in
-    let str = List.fold_left (fun acc v -> acc^ (string_of_flow_decl v)) str ol in
-    let str = str ^
-      (match soc.memory with
-        | No_mem -> ""
-        | Mem t -> 
-          Printf.sprintf "   /*Memory cell*/\n   %s ;\n" (id2s (Soc2cUtil.type_to_string t "_memory"))
-        | Mem_hidden -> ""
-      )
-    in
-    let str =  str ^ (if soc.instances <> [] then  "   /*INSTANCES*/\n" else "") in
-    let string_of_instance (id,sk) = 
-      Printf.sprintf "   %s_type %s;\n" (get_ctx_name sk) (id2s id)
-    in
-    let str =  List.fold_left (fun acc inst -> acc^(string_of_instance inst)) str soc.instances in
-    let str = Printf.sprintf  "%s} %s;\n\n" str ctx_name_type in
-    str
 
 module KeySet = Set.Make(struct type t = Soc.key let compare = compare end)
 module ItemKeySet = Set.Make(struct type t = Lic.item_key let compare = compare end)
@@ -273,11 +243,11 @@ let (typedef : LicPrg.t -> Soc.tbl -> Soc.t -> string) =
               )
               (acc,visited) soc.instances
           in
-          let acc = acc ^ (typedef_of_soc soc) in
+          let acc = acc ^ (Soc2cDep.typedef_of_soc soc) in
           acc,visited
     in
     let soc_ctx_typedef_with = 
-      if is_memory_less main_soc then "" else fst (soc_with_mem ("",visited) main_soc)
+      if SocUtils.ctx_is_global main_soc then "" else fst (soc_with_mem ("",visited) main_soc)
     in
     (* Then we still have to print memoryless soc that can not appear
        as a soc instance *)
@@ -285,7 +255,7 @@ let (typedef : LicPrg.t -> Soc.tbl -> Soc.t -> string) =
       let socs = Soc.SocMap.bindings soc_tbl in
       let socs = snd (List.split socs) in
       let memless_soc_to_string acc soc =
-        if is_memory_less soc then acc^(typedef_of_soc soc) else acc
+        if SocUtils.is_memory_less soc then acc^(Soc2cDep.typedef_of_soc soc) else acc
       in 
       List.fold_left  memless_soc_to_string "" socs
     in 
@@ -354,22 +324,29 @@ let (constdef : LicPrg.t -> string) =
         (long2s k)
         (const_to_c c)
     in
-    LicPrg.fold_consts (fun k t acc -> acc ^ (to_c k t)) licprg  "\n// Constant definitions \n"
+    let str = LicPrg.fold_consts (fun k t acc -> acc ^ (to_c k t)) licprg  "" in
+    if str = "" then "" else
+      "\n// Constant definitions \n" ^ str
 
 
 (****************************************************************************)
 
 let (gen_memoryless_ctx : Soc.tbl -> string) =
   fun stbl -> 
-    let acc = Printf.sprintf "\n// Allocation of memoryless ctx\n" in
     let do_soc sk soc acc =
-      if is_memory_less soc && not (inlined_soc soc) then 
+      if (SocUtils.ctx_is_global soc) && not (inlined_soc soc) then 
         let ctx_name = get_ctx_name soc.key in
         let ctx_name_type = ctx_name^"_type" in    
         Printf.sprintf "%sextern %s %s;\n" acc ctx_name_type ctx_name 
-      else acc
+      else
+        acc
     in
-    Soc.SocMap.fold do_soc stbl acc
+    let acc = Soc.SocMap.fold do_soc stbl "" in
+    if acc = "" then "" else 
+      Printf.sprintf "\n// Allocation of memoryless ctx\n%s" acc
+
+(* a shortcut *)
+let io_transmit_mode () = Lv6MainArgs.global_opt.Lv6MainArgs.io_transmit_mode
       
 (****************************************************************************)
 let (gen_loop_file : Soc.t -> out_channel -> Soc.tbl -> unit) =
@@ -491,13 +468,29 @@ void "^n^"_O_n(void* cdata, _integer _V) {
 }"^ (gen_memoryless_ctx stbl) ^
 "/* Main procedure *************************/
 int main(){
-   
-   int s = 0;
-   /* Context allocation */
-   "^ctx^"_type* ctx = "^(if is_memory_less soc then (
-     "&"^ ctx^ ";"
-   ) else (ctx^"_new_ctx(NULL);")));
-
+  int s = 0;" ^ (
+      match io_transmit_mode () with
+        | Lv6MainArgs.Stack ->
+          let to_c_decl (n,t) = ((Soc2cUtil.type_to_string t "")^ " " ^n^";\n  ") in
+          let inputs_t  = List.map to_c_decl inputs_io in
+          let outputs_t = List.map to_c_decl outputs_io in
+          let inputs_decl = Printf.sprintf "\n  %s" (String.concat "" inputs_t) in
+          let outputs_decl = Printf.sprintf "%s" (String.concat "" outputs_t) in
+          let ctx_decl = if SocUtils.is_memory_less soc then "" else 
+              ctx^"_type* ctx ;\n  "^ ctx^"_reset(ctx);"
+          in
+          inputs_decl ^ outputs_decl ^ ctx_decl
+        | Lv6MainArgs.Heap -> ("
+          /* Context allocation */
+  " ^ (if SocUtils.is_memory_less soc then ctx^"_type* ctx = &"^ctx^";\n"
+    else ctx^"_type* ctx = "^ ctx^"_new_ctx(NULL);")
+        )
+        | Lv6MainArgs.HeapStack -> ("
+          /* Context allocation */
+  " ^ (if SocUtils.is_memory_less soc then ctx^""
+    else ctx^"_type* ctx ;\n"^ ctx^"_reset(ctx);")
+        )
+    ));
     let to_rif_decl (n,t) = ("\\\""^n^"\\\":" ^(type_to_string t)) in
     let inputs_t  = List.map to_rif_decl inputs_io in
     let outputs_t = List.map to_rif_decl outputs_io in
@@ -505,43 +498,65 @@ int main(){
     let outputs_decl = Printf.sprintf "#outputs %s" (String.concat " " outputs_t) in
     
     putc  ("
-    printf(\""^inputs_decl^"\\n\");
-    printf(\""^outputs_decl^"\\n\");
-
-   /* Main loop */
-   ISATTY = isatty(0);
-   while(1){
-      if (ISATTY) printf(\"#step %d \\n\", s+1);
-      else if(s) printf(\"\\n\");
-      fflush(stdout);
-      ++s;
+  printf(\""^inputs_decl^"\\n\");
+  printf(\""^outputs_decl^"\\n\");
+
+  /* Main loop */
+  ISATTY = isatty(0);
+  while(1){
+    if (ISATTY) printf(\"#step %d \\n\", s+1);
+    else if(s) printf(\"\\n\");
+    fflush(stdout);
+    ++s;
 ");
     List.iter (fun (id,t) -> 
       let t = type_to_string2 t in
-      let str = Printf.sprintf "      ctx->%s = _get_%s(\"%s\");\n" id t id in
+      let str = 
+        if io_transmit_mode () = Lv6MainArgs.Stack 
+        then Printf.sprintf "    %s = _get_%s(\"%s\");\n" id t id 
+        else Printf.sprintf "    ctx->%s = _get_%s(\"%s\");\n" id t id 
+      in
       putc str
     ) 
       inputs;
     let inputs_fmt  = List.map (fun (_,t) -> type_to_format_string t) inputs in
     let outputs_fmt = List.map (fun (_,t) -> type_to_format_string t) outputs in
-    putc ("      " ^ step^"(ctx);
-      // printf(\"" ^ (String.concat " " inputs_fmt)^ " #outs " ^ 
-             (String.concat " " outputs_fmt)^ "\\n\"," ^
-             (String.concat "," (List.map (fun (id,_) -> "ctx->"^id ) (inputs@outputs)))^ 
-            ");
-      printf(\"" ^ 
-             (String.concat " " outputs_fmt)^ "\\n\"," ^
+    if io_transmit_mode () = Lv6MainArgs.Stack 
+    then
+      let i =  fst (List.split inputs_io) in
+      let o =  fst (List.split outputs_io) in
+      let o =  List.map (fun s -> "&"^s) o in      
+      let io = String.concat "," (i@o) in
+      let io = if SocUtils.is_memory_less soc then io else if io = "" then "ctx" else io^",ctx" in
+      putc ("    " ^ step^"("^io^");
+    // printf(\"" ^ (String.concat " " inputs_fmt)^ " #outs " ^ 
+               (String.concat " " outputs_fmt)^ "\\n\"," ^
+               (String.concat "," (List.map (fun (id,_) -> ""^id ) (inputs@outputs)))^ 
+               ");
+    printf(\"" ^ 
+               (String.concat " " outputs_fmt)^ "\\n\"," ^
+               (String.concat "," (List.map (fun (id,_) -> ""^id ) (outputs)))^ 
+               ");
+  }"
+    ) else (
+      putc ("    " ^ step^"(ctx);
+    // printf(\"" ^ (String.concat " " inputs_fmt)^ " #outs " ^ 
+               (String.concat " " outputs_fmt)^ "\\n\"," ^
+               (String.concat "," (List.map (fun (id,_) -> "ctx->"^id ) (inputs@outputs)))^ 
+               ");
+    printf(\"" ^ 
+               (String.concat " " outputs_fmt)^ "\\n\"," ^
              (String.concat "," (List.map (fun (id,_) -> "ctx->"^id ) (outputs)))^ 
-            ");
-   }
-   return 1;
+             ");
+  }"));
+    putc "\n  return 1;
    
 }
-")  
+"
 
 (****************************************************************************)
 (* The entry point for lus2lic --to-c *)
-let (f : Lv6MainArgs.t -> Soc.key -> Soc.tbl -> LicPrg.t -> unit) =
+           let (f : Lv6MainArgs.t -> Soc.key -> Soc.tbl -> LicPrg.t -> unit) =
   fun args msoc stbl licprg -> 
     let socs = Soc.SocMap.bindings stbl in
     let socs = snd (List.split socs) in 
@@ -597,10 +612,12 @@ typedef float _float;
     putc (constdef licprg);
 (*     putc (Soc2cExtern.cpy_declaration licprg); *)
     putc (Soc2cExtern.const_declaration licprg);
-    puth "/////////////////////////////////////////////////\n";
-    puth "//// Static allocation of memoryless soc ctx\n";
-    List.iter (soc2c 1 och occ stbl) socs;
-    puth "/////////////////////////////////////////////////\n";
+    if io_transmit_mode () = Lv6MainArgs.Heap then (
+      puth "/////////////////////////////////////////////////\n";
+      puth "//// Static allocation of memoryless soc ctx\n";
+      List.iter (soc2c 1 och occ stbl) socs;
+      puth "/////////////////////////////////////////////////\n"
+    );
     putc "//// Defining step functions\n";
     List.iter (soc2c 2 och occ stbl) socs;
     
diff --git a/src/soc2cDep.ml b/src/soc2cDep.ml
index c07de43d..54862e01 100644
--- a/src/soc2cDep.ml
+++ b/src/soc2cDep.ml
@@ -1,48 +1,77 @@
-(* Time-stamp: <modified the 21/01/2015 (at 17:52) by Erwan Jahier> *)
+(* Time-stamp: <modified the 06/02/2015 (at 10:52) by Erwan Jahier> *)
 
 open Lv6MainArgs
 
-let gen_assign x         = 
-  match global_opt.c_code_gen with 
-    | Heap -> Soc2cHeap.gen_assign x
-
 let gen_assign_var_expr x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> Soc2cHeap.gen_assign_var_expr x
+    | HeapStack -> Soc2cHeap.gen_assign_var_expr x
+    | Stack ->  Soc2cStack.gen_assign_var_expr x 
 
 let step_name x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> Soc2cHeap.step_name x
+    | HeapStack -> Soc2cHeap.step_name x 
+    | Stack ->  Soc2cStack.step_name x  
+
+let get_step_prototype x y =
+  match global_opt.io_transmit_mode with 
+    | Heap -> Soc2cHeap.get_step_prototype x y
+    | HeapStack -> Soc2cHeap.get_step_prototype x y
+    | Stack ->  Soc2cStack.get_step_prototype x  y
 
 let string_of_var_expr x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> Soc2cHeap.string_of_var_expr x
+    | HeapStack -> Soc2cHeap.string_of_var_expr x 
+    | Stack ->  Soc2cStack.string_of_var_expr x  
 
 let ctx_var x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> Soc2cHeap.ctx_var x
+    | HeapStack -> Soc2cHeap.ctx_var x 
+    | Stack ->  Soc2cStack.ctx_var x  
 
 
 let gen_step_call x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> Soc2cHeap.gen_step_call x
+    | HeapStack -> Soc2cHeap.gen_step_call x 
+    | Stack ->  Soc2cStack.gen_step_call x  
 
 let inlined_soc x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> Soc2cHeap.inlined_soc x
+    | HeapStack -> Soc2cHeap.inlined_soc x 
+    | Stack ->  Soc2cStack.inlined_soc x  
 
+let typedef_of_soc x =  
+  match global_opt.io_transmit_mode with 
+    | Heap -> Soc2cHeap.typedef_of_soc x
+    | HeapStack -> Soc2cHeap.typedef_of_soc x 
+    | Stack -> Soc2cStack.typedef_of_soc x  
 
 
 let get_predef_op x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> SocPredef2cHeap.get_predef_op x
+    | HeapStack -> SocPredef2cHeap.get_predef_op x 
+    | Stack -> SocPredef2cStack.get_predef_op x  
 let get_iterator x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> SocPredef2cHeap.get_iterator x
+    | HeapStack -> SocPredef2cHeap.get_iterator x 
+    | Stack -> SocPredef2cStack.get_iterator x  
 let get_condact x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> SocPredef2cHeap.get_condact x
+    | HeapStack -> SocPredef2cHeap.get_condact x 
+    | Stack -> SocPredef2cStack.get_condact x  
 let get_boolred x =  
-  match global_opt.c_code_gen with 
+  match global_opt.io_transmit_mode with 
     | Heap -> SocPredef2cHeap.get_boolred x
+    | HeapStack -> SocPredef2cHeap.get_boolred x 
+    | Stack -> SocPredef2cStack.get_boolred x  
+
+
 
diff --git a/src/soc2cDep.mli b/src/soc2cDep.mli
index c46d6325..d1350f6e 100644
--- a/src/soc2cDep.mli
+++ b/src/soc2cDep.mli
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 03/10/2014 (at 11:17) by Erwan Jahier> *)
+(* Time-stamp: <modified the 06/02/2015 (at 11:07) by Erwan Jahier> *)
 
 
 (** Choose between the various C code generators (heap-based, Stack
@@ -8,16 +8,21 @@
     with this name...  *)
 
 
-(* [gen_assign t vi vo size] generated the C code that assign vo to vi,
-   using memcpy or = depending on the type t *)
-val gen_assign : Data.t  -> string -> string -> string -> string
-
 (* ditto *)
 val gen_assign_var_expr : Soc.t -> Soc.var_expr -> Soc.var_expr -> string
 
 (* Generates the C step name from the soc key and the soc step name *)
 val step_name : Soc.key -> string -> string
 
+(* returns the step declaration (to put in the .h) and step header
+    (to put in the .c) 
+   For instance , something like:
+   "void step(ctx_type, int, int, int* );",  
+   "void step(ctx_type ctx, int x, int y,int* z){",  
+*)
+val get_step_prototype : Soc.step_method -> Soc.t -> string * string
+
+
 val string_of_var_expr: Soc.t -> Soc.var_expr -> string
 
 
@@ -51,4 +56,6 @@ val get_condact : Soc.t -> Soc.t -> Soc.var_expr list -> string
 (** Returns the C code implementing a boolred *)
 val get_boolred : Soc.t -> int -> int -> int -> string 
 
+val typedef_of_soc : Soc.t -> string
+
 
diff --git a/src/soc2cExtern.ml b/src/soc2cExtern.ml
index b8babd3b..832c0057 100644
--- a/src/soc2cExtern.ml
+++ b/src/soc2cExtern.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 03/10/2014 (at 17:41) by Erwan Jahier> *)
+(* Time-stamp: <modified the 06/02/2015 (at 16:07) by Erwan Jahier> *)
 
 open Soc2cIdent
 
@@ -25,6 +25,7 @@ let (type_decl : LicPrg.t -> string) =
     let str = LicPrg.fold_types type_to_string prg "" in
     if str = "" then "" else (preambule^""^str^"\n")
 
+
 (* Now done in soc2cGenAssign.ml
 let (cpy_def : LicPrg.t -> string) =
   fun prg -> 
@@ -121,7 +122,7 @@ let (gen_files : Soc.t -> Soc.tbl -> LicPrg.t -> string -> string-> string -> bo
 (*         output_string ext_och (cpy_decl licprg); *)
         List.iter (fun (sm,soc) -> 
           let sname = Soc2cDep.step_name soc.key sm.name in
-          if SocUtils.is_memory_less soc then 
+          if SocUtils.ctx_is_global soc then 
             output_string ext_och (Printf.sprintf "void %s();\n" sname)
           else
             let ctx = get_ctx_name soc.key in
@@ -139,7 +140,7 @@ let (gen_files : Soc.t -> Soc.tbl -> LicPrg.t -> string -> string-> string -> bo
         output_string ext_occ (const_def licprg);
         List.iter (fun (sm,soc) -> 
           let sname = Soc2cDep.step_name soc.key sm.name in
-          if SocUtils.is_memory_less soc then 
+          if SocUtils.ctx_is_global soc then 
             output_string ext_occ (Printf.sprintf "void %s(){\n   /* finish me! */\n}\n" sname)
           else
             let ctx = get_ctx_name soc.key in
diff --git a/src/soc2cHeap.ml b/src/soc2cHeap.ml
index 14ca58a5..6c9d2224 100644
--- a/src/soc2cHeap.ml
+++ b/src/soc2cHeap.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 03/10/2014 (at 18:03) by Erwan Jahier> *)
+(* Time-stamp: <modified the 06/02/2015 (at 16:08) by Erwan Jahier> *)
 
 open Soc2cUtil
 open Soc2cIdent
@@ -153,3 +153,42 @@ let (gen_step_call : Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list ->
         in
         let str = Printf.sprintf "  %s(%s); \n" (step_name called_soc.key sname) step_arg in
         (si_str ^ str ^ so_str)
+
+(* exported *) 
+let (typedef_of_soc : Soc.t -> string) =
+  fun soc -> 
+    if inlined_soc soc then ""  (* don't generate code if inlined *) else
+    let ctx_name = get_ctx_name soc.key in
+    let ctx_name_type = ctx_name^"_type" in    
+    let il,ol = soc.profile in
+    let str = Printf.sprintf  "/* %s */\ntypedef struct {\n   /*INPUTS*/\n" ctx_name in
+    let str = List.fold_left (fun acc v -> acc^ (string_of_flow_decl v)) str il in
+    let str = str ^ "   /*OUTPUTS*/\n" in
+    let str = List.fold_left (fun acc v -> acc^ (string_of_flow_decl v)) str ol in
+    let str = str ^
+      (match soc.memory with
+        | No_mem -> ""
+        | Mem t -> 
+          Printf.sprintf "   /*Memory cell*/\n   %s ;\n" (id2s (Soc2cUtil.type_to_string t "_memory"))
+        | Mem_hidden -> ""
+      )
+    in
+    let str =  str ^ (if soc.instances <> [] then  "   /*INSTANCES*/\n" else "") in
+    let string_of_instance (id,sk) = 
+      Printf.sprintf "   %s_type %s;\n" (get_ctx_name sk) (id2s id)
+    in
+    let str =  List.fold_left (fun acc inst -> acc^(string_of_instance inst)) str soc.instances in
+    let str = Printf.sprintf  "%s} %s;\n\n" str ctx_name_type in
+    str
+
+let (get_step_prototype : Soc.step_method -> Soc.t -> string * string) =
+  fun sm soc ->
+    let sname = step_name soc.key sm.name in
+    let ctx = if SocUtils.is_memory_less soc then "" else
+        Printf.sprintf "%s_type* ctx" (get_ctx_name soc.key)
+    in
+    let ctx_decl = if SocUtils.is_memory_less soc then "" else
+        Printf.sprintf "%s_type*" (get_ctx_name soc.key)
+    in
+    Printf.sprintf "void %s(%s);\n" sname ctx_decl,
+    Printf.sprintf "void %s(%s){\n" sname ctx 
diff --git a/src/soc2cHeap.mli b/src/soc2cHeap.mli
index 4e382cc1..bffcc930 100644
--- a/src/soc2cHeap.mli
+++ b/src/soc2cHeap.mli
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 03/10/2014 (at 10:17) by Erwan Jahier> *)
+(* Time-stamp: <modified the 06/02/2015 (at 11:07) by Erwan Jahier> *)
 
 (** Gathers all entities (functions, types) that implement the
     heap-based C generator.  *)
@@ -13,6 +13,8 @@ val gen_assign_var_expr : Soc.t -> Soc.var_expr -> Soc.var_expr -> string
 (* Generates the C step name from the soc key and the soc step name *)
 val step_name : Soc.key -> string -> string
 
+val get_step_prototype : Soc.step_method -> Soc.t -> string * string
+
 val string_of_var_expr: Soc.t -> Soc.var_expr -> string
 
 
@@ -32,3 +34,5 @@ val gen_step_call : Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list ->
      string -> string -> string -> string
 (* should this soc be inlined? (depends on Lv6MainArgs.global_opt) *)
 val inlined_soc : Soc.t -> bool
+
+val typedef_of_soc : Soc.t -> string
diff --git a/src/soc2cIdent.ml b/src/soc2cIdent.ml
index fcd2826b..13eaf6b1 100644
--- a/src/soc2cIdent.ml
+++ b/src/soc2cIdent.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 27/01/2015 (at 10:31) by Erwan Jahier> *)
+(* Time-stamp: <modified the 28/01/2015 (at 15:18) by Erwan Jahier> *)
 open Soc
 
 let colcol = Str.regexp "::"
diff --git a/src/soc2cStack.ml b/src/soc2cStack.ml
new file mode 100644
index 00000000..ebb2a2de
--- /dev/null
+++ b/src/soc2cStack.ml
@@ -0,0 +1,194 @@
+(* Time-stamp: <modified the 06/02/2015 (at 15:15) by Erwan Jahier> *)
+
+open Soc2cUtil
+open Soc2cIdent
+open Soc
+
+
+let (mem_interface : Soc.t -> string -> bool) =
+  fun soc id -> 
+    let ins,outs = soc.profile in
+    List.mem_assoc id ins || List.mem_assoc id outs
+
+let rec (string_of_var_expr: Soc.t -> Soc.var_expr -> string) = 
+  fun soc -> function
+    | Const("true", _) -> "_true"
+    | Const("false", _) -> "_false"
+    | Const(id, _) -> id2s id
+    | Var ("_memory",_)   -> (* Clutch! it's not an interface var... *) "ctx->_memory" 
+    | Var (id,_)   -> id2s id
+    | Field(f, id,_) -> Printf.sprintf "%s.%s" (string_of_var_expr soc f) (id2s id) 
+    | Index(f, index,_) -> Printf.sprintf "%s[%i]" (string_of_var_expr soc f) index
+    | Slice(f,fi,la,st,wi,vt) -> assert false (* should not occur *)
+
+
+(* exported *) 
+let rec (gen_assign : Data.t  -> string -> string -> string -> string) =
+  fun t vi vo size -> 
+    match t with
+      | Data.Alias(_,t) -> gen_assign t vi vo size
+      | Data.Enum _  
+      | Data.Struct(_) (* should I rather use memcpy for struct? *)
+      | Data.Bool | Data.Int | Data.Real -> Printf.sprintf "  %s = %s;\n" vi vo
+      | Data.Alpha(_) (* dead code ? *) 
+      | Data.Array(_) -> 
+        let t_str = Soc2cIdent.type_to_short_string t in
+        Printf.sprintf "  _assign_%s(%s, %s, sizeof(%s));\n" t_str vi vo vi
+
+      | Data.Extern (id) -> 
+        Printf.sprintf "  _assign_%s(&%s, &%s, sizeof(%s));\n" (id2s id) vi vo vo
+
+let (is_soc_output : Soc.var_expr -> Soc.t -> bool) =
+  fun v soc -> 
+    match v with
+      | Var(v) ->  List.mem v (snd soc.profile)
+      | _ -> false
+
+let (gen_assign_var_expr : Soc.t -> Soc.var_expr -> Soc.var_expr -> string) =
+fun soc vi vo -> 
+  match vi,vo with
+    | Slice _, _  | _, Slice _ ->  assert false
+    | _,_ -> 
+      let left = string_of_var_expr soc vi in
+      let left = if is_soc_output vi soc then "*"^left else left  in
+      gen_assign (Soc.data_type_of_var_expr vi) left (string_of_var_expr soc vo)
+        (Printf.sprintf "sizeof(%s)" (string_of_var_expr soc vo))
+
+
+let (step_name : Soc.key -> string -> string) =
+  fun sk sm -> 
+    let str = Printf.sprintf "%s_%s" (Soc2cIdent.get_soc_name sk) sm in
+    id2s str
+
+let (ctx_var : var_kind -> Ident.t -> string) =
+  fun opt id -> 
+    Printf.sprintf "%s" (id2s id)
+
+let (list_split : 'a list -> int -> 'a list * 'a list) =
+  fun l s ->
+    let rec aux s l acc =
+      match s,l with
+        | 0, _ -> List.rev acc,l
+        | _, x::l -> aux (s-1) l (x::acc)
+        | _, [] -> assert false
+    in 
+    aux s l []
+
+let _ = assert (list_split [1;2;3;4;5;6] 3 = ([1;2;3],[4;5;6]))
+
+let (inline_soc :  Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list -> string option) =
+  fun soc called_soc vel_out vel_in -> 
+    let called_soc_name,_,_ = called_soc.key in 
+    match called_soc_name with
+      (* those soc are inlined. Currently we only inline ite because
+         of its polymorphism. Simple arith operators (+,-,*,/,etc.)
+         should be inlined too. *)
+      | "Lustre::if" -> 
+        let c,vel_in= match vel_in with [] -> assert false | c::l -> c,l in 
+        let s = (List.length vel_out) in
+        let vel_in_t, vel_in_e = list_split vel_in s in
+        let lt = List.map2 (gen_assign_var_expr soc) vel_out vel_in_t in
+        let le = List.map2 (gen_assign_var_expr soc) vel_out vel_in_e in
+        let str = "   if ("^(string_of_var_expr soc c)  ^ " == _true) {\n   "^
+          (String.concat "   " lt)^ "   } else {\n   "^
+          (String.concat "   " le)^ "   }\n"
+        in
+        Some str
+      | _  -> 
+        try
+          if 
+            Lv6MainArgs.global_opt.Lv6MainArgs.gen_c_inline_predef 
+            && Soc2cPredef.is_call_supported called_soc_name soc 
+          then
+            let vel_in = List.map (string_of_var_expr soc) vel_in in
+            let vel_out_str = List.map (string_of_var_expr soc) vel_out in
+            let vel_out = List.map2
+              (fun v s -> if is_soc_output v soc then "*"^s else s) vel_out vel_out_str
+            in
+            Some (Soc2cPredef.gen_call called_soc_name soc vel_out vel_in)
+          else 
+            None
+        with Not_found -> 
+(*           Printf.eprintf "won't inline %s\n" called_soc_name; *)
+          None
+(* exported *) 
+let (inlined_soc : Soc.t -> bool) =
+  fun soc ->
+    let soc_name,_,_ = soc.key in 
+    soc_name = "Lustre::if" || Soc2cPredef.is_call_supported soc_name soc 
+
+
+(* exported *) 
+let (gen_step_call : Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list -> 
+     string -> string -> string -> string) =
+  fun soc called_soc vel_out vel_in ctx sname step_arg -> 
+    match inline_soc soc called_soc vel_out vel_in with
+      | Some str -> str
+      | None ->
+        let vel_in = List.map (string_of_var_expr soc) vel_in in
+        let vel_out_str = List.map (string_of_var_expr soc) vel_out in
+        let vel_out = 
+          List.map2 (fun v s -> if is_soc_output v soc then s else "&"^s) vel_out vel_out_str
+        in
+        let step_arg = if step_arg = "" then [] else [step_arg] in
+        let step_arg = String.concat "," (vel_in@vel_out@step_arg) in
+        let str = Printf.sprintf "  %s(%s); \n" (step_name called_soc.key sname) step_arg in
+        str
+
+(* exported *) 
+let (typedef_of_soc : Soc.t -> string) =
+  fun soc -> 
+    if inlined_soc soc then ""  (* don't generate code if inlined *) else
+      if SocUtils.is_memory_less soc then "" else
+    let ctx_name = get_ctx_name soc.key in
+    let ctx_name_type = ctx_name^"_type" in    
+    let str = Printf.sprintf  "/* %s */\ntypedef struct {\n" ctx_name in
+    let str = str ^
+      (match soc.memory with
+        | No_mem -> ""
+        | Mem t ->  Printf.sprintf "   /*Memory cell*/\n   %s ;\n" 
+          (id2s (Soc2cUtil.type_to_string t "_memory"))
+        | Mem_hidden -> ""
+      )
+    in
+    let str =  str ^ (if soc.instances <> [] then  "   /*INSTANCES*/\n" else "") in
+    let string_of_instance (id,sk) = 
+      Printf.sprintf "   %s_type %s;\n" (get_ctx_name sk) (id2s id)
+    in
+    let str =  List.fold_left (fun acc inst -> acc^(string_of_instance inst)) str soc.instances in
+    let str = Printf.sprintf  "%s} %s;\n\n" str ctx_name_type in
+    str
+
+(* exported *)
+(* for soc of type (int * int -> int), it generates something like 
+
+"void step(int, int, int*, soc_ctx_type* );",
+"void step(int x, int y, int* res, soc_ctx_type* ctx){"
+
+*) 
+let (get_step_prototype : Soc.step_method -> Soc.t -> string * string) =
+  fun sm soc ->
+    let sname = step_name soc.key sm.name in
+    let inputs, outputs = soc.Soc.profile in
+    let inputs  = SocUtils.filter_step_params sm.Soc.idx_ins  inputs in
+    let outputs = SocUtils.filter_step_params sm.Soc.idx_outs outputs in
+    let to_param (id,dt) = Soc2cUtil.type_to_string dt "",id in
+    let in_params = List.map to_param inputs in
+    let out_params = List.map to_param outputs in
+    let out_params = List.map (fun (t,id) -> t^"*",id) out_params in
+
+    let in_params_decl  = List.map fst in_params  in
+    let out_params_decl = List.map fst out_params in
+    let in_params  = List.map (fun (t,id) -> t^" "^id) in_params  in
+    let out_params = List.map (fun (t,id) -> t^" "^id) out_params in
+   
+    let params = String.concat "," (in_params@out_params) in
+    let params_decl = String.concat "," (in_params_decl@out_params_decl) in
+    if SocUtils.is_memory_less soc then
+      Printf.sprintf "void %s(%s);\n" sname params_decl,
+      Printf.sprintf "void %s(%s){\n" sname params
+    else 
+      let ctx = Printf.sprintf "%s_type* ctx" (get_ctx_name soc.key)  in
+      let ctx_decl = Printf.sprintf "%s_type*" (get_ctx_name soc.key) in
+      Printf.sprintf "void %s(%s,%s);\n" sname params_decl ctx_decl,
+      Printf.sprintf "void %s(%s,%s){\n" sname params ctx
diff --git a/src/soc2cStack.mli b/src/soc2cStack.mli
new file mode 100644
index 00000000..32896afa
--- /dev/null
+++ b/src/soc2cStack.mli
@@ -0,0 +1,41 @@
+(* Time-stamp: <modified the 06/02/2015 (at 11:06) by Erwan Jahier> *)
+
+(** Gathers all entities (functions, types) that implement the
+    heap-based C generator.  *)
+
+(** [gen_assign t vi vo size] generated the C code that assign vo to vi,
+   using memcpy or = depending on the type t *)
+val gen_assign : Data.t  -> string -> string -> string -> string
+
+(** ditto *)
+val gen_assign_var_expr : Soc.t -> Soc.var_expr -> Soc.var_expr -> string
+
+(** Generates the C step name from the soc key and the soc step name *)
+val step_name : Soc.key -> string -> string
+
+(** Returns the prototype (.c) and the decl (.h) of the step function.
+   For the stack based approach, we need to arg I/O params.
+ *)
+val get_step_prototype : Soc.step_method -> Soc.t -> string * string
+
+val string_of_var_expr: Soc.t -> Soc.var_expr -> string
+
+
+(* [ctx_var vk id] *)
+val ctx_var : Soc2cUtil.var_kind -> Ident.t -> string
+  
+(**  [gen_step_call soc called_soc vel_out vel_in ctx sname step_arg]
+ Generates the C code that performs the call to a step method of
+   [called_soc] from [soc].
+   - [vel_out] and [vel_in] are the called_soc O/I arguments
+   - [ctx] is the C name of the context of the called_soc
+   - [sname] is the C name of the step to call
+   - [step_arg] is a string holding the arg of the step (empty for proc call)
+*)
+
+val gen_step_call : Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list -> 
+     string -> string -> string -> string
+(* should this soc be inlined? (depends on Lv6MainArgs.global_opt) *)
+val inlined_soc : Soc.t -> bool
+
+val typedef_of_soc : Soc.t -> string
diff --git a/src/soc2cUtil.ml b/src/soc2cUtil.ml
index 38b15d0a..3ea2b5bd 100644
--- a/src/soc2cUtil.ml
+++ b/src/soc2cUtil.ml
@@ -1,12 +1,12 @@
-(* Time-stamp: <modified the 21/01/2015 (at 17:48) by Erwan Jahier> *)
+(* Time-stamp: <modified the 06/02/2015 (at 16:07) by Erwan Jahier> *)
 
 open Soc2cIdent
 open Data
 
 
 type var_kind = (* XXX poor names: fixme! *)
-  | ML_IO of Soc.key (* for idents that are part of a MemoryLess soc interface *)
-  | M_IO (* for idents that are part of a soc interface with Memories*)
+  | ML_IO of Soc.key (* For memoryless soc in Heap mode *)
+  | M_IO (* *)
   | Local (* for soc local variables *)
 
 let rec (type_to_string : Data.t -> string -> string) = 
@@ -34,6 +34,9 @@ let rec (type_to_string : Data.t -> string -> string) =
     in
     aux [] v n
 
+let string_of_flow_decl (id, t) = 
+  Printf.sprintf "   %s;\n" (type_to_string t (id2s id)) 
+
 
 let rec (lic_type_to_c: Lic.type_  -> string -> string) =
   fun t n -> 
diff --git a/src/soc2cUtil.mli b/src/soc2cUtil.mli
index 7cf0e1fc..0e9283f6 100644
--- a/src/soc2cUtil.mli
+++ b/src/soc2cUtil.mli
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 09/10/2014 (at 15:37) by Erwan Jahier> *)
+(* Time-stamp: <modified the 04/02/2015 (at 14:23) by Erwan Jahier> *)
 
 (** *)
 
@@ -6,6 +6,8 @@
 val type_to_string : Data.t -> string -> string
 val lic_type_to_c: Lic.type_  -> string -> string
 
+val string_of_flow_decl : string * Data.t -> string
+
 type var_kind = (* XXX poor names: fixme! *)
   | ML_IO of Soc.key (* for idents that are part of a MemoryLess soc interface *)
   | M_IO (* for idents that are part of a soc interface with Memories*)
diff --git a/src/socPredef2cHeap.ml b/src/socPredef2cHeap.ml
index 51499c16..0e379e6c 100644
--- a/src/socPredef2cHeap.ml
+++ b/src/socPredef2cHeap.ml
@@ -1,4 +1,5 @@
-(* Time-stamp: <modified the 14/01/2015 (at 14:55) by Erwan Jahier> *)
+
+(* Time-stamp: <modified the 06/02/2015 (at 16:09) by Erwan Jahier> *)
 
 open Data
 open Soc
diff --git a/src/socPredef2cStack.ml b/src/socPredef2cStack.ml
new file mode 100644
index 00000000..b352e047
--- /dev/null
+++ b/src/socPredef2cStack.ml
@@ -0,0 +1,300 @@
+
+(* Time-stamp: <modified the 05/02/2015 (at 11:26) by Erwan Jahier> *)
+
+open Data
+open Soc
+open Soc2cIdent
+
+(* A boring but simple module... *)
+
+(* XXX should i use gen_assign here? for the time being, its useless as
+   there is no binop (nor unop) over arrays.
+*)
+let (lustre_binop : Soc.key -> string -> string) =
+  fun sk op  -> 
+    Printf.sprintf "  *z = (x %s y);\n" op
+
+let (lustre_unop : Soc.key -> string -> string) =
+  fun sk op  -> 
+    (* use gen_assign? *)
+    Printf.sprintf"  *z = %s x;\n" op 
+
+let (lustre_ite : Soc.key -> string) =
+  fun sk -> 
+    let t = match sk with  (_,_::t::_,_) -> t | _ ->  assert false in
+(*     Printf.sprintf"  %s.z = (%s.c)? %s.xt : %s.xe;\n" ctx ctx ctx ctx *)
+    Soc2cHeap.gen_assign t (Printf.sprintf "*z")
+       (Printf.sprintf "(c)? xt : xe")
+       (Printf.sprintf "sizeof(*z)")
+
+let (lustre_impl : Soc.key -> string) =
+  fun sk -> 
+    (* use gen_assign? *)
+    Printf.sprintf"  *z = (!x || y);\n"
+
+    
+let (lustre_arrow : Soc.key -> string) =
+  fun sk -> 
+    let x,y,z = "x", "y", "*z" in
+    let t = match sk with  (_,_::t::_,_) -> t | _ ->  assert false in
+    let vo = Printf.sprintf"((ctx->_memory)? %s : %s)" x y in
+    let size = Printf.sprintf "sizeof(%s)" x in
+    (Soc2cHeap.gen_assign t z vo size) ^ 
+      ("  ctx->_memory = _false;\n")
+      
+let (lustre_hat : Soc.key -> string) =
+  fun (n,tl,si_opt) -> 
+    let i,t = match tl with
+      | [_;Data.Array(t,i)] -> i,t
+      | _ -> assert false
+    in
+    let buff = ref "" in
+    for j=0 to i-1 do
+      buff := !buff^(Soc2cHeap.gen_assign t (Printf.sprintf "z[%d]" j)
+                       (Printf.sprintf "x") (Printf.sprintf "sizeof(x)")); 
+    done;
+    !buff
+
+let (lustre_array: Soc.key -> string) =
+  fun (n,tl,si_opt) -> 
+    let t,i = match List.hd (List.rev tl) with
+      | Data.Array(t,i) -> t,i
+      | _ -> assert false
+    in
+    let buff = ref "" in
+    for j=0 to i-1 do
+      buff := !buff^(Soc2cHeap.gen_assign t (Printf.sprintf "z[%d]" j)
+                       (Printf.sprintf "x%d" (j+1)) 
+                       (Printf.sprintf "sizeof(x%d)" (j+1))); 
+    done;
+    !buff
+ 
+let (lustre_concat: Soc.key -> string) =
+  fun (n,tl,si_opt) -> 
+    let t,s1,s2 = match tl with
+      | [Data.Array(t,s1); Data.Array(_,s2); _] -> t,s1,s2
+      | _ -> assert false
+    in
+    let t1 = Printf.sprintf "x"
+    and t2 = Printf.sprintf "y" 
+    and t12 = Printf.sprintf "z" in  
+    (Printf.sprintf "  memcpy(%s, &%s, sizeof(%s));\n" t12 t1 t1)^ 
+      (Printf.sprintf "  memcpy(%s[%d], &%s, sizeof(%s));\n" t12 s1 t2 t2) 
+(* Both seems to work *)
+(*      let buff = ref "" in  *)
+(*      for j=0 to s1-1 do  *)
+(*        buff := !buff^(Soc2cHeap.gen_assign t (Printf.sprintf "%s.z[%d]" ctx j)  *)
+(*                         (Printf.sprintf "%s.x[%d]" ctx j));   *)
+(*      done;  *)
+(*      for j=s1 to s1+s2-1 do  *)
+(*        buff := !buff^(Soc2cHeap.gen_assign t (Printf.sprintf "%s.z[%d]" ctx j)  *)
+(*                         (Printf.sprintf "%s.y[%d]" ctx (j-s1)));   *)
+(*      done;  *)
+(*      !buff  *)
+
+let (lustre_slice: Soc.key -> string) =
+  fun (n,tl,si_opt) -> 
+    let t,size = match List.hd (List.rev tl) with
+      | Data.Array(t,i) -> t,i
+      | _ -> assert false
+    in
+    match si_opt with
+      | Slic(b,e,step) -> 
+        let buff = ref "" in  
+        let j=ref 0 in
+        for i = b to e do
+          if (i-b) mod step = 0 then (
+            buff := !buff^(Soc2cHeap.gen_assign t (Printf.sprintf "z[%d]" !j)  
+                             (Printf.sprintf "x[%d]" i)
+                             (Printf.sprintf "sizeof(x[%d])" i)
+            );   
+            incr j);
+          done; 
+          !buff
+      | _ -> assert false
+
+
+
+(* exported *)
+let (get_predef_op: Soc.key -> string) =
+  fun sk -> 
+    let (n,tl,si_opt) = sk in
+    match n with
+      | "Lustre::rplus" 
+      | "Lustre::plus"
+      | "Lustre::iplus"  -> lustre_binop sk "+" 
+      | "Lustre::itimes" 
+      | "Lustre::times"
+      | "Lustre::rtimes" -> lustre_binop sk "*" 
+      | "Lustre::idiv"
+      | "Lustre::div"  
+      | "Lustre::rdiv"   -> lustre_binop sk "/" 
+      | "Lustre::islash" 
+      | "Lustre::slash" 
+      | "Lustre::rslash" -> lustre_binop sk "/"
+      | "Lustre::iminus"
+      | "Lustre::minus"
+      | "Lustre::rminus" -> lustre_binop sk "-" 
+
+      | "Lustre::mod" -> lustre_binop sk "%"
+      | "Lustre::iuminus"
+      | "Lustre::uminus" 
+      | "Lustre::ruminus"-> lustre_unop sk "-" 
+
+      | "Lustre::eq" -> lustre_binop sk "==" 
+
+      | "Lustre::and" -> lustre_binop sk "&&" 
+      | "Lustre::neq" -> lustre_binop sk "!="  
+      | "Lustre::or"  -> lustre_binop sk "||"  
+
+      | "Lustre::xor" -> lustre_binop sk "!=" 
+      | "Lustre::not" -> lustre_unop  sk "!"
+      | "Lustre::real2int" -> lustre_unop sk "(_integer)"
+      | "Lustre::int2real" -> lustre_unop sk "(_real)"
+
+      | "Lustre::lt"
+      | "Lustre::rlt"
+      | "Lustre::ilt" -> lustre_binop sk "<"
+      | "Lustre::gt"
+      | "Lustre::rgt"
+      | "Lustre::igt" -> lustre_binop sk ">"
+      | "Lustre::lte" 
+      | "Lustre::rlte"
+      | "Lustre::ilte" -> lustre_binop sk "<="
+      | "Lustre::gte"
+      | "Lustre::rgte"
+      | "Lustre::igte" -> lustre_binop sk ">="
+      | "Lustre::impl" -> lustre_impl sk
+
+      | "Lustre::if"
+      | "Lustre::rif"
+      | "Lustre::iif" -> lustre_ite sk
+
+      | "Lustre::current" -> assert false
+      | "Lustre::arrow" -> lustre_arrow sk
+
+      | "Lustre::hat" -> lustre_hat sk
+      | "Lustre::array" -> lustre_array sk
+      | "Lustre::concat" -> lustre_concat sk
+      | "Lustre::array_slice" -> lustre_slice sk
+
+
+      | "Lustre::nor" -> assert false (* ougth to be translated into boolred *)
+      | "Lustre::diese" -> assert false (* ditto *)
+
+      | _ -> assert false
+
+
+let rec type_elt_of_array = function 
+  | Data.Array(t,_) -> t
+  | Data.Alias(_,t) -> type_elt_of_array t
+  | _ -> assert false
+
+
+(* exported *)
+let (get_iterator : Soc.t -> string -> Soc.t -> int -> string) = 
+  fun soc iterator it_soc n -> 
+    let iter_inputs,iter_outputs = soc.profile in
+    let node_step = match soc.step with [step] -> step.name  | _ ->  assert false in
+    let step_args, ctx, array_index = 
+      match soc.instances with
+        | [] -> (
+          let (array_index : int -> var -> Soc.var_expr) =
+            fun i (vn,vt) -> Var(Printf.sprintf "%s[%d]" vn i, type_elt_of_array vt)
+          in          
+          Array.make n "", 
+          Array.make n (get_ctx_name it_soc.key),
+          array_index
+        )
+        | _  -> 
+          let inst_names = List.map fst soc.instances in 
+          let inst_names = List.rev inst_names in
+          let step_args = List.map (fun sn  -> ("&ctx->"^(id2s sn))) inst_names in
+          let ctx = List.map (fun sn  -> ("ctx->"^(id2s sn))) inst_names in
+          let (array_index : int -> var -> Soc.var_expr) =
+            fun i (vn,vt) -> Var(Printf.sprintf "ctx->%s[%d]" vn i,vt) 
+          in
+          Array.of_list step_args,
+          Array.of_list ctx,
+          array_index
+    in
+    let buff = ref "" in
+    for i=0 to n-1 do
+      let vel_in, vel_out =
+        match iterator with
+          | "map" -> 
+            (List.map (array_index i) iter_inputs,
+             List.map (array_index i) iter_outputs)
+          | "fold" | "red" | "fill" | "fillred" ->
+            let name, telt = List.hd iter_inputs in
+            let a_in = name in
+            let a_in = Var(a_in, telt) in
+            ( a_in::(List.map (array_index i) (List.tl iter_inputs)),
+              a_in::(List.map (array_index i) (List.tl iter_outputs)))
+          | _ -> assert false (* should not occur *)
+      in
+      buff := !buff^(
+        Soc2cHeap.gen_step_call
+          soc it_soc vel_out vel_in ctx.(i) node_step step_args.(i))
+    done;
+
+    if iterator <> "map" then (
+      let type_in = (snd (List.hd iter_inputs)) in
+      let a_in  =  (fst (List.hd iter_inputs)) in
+      let a_out = "*" ^ (fst (List.hd iter_outputs)) in
+      buff := !buff^(Soc2cHeap.gen_assign type_in a_out a_in
+                       (Printf.sprintf "sizeof(%s)" a_in))  (* a_out=a_n *)
+    );
+    !buff
+ 
+
+(* exported *)
+let (get_condact : Soc.t -> Soc.t -> var_expr list -> string ) = 
+  fun soc condact_soc el -> 
+        let buff = ref "" in
+    let add str = buff:=!buff^(str^"\n") in
+
+    let clk = Printf.sprintf "i0" in
+    let vel_in,vel_out = soc.profile in
+    let vel_in = List.tl vel_in in
+    let vel_in  = List.map (fun var -> Var var) vel_in  in
+    let vel_out = List.map (fun var -> Var var) vel_out in
+    add (Printf.sprintf "  if (%s == _true) { " clk); 
+    (if SocUtils.is_memory_less condact_soc then
+      let condact_ctx = get_ctx_name condact_soc.key in
+      add (Soc2cStack.gen_step_call soc condact_soc vel_out vel_in condact_ctx "step" "")
+    else
+      let condact_ctx = 
+        let inst_name =
+          match soc.instances with
+            | [inst] -> (id2s (fst inst))
+            | _ -> assert false
+        in
+        Printf.sprintf  "ctx->%s" inst_name
+      in
+      add (Soc2cStack.gen_step_call soc condact_soc vel_out vel_in 
+             condact_ctx "step"  ("&"^condact_ctx))
+    );
+    add "    ctx->_memory = _false;";
+    add "   } else if (ctx->_memory == _true) {";
+    List.iter2 (fun var ve -> 
+      add (Printf.sprintf "    %s = %s;" (Soc2cHeap.string_of_var_expr soc var)
+             (Soc2cHeap.string_of_var_expr soc ve) )
+    ) vel_out el ;
+    add "    ctx->_memory = _false;";
+    add "  }";
+    !buff
+
+
+(* exported *)
+let (get_boolred : Soc.t -> int -> int -> int -> string )= 
+  fun soc i j k -> 
+    let ctx = get_ctx_name soc.key in
+    let buff = ref "" in
+    let add str = buff:=!buff^(str^"\n") in
+    add "  int cpt,i;";
+    add "  cpt=0;";
+    add (Printf.sprintf
+           "  for (i = 0 ; i < %d ; i += 1) if (%s.i0[i] == _true) cpt++;" k ctx);    
+    add (Printf.sprintf "  %s.o0 = (%d <= cpt && cpt <= %d) ? _true : _false;" ctx i j );
+    !buff
diff --git a/src/socPredef2cStack.mli b/src/socPredef2cStack.mli
new file mode 100644
index 00000000..fb1706b6
--- /dev/null
+++ b/src/socPredef2cStack.mli
@@ -0,0 +1,15 @@
+(* Time-stamp: <modified the 04/02/2015 (at 14:38) by Erwan Jahier> *)
+
+
+(** Returns the C code corresponding a soc key  *)
+val get_predef_op: Soc.key -> string
+
+(** Returns the C code implementing an iterator (map, fill, red) *)
+val get_iterator : Soc.t -> string ->  Soc.t ->  int -> string
+
+
+(** Returns the C code implementing a condact *)
+val get_condact : Soc.t -> Soc.t -> Soc.var_expr list -> string 
+
+(** Returns the C code implementing a boolred *)
+val get_boolred : Soc.t -> int -> int -> int -> string 
diff --git a/src/socUtils.ml b/src/socUtils.ml
index 2424303e..a0d166de 100644
--- a/src/socUtils.ml
+++ b/src/socUtils.ml
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 14/08/2014 (at 16:30) by Erwan Jahier> *)
+(** Time-stamp: <modified the 06/02/2015 (at 15:59) by Erwan Jahier> *)
 
 
 open Soc
@@ -353,3 +353,29 @@ let (my_string_of_float_precision : int option -> float -> string) =
 let (is_memory_less : Soc.t -> bool) =
   fun soc -> 
     soc.memory = No_mem && soc.instances = []
+
+(* exported *)
+let (ctx_is_global : Soc.t -> bool) =
+  fun soc -> 
+    match Lv6MainArgs.global_opt.Lv6MainArgs.io_transmit_mode with
+      | Lv6MainArgs.Heap -> is_memory_less soc
+      | Lv6MainArgs.Stack | Lv6MainArgs.HeapStack -> false
+
+    
+
+let (filter_step_params : int list -> 'a list -> 'a list) =
+  fun il vl -> (* we suppose that the index list is in increasing order *)
+   let rec aux il vl idx acc =
+     match il,vl with
+       | [],_ -> acc
+       | _::_, [] -> assert false
+       | i::til,v::tvl -> 
+         if i = idx then aux til tvl (idx+1) (v::acc) 
+         else if i > idx then aux il tvl (idx+1) acc 
+         else assert false
+   in 
+   List.rev (aux il vl 0 [])
+
+
+let _ = (
+  assert (filter_step_params [0;1;4] ["v1";"v2";"v3";"v4";"v5"] =  ["v1";"v2";"v5"]))
diff --git a/src/socUtils.mli b/src/socUtils.mli
index 89008942..243fb70a 100644
--- a/src/socUtils.mli
+++ b/src/socUtils.mli
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 20/06/2014 (at 10:32) by Erwan Jahier> *)
+(** Time-stamp: <modified the 06/02/2015 (at 16:00) by Erwan Jahier> *)
 
 
 (** Donne toute les méthodes d'un composant. *)
@@ -50,3 +50,19 @@ val gen_index_list : int -> int list
 val my_string_of_float_precision : int option -> float -> string
 
 val is_memory_less : Soc.t -> bool
+
+(** should we omit the ctx in arg of the step function?
+    yes in Heap mode when the soc is memory less.
+ *)
+val ctx_is_global : Soc.t -> bool
+
+(** [filter_step_params index_list var_list]
+
+only keeps the var present in the index list. 
+
+For instance, 
+filter_step_params [0;1;4] [v1;v2;v3;v4;v5] =  [v1;v2;v5]
+
+nb : we suppose that the index list is in increasing order.
+*)
+val filter_step_params : int list -> 'a list -> 'a list
diff --git a/test/Makefile b/test/Makefile
index 9a386577..7ce7db11 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,11 +1,11 @@
 # to run the test, one needs to (apt-get) install:
 # dejagnu tcl tcllib
 
-all:  clean qtest reftest lus2lic.time 
-test: clean qtest
+all:  clean ltop qtest rest
+test: clean ltop qtest
 rest: reftest lus2lic.time 
 
-TEST_MACHINE=ssh granier
+TEST_MACHINE=ssh ovaz
 #TEST_MACHINE=eval
 # This fixes sporadic memory errors I get when running tests
 OCAMLRUNPARAM=s=1M,i=32M,o=150
@@ -68,7 +68,7 @@ reftest:
 	time -o lus2lic.ref_time make $(LOG)
 	make lus2lic.time
 
-qtest:ltop 
+qtest: 
 	rm -f $(LOG)
 	$(TEST_MACHINE) "cd $(testdir); make tmpdirs"
 	time -o lus2lic.quick_time make -j 8 $(LOG)
diff --git a/test/lus2lic.sum b/test/lus2lic.sum
index 7b5d6072..c6548949 100644
--- a/test/lus2lic.sum
+++ b/test/lus2lic.sum
@@ -1,5 +1,5 @@
 ==> lus2lic0.sum <==
-Test Run By jahier on Tue Jan 27 10:37:57 
+Test Run By jahier on Mon Feb  9 15:44:03 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic0 tests ===
@@ -63,7 +63,7 @@ XFAIL: Test bad programs (assert): test_lus2lic_no_node should_fail/assert/lecte
 XFAIL: Test bad programs (assert): test_lus2lic_no_node should_fail/assert/s.lus
 
 ==> lus2lic1.sum <==
-Test Run By jahier on Tue Jan 27 10:38:01 
+Test Run By jahier on Mon Feb  9 15:44:08 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic1 tests ===
@@ -397,7 +397,7 @@ PASS: gcc -o multipar.exec multipar_multipar.c multipar_multipar_loop.c
 PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c multipar.lus  {}
 
 ==> lus2lic2.sum <==
-Test Run By jahier on Tue Jan 27 10:38:37 
+Test Run By jahier on Mon Feb  9 15:44:45 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic2 tests ===
@@ -727,7 +727,7 @@ PASS: gcc -o zzz2.exec zzz2_zzz2.c zzz2_zzz2_loop.c
 PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c zzz2.lus  {}
 
 ==> lus2lic3.sum <==
-Test Run By jahier on Tue Jan 27 10:39:48 
+Test Run By jahier on Mon Feb  9 15:45:48 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic3 tests ===
@@ -1230,7 +1230,7 @@ PASS: ./myec2c {-o multipar.c multipar.ec}
 PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node multipar.lus {}
 
 ==> lus2lic4.sum <==
-Test Run By jahier on Tue Jan 27 10:40:27 
+Test Run By jahier on Mon Feb  9 15:46:24 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic4 tests ===
@@ -1727,13 +1727,13 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node zzz2.lus {}
 ===============================
 # Total number of failures: 14
 lus2lic0.log:testcase ./lus2lic.tests/test0.exp completed in 4 seconds
-lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 35 seconds
-lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 71 seconds
-lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 39 seconds
-lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 71 seconds
+lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 36 seconds
+lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 62 seconds
+lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 36 seconds
+lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 75 seconds
 * Ref time: 
-0.05user 0.09system 3:41.58elapsed 0%CPU (0avgtext+0avgdata 3016maxresident)k
-0inputs+0outputs (0major+14901minor)pagefaults 0swaps
+0.04user 0.05system 3:36.73elapsed 0%CPU (0avgtext+0avgdata 5080maxresident)k
+160inputs+0outputs (0major+5488minor)pagefaults 0swaps
 * Quick time (-j 4):
-0.05user 0.05system 1:20.56elapsed 0%CPU (0avgtext+0avgdata 3016maxresident)k
-0inputs+0outputs (0major+14920minor)pagefaults 0swaps
+0.04user 0.02system 1:26.50elapsed 0%CPU (0avgtext+0avgdata 5072maxresident)k
+160inputs+0outputs (0major+5567minor)pagefaults 0swaps
diff --git a/test/lus2lic.time b/test/lus2lic.time
index 60639462..df8db41a 100644
--- a/test/lus2lic.time
+++ b/test/lus2lic.time
@@ -1,11 +1,11 @@
 lus2lic0.log:testcase ./lus2lic.tests/test0.exp completed in 4 seconds
-lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 35 seconds
-lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 71 seconds
-lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 39 seconds
-lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 71 seconds
+lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 36 seconds
+lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 62 seconds
+lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 36 seconds
+lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 75 seconds
 * Ref time: 
-0.05user 0.09system 3:41.58elapsed 0%CPU (0avgtext+0avgdata 3016maxresident)k
-0inputs+0outputs (0major+14901minor)pagefaults 0swaps
+0.04user 0.05system 3:36.73elapsed 0%CPU (0avgtext+0avgdata 5080maxresident)k
+160inputs+0outputs (0major+5488minor)pagefaults 0swaps
 * Quick time (-j 4):
-0.05user 0.05system 1:20.56elapsed 0%CPU (0avgtext+0avgdata 3016maxresident)k
-0inputs+0outputs (0major+14920minor)pagefaults 0swaps
+0.04user 0.02system 1:26.50elapsed 0%CPU (0avgtext+0avgdata 5072maxresident)k
+160inputs+0outputs (0major+5567minor)pagefaults 0swaps
diff --git a/test/should_work/ex.lus b/test/should_work/ex.lus
index 6b289811..448c40e9 100644
--- a/test/should_work/ex.lus
+++ b/test/should_work/ex.lus
@@ -4,12 +4,12 @@ let
    o = true -> pre(i) and trueNode(i);
 tel
 
-node trueNode(x : bool) returns (y : bool);
+function trueNode(x : bool) returns (y : bool);
 let
    y = x or id(true,false);
 tel
 
-node id(f,a:bool) returns (g:bool);
+function id(f,a:bool) returns (g:bool);
 let
    g = f or a;
 tel
-- 
GitLab