Skip to content
Snippets Groups Projects
Commit 5fccce23 authored by Pierre Loic Garoche's avatar Pierre Loic Garoche
Browse files

- Dep type with a tuple has been replaced by a record type

- Modules now is more integrated and performed the building of the type/clock env.
  previously some computation were performed twice by different functions. Some of these functions have been moved from compiler_common to modules
parent f9f06e7d
No related branches found
No related tags found
No related merge requests found
...@@ -470,26 +470,26 @@ let print_stateless_C_prototype fmt (name, inputs, outputs) = ...@@ -470,26 +470,26 @@ let print_stateless_C_prototype fmt (name, inputs, outputs) =
name name
(Utils.fprintf_list ~sep:",@ " pp_c_decl_input_var) inputs (Utils.fprintf_list ~sep:",@ " pp_c_decl_input_var) inputs
let print_import_init fmt (Dep (local, basename, _, _)) = let print_import_init fmt dep =
if local then if dep.local then
let baseNAME = file_to_module_name basename in let baseNAME = file_to_module_name dep.name in
fprintf fmt "%a();" pp_global_init_name baseNAME fprintf fmt "%a();" pp_global_init_name baseNAME
else () else ()
let print_import_clear fmt (Dep (local, basename, _, _)) = let print_import_clear fmt dep =
if local then if dep.local then
let baseNAME = file_to_module_name basename in let baseNAME = file_to_module_name dep.name in
fprintf fmt "%a();" pp_global_clear_name baseNAME fprintf fmt "%a();" pp_global_clear_name baseNAME
else () else ()
let print_import_prototype fmt (Dep (_, s, _, _)) = let print_import_prototype fmt dep =
fprintf fmt "#include \"%s.h\"@," s fprintf fmt "#include \"%s.h\"@," dep.name
let print_import_alloc_prototype fmt (Dep (_, s, _, stateful)) = let print_import_alloc_prototype fmt dep =
if stateful then if dep.is_stateful then
fprintf fmt "#include \"%s_alloc.h\"@," s fprintf fmt "#include \"%s_alloc.h\"@," dep.name
let print_extern_alloc_prototypes fmt (Dep (_,_, header,_)) = let print_extern_alloc_prototypes fmt dep =
List.iter (fun decl -> match decl.top_decl_desc with List.iter (fun decl -> match decl.top_decl_desc with
| ImportedNode ind when not ind.nodei_stateless -> | ImportedNode ind when not ind.nodei_stateless ->
let static = List.filter (fun v -> v.var_dec_const) ind.nodei_inputs in let static = List.filter (fun v -> v.var_dec_const) ind.nodei_inputs in
...@@ -498,7 +498,7 @@ let print_extern_alloc_prototypes fmt (Dep (_,_, header,_)) = ...@@ -498,7 +498,7 @@ let print_extern_alloc_prototypes fmt (Dep (_,_, header,_)) =
fprintf fmt "extern %a;@.@." print_dealloc_prototype ind.nodei_id; fprintf fmt "extern %a;@.@." print_dealloc_prototype ind.nodei_id;
end end
| _ -> () | _ -> ()
) header ) dep.content
let pp_c_main_var_input fmt id = let pp_c_main_var_input fmt id =
......
...@@ -391,7 +391,7 @@ let print_alloc_header header_fmt basename prog machines dependencies = ...@@ -391,7 +391,7 @@ let print_alloc_header header_fmt basename prog machines dependencies =
(* Import the header *) (* Import the header *)
fprintf header_fmt "/* Import header from %s */@." basename; fprintf header_fmt "/* Import header from %s */@." basename;
fprintf header_fmt "@[<v>"; fprintf header_fmt "@[<v>";
print_import_prototype header_fmt (Dep (true, basename, [], true (* assuming it is staful *) )); print_import_prototype header_fmt {local=true; name=basename; content=[]; is_stateful=true} (* assuming it is staful *);
fprintf header_fmt "@]@."; fprintf header_fmt "@]@.";
fprintf header_fmt "/* Import dependencies */@."; fprintf header_fmt "/* Import dependencies */@.";
fprintf header_fmt "@[<v>"; fprintf header_fmt "@[<v>";
...@@ -434,7 +434,7 @@ let print_header_from_header header_fmt basename header = ...@@ -434,7 +434,7 @@ let print_header_from_header header_fmt basename header =
List.iter List.iter
(fun dep -> (fun dep ->
let (local, s) = dependency_of_top dep in let (local, s) = dependency_of_top dep in
print_import_prototype header_fmt (Dep (local, s, [], true (* assuming it is stateful *)))) print_import_prototype header_fmt {local=local; name=s; content=[]; is_stateful=true} (* assuming it is stateful *))
dependencies; dependencies;
fprintf header_fmt "@]@."; fprintf header_fmt "@]@.";
fprintf header_fmt "/* Types definitions */@."; fprintf header_fmt "/* Types definitions */@.";
......
...@@ -164,7 +164,7 @@ let print_main_header fmt = ...@@ -164,7 +164,7 @@ let print_main_header fmt =
let print_main_c main_fmt main_machine basename prog machines _ (*dependencies*) = let print_main_c main_fmt main_machine basename prog machines _ (*dependencies*) =
print_main_header main_fmt; print_main_header main_fmt;
fprintf main_fmt "#include <stdlib.h>@.#include <assert.h>@."; fprintf main_fmt "#include <stdlib.h>@.#include <assert.h>@.";
print_import_alloc_prototype main_fmt (Dep (true, basename, [], true (* assuming it is stateful*) )); print_import_alloc_prototype main_fmt {local=true; name=basename; content=[]; is_stateful=true} (* assuming it is stateful*) ;
pp_print_newline main_fmt (); pp_print_newline main_fmt ();
(* Print the svn version number and the supported C standard (C90 or C99) *) (* Print the svn version number and the supported C standard (C90 or C99) *)
......
...@@ -13,9 +13,9 @@ open Format ...@@ -13,9 +13,9 @@ open Format
open Lustre_types open Lustre_types
open Corelang open Corelang
let pp_dep fmt (Dep(b,id,tops,stateful)) = let pp_dep fmt dep =
Format.fprintf fmt "%b, %s, {%a}, %b" Format.fprintf fmt "%b, %s, {%a}, %b"
b id Printers.pp_prog tops stateful dep.local dep.name Printers.pp_prog dep.content dep.is_stateful
let pp_deps fmt deps = Format.fprintf fmt "@[<v 0>%a@ @]" (Utils.fprintf_list ~sep:"@ ," pp_dep) deps let pp_deps fmt deps = Format.fprintf fmt "@[<v 0>%a@ @]" (Utils.fprintf_list ~sep:"@ ," pp_dep) deps
...@@ -37,25 +37,25 @@ let header_libs header = ...@@ -37,25 +37,25 @@ let header_libs header =
) [] header ) [] header
let compiled_dependencies dep = let compiled_dependencies deps =
List.filter (fun (Dep (_, _, header, _)) -> header_has_code header) dep List.filter (fun dep -> header_has_code dep.content) deps
let lib_dependencies dep = let lib_dependencies deps =
List.fold_left List.fold_left
(fun accu (Dep (_, _, header, _)) -> Utils.list_union (header_libs header) accu) [] dep (fun accu dep -> Utils.list_union (header_libs dep.content) accu) [] deps
let fprintf_dependencies fmt (dep: dep_t list) = let fprintf_dependencies fmt (deps: dep_t list) =
(* Format.eprintf "Deps: %a@." pp_deps dep; *) (* Format.eprintf "Deps: %a@." pp_deps dep; *)
let compiled_dep = compiled_dependencies dep in let compiled_deps = compiled_dependencies deps in
(* Format.eprintf "Compiled Deps: %a@." pp_deps compiled_dep; *) (* Format.eprintf "Compiled Deps: %a@." pp_deps compiled_dep; *)
List.iter (fun s -> Log.report ~level:1 (fun fmt -> fprintf fmt "Adding dependency: %s@." s); List.iter (fun s -> Log.report ~level:1 (fun fmt -> fprintf fmt "Adding dependency: %s@." s);
fprintf fmt "\t${GCC} -I${INC} -c %s@." s) fprintf fmt "\t${GCC} -I${INC} -c %s@." s)
(("${INC}/io_frontend.c"):: (* IO functions when a main function is computed *) (("${INC}/io_frontend.c"):: (* IO functions when a main function is computed *)
(List.map (List.map
(fun (Dep (local, s, _, _)) -> (fun dep ->
(if local then s else Version.include_path ^ "/" ^ s) ^ ".c") (if dep.local then dep.name else Version.include_path ^ "/" ^ dep.name) ^ ".c")
compiled_dep)) compiled_deps))
module type MODIFIERS_MKF = module type MODIFIERS_MKF =
sig (* dep was (bool * ident * top_decl list) *) sig (* dep was (bool * ident * top_decl list) *)
...@@ -108,7 +108,7 @@ To be solved (later) with ...@@ -108,7 +108,7 @@ To be solved (later) with
fprintf fmt "\t${GCC} -I${INC} -I. -c %s_main.c@." basename; fprintf fmt "\t${GCC} -I${INC} -I. -c %s_main.c@." basename;
fprintf_dependencies fmt dependencies; fprintf_dependencies fmt dependencies;
fprintf fmt "\t${GCC} -o ${BINNAME} io_frontend.o %a %s.o %s_main.o %a@." fprintf fmt "\t${GCC} -o ${BINNAME} io_frontend.o %a %s.o %s_main.o %a@."
(Utils.fprintf_list ~sep:" " (fun fmt (Dep (_, s, _, _)) -> Format.fprintf fmt "%s.o" s)) (Utils.fprintf_list ~sep:" " (fun fmt dep -> Format.fprintf fmt "%s.o" dep.name))
(compiled_dependencies dependencies) (compiled_dependencies dependencies)
basename (* library .o *) basename (* library .o *)
basename (* main function . o *) basename (* main function . o *)
......
...@@ -33,7 +33,7 @@ let fsm_name node = node ^ "FSM" ...@@ -33,7 +33,7 @@ let fsm_name node = node ^ "FSM"
let print_mauve_header fmt mauve_machine basename prog machines _ (*dependencies*) = let print_mauve_header fmt mauve_machine basename prog machines _ (*dependencies*) =
fprintf fmt "#include \"mauve/runtime.hpp\"@."; fprintf fmt "#include \"mauve/runtime.hpp\"@.";
print_import_alloc_prototype fmt (Dep (true, basename, [], true (* assuming it is stateful*) )); print_import_alloc_prototype fmt {local=true; name=basename; content=[]; is_stateful=true} (* assuming it is stateful*) ;
pp_print_newline fmt (); pp_print_newline fmt ();
pp_print_newline fmt () pp_print_newline fmt ()
......
...@@ -158,7 +158,7 @@ let makefile_targets fmt basename nodename dependencies = ...@@ -158,7 +158,7 @@ let makefile_targets fmt basename nodename dependencies =
C_backend_makefile.fprintf_dependencies fmt dependencies; C_backend_makefile.fprintf_dependencies fmt dependencies;
fprintf fmt "\t${GCC} -Wno-attributes -o %s_main_eacsl io_frontend.o %a %s %s_main_eacsl.o %a@." fprintf fmt "\t${GCC} -Wno-attributes -o %s_main_eacsl io_frontend.o %a %s %s_main_eacsl.o %a@."
basename basename
(Utils.fprintf_list ~sep:" " (fun fmt (Dep (_, s, _, _)) -> Format.fprintf fmt "%s.o" s)) (Utils.fprintf_list ~sep:" " (fun fmt dep -> Format.fprintf fmt "%s.o" dep.name))
(C_backend_makefile.compiled_dependencies dependencies) (C_backend_makefile.compiled_dependencies dependencies)
("${FRAMACEACSL}/e_acsl.c " ("${FRAMACEACSL}/e_acsl.c "
^ "${FRAMACEACSL}/memory_model/e_acsl_bittree.c " ^ "${FRAMACEACSL}/memory_model/e_acsl_bittree.c "
......
...@@ -271,26 +271,27 @@ let has_c_prototype funname dependencies = ...@@ -271,26 +271,27 @@ let has_c_prototype funname dependencies =
let imported_node_opt = (* We select the last imported node with the name funname. let imported_node_opt = (* We select the last imported node with the name funname.
The order of evaluation of dependencies should be The order of evaluation of dependencies should be
compatible with overloading. (Not checked yet) *) compatible with overloading. (Not checked yet) *)
List.fold_left List.fold_left
(fun res (Dep (_, _, decls, _)) -> (fun res dep ->
match res with match res with
| Some _ -> res | Some _ -> res
| None -> | None ->
let matched = fun t -> match t.top_decl_desc with let decls = dep.content in
| ImportedNode nd -> nd.nodei_id = funname let matched = fun t -> match t.top_decl_desc with
| _ -> false | ImportedNode nd -> nd.nodei_id = funname
in | _ -> false
if List.exists matched decls then ( in
match (List.find matched decls).top_decl_desc with if List.exists matched decls then (
| ImportedNode nd -> Some nd match (List.find matched decls).top_decl_desc with
| _ -> assert false | ImportedNode nd -> Some nd
) | _ -> assert false
else )
None else
) None dependencies in None
match imported_node_opt with ) None dependencies in
| None -> false match imported_node_opt with
| Some nd -> (match nd.nodei_prototype with Some "C" -> true | _ -> false) | None -> false
| Some nd -> (match nd.nodei_prototype with Some "C" -> true | _ -> false)
(* (*
let pp_instance_call dependencies m self fmt i (inputs: value_t list) (outputs: var_decl list) = let pp_instance_call dependencies m self fmt i (inputs: value_t list) (outputs: var_decl list) =
try (* stateful node instance *) try (* stateful node instance *)
...@@ -687,7 +688,7 @@ let print_import_standard source_fmt = ...@@ -687,7 +688,7 @@ let print_import_standard source_fmt =
let print_lib_c source_fmt basename prog machines dependencies = let print_lib_c source_fmt basename prog machines dependencies =
print_import_standard source_fmt; print_import_standard source_fmt;
print_import_prototype source_fmt (Dep (true, basename, [], true (* assuming it is stateful *))); print_import_prototype source_fmt {local=true; name=basename; content=[]; is_stateful=true} (* assuming it is stateful *);
pp_print_newline source_fmt (); pp_print_newline source_fmt ();
(* Print the svn version number and the supported C standard (C90 or C99) *) (* Print the svn version number and the supported C standard (C90 or C99) *)
print_version source_fmt; print_version source_fmt;
......
...@@ -144,7 +144,7 @@ let fast_stages_processing prog = ...@@ -144,7 +144,7 @@ let fast_stages_processing prog =
(* Mini stage 1 *) (* Mini stage 1 *)
(* Extracting dependencies: fill some table with typing info *) (* Extracting dependencies: fill some table with typing info *)
ignore (Compiler_common.import_dependencies prog); ignore (Modules.load ~is_header:false prog);
(* Local inlining *) (* Local inlining *)
let prog = Inliner.local_inline prog (* type_env clock_env *) in let prog = Inliner.local_inline prog (* type_env clock_env *) in
(* Checking stateless/stateful status *) (* Checking stateless/stateful status *)
......
...@@ -153,26 +153,6 @@ let check_top_decls header = ...@@ -153,26 +153,6 @@ let check_top_decls header =
let new_cenv = clock_decls Basic_library.clock_env header in (* Clock calculus *) let new_cenv = clock_decls Basic_library.clock_env header in (* Clock calculus *)
header, new_tenv, new_cenv header, new_tenv, new_cenv
let get_envs_from_const const_decl (ty_env, ck_env) =
(Env.add_value ty_env const_decl.const_id const_decl.const_type,
Env.add_value ck_env const_decl.const_id (Clocks.new_var true))
let get_envs_from_consts const_decls (ty_env, ck_env) =
List.fold_right get_envs_from_const const_decls (ty_env, ck_env)
let rec get_envs_from_top_decl (ty_env, ck_env) top_decl =
match top_decl.top_decl_desc with
| Node nd -> (Env.add_value ty_env nd.node_id nd.node_type,
Env.add_value ck_env nd.node_id nd.node_clock)
| ImportedNode ind -> (Env.add_value ty_env ind.nodei_id ind.nodei_type,
Env.add_value ck_env ind.nodei_id ind.nodei_clock)
| Const c -> get_envs_from_const c (ty_env, ck_env)
| TypeDef _ -> List.fold_left get_envs_from_top_decl (ty_env, ck_env) (consts_of_enum_type top_decl)
| Open _ -> (ty_env, ck_env)
(* get type and clock environments from a header *)
let get_envs_from_top_decls header =
List.fold_left get_envs_from_top_decl (Env.initial, Env.initial) header
(* (*
List.fold_right List.fold_right
...@@ -226,39 +206,6 @@ let check_compatibility (prog, computed_types_env, computed_clocks_env) (header, ...@@ -226,39 +206,6 @@ let check_compatibility (prog, computed_types_env, computed_clocks_env) (header,
Location.pp_loc loc; Location.pp_loc loc;
raise exc raise exc
let is_stateful topdecl =
match topdecl.top_decl_desc with
| Node nd -> (match nd.node_stateless with Some b -> not b | None -> not nd.node_dec_stateless)
| ImportedNode nd -> not nd.nodei_stateless
| _ -> false
(* Beware of the side effect: reads and modifies Global.(type_env/clock_env) *)
let rec import_dependencies prog : dep_t list =
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v 4>.. extracting dependencies");
let dependencies = Corelang.get_dependencies prog in
let (compilation_deps, type_env, clock_env) =
List.fold_left
(fun (compilation_dep, type_env, clock_env) dep ->
let (local, s) = Corelang.dependency_of_top dep in
let basename = Options_management.name_dependency (local, s) in
Log.report ~level:1 (fun fmt -> Format.fprintf fmt "@ Library %s@ " basename);
let lusic = Modules.import_dependency dep.top_decl_loc (local, s) in
(*Log.report ~level:1 (fun fmt -> Format.fprintf fmt "");*)
let lusic_deps = import_dependencies lusic.Lusic.contents in
let (lusi_type_env, lusi_clock_env) = get_envs_from_top_decls lusic.Lusic.contents in
let is_stateful = List.exists is_stateful lusic.Lusic.contents in
let new_dep = Dep (local, s, lusic.Lusic.contents, is_stateful ) in
new_dep::lusic_deps@compilation_dep,
Env.overwrite type_env lusi_type_env,
Env.overwrite clock_env lusi_clock_env)
([], !Global.type_env, !Global.clock_env)
dependencies in
Global.type_env := type_env;
Global.clock_env := clock_env;
begin
Log.report ~level:1 (fun fmt -> fprintf fmt "@]@ ");
compilation_deps
end
let track_exception () = let track_exception () =
if !Options.track_exceptions if !Options.track_exceptions
......
...@@ -36,9 +36,9 @@ let compile_source_to_header prog computed_types_env computed_clocks_env dirname ...@@ -36,9 +36,9 @@ let compile_source_to_header prog computed_types_env computed_clocks_env dirname
else else
begin begin
Log.report ~level:1 (fun fmt -> fprintf fmt ".. loading compiled header file %s@," header_name); Log.report ~level:1 (fun fmt -> fprintf fmt ".. loading compiled header file %s@," header_name);
Modules.check_dependency lusic destname; Lusic.check_obsolete lusic destname;
let header = lusic.Lusic.contents in let header = lusic.Lusic.contents in
let (declared_types_env, declared_clocks_env) = get_envs_from_top_decls header in let (declared_types_env, declared_clocks_env) = Modules.get_envs_from_top_decls header in
check_compatibility check_compatibility
(prog, computed_types_env, computed_clocks_env) (prog, computed_types_env, computed_clocks_env)
(header, declared_types_env, declared_clocks_env) (header, declared_types_env, declared_clocks_env)
...@@ -56,10 +56,14 @@ let stage1 params prog dirname basename = ...@@ -56,10 +56,14 @@ let stage1 params prog dirname basename =
Log.report ~level:4 (fun fmt -> fprintf fmt ".. after automata expansion:@, @[<v 2>@,%a@]@ " Printers.pp_prog prog); Log.report ~level:4 (fun fmt -> fprintf fmt ".. after automata expansion:@, @[<v 2>@,%a@]@ " Printers.pp_prog prog);
(* Importing source *) (* Importing source *)
let _ = Modules.load ~is_header:false ISet.empty prog in let prog, dependencies, (typ_env, clk_env) = Modules.load ~is_header:false prog in
(* Extracting dependencies (and updating Global.(type_env/clock_env) *) (* Registering types and clocks for future checks *)
let dependencies = import_dependencies prog in Global.type_env := Env.overwrite !Global.type_env typ_env;
Global.clock_env := Env.overwrite !Global.clock_env clk_env;
(* (\* Extracting dependencies (and updating Global.(type_env/clock_env) *\)
* let dependencies = import_dependencies prog in *)
(* Sorting nodes *) (* Sorting nodes *)
let prog = SortProg.sort prog in let prog = SortProg.sort prog in
......
...@@ -228,12 +228,12 @@ type top_decl = ...@@ -228,12 +228,12 @@ type top_decl =
type program_t = top_decl list type program_t = top_decl list
type dep_t = Dep of type dep_t = {
bool local: bool;
* ident name: ident;
* (top_decl list) content: program_t;
* bool (* is stateful *) is_stateful: bool
}
......
...@@ -42,13 +42,17 @@ let compile_header dirname basename extension = ...@@ -42,13 +42,17 @@ let compile_header dirname basename extension =
begin begin
Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v>"); Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v>");
let header = parse_header true (dirname ^ "/" ^ header_name) in let header = parse_header true (dirname ^ "/" ^ header_name) in
ignore (Modules.load ~is_header:true ISet.empty header); (* Disbaled today, should be done anyway when following the regular compilation
ignore (Modules.load ~is_header:true ISet.empty header); *)
ignore (check_top_decls header); (* typing/clocking with an empty env *) ignore (check_top_decls header); (* typing/clocking with an empty env *)
create_dest_dir (); create_dest_dir ();
Log.report ~level:1 Log.report ~level:1
(fun fmt -> fprintf fmt ".. generating compiled header file %sc@," (destname ^ extension)); (fun fmt -> fprintf fmt ".. generating compiled header file %sc@," (destname ^ extension));
Lusic.write_lusic true header destname lusic_ext; Lusic.write_lusic true header destname lusic_ext;
generate_lusic_header destname lusic_ext; generate_lusic_header destname lusic_ext;
Log.report ~level:1 (fun fmt -> fprintf fmt ".. done !@ @]@ ") Log.report ~level:1 (fun fmt -> fprintf fmt ".. done !@ @]@ ")
end end
......
...@@ -56,7 +56,7 @@ let testgen_source dirname basename extension = ...@@ -56,7 +56,7 @@ let testgen_source dirname basename extension =
if !Options.gen_mcdc then ( if !Options.gen_mcdc then (
let prog_mcdc = PathConditions.mcdc prog in let prog_mcdc = PathConditions.mcdc prog in
(* We re-type the fresh equations *) (* We re-type the fresh equations *)
let _ = import_dependencies prog_mcdc in let _ = Modules.load ~is_header:false prog_mcdc in
let _ = type_decls !Global.type_env prog_mcdc in let _ = type_decls !Global.type_env prog_mcdc in
let destname = !Options.dest_dir ^ "/" ^ basename in let destname = !Options.dest_dir ^ "/" ^ basename in
......
...@@ -23,6 +23,7 @@ let check_symbol loc msg hashtbl name = ...@@ -23,6 +23,7 @@ let check_symbol loc msg hashtbl name =
then raise (Error (loc, Error.Unbound_symbol msg)) then raise (Error (loc, Error.Unbound_symbol msg))
else () else ()
let add_imported_node name value = let add_imported_node name value =
(*Format.eprintf "add_imported_node %s %a (owner=%s)@." name Printers.pp_imported_node (imported_node_of_top value) value.top_decl_owner;*) (*Format.eprintf "add_imported_node %s %a (owner=%s)@." name Printers.pp_imported_node (imported_node_of_top value) value.top_decl_owner;*)
try try
...@@ -122,12 +123,8 @@ let import_dependency_aux loc (local, dep) = ...@@ -122,12 +123,8 @@ let import_dependency_aux loc (local, dep) =
lusic lusic
with with
| Sys_error msg -> | Sys_error msg ->
begin
(*Format.eprintf "Error: %s@." msg;*)
raise (Error (loc, Error.Unknown_library basename)) raise (Error (loc, Error.Unknown_library basename))
end
| Corelang.Error (_, msg) -> raise (Corelang.Error (loc, msg))
let import_dependency loc (local, dep) = let import_dependency loc (local, dep) =
try try
import_dependency_aux loc (local, dep) import_dependency_aux loc (local, dep)
...@@ -139,50 +136,133 @@ let import_dependency loc (local, dep) = ...@@ -139,50 +136,133 @@ let import_dependency loc (local, dep) =
raise exc raise exc
) )
let check_dependency lusic basename = let get_lusic decl =
try match decl.top_decl_desc with
Lusic.check_obsolete lusic basename | Open (local, dep) -> (
with let loc = decl.top_decl_loc in
| Corelang.Error (loc, err) as exc -> ( let basename = Options_management.name_dependency (local, dep) in
Format.eprintf "Import error: %a%a@." let extension = ".lusic" in
Error.pp_error_msg err try
Location.pp_loc loc; let lusic = Lusic.read_lusic basename extension in
raise exc Lusic.check_obsolete lusic basename;
lusic
with
| Sys_error msg ->
raise (Error (loc, Error.Unknown_library basename))
) )
| _ -> assert false (* should not happen *)
let get_envs_from_const const_decl (ty_env, ck_env) =
(Env.add_value ty_env const_decl.const_id const_decl.const_type,
Env.add_value ck_env const_decl.const_id (Clocks.new_var true))
let rec load_rec ~is_header imported program = let get_envs_from_consts const_decls (ty_env, ck_env) =
List.fold_left (fun imported decl -> List.fold_right get_envs_from_const const_decls (ty_env, ck_env)
match decl.top_decl_desc with
| Node nd -> if is_header then let rec get_envs_from_top_decl (ty_env, ck_env) top_decl =
raise (Error(decl.top_decl_loc, match top_decl.top_decl_desc with
LoadError ("node " ^ nd.node_id ^ " declared in a header file"))) | Node nd -> (Env.add_value ty_env nd.node_id nd.node_type,
else Env.add_value ck_env nd.node_id nd.node_clock)
(add_node nd.node_id decl; imported) | ImportedNode ind -> (Env.add_value ty_env ind.nodei_id ind.nodei_type,
| ImportedNode ind -> Env.add_value ck_env ind.nodei_id ind.nodei_clock)
if is_header then | Const c -> get_envs_from_const c (ty_env, ck_env)
(add_imported_node ind.nodei_id decl; imported) | TypeDef _ -> List.fold_left get_envs_from_top_decl (ty_env, ck_env) (consts_of_enum_type top_decl)
else | Open _ -> (ty_env, ck_env)
raise (Error(decl.top_decl_loc,
LoadError ("imported node " ^ ind.nodei_id ^ " declared in a regular Lustre file"))) (* get type and clock environments from a header *)
| Const c -> (add_const is_header c.const_id decl; imported) let get_envs_from_top_decls header =
| TypeDef tdef -> (add_type is_header tdef.tydef_id decl; imported) List.fold_left get_envs_from_top_decl (Env.initial, Env.initial) header
| Open (local, dep) ->
let basename = Options_management.name_dependency (local, dep) in let is_stateful topdecl =
if ISet.mem basename imported then imported else match topdecl.top_decl_desc with
let lusic = import_dependency_aux decl.top_decl_loc (local, dep) | Node nd -> (match nd.node_stateless with Some b -> not b | None -> not nd.node_dec_stateless)
in load_rec ~is_header:true (ISet.add basename imported) lusic.Lusic.contents | ImportedNode nd -> not nd.nodei_stateless
) imported program | _ -> false
let rec load_rec ~is_header accu program =
List.fold_left (fun ((accu_prog, accu_dep, typ_env, clk_env) as accu) decl ->
(* Precompute the updated envs, will not be used in the Open case *)
let typ_env', clk_env' = get_envs_from_top_decl (typ_env, clk_env) decl in
match decl.top_decl_desc with
| Open (local, dep) ->
(* loading the dep *)
let basename = Options_management.name_dependency (local, dep) in
if List.exists
(fun dep -> basename = Options_management.name_dependency (dep.local, dep.name))
accu_dep
then
(* Library already imported. Just skip *)
accu
else (
Log.report ~level:1 (fun fmt -> Format.fprintf fmt "@ Library %s@ " basename);
let lusic = get_lusic decl in
(* Recursive call with accumulator on lusic *)
let (accu_prog, accu_dep, typ_env, clk_env) =
load_rec ~is_header:true accu lusic.Lusic.contents in
(* Building the dep *)
let is_stateful = List.exists is_stateful lusic.Lusic.contents in
let new_dep = { local = local;
name = dep;
content = lusic.Lusic.contents;
is_stateful = is_stateful } in
(* Returning the prog without the Open, the deps with the new
one and the updated envs *)
accu_prog, (new_dep::accu_dep), typ_env, clk_env
)
(* | Include xxx -> TODO
load the lus file
call load_rec ~is_header:false accu on the luscontent
*)
| Node nd ->
if is_header then
raise (Error(decl.top_decl_loc,
LoadError ("node " ^ nd.node_id ^ " declared in a header file")))
else (
(* Registering node *)
add_node nd.node_id decl;
(* Updating the type/clock env *)
decl::accu_prog, accu_dep, typ_env', clk_env'
)
| ImportedNode ind ->
if is_header then (
add_imported_node ind.nodei_id decl;
decl::accu_prog, accu_dep, typ_env', clk_env'
)
else
raise (Error(decl.top_decl_loc,
LoadError ("imported node " ^ ind.nodei_id ^
" declared in a regular Lustre file")))
| Const c -> (
add_const is_header c.const_id decl;
decl::accu_prog, accu_dep, typ_env', clk_env'
)
| TypeDef tdef -> (
add_type is_header tdef.tydef_id decl;
decl::accu_prog, accu_dep, typ_env', clk_env'
)
) accu program
(* Iterates through lusi definitions and records them in the hashtbl. Open instructions are evaluated and update these hashtbl as well. node_table/type/table/consts_table *) (* Iterates through lusi definitions and records them in the hashtbl. Open instructions are evaluated and update these hashtbl as well. node_table/type/table/consts_table *)
let load ~is_header program =
let load ~is_header imported program =
try try
load_rec ~is_header imported program let prog, deps, typ_env, clk_env =
load_rec ~is_header
([], (* accumulator for program elements *)
[], (* accumulator for dependencies *)
Env.initial, (* empty type env *)
Env.initial (* empty clock env *)
) program
in
List.rev prog, List.rev deps, (typ_env, clk_env)
with with
Corelang.Error (loc, err) as exc -> ( Corelang.Error (loc, err) as exc -> (
Format.eprintf "Import error: %a%a@." Format.eprintf "Import error: %a%a@."
Error.pp_error_msg err Error.pp_error_msg err
Location.pp_loc loc; Location.pp_loc loc;
raise exc raise exc
);; );;
open Lustre_types
open Utils
(* This module is used to load lusic files when open(ing) modules in
lustre/lusi sources *)
(* Load the provided program, either an actual program or a header lusi files:
- reject program that define imported node
- reject header that define lustre node
- inject #include lus file into the program
- loads #open lusic files
- record the node name and check that they are uniquely defined
- build the type/clock env from the imported nodes
Returns an extended prog along with dependencies of #open and a type/clock base env.
*)
val load: is_header:bool -> program_t -> program_t * dep_t list * ( Typing.type_expr Env.t * Clocks.clock_expr Env.t)
(* Returns an updated env with the type/clock declaration of the program *)
val get_envs_from_top_decls: program_t -> Typing.type_expr Env.t * Clocks.clock_expr Env.t
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment