From 0b053806358355f0092eb53ee86445648a229d41 Mon Sep 17 00:00:00 2001 From: Pascal Raymond <Pascal.Raymond@imag.fr> Date: Tue, 6 Jul 2010 10:48:48 +0200 Subject: [PATCH] Local constants in nodes added --- src/eff.ml | 1 - src/getEff.ml | 1 + src/instanciateModel.ml | 1 + src/lazyCompiler.ml | 121 ++++++++++++++++++++++++- src/licDump.ml | 9 ++ src/licDump.mli | 3 +- src/parserUtils.ml | 3 + src/syntaxTreeCore.ml | 3 +- src/test/should_work/Pascal/access.lus | 24 +++++ src/test/test.res.exp | 107 ++++++++++++++++++++++ src/test/test_ec.res.exp | 6 ++ src/test/test_lv4.res.exp | 28 ++++++ src/verbose.ml | 2 + src/verbose.mli | 1 + 14 files changed, 303 insertions(+), 7 deletions(-) create mode 100644 src/test/should_work/Pascal/access.lus diff --git a/src/eff.ml b/src/eff.ml index ffe1a86a..d6288ec9 100644 --- a/src/eff.ml +++ b/src/eff.ml @@ -387,7 +387,6 @@ type local_env = { lenv_vars : (Ident.t, var_info) Hashtbl.t ; } - let (lookup_type: local_env -> Ident.idref -> Lxm.t -> type_) = fun env id lxm -> Hashtbl.find env.lenv_types (Ident.name_of_idref id) diff --git a/src/getEff.ml b/src/getEff.ml index b78c043c..673e1b28 100644 --- a/src/getEff.ml +++ b/src/getEff.ml @@ -685,6 +685,7 @@ and (translate_predef_static_args: Eff.id_solver -> name = node_alias_ident; static_params = [] ; vars = None; + loc_consts = []; def = Alias { src = lxm_n ; it = by_pos_op }; has_mem = node_eff.has_mem_eff; is_safe = node_eff.is_safe_eff; diff --git a/src/instanciateModel.ml b/src/instanciateModel.ml index b2aa1377..677ef42f 100644 --- a/src/instanciateModel.ml +++ b/src/instanciateModel.ml @@ -74,6 +74,7 @@ let (check_arg : tables -> (Ident.t * static_arg srcflagged) list -> check_arg_a name = s; static_params = sparams; vars = Some (ParserUtils.build_node_var inl outl None); + loc_consts = []; def = Alias (flagit by_pos_op arg.src); has_mem = has_memory; is_safe = true; diff --git a/src/lazyCompiler.ml b/src/lazyCompiler.ml index 7513cbb7..2f3e434d 100644 --- a/src/lazyCompiler.ml +++ b/src/lazyCompiler.ml @@ -14,7 +14,7 @@ let finish_me msg = print_string ("\n\tXXX LazyCompiler:"^msg^" -> finish me!\n stack description. *) exception Recursion_error of (Ident.long as 'id) * (string list as 'stack) - + exception BadCheckRef_error let recursion_error (lxm : Lxm.t) (stack : string list) = @@ -654,12 +654,14 @@ and (node_check_interface_do: t -> Eff.node_key -> Lxm.t -> | _,_ -> prov_node_exp_eff - and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> bool -> Ident.pack_name -> SyntaxTreeCore.node_info srcflagged -> Eff.node_exp) = fun this nk lxm symbols provide_flag pack_name node_def -> let lxm = node_def.src in + (* Creates a local_env with just the global bindings, + local bindinds will be added later (side effect) + *) let local_env = make_local_env nk in let node_id_solver = { (* a [node_id_solver] is a [id_solver] where we begin to look @@ -704,8 +706,119 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> raise (Compile_error (lxm,"\n*** Unknown ident: " ^ (Ident.to_string id))) in - let make_node_eff node_def_eff = + let make_node_eff node_def_eff = ( (* building not aliased nodes *) +Verbose.exe ~level:3 ( fun () -> +Printf.printf "* local_env while entering make_node_eff:\n"; +LicDump.dump_local_env local_env +); + (********************************************************) + (* LOCAL CONSTANTS are evaluated and added to local_env *) + (********************************************************) + (* init intermediate table *) + let sz = List.length node_def.it.loc_consts in + let temp_const_eff_tab : (Ident.long, Eff.const Eff.check_flag) Hashtbl.t = + Hashtbl.create sz + in + let temp_const_def_tab : (Ident.t,(Lxm.t * SyntaxTreeCore.type_exp option * SyntaxTreeCore.val_exp)) Hashtbl.t = + Hashtbl.create sz + in + let init_local_const (lxm, cinfo) = ( + match cinfo with + | DefinedConst (i,topt,ve) -> ( + Verbose.printf ~level:3 " * local const %s will be treated\n" i; + Hashtbl.add temp_const_def_tab i (lxm,topt,ve) + ) + | ExternalConst _ + | EnumConst _ -> ( + let msg = "*** abstract constant bot allowed within node " + in + raise (Compile_error(lxm, msg)) + ) + ) in + List.iter init_local_const node_def.it.loc_consts ; + (* differs from node_id_solver only on id2const *) + let rec local_id_solver = { + id2var = node_id_solver.id2var; + id2const = local_id2const; + id2type = node_id_solver.id2type; + id2node = node_id_solver.id2node; + symbols = node_id_solver.symbols; + } + and treat_local_const id = ( + Verbose.printf ~level:3 " * call treat_local_const %s\n" id; + let id_key = ("", id) in + try ( + let ce = lookup_const_eff temp_const_eff_tab id_key lxm in + Verbose.printf ~level:3 " * const %s already treated = %s\n" id (LicDump.string_of_const_eff ce); + ce + ) with Not_found -> ( + let (lxmdef, toptdef, vedef) = Hashtbl.find temp_const_def_tab id in + Verbose.printf ~level:3 " * const %s not yet treated ...\n" id ; + (* yes, not yet checked *) + Hashtbl.add temp_const_eff_tab id_key Checking ; + (* computes the value with EvalConst.f id_solver ve ... *) + let ce = match (EvalConst.f local_id_solver vedef) with + | [ceff] -> ( + match toptdef with + | None -> ceff + | Some texp -> ( + let tdecl = GetEff.typ local_id_solver texp in + let teff = Eff.type_of_const ceff in + if (tdecl = teff ) then ceff else + raise (Compile_error (lxmdef, Printf.sprintf + " this constant is declared as '%s' but evaluated as '%s'" + (LicDump.string_of_type_eff4msg tdecl) + (LicDump.string_of_type_eff4msg teff) + ))) + ) + | [] -> assert false (* should not occur *) + | _::_ -> raise (Compile_error(lxmdef, "bad constant value: tuple not allowed")) + in + Verbose.printf ~level:3 " * const %s evaluated to %s\n"id (LicDump.string_of_const_eff ce); + Hashtbl.replace temp_const_eff_tab id_key (Checked ce) ; + ce + ) + ) + and local_id2const idrf lxm = ( + (* is id a local const ? *) + try ( + (* certainly NOT if id has a pack *) + let id = if (Ident.pack_of_idref idrf = None) + then Ident.name_of_idref idrf + else raise Not_found + in + let ce = treat_local_const id in + ce + ) with Not_found -> ( + (* not a local constant -> search in global env *) + Verbose.printf ~level:3 " * %s not a local const, should be global ?" (Ident.string_of_idref idrf); + let ce = node_id_solver.id2const idrf lxm in + Verbose.printf ~level:3 " YES -> %s\n" (LicDump.string_of_const_eff ce); + ce + ) + ) in + (* iters local_id2const n eeach declared constant *) + Hashtbl.iter (fun id _ -> let _ = treat_local_const id in ()) temp_const_def_tab ; + (* Finally, adds each local const to ICI *) + let add_local_const idref ceck = ( + Verbose.printf ~level:3 " * add_local_const %s = %s\n" + (snd idref) + (match ceck with + | Checking -> "Checking" + | Checked ce -> (LicDump.string_of_const_eff ce) + | Incorrect -> "Incorrect" + ); + match ceck with + | Checked ce -> Hashtbl.add local_env.lenv_const (snd idref) ce + | _ -> assert false + ) in + Hashtbl.iter add_local_const temp_const_eff_tab ; + + (********************************************************) + (* LOCAL FLOWS are added to local_env *) + (********************************************************) + (* (i.e. ins,outs,locs) *) match node_def.it.vars with | None -> assert false (* a node with a body should have a profile *) | Some vars -> @@ -798,7 +911,7 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> is_safe_eff = node_def.it.is_safe; is_polym_eff = !is_polymorphic } - in + ) in let (make_alias_node : Eff.node_exp -> node_vars option -> Eff.node_exp) = fun aliased_node vars_opt -> (* builds a node that calls the aliased node. It looks like: diff --git a/src/licDump.ml b/src/licDump.ml index fdab05d5..2f2a7103 100644 --- a/src/licDump.ml +++ b/src/licDump.ml @@ -695,3 +695,12 @@ let print_global_node_error lxm nkey msg = ( flush stderr ) + +(* debug *) +let dump_local_env e = ( + let pt i t = Printf.printf "type %s = %s\n" i (string_of_type_eff t) in + Hashtbl.iter pt e.lenv_types; + let pc i t = Printf.printf "const %s = %s\n" i (string_of_const_eff t) in + Hashtbl.iter pc e.lenv_const; +) + diff --git a/src/licDump.mli b/src/licDump.mli index 4c9f36c5..5b6cfba5 100644 --- a/src/licDump.mli +++ b/src/licDump.mli @@ -34,4 +34,5 @@ val string_of_clock2 : Eff.clock -> string val string_of_val_exp_eff : Eff.val_exp -> string val string_of_val_exp_eff_core : Eff.val_exp_core -> string - +(* dump Eff.local_env *) +val dump_local_env : Eff.local_env -> unit diff --git a/src/parserUtils.ml b/src/parserUtils.ml index 2fdb1a69..987a398e 100644 --- a/src/parserUtils.ml +++ b/src/parserUtils.ml @@ -402,6 +402,7 @@ let (treat_node_decl : bool -> Lxm.t -> static_param srcflagged list -> name = nstr; static_params = statics; vars = Some vars; + loc_consts = locconsts; def = Body { asserts = asserts ; eqs = eqs }; has_mem = has_memory; is_safe = true; @@ -426,6 +427,7 @@ let (treat_node_alias : bool -> Lxm.t -> static_param srcflagged list -> name = nstr; static_params = statics; vars = vars; + loc_consts = []; def = Alias (flagit (CALL_n value) value.src); has_mem = has_memory; is_safe = true; @@ -450,6 +452,7 @@ let treat_abstract_or_extern_node_do (* cf the profile of [treat_abstract_node] name = Lxm.id lxm; static_params = []; vars = Some vars; + loc_consts = []; def = if is_abstract then Abstract else Extern; has_mem = has_memory; is_safe = true; diff --git a/src/syntaxTreeCore.ml b/src/syntaxTreeCore.ml index a891707b..071a6084 100644 --- a/src/syntaxTreeCore.ml +++ b/src/syntaxTreeCore.ml @@ -28,6 +28,7 @@ and node_info = { static_params : static_param srcflagged list; vars : node_vars option; (* aliased node may have no i/o decl *) (* consts : ICI A FAIRE *) + loc_consts : (Lxm.t * const_info) list; def : node_def; has_mem : bool; is_safe : bool; @@ -155,7 +156,7 @@ and static_arg = (** constant *) -type const_info = +and const_info = | ExternalConst of (Ident.t * type_exp * val_exp option) | EnumConst of (Ident.t * type_exp) | DefinedConst of (Ident.t * type_exp option * val_exp) diff --git a/src/test/should_work/Pascal/access.lus b/src/test/should_work/Pascal/access.lus new file mode 100644 index 00000000..b9e2f3e8 --- /dev/null +++ b/src/test/should_work/Pascal/access.lus @@ -0,0 +1,24 @@ + +(* Recursive logarithmic, (lustre-v4 like) *) + +node quick_access + <<type t; const sz: int; const dflt: t>> + (tab: t^sz; ix: t) returns (res: t); + +const mid : int = sz div 2; + z2wde = mid + 1; + +let + res = with ( sz = 1) then + if ix = 0 then tab[0] else dflt + else + if ix < mid then + quick_access<<t, mid, dflt>>(tab[0..mid-1], ix) + else + quick_access<<t, sz-mid, dflt>>(tab[mid..sz-1], ix-mid) + ; +tel + +node quick_access_int8 = quick_access<<int, 8, -1>>; + + diff --git a/src/test/test.res.exp b/src/test/test.res.exp index c86c89ba..ac653c65 100644 --- a/src/test/test.res.exp +++ b/src/test/test.res.exp @@ -8423,6 +8423,113 @@ let tel -- end of node v1::v1 +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 should_work/Pascal/access.lus +Opening file should_work/Pascal/access.lus +-- ../lus2lic -vl 2 should_work/Pascal/access.lus + + +node n_access::quick_access_int_1_-1( + tab:A_int_1; + ix:int) +returns ( + res:int); +var + _v_1:bool; + _v_2:int; + _v_3:int; +let + res = _v_3; + _v_1 = ix = 0; + _v_2 = tab[0]; + _v_3 = if _v_1 then _v_2 else -1; +tel +-- end of node n_access::quick_access_int_1_-1 + +node n_access::quick_access_int_2_-1( + tab:A_int_2; + ix:int) +returns ( + res:int); +var + _v_1:bool; + _v_2:A_int_1; + _v_3:int; + _v_4:A_int_1; + _v_5:int; + _v_6:int; + _v_7:int; +let + res = _v_7; + _v_1 = ix < 1; + _v_2 = tab[0 .. 0]; + _v_3 = n_access::quick_access_int_1_-1(_v_2, ix); + _v_4 = tab[1 .. 1]; + _v_5 = ix - 1; + _v_6 = n_access::quick_access_int_1_-1(_v_4, _v_5); + _v_7 = if _v_1 then _v_3 else _v_6; +tel +-- end of node n_access::quick_access_int_2_-1 + +node n_access::quick_access_int_4_-1( + tab:A_int_4; + ix:int) +returns ( + res:int); +var + _v_1:bool; + _v_2:A_int_2; + _v_3:int; + _v_4:A_int_2; + _v_5:int; + _v_6:int; + _v_7:int; +let + res = _v_7; + _v_1 = ix < 2; + _v_2 = tab[0 .. 1]; + _v_3 = n_access::quick_access_int_2_-1(_v_2, ix); + _v_4 = tab[2 .. 3]; + _v_5 = ix - 2; + _v_6 = n_access::quick_access_int_2_-1(_v_4, _v_5); + _v_7 = if _v_1 then _v_3 else _v_6; +tel +-- end of node n_access::quick_access_int_4_-1 + +node n_access::quick_access_int_8_-1( + tab:A_int_8; + ix:int) +returns ( + res:int); +var + _v_1:bool; + _v_2:A_int_4; + _v_3:int; + _v_4:A_int_4; + _v_5:int; + _v_6:int; + _v_7:int; +let + res = _v_7; + _v_1 = ix < 4; + _v_2 = tab[0 .. 3]; + _v_3 = n_access::quick_access_int_4_-1(_v_2, ix); + _v_4 = tab[4 .. 7]; + _v_5 = ix - 4; + _v_6 = n_access::quick_access_int_4_-1(_v_4, _v_5); + _v_7 = if _v_1 then _v_3 else _v_6; +tel +-- end of node n_access::quick_access_int_8_-1 +node access::quick_access_int8(tab:A_int_8; ix:int) returns (res:int); +let + res = n_access::quick_access_int_8_-1(tab, ix); +tel +-- end of node access::quick_access_int8 +-- automatically defined aliases: +type A_int_8 = int^8; +type A_int_2 = int^2; +type A_int_4 = int^4; +type A_int_1 = int^1; ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 should_work/Pascal/consensus.lus Opening file should_work/Pascal/consensus.lus diff --git a/src/test/test_ec.res.exp b/src/test/test_ec.res.exp index 978c958f..e651583c 100644 --- a/src/test/test_ec.res.exp +++ b/src/test/test_ec.res.exp @@ -498,6 +498,12 @@ ec2c /tmp/xx.ec ====> ../lus2lic -vl 2 -ec should_work/NONREG/v1.lus -o /tmp/xx.ec ec2c /tmp/xx.ec +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 -ec should_work/Pascal/access.lus -o /tmp/xx.ec +ec2c /tmp/xx.ec +syntax errors... +syntax error - at line 5 + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 -ec should_work/Pascal/consensus.lus -o /tmp/xx.ec ec2c /tmp/xx.ec diff --git a/src/test/test_lv4.res.exp b/src/test/test_lv4.res.exp index abc55c7a..2e8d3f62 100644 --- a/src/test/test_lv4.res.exp +++ b/src/test/test_lv4.res.exp @@ -791,6 +791,34 @@ lus2ec /tmp/xx.lus uu__uu lus2ec /tmp/xx.lus v1__v1 --Pollux Version 2.3a +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 -lv4 should_work/Pascal/access.lus -o /tmp/xx.lus +lus2ec /tmp/xx.lus n_access__quick_access_int_1_ +--Pollux Version 2.3a + syntax error detected while reading `-` (token 49) line 6 in main file xx.lus + +1 PolluxErrors found +lus2ec /tmp/xx.lus n_access__quick_access_int_2_ +--Pollux Version 2.3a + syntax error detected while reading `-` (token 49) line 6 in main file xx.lus + +1 PolluxErrors found +lus2ec /tmp/xx.lus n_access__quick_access_int_4_ +--Pollux Version 2.3a + syntax error detected while reading `-` (token 49) line 6 in main file xx.lus + +1 PolluxErrors found +lus2ec /tmp/xx.lus n_access__quick_access_int_8_ +--Pollux Version 2.3a + syntax error detected while reading `-` (token 49) line 6 in main file xx.lus + +1 PolluxErrors found +lus2ec /tmp/xx.lus access__quick_access_int8 +--Pollux Version 2.3a + syntax error detected while reading `-` (token 49) line 6 in main file xx.lus + +1 PolluxErrors found + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 -lv4 should_work/Pascal/consensus.lus -o /tmp/xx.lus lus2ec /tmp/xx.lus n_consensus__consensus_1 diff --git a/src/verbose.ml b/src/verbose.ml index 0a278b55..ed10721b 100644 --- a/src/verbose.ml +++ b/src/verbose.ml @@ -36,6 +36,8 @@ let printf ?(level=1) s = Printf.kprintf let print_string ?(level=1) s = if (!_level >= level) then (print_string s; flush stdout) +let exe ?(level=1) p = + if (!_level >= level) then p () (**** VERSION GORE *****) (* diff --git a/src/verbose.mli b/src/verbose.mli index 3124d327..e08817db 100644 --- a/src/verbose.mli +++ b/src/verbose.mli @@ -17,4 +17,5 @@ val set_level : int -> unit val get_level : unit -> int val printf : ?level:int -> ('a, unit, string, unit) format4 -> 'a +val exe : ?level:int -> (unit -> unit) -> unit val print_string : ?level:int -> string -> unit -- GitLab