From acc2dbb3a79f2ba9ed0489bd8bff1bfc31846d4b Mon Sep 17 00:00:00 2001 From: Erwan Jahier <erwan.jahier@univ-grenoble-alpes.fr> Date: Tue, 27 Jun 2017 14:41:45 +0200 Subject: [PATCH] soc2c: the generated C code for '=' and '<>' was wrong in presence of arrays. I've fixed that using memcmp, which should be fine since compared elements are of the same types. --- _oasis | 2 +- src/lv6version.ml | 4 +- src/main.ml | 4 +- src/soc2c.ml | 25 ++++- src/soc2cDep.mli | 4 +- src/soc2cExtern.ml | 6 +- src/soc2cHeap.ml | 21 ++-- src/soc2cHeap.mli | 4 +- src/soc2cPredef.ml | 160 +++++++++++++++++---------- src/soc2cPredef.mli | 6 +- src/soc2cStack.ml | 23 ++-- src/soc2cStack.mli | 4 +- src/soc2cUtil.ml | 2 +- src/socPredef2cHeap.ml | 31 +++++- src/socPredef2cStack.ml | 28 ++++- test/lus2lic.sum | 40 ++++--- test/should_work/array_equals.lus | 4 + test/should_work/struct_equality.lus | 10 ++ utils/compare_exec_and_2c | 2 +- 19 files changed, 253 insertions(+), 127 deletions(-) create mode 100644 test/should_work/struct_equality.lus diff --git a/_oasis b/_oasis index 76579496..03ad8c59 100644 --- a/_oasis +++ b/_oasis @@ -1,6 +1,6 @@ OASISFormat: 0.4 Name: lustre-v6 -Version: 1.699 +Version: 1.700 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/lv6version.ml b/src/lv6version.ml index d78ce7fc..42d29581 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 = "699" -let sha_1 = "e74551e8ee5b3ea2eb120c2bfcaea92ca8940c9e" +let commit = "700" +let sha_1 = "fd3bc9566365dd3042af3302ecab8e9311e76e2d" let str = (branch ^ "." ^ commit ^ " (" ^ sha_1 ^ ")") let maintainer = "jahier@imag.fr" diff --git a/src/main.ml b/src/main.ml index eb61eb00..2f30d2cb 100644 --- a/src/main.ml +++ b/src/main.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 19/10/2016 (at 16:28) by Erwan Jahier> *) +(* Time-stamp: <modified the 27/06/2017 (at 14:26) by Erwan Jahier> *) open Lv6Verbose open AstV6 @@ -229,7 +229,7 @@ let res = if x < 0.0 then -x else x; tel -const seuil = 0.0001; +const seuil = 0.01; node r_equal(x,y:real) returns (res:bool); let res = if r_abs(x)>1.0 then r_abs(1.0-(y/x)) < seuil else r_abs(x-y) < seuil; diff --git a/src/soc2c.ml b/src/soc2c.ml index cf62cccb..f10272e1 100644 --- a/src/soc2c.ml +++ b/src/soc2c.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 01/06/2017 (at 16:12) by Erwan Jahier> *) +(* Time-stamp: <modified the 27/06/2017 (at 11:37) by Erwan Jahier> *) (* let put (os: out_channel) (fmt:('a, unit, string, unit) format4) : 'a = *) @@ -110,12 +110,31 @@ let (step2c : Soc.tbl -> 'a soc_pp -> Soc.step_method -> unit) = (* let sname = Soc2cDep.step_name sp.soc.key sm.name in *) let sname = Soc2cDep.step_name sp.soc.key sm.name in if sm.impl<>Extern then ( - let decl, def = Soc2cDep.get_step_prototype sm sp.soc in + let decl, def, ctype = Soc2cDep.get_step_prototype sm sp.soc in sp.hput (Printf.sprintf "%s\n" decl); sp.cput (Printf.sprintf "%s" def); (match sm.impl with | Extern -> () - | Predef -> sp.cput (Soc2cDep.get_predef_op sp.soc.key) + | Predef -> + (match sp.soc.key with + | ("Lustre::eq",(Array _)::_,_) -> + let str = Printf.sprintf + " *out = memcmp((const void *) i1, (const void *) i2, %s)!=0;\n" ctype in + sp.cput str + | ("Lustre::eq",(Struct _)::_,_) -> + let str = Printf.sprintf + " *out = memcmp((const void *) &i1, (const void *) &i2, %s)!=0;\n" ctype in + sp.cput str + | ("Lustre::neq",(Array _)::_,_) -> + let str = Printf.sprintf + " *out = !memcmp((const void *) i1, (const void *) i2, %s)!=0;\n" ctype in + sp.cput str + | ("Lustre::neq",(Struct _)::_,_) -> + let str = Printf.sprintf + " *out = !memcmp((const void *) &i1, (const void *) &i2, %s)!=0;\n" ctype in + sp.cput str + | n -> sp.cput (Soc2cDep.get_predef_op n) + ) | Gaol(vl, gaol) -> ( if Lv6MainArgs.global_opt.Lv6MainArgs.gen_wcet then List.iter diff --git a/src/soc2cDep.mli b/src/soc2cDep.mli index 6e4aeddd..a2637d99 100644 --- a/src/soc2cDep.mli +++ b/src/soc2cDep.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 06/10/2016 (at 17:28) by Erwan Jahier> *) +(* Time-stamp: <modified the 26/06/2017 (at 16:39) by Erwan Jahier> *) (** Choose between the various C code generators (heap-based, Stack @@ -20,7 +20,7 @@ val step_name : Soc.key -> string -> string "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 get_step_prototype : Soc.step_method -> Soc.t -> string * string * string val string_of_var_expr: Soc.t -> Soc.var_expr -> string diff --git a/src/soc2cExtern.ml b/src/soc2cExtern.ml index b9f12dbd..c41a065e 100644 --- a/src/soc2cExtern.ml +++ b/src/soc2cExtern.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 05/05/2017 (at 14:14) by Erwan Jahier> *) +(* Time-stamp: <modified the 26/06/2017 (at 16:39) by Erwan Jahier> *) open Soc2cIdent @@ -141,7 +141,7 @@ let (gen_files : Soc.t -> Soc.tbl -> LicPrg.t -> string -> string -> string -> List.iter (fun (sm,soc) -> let sname = Soc2cDep.step_name soc.key sm.name in - let proto_decl,_ = Soc2cDep.get_step_prototype sm soc in + let proto_decl,_,_ = Soc2cDep.get_step_prototype sm soc in output_string ext_och proto_decl; ) extern_steps; close_out ext_och; @@ -156,7 +156,7 @@ let (gen_files : Soc.t -> Soc.tbl -> LicPrg.t -> string -> string -> string -> output_string ext_occ (const_def licprg); List.iter (fun (sm,soc) -> let sname = Soc2cDep.step_name soc.key sm.name in - let _,proto_begin = Soc2cDep.get_step_prototype sm soc in + let _,proto_begin,_ = Soc2cDep.get_step_prototype sm soc in output_string ext_occ proto_begin; output_string ext_occ (Printf.sprintf " /* finish me! */\n}\n") ) extern_steps; diff --git a/src/soc2cHeap.ml b/src/soc2cHeap.ml index 50899fc1..197a0b4e 100644 --- a/src/soc2cHeap.ml +++ b/src/soc2cHeap.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 23/06/2017 (at 13:57) by Erwan Jahier> *) +(* Time-stamp: <modified the 27/06/2017 (at 11:27) by Erwan Jahier> *) open Soc2cUtil open Soc2cIdent @@ -99,17 +99,15 @@ let (inline_soc : (String.concat " " le)^ " }\n" in Some str - | "Lustre::diff" -> assert false - | "Lustre::equal" -> assert false | _ -> try if Lv6MainArgs.global_opt.Lv6MainArgs.gen_c_inline_predef - && Soc2cPredef.is_call_supported called_soc_name + && Soc2cPredef.is_call_supported called_soc.key then let vel_in = List.map (string_of_var_expr soc) vel_in in let vel_out = List.map (string_of_var_expr soc) vel_out in - Some (Soc2cPredef.gen_call called_soc_name soc vel_out vel_in) + Some (Soc2cPredef.gen_call called_soc.key soc vel_out vel_in) else None with Not_found -> @@ -119,7 +117,7 @@ let (inline_soc : let (inlined_soc : Soc.key -> bool) = fun key -> let soc_name,_,_ = key in - soc_name = "Lustre::if" || Soc2cPredef.is_call_supported soc_name + soc_name = "Lustre::if" || Soc2cPredef.is_call_supported key (* exported *) @@ -189,7 +187,7 @@ let (typedef_of_soc : Soc.t -> string) = 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) = +let (get_step_prototype : Soc.step_method -> Soc.t -> string * string * string) = fun sm soc -> let sname = step_name soc.key sm.name in let ctx = if SocUtils.is_memory_less soc then "" else @@ -198,5 +196,12 @@ let (get_step_prototype : Soc.step_method -> Soc.t -> string * string) = let ctx_decl = if SocUtils.is_memory_less soc then "" else Printf.sprintf "%s_type*" (get_ctx_name soc.key) in + let inputs, _ = soc.Soc.profile in + let ctype = match inputs with + | (_,t)::_ -> + Printf.sprintf "sizeof(%s)" (Soc2cUtil.data_type_to_c t "") + | [] -> "" (* soc without intputs won't need this output *) + in Printf.sprintf "void %s(%s);\n" sname ctx_decl, - Printf.sprintf "void %s(%s){\n" sname ctx + Printf.sprintf "void %s(%s){\n" sname ctx, + ctype diff --git a/src/soc2cHeap.mli b/src/soc2cHeap.mli index 5af3a1b4..53a6d726 100644 --- a/src/soc2cHeap.mli +++ b/src/soc2cHeap.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 06/10/2016 (at 17:29) by Erwan Jahier> *) +(* Time-stamp: <modified the 26/06/2017 (at 16:41) by Erwan Jahier> *) (** Gathers all entities (functions, types) that implement the heap-based C generator. *) @@ -13,7 +13,7 @@ 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 get_step_prototype : Soc.step_method -> Soc.t -> string * string * string val string_of_var_expr: Soc.t -> Soc.var_expr -> string diff --git a/src/soc2cPredef.ml b/src/soc2cPredef.ml index 8c4152a8..7bb3fb8a 100644 --- a/src/soc2cPredef.ml +++ b/src/soc2cPredef.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 06/10/2016 (at 17:32) by Erwan Jahier> *) +(* Time-stamp: <modified the 27/06/2017 (at 14:40) by Erwan Jahier> *) (* A local exception used to check if a predef is supported. The idea is that when gen_call_do is called with empty lists, @@ -9,12 +9,42 @@ *) exception Is_supported -let stdbin op ll rl = +let stdbin op ll rl = match (ll,rl) with | ([l], [r1;r2]) -> Printf.sprintf " %s = %s %s %s;\n" l r1 op r2 | ([],[]) -> raise Is_supported | _ -> assert false +(* to deal with == and <> over arrays *) +let stdbin_eq_array is_eq (op,tl,_) ll rl = + let cast = "(const void *)" in + let ctype = match tl with + | t::_ -> Printf.sprintf "sizeof(%s)" (Soc2cUtil.data_type_to_c t "") + | [] -> assert false + in + let not_opt = if is_eq then "" else "!" in + match (ll,rl) with + | ([l], [r1;r2]) -> + Printf.sprintf " %s = %smemcmp(%s %s, %s %s, %s)!=0;\n" + l not_opt cast r1 cast r2 ctype + | ([],[]) -> raise Is_supported + | _ -> assert false + +(* to deal with == and <> over structs *) +let stdbin_eq_struct is_eq (op,tl,_) ll rl = + let cast = "(const void *)" in + let ctype = match tl with + | t::_ -> Printf.sprintf "sizeof(%s)" (Soc2cUtil.data_type_to_c t "") + | [] -> assert false + in + let not_opt = if is_eq then "" else "!" in + match (ll,rl) with + | ([l], [r1;r2]) -> + Printf.sprintf " %s = %smemcmp(%s &%s, %s &%s, %s)!=0;\n" + l not_opt cast r1 cast r2 ctype + | ([],[]) -> raise Is_supported + | _ -> assert false + let stduna op ll rl = match (ll,rl) with | ([l], [r]) -> Printf.sprintf " %s = %s %s;\n" l op r @@ -30,65 +60,77 @@ let stdimpl ll rl = (* exported *) (* ZZZ code dupl with SocPredef2cHeap.get_predef_op *) -let (gen_call_do : string -> string list -> string list -> string) = - fun op vel_in vel_out -> - let lstduna str = stduna str vel_in vel_out in - let lstdbin str = stdbin str vel_in vel_out in - let lstdimpl () = stdimpl vel_in vel_out in - match op with - | "Lustre::uminus" -> lstduna "-" - | "Lustre::iuminus" -> lstduna "-" - | "Lustre::ruminus" -> lstduna "-" - | "Lustre::not" -> lstduna "!" - - | "Lustre::mod" -> lstdbin "%" - | "Lustre::plus" -> lstdbin "+" - | "Lustre::iplus" -> lstdbin "+" - | "Lustre::rplus" -> lstdbin "+" - | "Lustre::times" -> lstdbin "*" - | "Lustre::itimes" -> lstdbin "*" - | "Lustre::rtimes" -> lstdbin "*" - | "Lustre::div" -> lstdbin "/" - | "Lustre::idiv" -> lstdbin "/" - | "Lustre::rdiv" -> lstdbin "/" - | "Lustre::minus" -> lstdbin "-" - | "Lustre::iminus" -> lstdbin "-" - | "Lustre::rminus" -> lstdbin "-" - - | "Lustre::real2int" -> lstduna "(_integer)" - | "Lustre::int2real" -> lstduna "(_real)" - - | "Lustre::lt" -> lstdbin "<" - | "Lustre::ilt" -> lstdbin "<" - | "Lustre::rlt" -> lstdbin "<" - | "Lustre::gt" -> lstdbin ">" - | "Lustre::igt" -> lstdbin ">" - | "Lustre::rgt" -> lstdbin ">" - | "Lustre::lte" -> lstdbin "<=" - | "Lustre::ilte"-> lstdbin "<=" - | "Lustre::rlte"-> lstdbin "<=" - | "Lustre::gte" -> lstdbin ">=" - | "Lustre::igte"-> lstdbin ">=" - | "Lustre::rgte"-> lstdbin ">=" - - | "Lustre::and" -> lstdbin "&" - | "Lustre::or" -> lstdbin "|" - | "Lustre::xor" -> lstdbin "!=" - | "Lustre::impl" -> lstdimpl () - - | "Lustre::equal" -> lstdbin "==" - | "Lustre::diff" -> lstdbin "!=" - - | _ -> raise Not_found - -let (gen_call : string -> Soc.t -> string list -> string list -> string) = - fun op soc vel_in vel_out -> +let (gen_call_do : Soc.key -> string list -> string list -> string) = + fun sk vel_in vel_out -> + let (op,tl,_) = sk in + let lstduna str = stduna str vel_in vel_out in + let lstdbin str = stdbin str vel_in vel_out in + let lstdimpl () = stdimpl vel_in vel_out in + match sk with + | "Lustre::uminus",_,_ -> lstduna "-" + | "Lustre::iuminus",_,_ -> lstduna "-" + | "Lustre::ruminus",_,_ -> lstduna "-" + | "Lustre::not",_,_ -> lstduna "!" + + | "Lustre::mod",_,_ -> lstdbin "%" + | "Lustre::plus",_,_ -> lstdbin "+" + | "Lustre::iplus",_,_ -> lstdbin "+" + | "Lustre::rplus",_,_ -> lstdbin "+" + | "Lustre::times",_,_ -> lstdbin "*" + | "Lustre::itimes",_,_ -> lstdbin "*" + | "Lustre::rtimes",_,_ -> lstdbin "*" + | "Lustre::div",_,_ -> lstdbin "/" + | "Lustre::idiv",_,_ -> lstdbin "/" + | "Lustre::rdiv",_,_ -> lstdbin "/" + | "Lustre::minus",_,_ -> lstdbin "-" + | "Lustre::iminus",_,_ -> lstdbin "-" + | "Lustre::rminus",_,_ -> lstdbin "-" + + | "Lustre::real2int",_,_ -> lstduna "(_integer)" + | "Lustre::int2real",_,_ -> lstduna "(_real)" + + | "Lustre::lt",_,_ -> lstdbin "<" + | "Lustre::ilt",_,_ -> lstdbin "<" + | "Lustre::rlt",_,_ -> lstdbin "<" + | "Lustre::gt",_,_ -> lstdbin ">" + | "Lustre::igt",_,_ -> lstdbin ">" + | "Lustre::rgt",_,_ -> lstdbin ">" + | "Lustre::lte",_,_ -> lstdbin "<=" + | "Lustre::ilte",_,_-> lstdbin "<=" + | "Lustre::rlte",_,_-> lstdbin "<=" + | "Lustre::gte",_,_ -> lstdbin ">=" + | "Lustre::igte",_,_-> lstdbin ">=" + | "Lustre::rgte",_,_-> lstdbin ">=" + + | "Lustre::and",_,_ -> lstdbin "&" + | "Lustre::or",_,_ -> lstdbin "|" + | "Lustre::xor",_,_ -> lstdbin "!=" + | "Lustre::impl",_,_ -> lstdimpl () + + | (("Lustre::eq"|"Lustre::equal"),(Array _)::_,_) -> + stdbin_eq_array true sk vel_in vel_out + | (("Lustre::neq"|"Lustre::diff"),(Array _)::_,_) -> + stdbin_eq_array false sk vel_in vel_out + | (("Lustre::eq"|"Lustre::equal"),(Struct _)::_,_)-> + stdbin_eq_struct true sk vel_in vel_out + | (("Lustre::neq"|"Lustre::diff"),(Struct _)::_,_)-> + stdbin_eq_struct false sk vel_in vel_out + + | "Lustre::eq",_,_ -> lstdbin "==" + | "Lustre::equal",_,_ -> lstdbin "==" + | "Lustre::neq",_,_ -> lstdbin "!=" + | "Lustre::diff",_,_ -> lstdbin "!=" + + | _ -> raise Not_found + +let (gen_call : Soc.key -> Soc.t -> string list -> string list -> string) = + fun sk soc vel_in vel_out -> assert ((vel_in,vel_out) <> ([],[])); - gen_call_do op vel_in vel_out + gen_call_do sk vel_in vel_out -let (is_call_supported : string -> bool) = - fun op -> - try ignore (gen_call_do op [] []); assert false (* sno *) +let (is_call_supported : Soc.key -> bool) = + fun sk -> + try ignore (gen_call_do sk [] []); assert false (* sno *) with | Is_supported -> true | Not_found -> false diff --git a/src/soc2cPredef.mli b/src/soc2cPredef.mli index f4aaeef6..a1d27e21 100644 --- a/src/soc2cPredef.mli +++ b/src/soc2cPredef.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 06/10/2016 (at 17:32) by Erwan Jahier> *) +(* Time-stamp: <modified the 27/06/2017 (at 11:10) by Erwan Jahier> *) (* provides a direct definition to predefined arith operators. @@ -6,6 +6,6 @@ raises Not_found if it is not used with such a predef op *) -val gen_call : string -> Soc.t -> string list -> string list -> string +val gen_call : Soc.key -> Soc.t -> string list -> string list -> string -val is_call_supported : string -> bool +val is_call_supported : Soc.key -> bool diff --git a/src/soc2cStack.ml b/src/soc2cStack.ml index c827954f..21ae4437 100644 --- a/src/soc2cStack.ml +++ b/src/soc2cStack.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 23/06/2017 (at 11:16) by Erwan Jahier> *) +(* Time-stamp: <modified the 27/06/2017 (at 11:28) by Erwan Jahier> *) open Soc2cUtil open Soc2cIdent @@ -137,14 +137,12 @@ let (inline_soc: Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list -> (String.concat " " le)^ " }\n" in Some str - | "Lustre::diff" -> assert false - | "Lustre::equal" -> assert false | _ -> try if Lv6MainArgs.global_opt.Lv6MainArgs.gen_c_inline_predef - && Soc2cPredef.is_call_supported called_soc_name + && Soc2cPredef.is_call_supported called_soc.key then let vel_in_str = List.map (string_of_var_expr soc) vel_in in let vel_in = List.map2 @@ -157,7 +155,7 @@ let (inline_soc: Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list -> (fun v s -> if is_soc_output v soc && ve_not_an_array v then "*"^s else s) vel_out vel_out_str in - Some (Soc2cPredef.gen_call called_soc_name soc vel_out vel_in) + Some (Soc2cPredef.gen_call called_soc.key soc vel_out vel_in) else None with Not_found -> @@ -167,7 +165,7 @@ let (inline_soc: Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list -> let (inlined_soc : Soc.key -> bool) = fun key -> let soc_name,_,_ = key in - soc_name = "Lustre::if" || Soc2cPredef.is_call_supported soc_name + soc_name = "Lustre::if" || Soc2cPredef.is_call_supported key (* exported *) @@ -229,7 +227,7 @@ let (typedef_of_soc : Soc.t -> string) = "void step(int x, int y, int* res, soc_ctx_type* ctx){" *) -let (get_step_prototype : Soc.step_method -> Soc.t -> string * string) = +let (get_step_prototype : Soc.step_method -> Soc.t -> string * string * string) = fun sm soc -> let sname = step_name soc.key sm.name in let inputs, outputs = soc.Soc.profile in @@ -254,11 +252,18 @@ let (get_step_prototype : Soc.step_method -> Soc.t -> string * string) = let out_params_decl = List.map (to_param_decl true) outputs in let params = String.concat "," (in_params@out_params) in let params_decl = String.concat "," (in_params_decl@out_params_decl) in + let ctype = match inputs with + | (_,t)::_ -> + Printf.sprintf "sizeof(%s)" (Soc2cUtil.data_type_to_c t "") + | [] -> "" (* soc without intputs won't need this output *) + 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 + Printf.sprintf "void %s(%s){\n" sname params, + ctype 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){" sname params ctx + Printf.sprintf "void %s(%s,%s){" sname params ctx, + ctype diff --git a/src/soc2cStack.mli b/src/soc2cStack.mli index 44b7044d..0876d028 100644 --- a/src/soc2cStack.mli +++ b/src/soc2cStack.mli @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 06/10/2016 (at 17:28) by Erwan Jahier> *) +(* Time-stamp: <modified the 26/06/2017 (at 16:41) by Erwan Jahier> *) (** Gathers all entities (functions, types) that implement the heap-based C generator. *) @@ -21,7 +21,7 @@ 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 get_step_prototype : Soc.step_method -> Soc.t -> string * string * string val string_of_var_expr: Soc.t -> Soc.var_expr -> string diff --git a/src/soc2cUtil.ml b/src/soc2cUtil.ml index c121c7e2..0064d6ae 100644 --- a/src/soc2cUtil.ml +++ b/src/soc2cUtil.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 21/11/2016 (at 17:03) by Erwan Jahier> *) +(* Time-stamp: <modified the 26/06/2017 (at 17:00) by Erwan Jahier> *) open Soc2cIdent open Data diff --git a/src/socPredef2cHeap.ml b/src/socPredef2cHeap.ml index 44509b58..db4e51cf 100644 --- a/src/socPredef2cHeap.ml +++ b/src/socPredef2cHeap.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 10/01/2017 (at 17:59) by Erwan Jahier> *) +(* Time-stamp: <modified the 27/06/2017 (at 11:38) by Erwan Jahier> *) open Data open Soc @@ -6,13 +6,30 @@ 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 -> - let ctx = get_ctx_name sk in - Printf.sprintf " %s.out = (%s.i1 %s %s.i2);\n" ctx ctx op ctx + let ctx = get_ctx_name sk in + let cast = "(const void *)" in + let ctype = match sk with + | _,t::_,_ -> Printf.sprintf "sizeof(%s)" (Soc2cUtil.data_type_to_c t "") + | _, [],_ -> assert false + in + (match sk with + | (("Lustre::eq"|"Lustre::equal"),(Array _)::_,_) -> + Printf.sprintf " %s.out = memcmp(%s %s.i1, %s %s.i2, %s)!=0;\n" + ctx ctx cast ctx cast ctype + | (("Lustre::eq"|"Lustre::equal"),(Struct _)::_,_) -> + Printf.sprintf " %s.out = memcmp(%s &%s.i1, %s &%s.i2, %s)!=0;\n" + ctx ctx cast ctx cast ctype + | (("Lustre::neq"|"Lustre::diff"),(Array _)::_,_) -> + Printf.sprintf " %s.out = !memcmp(%s %s.i1, %s %s.i2, %s)!=0;\n" + ctx ctx cast ctx cast ctype + | (("Lustre::neq"|"Lustre::diff"),(Struct _)::_,_) -> + Printf.sprintf " %s.out = !memcmp(%s &%s.i1, %s &%s.i2, %s)!=0;\n" + ctx ctx cast ctx cast ctype + | _ -> + Printf.sprintf " %s.out = (%s.i1 %s %s.i2);\n" ctx ctx op ctx + ) let (lustre_unop : Soc.key -> string -> string) = fun sk op -> @@ -155,9 +172,11 @@ let (get_predef_op: Soc.key -> string) = | "Lustre::ruminus"-> lustre_unop sk "-" | "Lustre::eq" -> lustre_binop sk "==" + | "Lustre::equal" -> lustre_binop sk "==" | "Lustre::and" -> lustre_binop sk "&&" | "Lustre::neq" -> lustre_binop sk "!=" + | "Lustre::diff" -> lustre_binop sk "!=" | "Lustre::or" -> lustre_binop sk "||" | "Lustre::xor" -> lustre_binop sk "!=" diff --git a/src/socPredef2cStack.ml b/src/socPredef2cStack.ml index 8260a645..a2b2111d 100644 --- a/src/socPredef2cStack.ml +++ b/src/socPredef2cStack.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 10/01/2017 (at 18:04) by Erwan Jahier> *) +(* Time-stamp: <modified the 27/06/2017 (at 11:38) by Erwan Jahier> *) open Data open Soc @@ -6,12 +6,26 @@ 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 " *out = (i1 %s i2);\n" op + fun sk op -> + let cast = "(const void *)" in + let ctype = match sk with + | _,t::_,_ -> Printf.sprintf "sizeof(%s)" (Soc2cUtil.data_type_to_c t "") + | _, [],_ -> assert false + in + (match sk with + | (("Lustre::eq"|"Lustre::equal"),(Array _)::_,_) -> + Printf.sprintf " *out = memcmp(%s i1, %s i2, %s)!=0;\n" cast cast ctype + | (("Lustre::eq"|"Lustre::equal"),(Struct _)::_,_) -> + Printf.sprintf " *out = memcmp(%s &i1, %s &i2, %s)!=0;\n" cast cast ctype + | (("Lustre::neq"|"Lustre::diff"),(Array _)::_,_) -> + Printf.sprintf " *out = !memcmp(%s i1, %s i2, %s)!=0;\n" cast cast ctype + | (("Lustre::neq"|"Lustre::diff"),(Struct _)::_,_) -> + Printf.sprintf " *out = !memcmp(%s &i1, %s &i2, %s)!=0;\n" cast cast ctype + + | _ -> + Printf.sprintf " *out = (i1 %s i2);\n" op + ) let (lustre_unop : Soc.key -> string -> string) = fun sk op -> @@ -160,9 +174,11 @@ let (get_predef_op: Soc.key -> string) = | "Lustre::ruminus"-> lustre_unop sk "-" | "Lustre::eq" -> lustre_binop sk "==" + | "Lustre::equal" -> lustre_binop sk "==" | "Lustre::and" -> lustre_binop sk "&&" | "Lustre::neq" -> lustre_binop sk "!=" + | "Lustre::diff" -> lustre_binop sk "!=" | "Lustre::or" -> lustre_binop sk "||" | "Lustre::xor" -> lustre_binop sk "!=" diff --git a/test/lus2lic.sum b/test/lus2lic.sum index 0f056dd2..92485024 100644 --- a/test/lus2lic.sum +++ b/test/lus2lic.sum @@ -1,5 +1,5 @@ ==> lus2lic0.sum <== -Test Run By jahier on Fri Jun 23 10:28:36 +Test Run By jahier on Tue Jun 27 14:29:44 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 Fri Jun 23 10:28:36 +Test Run By jahier on Tue Jun 27 14:29:45 Native configuration is x86_64-unknown-linux-gnu === lus2lic1 tests === @@ -401,7 +401,7 @@ PASS: sh multipar.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c multipar.lus {} ==> lus2lic2.sum <== -Test Run By jahier on Fri Jun 23 10:29:29 +Test Run By jahier on Tue Jun 27 14:30:37 Native configuration is x86_64-unknown-linux-gnu === lus2lic2 tests === @@ -621,6 +621,9 @@ PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c stopwatch.lus {} PASS: ./lus2lic {-2c struct0.lus -n struct0} PASS: sh struct0.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c struct0.lus {} +PASS: ./lus2lic {-2c struct_equality.lus -n struct_equality} +PASS: sh struct_equality.sh +FAIL: Try to compare lus2lic -exec and -2c: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c struct_equality.lus {} PASS: ./lus2lic {-2c struct_with.lus -n struct_with} PASS: sh struct_with.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c struct_with.lus {} @@ -741,7 +744,7 @@ PASS: sh zzz2.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c zzz2.lus {} ==> lus2lic3.sum <== -Test Run By jahier on Fri Jun 23 10:30:40 +Test Run By jahier on Tue Jun 27 14:31:50 Native configuration is x86_64-unknown-linux-gnu === lus2lic3 tests === @@ -1249,7 +1252,7 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node multipar.lus {} ==> lus2lic4.sum <== -Test Run By jahier on Fri Jun 23 10:32:56 +Test Run By jahier on Tue Jun 27 14:34:05 Native configuration is x86_64-unknown-linux-gnu === lus2lic4 tests === @@ -1558,6 +1561,9 @@ PASS: ./lus2lic {-o struct0.lic struct0.lus} PASS: ./lus2lic {-ec -o struct0.ec struct0.lus} PASS: ./myec2c {-o struct0.c struct0.ec} PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node struct0.lus {} +PASS: ./lus2lic {-o struct_equality.lic struct_equality.lus} +PASS: ./lus2lic {-ec -o struct_equality.ec struct_equality.lus} +FAIL: Try ec2c on the result: ./myec2c {-o struct_equality.c struct_equality.ec} PASS: ./lus2lic {-o struct_with.lic struct_with.lus} PASS: ./lus2lic {-ec -o struct_with.ec struct_with.lus} PASS: ./myec2c {-o struct_with.c struct_with.ec} @@ -1748,8 +1754,8 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node zzz2.lus {} === lus2lic2 Summary === -# of expected passes 327 -# of unexpected failures 1 +# of expected passes 329 +# of unexpected failures 2 ==> lus2lic3.sum <== === lus2lic3 Summary === @@ -1762,18 +1768,18 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node zzz2.lus {} === lus2lic4 Summary === -# of expected passes 465 -# of unexpected failures 6 +# of expected passes 467 +# of unexpected failures 7 =============================== -# Total number of failures: 23 +# Total number of failures: 25 lus2lic0.log:testcase ./lus2lic.tests/test0.exp completed in 0 seconds lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 52 seconds -lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 71 seconds -lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 136 seconds -lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 65 seconds +lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 72 seconds +lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 135 seconds +lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 64 seconds * Ref time: -0.04user 0.03system 5:25.43elapsed 0%CPU (0avgtext+0avgdata 5624maxresident)k -160inputs+0outputs (0major+6173minor)pagefaults 0swaps +0.05user 0.02system 5:30.19elapsed 0%CPU (0avgtext+0avgdata 5548maxresident)k +64inputs+0outputs (0major+6187minor)pagefaults 0swaps * Quick time (-j 4): -0.04user 0.04system 2:18.88elapsed 0%CPU (0avgtext+0avgdata 5620maxresident)k -96inputs+0outputs (0major+6165minor)pagefaults 0swaps +0.05user 0.02system 2:39.50elapsed 0%CPU (0avgtext+0avgdata 5672maxresident)k +128inputs+0outputs (0major+6172minor)pagefaults 0swaps diff --git a/test/should_work/array_equals.lus b/test/should_work/array_equals.lus index 96cfcdf3..f788fa72 100644 --- a/test/should_work/array_equals.lus +++ b/test/should_work/array_equals.lus @@ -2,5 +2,9 @@ node array_equals(x,y:bool^2) returns (res:bool); let res = (x=y); +tel +node array_not_equals(x,y:bool^2) returns (res:bool); +let + res = (x<>y); tel -- end of some_node \ No newline at end of file diff --git a/test/should_work/struct_equality.lus b/test/should_work/struct_equality.lus new file mode 100644 index 00000000..660b636f --- /dev/null +++ b/test/should_work/struct_equality.lus @@ -0,0 +1,10 @@ +type complex = struct { + re : real = 42.0; + im : real = 42.0; +}; + +node struct_equality(a,b : complex) returns (res:bool); +let + res = a=b; +tel + -- end of struct_equality \ No newline at end of file diff --git a/utils/compare_exec_and_2c b/utils/compare_exec_and_2c index 7dc92dd8..27256278 100755 --- a/utils/compare_exec_and_2c +++ b/utils/compare_exec_and_2c @@ -51,7 +51,7 @@ PRECISION=4 if lurette -l 10 -o xxx.rif \ -sut "./$node.exec" \ - -env "lutin $env -n $env_node -p $PRECISION" \ + -env "lutin $env -n $env_node -p $PRECISION -seed 42" \ -oracle "lus2lic $_oracle -n $oracle $OPT"; # lurettetop_exe -p $PRECISION -rp "sut:socket:127.0.0.1:$PORT" -rp "env:lutin:$env:-p:$PRECISION" -rp "oracle:v6:$_oracle:$oracle:$OPT" \ # -go -l 10 -ns2c --stop-on-oracle-error; -- GitLab