From f13539052aae260d33816e1d8120f9bfeca6461e Mon Sep 17 00:00:00 2001
From: Erwan Jahier <jahier@imag.fr>
Date: Thu, 12 Jun 2014 11:05:30 +0200
Subject: [PATCH] Soc2c : handle "x^<int>" expressions.

Always use Soc2cPredef.gen_assign to generate var assignments.

Also, use affection for assigning structures.

nb: 21 more tests passes.
---
 src/soc2c.ml                       | 34 +++++++-------------
 src/soc2cUtil.ml                   | 20 ++++++++++++
 src/socPredef2c.ml                 | 46 ++++++++++++++++++++++-----
 test/lus2lic.sum                   | 50 +++++++++++++++---------------
 test/lus2lic.time                  |  2 +-
 test/should_work/trivial_array.lus |  4 +--
 6 files changed, 97 insertions(+), 59 deletions(-)
 create mode 100644 src/soc2cUtil.ml

diff --git a/src/soc2c.ml b/src/soc2c.ml
index c871fece..359fcc20 100644
--- a/src/soc2c.ml
+++ b/src/soc2c.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 12/06/2014 (at 09:39) by Erwan Jahier> *)
+(* Time-stamp: <modified the 12/06/2014 (at 10:40) by Erwan Jahier> *)
 
 
 (* let put (os: out_channel) (fmt:('a, unit, string, unit) format4) : 'a = *)
@@ -90,9 +90,9 @@ let gen_set_inputs ctx soc curr_soc vel =
   if vel = [] then "" (* occurs for pre *) else 
     let inputs = fst soc.profile in
     let l = try (
-      List.map2
-        (fun  (name,_t) ve -> 
-          Printf.sprintf "  %s.%s = %s;\n" ctx name (string_of_var_expr curr_soc ve)) 
+      List.map2 (fun (name, t) ve -> 
+        Soc2cUtil.gen_assign t (Printf.sprintf "%s.%s" ctx name)
+          (string_of_var_expr curr_soc ve)) 
         inputs  
         vel
     ) with _ -> assert false (* XXX not all parameters are necessaryly used! *)
@@ -104,8 +104,9 @@ let gen_get_outputs ctx soc curr_soc vel =
     let  outputs = snd soc.profile in
     let l = try (
       List.map2
-        (fun  (name,_t)  ve -> 
-          Printf.sprintf "  %s = %s.%s;\n" (string_of_var_expr curr_soc ve) ctx name)
+        (fun  (name,t)  ve -> 
+          Soc2cUtil.gen_assign t (string_of_var_expr curr_soc ve)
+            (Printf.sprintf "%s.%s" ctx name))
         outputs  
         vel
     ) with _ -> assert false
@@ -131,24 +132,11 @@ let (gao2c : Soc.tbl -> 'a soc_pp -> Soc.gao -> unit) =
           str
         )
         | Call(vel_out, Assign, vel_in) -> (
-          let l = List.map2 
-            (fun vi vo -> 
-              match Soc.data_type_of_var_expr vi with
-                | Enum _  
-                | Bool | Int | Real -> 
-                  Printf.sprintf "   %s = %s;\n" 
-                    (string_of_var_expr sp.soc vi) (string_of_var_expr sp.soc vo)
-                | Extern (_)
-                | Alpha(_) (* dead code ? *)
-                | Alias(_) 
-                | Struct(_)
-                | Array(_) -> 
-                  Printf.sprintf "   memcpy(%s, %s, sizeof(%s));\n" 
-                    (string_of_var_expr sp.soc vi) 
-                    (string_of_var_expr sp.soc vo)
-                    (string_of_var_expr sp.soc vo)
-            ) vel_out  vel_in
+          let gen_assign2 vi vo =
+            Soc2cUtil.gen_assign (Soc.data_type_of_var_expr vi)
+              (string_of_var_expr sp.soc vi) (string_of_var_expr sp.soc vo)
           in
+          let l = List.map2 gen_assign2 vel_out vel_in in
           String.concat "" l 
         )
         | Call(vel_out, Method((inst_name,sk),sname), vel_in) -> ( 
diff --git a/src/soc2cUtil.ml b/src/soc2cUtil.ml
new file mode 100644
index 00000000..2b05a507
--- /dev/null
+++ b/src/soc2cUtil.ml
@@ -0,0 +1,20 @@
+(* Time-stamp: <modified the 12/06/2014 (at 11:01) by Erwan Jahier> *)
+
+
+(* assign vo to vi, using memcpy or = depending on the type t *) 
+let rec (gen_assign : Data.t  -> string -> string -> string) =
+  fun t vi vo -> 
+    match t with
+      | Alias(_,t) -> gen_assign t vi vo
+      | Enum _  
+      | Struct(_) (* should I rather use memcpy for struct? *)
+      | Bool | Int | Real -> 
+        Printf.sprintf "  %s = %s;\n" vi vo
+      | Alpha(_) (* dead code ? *)
+      | Array(_) -> 
+        Printf.sprintf "  memcpy(%s, %s, sizeof(%s));\n" vi vo vo
+
+      | Extern (id) -> 
+        (* what should i do for extern types? Ask the user to provide the
+           copy function I guess *)
+        Printf.sprintf "  cpy_%s(%s, %s);\n" id vi vo 
diff --git a/src/socPredef2c.ml b/src/socPredef2c.ml
index c22bc43c..8f7bbb12 100644
--- a/src/socPredef2c.ml
+++ b/src/socPredef2c.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 12/06/2014 (at 09:49) by Erwan Jahier> *)
+(* Time-stamp: <modified the 12/06/2014 (at 10:46) by Erwan Jahier> *)
 
 open Data
 open Soc
@@ -53,6 +53,39 @@ let (lustre_merge : Soc.key -> string) =
         Printf.sprintf"  switch (%s.clk){\n%s}\n" ctx cases
       | _ -> assert false
 
+
+let (lustre_hat : Soc.key -> string) =
+  fun (n,tl,si_opt) -> 
+    let ctx = get_ctx_name (n,tl,si_opt) in
+    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^(Soc2cUtil.gen_assign t (Printf.sprintf "%s.z[%d]" ctx j)
+                       (Printf.sprintf "%s.x" ctx)); 
+    done;
+    !buff
+
+let (lustre_array: Soc.key -> string) =
+  fun sk -> 
+    let ctx = get_ctx_name sk in
+    assert false
+
+ 
+let (lustre_concat: Soc.key -> string) =
+  fun sk -> 
+    let ctx = get_ctx_name sk in
+    assert false
+
+let (lustre_slice: Soc.key -> string) =
+  fun sk -> 
+    let ctx = get_ctx_name sk in 
+    assert false
+
+
+
 (* exported *)
 let (get: Soc.key -> string) =
   fun sk -> 
@@ -111,14 +144,11 @@ let (get: Soc.key -> string) =
       | "Lustre::arrow" -> lustre_arrow sk
       | "Lustre::merge" -> lustre_merge sk
 
-      (*
-        | "Lustre::hat" -> lustre_hat tl
-        | "Lustre::array" -> lustre_array tl
-        | "Lustre::concat" -> lustre_concat
-
+      | "Lustre::hat" -> lustre_hat sk
+      | "Lustre::array" -> lustre_array sk
+      | "Lustre::concat" -> lustre_concat sk
+      | "Lustre::array_slice" -> lustre_slice sk
 
-        | "Lustre::array_slice" -> lustre_slice tl si_opt
-      *)
       | "Lustre::current" -> assert false (* o*)
       | "Lustre::nor" -> assert false (* ougth to be translated into boolred *)
       | "Lustre::diese" -> assert false (* ditto *)
diff --git a/test/lus2lic.sum b/test/lus2lic.sum
index 8eb24901..e59076bc 100644
--- a/test/lus2lic.sum
+++ b/test/lus2lic.sum
@@ -1,4 +1,4 @@
-Test Run By jahier on Thu Jun 12 09:40:57 2014
+Test Run By jahier on Thu Jun 12 11:01:44 2014
 Native configuration is i686-pc-linux-gnu
 
 		=== lus2lic tests ===
@@ -31,7 +31,7 @@ PASS: ./lus2lic {-o /tmp/normal.lic should_work/normal.lus}
 PASS: ./lus2lic {-ec -o /tmp/normal.ec should_work/normal.lus}
 PASS: ./myec2c {-o /tmp/normal.c /tmp/normal.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/normal.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/normal.lus -n normal}
+PASS: ./lus2lic {-2c should_work/normal.lus -n normal}
 FAIL: Check that the generated C code compiles  : gcc normal_normal.c normal_normal_loop.c 
 PASS: ./lus2lic {-o /tmp/nodeparam.lic should_work/nodeparam.lus}
 PASS: ./lus2lic {-ec -o /tmp/nodeparam.ec should_work/nodeparam.lus}
@@ -75,7 +75,7 @@ PASS: ./lus2lic {-o /tmp/ELMU.lic should_work/ELMU.lus}
 PASS: ./lus2lic {-ec -o /tmp/ELMU.ec should_work/ELMU.lus}
 PASS: ./myec2c {-o /tmp/ELMU.c /tmp/ELMU.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/ELMU.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/ELMU.lus -n ELMU}
+PASS: ./lus2lic {-2c should_work/ELMU.lus -n ELMU}
 FAIL: Check that the generated C code compiles  : gcc ELMU_ELMU.c ELMU_ELMU_loop.c 
 PASS: ./lus2lic {-o /tmp/testPilote.lic should_work/testPilote.lus}
 PASS: ./lus2lic {-ec -o /tmp/testPilote.ec should_work/testPilote.lus}
@@ -310,7 +310,7 @@ PASS: ./lus2lic {-o /tmp/matrice2.lic should_work/matrice2.lus}
 PASS: ./lus2lic {-ec -o /tmp/matrice2.ec should_work/matrice2.lus}
 PASS: ./myec2c {-o /tmp/matrice2.c /tmp/matrice2.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/matrice2.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/matrice2.lus -n matrice2}
+PASS: ./lus2lic {-2c should_work/matrice2.lus -n matrice2}
 FAIL: Check that the generated C code compiles  : gcc matrice2_matrice2.c matrice2_matrice2_loop.c 
 PASS: ./lus2lic {-o /tmp/v1.lic should_work/v1.lus}
 PASS: ./lus2lic {-ec -o /tmp/v1.ec should_work/v1.lus}
@@ -322,7 +322,7 @@ PASS: ./lus2lic {-o /tmp/ply02.lic should_work/ply02.lus}
 PASS: ./lus2lic {-ec -o /tmp/ply02.ec should_work/ply02.lus}
 PASS: ./myec2c {-o /tmp/ply02.c /tmp/ply02.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/ply02.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/ply02.lus -n ply02}
+PASS: ./lus2lic {-2c should_work/ply02.lus -n ply02}
 FAIL: Check that the generated C code compiles  : gcc ply02_ply02.c ply02_ply02_loop.c 
 PASS: ./lus2lic {-o /tmp/call04.lic should_work/call04.lus}
 PASS: ./lus2lic {-ec -o /tmp/call04.ec should_work/call04.lus}
@@ -369,7 +369,7 @@ PASS: ./lus2lic {-o /tmp/is_stable.lic should_work/is_stable.lus}
 PASS: ./lus2lic {-ec -o /tmp/is_stable.ec should_work/is_stable.lus}
 PASS: ./myec2c {-o /tmp/is_stable.c /tmp/is_stable.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/is_stable.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/is_stable.lus -n is_stable}
+PASS: ./lus2lic {-2c should_work/is_stable.lus -n is_stable}
 FAIL: Check that the generated C code compiles  : gcc is_stable_is_stable.c is_stable_is_stable_loop.c 
 PASS: ./lus2lic {-o /tmp/test_clash.lic should_work/test_clash.lus}
 PASS: ./lus2lic {-ec -o /tmp/test_clash.ec should_work/test_clash.lus}
@@ -443,14 +443,14 @@ PASS: ./lus2lic {-o /tmp/ply03.lic should_work/ply03.lus}
 PASS: ./lus2lic {-ec -o /tmp/ply03.ec should_work/ply03.lus}
 PASS: ./myec2c {-o /tmp/ply03.c /tmp/ply03.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/ply03.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/ply03.lus -n ply03}
+PASS: ./lus2lic {-2c should_work/ply03.lus -n ply03}
 FAIL: Check that the generated C code compiles  : gcc ply03_ply03.c ply03_ply03_loop.c 
 PASS: ./lus2lic {-o /tmp/param_struct.lic should_work/param_struct.lus}
 PASS: ./lus2lic {-ec -o /tmp/param_struct.ec should_work/param_struct.lus}
 PASS: ./myec2c {-o /tmp/param_struct.c /tmp/param_struct.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/param_struct.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/param_struct.lus -n param_struct}
-FAIL: Check that the generated C code compiles  : gcc param_struct_param_struct.c param_struct_param_struct_loop.c 
+PASS: ./lus2lic {-2c should_work/param_struct.lus -n param_struct}
+PASS: gcc param_struct_param_struct.c param_struct_param_struct_loop.c 
 PASS: ./lus2lic {-o /tmp/minmax2.lic should_work/minmax2.lus}
 PASS: ./lus2lic {-ec -o /tmp/minmax2.ec should_work/minmax2.lus}
 PASS: ./myec2c {-o /tmp/minmax2.c /tmp/minmax2.ec}
@@ -575,8 +575,8 @@ PASS: ./lus2lic {-o /tmp/param_node4.lic should_work/param_node4.lus}
 PASS: ./lus2lic {-ec -o /tmp/param_node4.ec should_work/param_node4.lus}
 PASS: ./myec2c {-o /tmp/param_node4.c /tmp/param_node4.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/param_node4.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/param_node4.lus -n param_node4}
-FAIL: Check that the generated C code compiles  : gcc param_node4_param_node4.c param_node4_param_node4_loop.c 
+PASS: ./lus2lic {-2c should_work/param_node4.lus -n param_node4}
+PASS: gcc param_node4_param_node4.c param_node4_param_node4_loop.c 
 PASS: ./lus2lic {-o /tmp/bad_call03.lic should_work/bad_call03.lus}
 PASS: ./lus2lic {-ec -o /tmp/bad_call03.ec should_work/bad_call03.lus}
 PASS: ./myec2c {-o /tmp/bad_call03.c /tmp/bad_call03.ec}
@@ -593,7 +593,7 @@ PASS: ./lus2lic {-o /tmp/produitBool.lic should_work/produitBool.lus}
 PASS: ./lus2lic {-ec -o /tmp/produitBool.ec should_work/produitBool.lus}
 PASS: ./myec2c {-o /tmp/produitBool.c /tmp/produitBool.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/produitBool.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/produitBool.lus -n produitBool}
+PASS: ./lus2lic {-2c should_work/produitBool.lus -n produitBool}
 FAIL: Check that the generated C code compiles  : gcc produitBool_produitBool.c produitBool_produitBool_loop.c 
 PASS: ./lus2lic {-o /tmp/noeudsIndependants.lic should_work/noeudsIndependants.lus}
 PASS: ./lus2lic {-ec -o /tmp/noeudsIndependants.ec should_work/noeudsIndependants.lus}
@@ -611,8 +611,8 @@ PASS: ./lus2lic {-o /tmp/param_node3.lic should_work/param_node3.lus}
 PASS: ./lus2lic {-ec -o /tmp/param_node3.ec should_work/param_node3.lus}
 PASS: ./myec2c {-o /tmp/param_node3.c /tmp/param_node3.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/param_node3.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/param_node3.lus -n param_node3}
-FAIL: Check that the generated C code compiles  : gcc param_node3_param_node3.c param_node3_param_node3_loop.c 
+PASS: ./lus2lic {-2c should_work/param_node3.lus -n param_node3}
+PASS: gcc param_node3_param_node3.c param_node3_param_node3_loop.c 
 PASS: ./lus2lic {-o /tmp/pipeline.lic should_work/pipeline.lus}
 PASS: ./lus2lic {-ec -o /tmp/pipeline.ec should_work/pipeline.lus}
 PASS: ./myec2c {-o /tmp/pipeline.c /tmp/pipeline.ec}
@@ -786,7 +786,7 @@ PASS: ./lus2lic {-o /tmp/left.lic should_work/left.lus}
 PASS: ./lus2lic {-ec -o /tmp/left.ec should_work/left.lus}
 PASS: ./myec2c {-o /tmp/left.c /tmp/left.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/left.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/left.lus -n left}
+PASS: ./lus2lic {-2c should_work/left.lus -n left}
 FAIL: Check that the generated C code compiles  : gcc left_left.c left_left_loop.c 
 PASS: ./lus2lic {-o /tmp/ts04.lic should_work/ts04.lus}
 PASS: ./lus2lic {-ec -o /tmp/ts04.ec should_work/ts04.lus}
@@ -824,7 +824,7 @@ PASS: ./lus2lic {-o /tmp/param_node2.lic should_work/param_node2.lus}
 PASS: ./lus2lic {-ec -o /tmp/param_node2.ec should_work/param_node2.lus}
 PASS: ./myec2c {-o /tmp/param_node2.c /tmp/param_node2.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/param_node2.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/param_node2.lus -n param_node2}
+PASS: ./lus2lic {-2c should_work/param_node2.lus -n param_node2}
 FAIL: Check that the generated C code compiles  : gcc param_node2_param_node2.c param_node2_param_node2_loop.c 
 PASS: ./lus2lic {-o /tmp/o2l_feux_compl.lic should_work/o2l_feux_compl.lus}
 PASS: ./lus2lic {-ec -o /tmp/o2l_feux_compl.ec should_work/o2l_feux_compl.lus}
@@ -983,7 +983,7 @@ PASS: ./lus2lic {-o /tmp/xxx.lic should_work/xxx.lus}
 PASS: ./lus2lic {-ec -o /tmp/xxx.ec should_work/xxx.lus}
 PASS: ./myec2c {-o /tmp/xxx.c /tmp/xxx.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/xxx.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/xxx.lus -n xxx}
+PASS: ./lus2lic {-2c should_work/xxx.lus -n xxx}
 FAIL: Check that the generated C code compiles  : gcc xxx_xxx.c xxx_xxx_loop.c 
 PASS: ./lus2lic {-o /tmp/moyenne.lic should_work/moyenne.lus}
 PASS: ./lus2lic {-ec -o /tmp/moyenne.ec should_work/moyenne.lus}
@@ -1006,8 +1006,8 @@ PASS: ./lus2lic {-o /tmp/bug.lic should_work/bug.lus}
 PASS: ./lus2lic {-ec -o /tmp/bug.ec should_work/bug.lus}
 PASS: ./myec2c {-o /tmp/bug.c /tmp/bug.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/bug.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/bug.lus -n bug}
-FAIL: Check that the generated C code compiles  : gcc bug_bug.c bug_bug_loop.c 
+PASS: ./lus2lic {-2c should_work/bug.lus -n bug}
+PASS: gcc bug_bug.c bug_bug_loop.c 
 PASS: ./lus2lic {-o /tmp/ck4.lic should_work/ck4.lus}
 PASS: ./lus2lic {-ec -o /tmp/ck4.ec should_work/ck4.lus}
 PASS: ./myec2c {-o /tmp/ck4.c /tmp/ck4.ec}
@@ -1111,7 +1111,7 @@ PASS: ./lus2lic {-o /tmp/simpleRed.lic should_work/simpleRed.lus}
 PASS: ./lus2lic {-ec -o /tmp/simpleRed.ec should_work/simpleRed.lus}
 PASS: ./myec2c {-o /tmp/simpleRed.c /tmp/simpleRed.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/simpleRed.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/simpleRed.lus -n simpleRed}
+PASS: ./lus2lic {-2c should_work/simpleRed.lus -n simpleRed}
 FAIL: Check that the generated C code compiles  : gcc simpleRed_simpleRed.c simpleRed_simpleRed_loop.c 
 PASS: ./lus2lic {-o /tmp/map.lic should_work/map.lus}
 PASS: ./lus2lic {-ec -o /tmp/map.ec should_work/map.lus}
@@ -1379,8 +1379,8 @@ PASS: ./lus2lic {-o /tmp/param_node.lic should_work/param_node.lus}
 PASS: ./lus2lic {-ec -o /tmp/param_node.ec should_work/param_node.lus}
 PASS: ./myec2c {-o /tmp/param_node.c /tmp/param_node.ec}
 PASS: ../utils/test_lus2lic_no_node should_work/param_node.lus
-FAIL: Generate c code  : ./lus2lic {-2c should_work/param_node.lus -n param_node}
-FAIL: Check that the generated C code compiles  : gcc param_node_param_node.c param_node_param_node_loop.c 
+PASS: ./lus2lic {-2c should_work/param_node.lus -n param_node}
+PASS: gcc param_node_param_node.c param_node_param_node_loop.c 
 PASS: ./lus2lic {-o /tmp/simple.lic should_work/simple.lus}
 PASS: ./lus2lic {-ec -o /tmp/simple.ec should_work/simple.lus}
 PASS: ./myec2c {-o /tmp/simple.c /tmp/simple.ec}
@@ -1474,9 +1474,9 @@ XPASS: Test bad programs (semantics): lus2lic {-o /tmp/bug.lic should_fail/seman
 
 		=== lus2lic Summary ===
 
-# of expected passes		1131
-# of unexpected failures	273
+# of expected passes		1152
+# of unexpected failures	252
 # of unexpected successes	21
 # of expected failures		37
-testcase ./lus2lic.tests/non-reg.exp completed in 115 seconds
+testcase ./lus2lic.tests/non-reg.exp completed in 116 seconds
 testcase ./lus2lic.tests/progression.exp completed in 0 seconds
diff --git a/test/lus2lic.time b/test/lus2lic.time
index 85a6b7ac..45ce21b1 100644
--- a/test/lus2lic.time
+++ b/test/lus2lic.time
@@ -1,2 +1,2 @@
-testcase ./lus2lic.tests/non-reg.exp completed in 115 seconds
+testcase ./lus2lic.tests/non-reg.exp completed in 116 seconds
 testcase ./lus2lic.tests/progression.exp completed in 0 seconds
diff --git a/test/should_work/trivial_array.lus b/test/should_work/trivial_array.lus
index efc184e0..dc6bbec3 100644
--- a/test/should_work/trivial_array.lus
+++ b/test/should_work/trivial_array.lus
@@ -1,5 +1,5 @@
-node trivial_array(x:bool^2) returns (y: bool^2);
+node trivial_array(x:bool) returns (y: bool^2);
 let
-	y = x;
+	y = x^2;
 tel
 
-- 
GitLab