From 6f975e9bc4d6dfff63fcf0ab056956d1bbb018ad Mon Sep 17 00:00:00 2001
From: Erwan Jahier <erwan.jahier@univ-grenoble-alpes.fr>
Date: Wed, 5 Jul 2017 11:23:58 +0200
Subject: [PATCH] More work on the -eeb option.

It was generetaing wrong code in conjunction with -ec.

In particular, it was generating n-any "and" instead of binary "and".

Also, I needed (in L2LExpandEnum) to generated a Lic.ARRAY of const
instead of a Lic.Array_const_eff so that LicDump properly generated
ec code.
---
 Makefile.dev           |  2 +-
 _oasis                 |  2 +-
 src/l2lExpandArrays.ml | 47 ++++++++++++++++++++++++++++--------------
 src/l2lExpandEnum.ml   | 45 ++++++++++++++++++++--------------------
 src/lic.ml             |  9 ++++++--
 src/licDump.ml         | 31 +++++++++++++++++++++-------
 src/lv6version.ml      |  4 ++--
 test/lus2lic.sum       | 22 ++++++++++----------
 8 files changed, 100 insertions(+), 62 deletions(-)

diff --git a/Makefile.dev b/Makefile.dev
index 3ad324d1..6a6fe481 100644
--- a/Makefile.dev
+++ b/Makefile.dev
@@ -117,7 +117,7 @@ verimag:
 ###############################
 # tags
 
-OTAGS=otags
+OTAGS=~/.opam/4.02.1+PIC/bin/otags
 # otags don't manage to parse gnuplotRif.ml
 NO_TAGS=gnuplotRif.ml
 tags:
diff --git a/_oasis b/_oasis
index f1e9b432..b2ba114c 100644
--- a/_oasis
+++ b/_oasis
@@ -1,6 +1,6 @@
 OASISFormat: 0.4
 Name:        lustre-v6
-Version:     1.701
+Version:     1.702
 Synopsis:    The Lustre V6 Verimag compiler
 Description: This package contains:
    (1) lus2lic: the (current) name of the compiler (and interpreter via -exec).
diff --git a/src/l2lExpandArrays.ml b/src/l2lExpandArrays.ml
index ebfcce5c..22b49d7c 100644
--- a/src/l2lExpandArrays.ml
+++ b/src/l2lExpandArrays.ml
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 04/07/2017 (at 15:23) by Erwan Jahier> *)
+(** Time-stamp: <modified the 05/07/2017 (at 11:21) by Erwan Jahier> *)
 
 (* Replace structures and arrays by as many variables as necessary.
    Since structures can be nested, it migth be a lot of new variables...
@@ -375,15 +375,13 @@ and (break_tuple : Lxm.t -> left list -> val_exp -> Lic.eq_info srcflagged list)
 	     | CallByPosLic ({it= TUPLE}, vel)
 	     | CallByPosLic ({it= CONCAT}, vel)
 	     | CallByPosLic ({it= ARRAY}, vel) -> List.flatten (List.map aux vel)
-(* necessary ?                                                         
         | CallByPosLic ({src=lxm;it= CONST (Array_const_eff(cl,t))}, []) ->
            List.map (fun c ->
                      { ve_core = CallByPosLic ({src=lxm;it= CONST c}, []);
                        ve_typ = [t];
                        ve_clk = [List.hd ve.ve_clk];
-                       ve_src = [List.hd ve.ve_src]
+                       ve_src = ve.ve_src
                      }) cl
- *)  
 	     | CallByPosLic ({src=lxm;it= HAT(i)}, vel) ->
           let ve1 = List.hd vel in
 	       let ve1l = aux ve1 in
@@ -413,7 +411,8 @@ and (break_tuple : Lxm.t -> left list -> val_exp -> Lic.eq_info srcflagged list)
 		        ve2l		          
 	     | CallByPosLic ({it= PREDEF_CALL(
           {src=if_lxm ; it = ("Lustre","if"),[]}); src=lxm}, [cond; ve1; ve2]) -> (
-	       let ve1l, ve2l = aux ve1, aux ve2 in
+	       let ve1l = aux ve1 in
+	       let ve2l = aux ve2 in
           let l1,l2= List.length ve1l, List.length ve2l in
 		    if (l1 <> l2) then
 		      let vel2str vel = 
@@ -421,7 +420,7 @@ and (break_tuple : Lxm.t -> left list -> val_exp -> Lic.eq_info srcflagged list)
 		      in
 		      let msg = Printf.sprintf 
               "error: expression \n %s\n   cannot be broken \n %s (%d)
-		         \n   should have the same arity as\n%s(%d)"
+  should have the same arity as\n%s(%d)"
               (LicDump.string_of_val_exp_eff ve)
               (vel2str ve1l) l1  (vel2str ve2l) l2
             in
@@ -477,19 +476,30 @@ and expand_val_exp_list lctx acc vel =
     ([],acc) (List.rev vel)
 
     
-and (build_and_eq : Lic.node_key srcflagged -> val_exp list -> val_exp list
-                    -> val_exp list) =
+and (build_and_eq: Lic.node_key srcflagged -> val_exp list -> val_exp list -> val_exp) =
   fun op vel1 vel2 ->
-  (* transform [(x1;x2] = [y1;y2] into [x1=y1;x2=y2 ]*)
+  (* transform "[(x1;x2] = [y1;y2]" into "x1=y1 and x2=y2" *)
   assert (op.it = (("Lustre","eq"),[]) || op.it = (("Lustre","neq"),[]));
-  let f ve1 ve2 =
+  let and_op = {src = op.src; it=(("Lustre","and"),[]) } in
+  let make_eq ve1 ve2 =
     let lxm = op.src in
     {ve_core = CallByPosLic({src=lxm;it=PREDEF_CALL(op)},[ve1;ve2]);
      ve_typ = [Bool_type_eff];
      ve_clk = ve1.ve_clk;
-     ve_src = op.src}
+     ve_src = lxm}
+  in
+  let make_and acc ve1 ve2 =
+    let eq = make_eq ve1 ve2 in
+    let lxm = op.src in
+    {ve_core = CallByPosLic({src=lxm;it=PREDEF_CALL(and_op)},[acc;eq]);
+     ve_typ = [Bool_type_eff];
+     ve_clk = ve1.ve_clk;
+     ve_src = lxm}
   in
-  List.map2 f vel1 vel2         
+  match vel1,vel2 with
+  | ve1::vel1, ve2::vel2 -> List.fold_left2 make_and (make_eq ve1 ve2) vel1 vel2
+  | _,_ -> assert false (* sno *)
+                  
 and (expand_val_exp: local_ctx -> acc -> val_exp -> val_exp * acc) =
   fun lctx acc ve ->
     match ve.ve_core with
@@ -517,10 +527,15 @@ and (expand_val_exp: local_ctx -> acc -> val_exp -> val_exp * acc) =
               let vel,acc = expand_val_exp_list lctx acc vel in
               match vel with
               | [{ve_core = CallByPosLic ({it = TUPLE}, ve1::ve12::vel1) };
-                 {ve_core = CallByPosLic ({it = TUPLE}, ve2::ve22::vel2) }] ->
-                 let vel_eq = build_and_eq op (ve1::ve12::vel1) (ve2::ve22::vel2) in
-                 let and_op = PREDEF_CALL {src=lxm;it=(("Lustre","and"),[])} in
-                 and_op, acc, vel_eq 
+                 {ve_core = CallByPosLic ({it = TUPLE}, ve2::ve22::vel2) }
+                ] ->
+                 let and_ve = build_and_eq op (ve1::ve12::vel1) (ve2::ve22::vel2) in
+                 let and_op, and_vel =
+                   match and_ve.ve_core with
+                   | CallByPosLic(op,vel) -> op.it, vel
+                   | _ -> assert false (* sno *)
+                 in
+                 and_op, acc, and_vel 
                 
               | [ve1; ve2] -> by_pos_op, acc, vel
               | _  -> assert false (* sno *)
diff --git a/src/l2lExpandEnum.ml b/src/l2lExpandEnum.ml
index f680aa58..1ef7f23a 100644
--- a/src/l2lExpandEnum.ml
+++ b/src/l2lExpandEnum.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 30/06/2017 (at 09:52) by Erwan Jahier> *)
+(* Time-stamp: <modified the 05/07/2017 (at 10:20) by Erwan Jahier> *)
 
 
 open Lxm
@@ -100,28 +100,29 @@ let rec (doit : target -> LicPrg.t -> LicPrg.t) =
           List.fold_left (fun vel ve -> (do_val_exp ve)::vel) [] (List.rev vel)
         in
         let ec =  Lv6MainArgs.global_opt.Lv6MainArgs.ec in
-        let op =
-          { op with
-            it = match op.it, ec with
-                 | Lic.CONST c,_ -> Lic.CONST (do_const c)
-                 | Lic.CONST_REF idl, true -> (
-                   match target, LicPrg.find_const inprg idl with
-                   | _, None -> op.it
-                   | BA, Some (Enum_const_eff (s,Enum_type_eff(_,ll))) ->
-                      let xl = 
-                        List.map (fun x -> Bool_const_eff(if x=s then true else false)) ll 
-                      in
-                      Lic.CONST
-                        (Array_const_eff(xl,Array_type_eff(Bool_type_eff,List.length ll)))
-                   | I, Some (Enum_const_eff (s,Enum_type_eff(_,ll))) -> (
-                     let i = Lv6util.pos_in_list 0 s ll in
-                     Lic.CONST (Int_const_eff (string_of_int i))
-                   )
-                   | _,_ -> op.it 
-                 )
-                 | _,_ -> op.it
-          }
+        let op_it,vel =
+          match op.it, ec with
+          | Lic.CONST c,_ -> Lic.CONST (do_const c), vel
+          | Lic.CONST_REF idl, true -> (
+            match target, LicPrg.find_const inprg idl with
+            | _, None -> op.it,vel
+            | BA, Some (Enum_const_eff (s,Enum_type_eff(_,ll))) ->
+               let f x =
+                 let c = CONST(Bool_const_eff(if x=s then true else false)) in
+                 let c = { it = c ; src = op.src } in
+                 { ve with ve_core = CallByPosLic(c, []); ve_typ = [Bool_type_eff] }
+               in
+               let xl = List.map f ll in
+               Lic.ARRAY, xl
+            | I, Some (Enum_const_eff (s,Enum_type_eff(_,ll))) -> (
+              let i = Lv6util.pos_in_list 0 s ll in
+              Lic.CONST (Int_const_eff (string_of_int i)), vel
+            )
+            | _,_ -> op.it, vel
+          )
+          | _,_ -> op.it, vel
         in
+        let op = { op with it = op_it } in
         CallByPosLic(op, vel)
 	   )
     in 
diff --git a/src/lic.ml b/src/lic.ml
index ab7d2016..6902f3dd 100644
--- a/src/lic.ml
+++ b/src/lic.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 30/06/2017 (at 11:28) by Erwan Jahier> *)
+(* Time-stamp: <modified the 05/07/2017 (at 09:14) by Erwan Jahier> *)
 
 (** Define the Data Structure representing Compiled programs. By
     compiled we mean that constant are propagated, packages are
@@ -229,7 +229,12 @@ and const =
   | Enum_const_eff   of (Lv6Id.long * type_)
   (* type_ structure : liste (champ,valeur) + type_ structure *)
   | Struct_const_eff of ((Lv6Id.t * const) list * type_)
-  (* type_ tableau : liste des valeurs + type_ des elts + taille *)
+  (* type_ tableau : liste des valeurs + type_ des elts + taille 
+     Is it really a good idea to live both with 
+        - constant arrays (and struct), i.e.,  Array_const_eff
+        - array of constants, i.e., ARRAY(const)
+     ? 
+   *)
   | Array_const_eff of (const list * type_) (* type of the const element *)
   | Tuple_const_eff of const list
 (*---------------------------------------------------------------------
diff --git a/src/licDump.ml b/src/licDump.ml
index 82dfe628..46912303 100644
--- a/src/licDump.ml
+++ b/src/licDump.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 27/06/2017 (at 15:36) by Erwan Jahier> *)
+(* Time-stamp: <modified the 04/07/2017 (at 17:17) by Erwan Jahier> *)
 
 open Lv6errors
 open Printf
@@ -451,12 +451,9 @@ and (string_of_by_pos_op_eff: Lic.by_pos_op srcflagged -> Lic.val_exp list -> st
         let op_str = snd (fst op.it) in
         let op_short_str = op2string (AstPredef.string_to_op op_str) in
         if AstPredef.is_infix (AstPredef.string_to_op op_str) then (
-          match vel with 
-          | [ve1; ve2] -> 
+          let ve1, ve2 = cut_list vel in
              (string_of_val_exp_eff ve1) ^ " " ^ op_short_str ^ 
-               " " ^ (string_of_val_exp_eff ve2)
-          | _ -> assert false
-        ) 
+               " " ^ (string_of_val_exp_eff ve2) )
         else 
           (op_short_str ^
              (match op_str with
@@ -561,7 +558,27 @@ and (string_of_by_pos_op_eff: Lic.by_pos_op srcflagged -> Lic.val_exp list -> st
   else 
     ("(" ^ str ^ ")")
 
-
+and (cut_list : val_exp list -> val_exp * val_exp) =
+  function
+  | [] | [_] -> assert false
+  | [ve1;ve2] -> ve1,ve2
+  | vel -> (* sometimes, the flatenning has been too effective, hence 
+              we build back the tuple. Actually it should not occur, 
+              but... sigh... *)
+     let s = (List.length vel)/2 in
+     let f (cpt, l1, l2) ve =
+       if cpt < s then cpt+1, ve::l1, l2 else cpt+1, l1, ve::l2
+     in
+     let _,vel1,vel2 = List.fold_left f (0,[],[]) vel in
+     let vel1 = List.rev vel1 in
+     let vel2 = List.rev vel2 in
+     let ve1,ve2 = List.hd vel1, List.hd vel2 in
+     let ve1 = { ve1 with ve_core = CallByPosLic({src=ve1.ve_src;it=TUPLE}, vel1)} in
+     let ve2 = { ve2 with ve_core = CallByPosLic({src=ve2.ve_src;it=TUPLE}, vel2)} in
+     (* ve_type, ve_clock, and ve_src are wrong, but we build this tuple only
+      for printing purpose *)
+     ve1,ve2
+  
 and string_of_val_exp_eff ve = string_of_val_exp_eff_core ve.ve_core
 and string_of_val_exp_eff_core ve_core = 
   match ve_core with
diff --git a/src/lv6version.ml b/src/lv6version.ml
index 1d738530..75b6f95a 100644
--- a/src/lv6version.ml
+++ b/src/lv6version.ml
@@ -1,7 +1,7 @@
 (** Automatically generated from Makefile *) 
 let tool = "lus2lic"
 let branch = "master"
-let commit = "701"
-let sha_1 = "acc2dbb3a79f2ba9ed0489bd8bff1bfc31846d4b"
+let commit = "702"
+let sha_1 = "a6fab49ad78a8446078f410e07c79e7d47bd8e0a"
 let str = (branch ^ "." ^ commit ^ " (" ^ sha_1 ^ ")")
 let maintainer = "jahier@imag.fr"
diff --git a/test/lus2lic.sum b/test/lus2lic.sum
index 4182add2..708e9588 100644
--- a/test/lus2lic.sum
+++ b/test/lus2lic.sum
@@ -1,5 +1,5 @@
 ==> lus2lic0.sum <==
-Test Run By jahier on Tue Jul  4 15:58:04 
+Test Run By jahier on Wed Jul  5 11:16:43 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic0 tests ===
@@ -64,7 +64,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 Jul  4 15:58:05 
+Test Run By jahier on Wed Jul  5 11:16:44 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic1 tests ===
@@ -403,7 +403,7 @@ PASS: sh multipar.sh
 PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c multipar.lus  {}
 
 ==> lus2lic2.sum <==
-Test Run By jahier on Tue Jul  4 15:59:00 
+Test Run By jahier on Wed Jul  5 11:17:40 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic2 tests ===
@@ -743,7 +743,7 @@ PASS: sh zzz2.sh
 PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c zzz2.lus  {}
 
 ==> lus2lic3.sum <==
-Test Run By jahier on Tue Jul  4 16:00:19 
+Test Run By jahier on Wed Jul  5 11:18:55 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic3 tests ===
@@ -1253,7 +1253,7 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node multipar.lus {}
 
 
 ==> lus2lic4.sum <==
-Test Run By jahier on Tue Jul  4 16:02:37 
+Test Run By jahier on Wed Jul  5 11:21:14 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic4 tests ===
@@ -1771,13 +1771,13 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node zzz2.lus {}
 ===============================
 # Total number of failures: 22
 lus2lic0.log:testcase ./lus2lic.tests/test0.exp completed in 1 seconds
-lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 55 seconds
+lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 56 seconds
 lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 74 seconds
-lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 137 seconds
+lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 138 seconds
 lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 67 seconds
 * Ref time: 
-0.05user 0.02system 5:39.47elapsed 0%CPU (0avgtext+0avgdata 5644maxresident)k
-128inputs+0outputs (0major+6125minor)pagefaults 0swaps
+0.05user 0.02system 5:38.56elapsed 0%CPU (0avgtext+0avgdata 5616maxresident)k
+128inputs+0outputs (0major+6179minor)pagefaults 0swaps
 * Quick time (-j 4):
-0.04user 0.03system 2:22.63elapsed 0%CPU (0avgtext+0avgdata 5724maxresident)k
-160inputs+0outputs (0major+6134minor)pagefaults 0swaps
+0.05user 0.02system 2:39.72elapsed 0%CPU (0avgtext+0avgdata 5708maxresident)k
+32inputs+0outputs (0major+6198minor)pagefaults 0swaps
-- 
GitLab