From a7062da6157cf76d63b01c85732f3ba1a8d1d49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9lio=20Brun?= <lelio.brun@isae-supaero.fr> Date: Mon, 28 Jun 2021 21:52:46 +0200 Subject: [PATCH] another step towards refactoring --- src/annotations.mli | 2 + src/backends/Ada/ada_backend.ml | 28 +- src/backends/Ada/ada_backend.mli | 5 + src/backends/Ada/ada_backend_adb.ml | 364 +++++++-------- src/backends/Ada/ada_backend_adb.mli | 12 + src/backends/Ada/ada_backend_ads.ml | 424 +++++++++--------- src/backends/Ada/ada_backend_ads.mli | 12 + src/backends/Ada/ada_backend_common.ml | 111 ++--- src/backends/Ada/ada_backend_common.mli | 8 +- src/backends/Ada/ada_backend_wrapper.ml | 356 +++++++-------- src/backends/Ada/ada_backend_wrapper.mli | 26 ++ src/backends/Ada/ada_printer.ml | 43 +- src/backends/Ada/misc_lustre_function.mli | 41 ++ src/backends/Ada/misc_printer.mli | 11 +- src/backends/C/c_backend.ml | 34 +- src/backends/C/c_backend.mli | 6 + src/backends/C/c_backend_common.ml | 37 +- src/backends/C/c_backend_common.mli | 147 +++++- src/backends/C/c_backend_header.ml | 20 +- src/backends/C/c_backend_header.mli | 17 + src/backends/C/c_backend_main.ml | 12 +- src/backends/C/c_backend_main.mli | 11 + src/backends/C/c_backend_makefile.ml | 16 +- src/backends/C/c_backend_makefile.mli | 17 + src/backends/C/c_backend_mauve.ml | 2 +- src/backends/C/c_backend_mauve.mli | 7 + src/backends/C/c_backend_spec.ml | 9 +- src/backends/C/c_backend_src.ml | 41 +- src/backends/C/c_backend_src.mli | 29 ++ src/backends/EMF/EMF_backend.ml | 27 +- src/backends/EMF/EMF_backend.mli | 1 + src/backends/EMF/EMF_common.ml | 29 +- src/backends/EMF/EMF_common.mli | 24 + src/backends/EMF/EMF_library_calls.ml | 4 +- src/backends/EMF/EMF_library_calls.mli | 2 + src/backends/Horn/horn_backend.ml | 2 +- src/backends/Horn/horn_backend.mli | 1 + .../Horn/horn_backend_collecting_sem.ml | 41 +- .../Horn/horn_backend_collecting_sem.mli | 7 + src/backends/Horn/horn_backend_common.ml | 3 +- src/backends/Horn/horn_backend_common.mli | 37 ++ src/backends/Horn/horn_backend_printers.ml | 88 ++-- src/backends/Horn/horn_backend_printers.mli | 8 + src/backends/Horn/horn_backend_traces.ml | 65 ++- src/backends/Horn/horn_backend_traces.mli | 1 + src/backends/backends.mli | 1 + src/basic_library.mli | 1 + src/causality.ml | 18 +- src/causality.mli | 14 + src/checks/access.ml | 4 +- src/checks/access.mli | 1 + src/checks/algebraicLoop.ml | 29 +- src/checks/algebraicLoop.mli | 4 + src/clock_calculus.mli | 2 + src/clocks.mli | 6 + src/compiler_common.mli | 13 + src/compiler_stages.ml | 23 +- src/inliner.mli | 7 + src/machine_code_common.mli | 2 + src/optimize_machine.mli | 16 + src/optimize_prog.mli | 3 + src/options.ml | 2 + src/options.mli | 5 + src/options_management.mli | 2 + src/plugins/mpfr/lustrec_mpfr.mli | 18 + src/plugins/plugins.mli | 5 + src/printers.mli | 5 + src/scheduling.mli | 7 + src/spec.mli | 3 + src/tools/stateflow/common/activeStates.ml | 13 +- src/tools/stateflow/common/activeStates.mli | 7 + src/tools/stateflow/common/basetypes.ml | 3 +- src/tools/stateflow/common/basetypes.mli | 77 ++++ src/tools/stateflow/common/datatype.ml | 43 +- src/tools/stateflow/common/datatype.mli | 53 +++ .../stateflow/json-parser/json_parser.mli | 0 .../json-parser/main_parse_json_file.mli | 0 .../test_json_parser_variables.mli | 0 src/tools/stateflow/models/model_medium.mli | 0 src/tools/stateflow/models/model_simple.mli | 7 + .../stateflow/models/model_stopwatch.mli | 7 + src/tools/stateflow/semantics/cPS.mli | 0 .../semantics/cPS_ccode_generator.mli | 0 .../stateflow/semantics/cPS_evaluator.mli | 0 .../stateflow/semantics/cPS_interpreter.mli | 0 .../semantics/cPS_lustre_generator.mli | 0 .../stateflow/semantics/cPS_transformer.mli | 0 src/tools/stateflow/semantics/theta.mli | 0 src/type_predef.mli | 2 + src/typing.mli | 6 + src/utils/dimension.ml | 6 +- src/utils/dimension.mli | 5 + src/utils/location.ml | 2 +- src/utils/location.mli | 1 + src/utils/utils.ml | 12 +- src/utils/utils.mli | 60 +++ src/verifierList.mli | 1 + 97 files changed, 1723 insertions(+), 961 deletions(-) create mode 100644 src/tools/stateflow/common/activeStates.mli create mode 100644 src/tools/stateflow/common/basetypes.mli create mode 100644 src/tools/stateflow/common/datatype.mli create mode 100644 src/tools/stateflow/json-parser/json_parser.mli create mode 100644 src/tools/stateflow/json-parser/main_parse_json_file.mli create mode 100644 src/tools/stateflow/json-parser/test_json_parser_variables.mli create mode 100644 src/tools/stateflow/models/model_medium.mli create mode 100644 src/tools/stateflow/models/model_simple.mli create mode 100644 src/tools/stateflow/models/model_stopwatch.mli create mode 100644 src/tools/stateflow/semantics/cPS.mli create mode 100644 src/tools/stateflow/semantics/cPS_ccode_generator.mli create mode 100644 src/tools/stateflow/semantics/cPS_evaluator.mli create mode 100644 src/tools/stateflow/semantics/cPS_interpreter.mli create mode 100644 src/tools/stateflow/semantics/cPS_lustre_generator.mli create mode 100644 src/tools/stateflow/semantics/cPS_transformer.mli create mode 100644 src/tools/stateflow/semantics/theta.mli diff --git a/src/annotations.mli b/src/annotations.mli index 9fe9f3fa..98dea773 100644 --- a/src/annotations.mli +++ b/src/annotations.mli @@ -1,5 +1,7 @@ open Utils +val expr_annotations: (string list, ident * tag) Hashtbl.t + val add_node_ann: ident -> string list -> unit val add_expr_ann: ident -> tag -> string list -> unit val get_expr_annotations: ident list -> (ident * tag) list diff --git a/src/backends/Ada/ada_backend.ml b/src/backends/Ada/ada_backend.ml index 62dfbc88..246f9e46 100644 --- a/src/backends/Ada/ada_backend.ml +++ b/src/backends/Ada/ada_backend.ml @@ -114,9 +114,9 @@ let extract_contract machines m = @param basename name of the lustre file @param prog list of machines to translate **) let translate_to_ada basename machines = - let module Ads = Ada_backend_ads.Main in - let module Adb = Ada_backend_adb.Main in - let module Wrapper = Ada_backend_wrapper.Main in + (* let module Ads = Ada_backend_ads.Main in + * let module Adb = Ada_backend_adb.Main in + * let module Wrapper = Ada_backend_wrapper.Main in *) let is_real_machine m = match m.mspec.mnode_spec with Some (Contract _) -> false | _ -> true in @@ -145,9 +145,9 @@ let translate_to_ada basename machines = | main_node -> ( match Machine_code_common.get_machine_opt filtered_machines main_node with | None -> - Format.eprintf "Ada Code generation error: %a@." Error.pp_error_msg + Format.eprintf "Ada Code generation error: %a@." Error.pp Error.Main_not_found; - raise (Error.Error (Location.dummy_loc, Error.Main_not_found)) + raise (Error.Error (Location.dummy, Error.Main_not_found)) | Some m -> Some m) in @@ -158,10 +158,10 @@ let translate_to_ada basename machines = List.iter check machines; log_str_level_two 1 "Generating ads"; - List.iter (write_file destname (_pp_filename "ads") Ads.pp_file) _machines; + List.iter (write_file destname (_pp_filename "ads") Ada_backend_ads.pp_file) _machines; log_str_level_two 1 "Generating adb"; - List.iter (write_file destname (_pp_filename "adb") Adb.pp_file) _machines; + List.iter (write_file destname (_pp_filename "adb") Ada_backend_adb.pp_file) _machines; (* If a main node is given we generate a main adb file and a project file *) log_str_level_two 1 "Generating wrapper files"; @@ -169,19 +169,19 @@ let translate_to_ada basename machines = | None -> () | Some machine -> - write_file destname pp_main_filename Wrapper.pp_main_adb + write_file destname pp_main_filename Ada_backend_wrapper.pp_main_adb (*get_typed_submachines filtered_machines machine*) machine; write_file destname - (fun fmt _ -> Wrapper.pp_project_name (basename ^ "_exe") fmt) - (Wrapper.pp_project_file filtered_machines basename) + (fun fmt _ -> Ada_backend_wrapper.pp_project_name (basename ^ "_exe") fmt) + (Ada_backend_wrapper.pp_project_file filtered_machines basename) main_machine); - write_file destname Wrapper.pp_project_configuration_name - (fun fmt _ -> Wrapper.pp_project_configuration_file fmt) + write_file destname Ada_backend_wrapper.pp_project_configuration_name + (fun fmt _ -> Ada_backend_wrapper.pp_project_configuration_file fmt) basename; write_file destname - (fun fmt _ -> Wrapper.pp_project_name (basename ^ "_lib") fmt) - (Wrapper.pp_project_file filtered_machines basename) + (fun fmt _ -> Ada_backend_wrapper.pp_project_name (basename ^ "_lib") fmt) + (Ada_backend_wrapper.pp_project_file filtered_machines basename) None (* Local Variables: *) diff --git a/src/backends/Ada/ada_backend.mli b/src/backends/Ada/ada_backend.mli index e69de29b..8de317ed 100644 --- a/src/backends/Ada/ada_backend.mli +++ b/src/backends/Ada/ada_backend.mli @@ -0,0 +1,5 @@ +(** Main function of the Ada backend. It calls all the subfunction creating all + the file and fill them with Ada code representing the machines list given. + @param basename name of the lustre file @param prog list of machines to + translate **) +val translate_to_ada: string -> Machine_code_types.machine_t list -> unit diff --git a/src/backends/Ada/ada_backend_adb.ml b/src/backends/Ada/ada_backend_adb.ml index 2d3c3a35..7c9e6aaf 100644 --- a/src/backends/Ada/ada_backend_adb.ml +++ b/src/backends/Ada/ada_backend_adb.ml @@ -9,6 +9,7 @@ (* *) (********************************************************************) +open Utils open Format open Machine_code_types open Lustre_types @@ -20,200 +21,201 @@ open Ada_printer open Ada_backend_common (** Main module for generating packages bodies **) -module Main = struct - (** Printing function for basic assignement [var := value]. - @param fmt the formater to print on @param var_name the name of the - variable @param value the value to be assigned **) - let pp_assign env fmt var value = - fprintf fmt "%a := %a" (pp_var env) var (pp_value env) value +(** Printing function for basic assignement [var := value]. - (** Printing function for instruction. See {!type:Machine_code_types.instr_t} - for more details on machine types. + @param fmt the formater to print on @param var_name the name of the + variable @param value the value to be assigned **) +let pp_assign env fmt var value = + fprintf fmt "%a := %a" (pp_var env) var (pp_value env) value - @param typed_submachines list of all typed machine instances of this - machine @param machine the current machine @param fmt the formater to - print on @param instr the instruction to print **) - let rec pp_machine_instr typed_submachines env instr fmt = - let pp_instr = pp_machine_instr typed_submachines env in - (* Print args for a step call *) - let pp_state i fmt = fprintf fmt "%t.%s" pp_state_name i in - (* Print a when branch of a case *) - let pp_when (cond, instrs) fmt = - fprintf fmt "when %s =>@,%a" cond pp_block (List.map pp_instr instrs) - in - (* Print a case *) - let pp_case fmt (g, hl) = - fprintf fmt "case %a is@,%aend case" (pp_value env) g pp_block - (List.map pp_when hl) - in - (* Print a if *) - (* If neg is true the we must test for the negation of the condition. It - first check that we don't have a negation and a else case, if so it - inverses the two branch and remove the negation doing a recursive call. *) - let pp_if fmt (neg, g, instrs1, instrs2) = - let pp_cond = - if neg then fun fmt x -> fprintf fmt "! (%a)" (pp_value env) x - else pp_value env - in - let pp_else = - match instrs2 with - | None -> - fun fmt -> fprintf fmt "" - | Some i2 -> - fun fmt -> fprintf fmt "else@,%a" pp_block (List.map pp_instr i2) - in - fprintf fmt "if %a then@,%a%tend if" pp_cond g pp_block - (List.map pp_instr instrs1) - pp_else - in - match get_instr_desc instr with - (* no reset *) - | MNoReset _ -> - () - (* TODO: handle clear_reset *) - | MClearReset -> - () - (* reset *) - | MSetReset i when List.mem_assoc i typed_submachines -> - let substitution, submachine = get_instance i typed_submachines in - let pp_package = - pp_package_name_with_polymorphic substitution submachine - in - let args = - if is_machine_statefull submachine then [ [ pp_state i ] ] else [] - in - pp_call fmt (pp_package_access (pp_package, pp_reset_procedure_name), args) - | MLocalAssign (ident, value) -> - pp_assign env fmt ident value - | MStateAssign (ident, value) -> - pp_assign env fmt ident value - | MStep ([ i0 ], i, vl) when is_builtin_fun i -> - let value = mk_val (Fun (i, vl)) i0.var_type in - pp_assign env fmt i0 value - | MStep (il, i, vl) when List.mem_assoc i typed_submachines -> - let substitution, submachine = get_instance i typed_submachines in - let pp_package = - pp_package_name_with_polymorphic substitution submachine - in - let input = List.map (fun x fmt -> pp_value env fmt x) vl in - let output = List.map pp_var_name il in - let args = - (if is_machine_statefull submachine then [ [ pp_state i ] ] else []) - @ (if input != [] then [ input ] else []) - @ if output != [] then [ output ] else [] - in - pp_call fmt (pp_package_access (pp_package, pp_step_procedure_name), args) - | MBranch (_, []) -> - assert false - | MBranch (g, (c1, i1) :: tl) when c1 = tag_false || c1 = tag_true -> - pp_if fmt (build_if g c1 i1 tl) - | MBranch (g, hl) -> - pp_case fmt (g, hl) - | MComment s -> - let lines = String.split_on_char '\n' s in - fprintf fmt "%a" (Utils.fprintf_list ~sep:"" pp_oneline_comment) lines - | _ -> - assert false +(** Printing function for instruction. See {!type:Machine_code_types.instr_t} + for more details on machine types. - (** Print the definition of the step procedure from a machine. - - @param typed_submachines list of all typed machine instances of this - machine @param fmt the formater to print on @param machine the machine **) - let pp_step_definition env typed_submachines fmt (m, m_spec_opt, guarantees) = - let transform_local_to_state_assign instr = - match instr.instr_desc with - | MLocalAssign (ident, value) -> - { instr with instr_desc = MStateAssign (ident, value) } - | _ -> - instr + @param typed_submachines list of all typed machine instances of this + machine @param machine the current machine @param fmt the formater to + print on @param instr the instruction to print **) +let rec pp_machine_instr typed_submachines env instr fmt = + let pp_instr = pp_machine_instr typed_submachines env in + (* Print args for a step call *) + let pp_state i fmt = fprintf fmt "%t.%s" pp_state_name i in + (* Print a when branch of a case *) + let pp_when (cond, instrs) fmt = + fprintf fmt "when %s =>@,%a" cond pp_block (List.map pp_instr instrs) + in + (* Print a case *) + let pp_case fmt (g, hl) = + fprintf fmt "case %a is@,%aend case" (pp_value env) g pp_block + (List.map pp_when hl) + in + (* Print a if *) + (* If neg is true the we must test for the negation of the condition. It + first check that we don't have a negation and a else case, if so it + inverses the two branch and remove the negation doing a recursive call. *) + let pp_if fmt (neg, g, instrs1, instrs2) = + let pp_cond = + if neg then fun fmt x -> fprintf fmt "! (%a)" (pp_value env) x + else pp_value env in - let pp_local_ghost_list, spec_instrs = - match m_spec_opt with + let pp_else = + match instrs2 with | None -> - [], [] - | Some m_spec -> - ( List.map - (build_pp_var_decl_local (Some (true, false, [], []))) - (List.filter - (fun x -> not (List.mem x.var_id guarantees)) - m_spec.mstep.step_locals), - List.map transform_local_to_state_assign m_spec.mstep.step_instrs ) + fun fmt -> fprintf fmt "" + | Some i2 -> + fun fmt -> fprintf fmt "else@,%a" pp_block (List.map pp_instr i2) + in + fprintf fmt "if %a then@,%a%tend if" pp_cond g pp_block + (List.map pp_instr instrs1) + pp_else + in + match get_instr_desc instr with + (* no reset *) + | MNoReset _ -> + () + (* TODO: handle clear_reset *) + | MClearReset -> + () + (* reset *) + | MSetReset i when List.mem_assoc i typed_submachines -> + let substitution, submachine = get_instance i typed_submachines in + let pp_package = + pp_package_name_with_polymorphic substitution submachine in - let pp_local_list = - List.map (build_pp_var_decl_local None) m.mstep.step_locals + let args = + if is_machine_statefull submachine then [ [ pp_state i ] ] else [] in - let pp_instr_list = - List.map - (pp_machine_instr typed_submachines env) - (m.mstep.step_instrs @ spec_instrs) + pp_call fmt (pp_package_access (pp_package, pp_reset_procedure_name), args) + | MLocalAssign (ident, value) -> + pp_assign env fmt ident value + | MStateAssign (ident, value) -> + pp_assign env fmt ident value + | MStep ([ i0 ], i, vl) when is_builtin_fun i -> + let value = mk_val (Fun (i, vl)) i0.var_type in + pp_assign env fmt i0 value + | MStep (il, i, vl) when List.mem_assoc i typed_submachines -> + let substitution, submachine = get_instance i typed_submachines in + let pp_package = + pp_package_name_with_polymorphic substitution submachine in - let content = - AdaProcedureContent - ( ((if pp_local_ghost_list = [] then [] else [ pp_local_ghost_list ]) - @ if pp_local_list = [] then [] else [ pp_local_list ]), - pp_instr_list ) + let input = List.map (fun x fmt -> pp_value env fmt x) vl in + let output = List.map pp_var_name il in + let args = + (if is_machine_statefull submachine then [ [ pp_state i ] ] else []) + @ (if input != [] then [ input ] else []) + @ if output != [] then [ output ] else [] in - pp_procedure pp_step_procedure_name (build_pp_arg_step m) None fmt content + pp_call fmt (pp_package_access (pp_package, pp_step_procedure_name), args) + | MBranch (_, []) -> + assert false + | MBranch (g, (c1, i1) :: tl) when c1 = tag_false || c1 = tag_true -> + pp_if fmt (build_if g c1 i1 tl) + | MBranch (g, hl) -> + pp_case fmt (g, hl) + | MComment s -> + let lines = String.split_on_char '\n' s in + fprintf fmt "%a" (pp_print_list ~pp_sep:pp_print_nothing pp_oneline_comment) lines + | _ -> + assert false - (** Print the definition of the reset procedure from a machine. +(** Print the definition of the step procedure from a machine. - @param typed_submachines list of all typed machine instances of this - machine @param fmt the formater to print on @param machine the machine **) - let pp_reset_definition env typed_submachines fmt (m, m_spec_opt) = - let build_assign = function - | var -> - mkinstr (MStateAssign (var, mk_default_value var.var_type)) - in - let env, memory = - match m_spec_opt with None -> env, m.mmemory | Some _ -> env, m.mmemory - in - let assigns = List.map build_assign memory in - let pp_instr_list = - List.map (pp_machine_instr typed_submachines env) (assigns @ m.minit) - in - pp_procedure pp_reset_procedure_name (build_pp_arg_reset m) None fmt - (AdaProcedureContent ([], pp_instr_list)) + @param typed_submachines list of all typed machine instances of this + machine @param fmt the formater to print on @param machine the machine **) +let pp_step_definition env typed_submachines fmt (m, m_spec_opt, guarantees) = + let transform_local_to_state_assign instr = + match instr.instr_desc with + | MLocalAssign (ident, value) -> + { instr with instr_desc = MStateAssign (ident, value) } + | _ -> + instr + in + let pp_local_ghost_list, spec_instrs = + match m_spec_opt with + | None -> + [], [] + | Some m_spec -> + ( List.map + (build_pp_var_decl_local (Some (true, false, [], []))) + (List.filter + (fun x -> not (List.mem x.var_id guarantees)) + m_spec.mstep.step_locals), + List.map transform_local_to_state_assign m_spec.mstep.step_instrs ) + in + let pp_local_list = + List.map (build_pp_var_decl_local None) m.mstep.step_locals + in + let pp_instr_list = + List.map + (pp_machine_instr typed_submachines env) + (m.mstep.step_instrs @ spec_instrs) + in + let content = + AdaProcedureContent + ( ((if pp_local_ghost_list = [] then [] else [ pp_local_ghost_list ]) + @ if pp_local_list = [] then [] else [ pp_local_list ]), + pp_instr_list ) + in + pp_procedure pp_step_procedure_name (build_pp_arg_step m) None fmt content - (** Print the package definition(ads) of a machine. It requires the list of - all typed instance. A typed submachine instance is (ident, type_machine) - with ident the instance name and typed_machine is (substitution, machine) - with machine the machine associated to the instance and substitution the - instanciation of all its polymorphic types. @param fmt the formater to - print on @param typed_submachines list of all typed machine instances of - this machine @param m the machine **) - let pp_file fmt (typed_submachines, ((opt_spec_machine, guarantees), machine)) - = - let env = List.map (fun x -> x.var_id, pp_state_name) machine.mmemory in - let pp_reset fmt = - if is_machine_statefull machine then - fprintf fmt "%a;@,@," - (pp_reset_definition env typed_submachines) - (machine, opt_spec_machine) - else fprintf fmt "" - in - let aux pkgs (id, _) = - try - let pkg, _ = List.assoc id ada_supported_funs in - if List.mem pkg pkgs then pkgs else pkg :: pkgs - with Not_found -> pkgs - in - let packages = List.map pp_str (List.fold_left aux [] machine.mcalls) in - let pp_content fmt = - fprintf fmt "%t%a" (*Define the reset procedure*) pp_reset - (*Define the step procedure*) - (pp_step_definition env typed_submachines) - (machine, opt_spec_machine, guarantees) - in - fprintf fmt "%a%t%a;@." - (* Include all the required packages*) - (Utils.fprintf_list ~sep:";@," (pp_with AdaPrivate)) - packages - (Utils.pp_final_char_if_non_empty ";@,@," packages) - (*Print package*) - (pp_package (pp_package_name machine) [] true) - pp_content -end +(** Print the definition of the reset procedure from a machine. + + @param typed_submachines list of all typed machine instances of this + machine @param fmt the formater to print on @param machine the machine **) +let pp_reset_definition env typed_submachines fmt (m, m_spec_opt) = + let build_assign = function + | var -> + mkinstr (MStateAssign (var, mk_default_value var.var_type)) + in + let env, memory = + match m_spec_opt with None -> env, m.mmemory | Some _ -> env, m.mmemory + in + let assigns = List.map build_assign memory in + let pp_instr_list = + List.map (pp_machine_instr typed_submachines env) (assigns @ m.minit) + in + pp_procedure pp_reset_procedure_name (build_pp_arg_reset m) None fmt + (AdaProcedureContent ([], pp_instr_list)) + +(** Print the package definition(ads) of a machine. It requires the list of + all typed instance. A typed submachine instance is (ident, type_machine) + with ident the instance name and typed_machine is (substitution, machine) + with machine the machine associated to the instance and substitution the + instanciation of all its polymorphic types. @param fmt the formater to + print on @param typed_submachines list of all typed machine instances of + this machine @param m the machine **) +let pp_file fmt (typed_submachines, ((opt_spec_machine, guarantees), machine)) + = + let env = List.map (fun x -> x.var_id, pp_state_name) machine.mmemory in + let pp_reset fmt = + if is_machine_statefull machine then + fprintf fmt "%a;@,@," + (pp_reset_definition env typed_submachines) + (machine, opt_spec_machine) + else fprintf fmt "" + in + let aux pkgs (id, _) = + try + let pkg, _ = List.assoc id ada_supported_funs in + if List.mem pkg pkgs then pkgs else pkg :: pkgs + with Not_found -> pkgs + in + let packages = List.map pp_str (List.fold_left aux [] machine.mcalls) in + let pp_content fmt = + fprintf fmt "%t%a" (*Define the reset procedure*) pp_reset + (*Define the step procedure*) + (pp_step_definition env typed_submachines) + (machine, opt_spec_machine, guarantees) + in + fprintf fmt "%a%a;@." + (* Include all the required packages*) + (pp_print_list + ~pp_sep:pp_print_semicolon + ~pp_epilogue:(fun fmt () -> fprintf fmt ";@,@,") + (pp_with AdaPrivate)) + packages + (*Print package*) + (pp_package (pp_package_name machine) [] true) + pp_content (* Local Variables: *) (* compile-command: "make -C ../../.." *) diff --git a/src/backends/Ada/ada_backend_adb.mli b/src/backends/Ada/ada_backend_adb.mli index e69de29b..e52d73d4 100644 --- a/src/backends/Ada/ada_backend_adb.mli +++ b/src/backends/Ada/ada_backend_adb.mli @@ -0,0 +1,12 @@ +open Utils +open Machine_code_types + +(** Print the package definition(ads) of a machine. It requires the list of + all typed instance. A typed submachine instance is (ident, type_machine) + with ident the instance name and typed_machine is (substitution, machine) + with machine the machine associated to the instance and substitution the + instanciation of all its polymorphic types. @param fmt the formater to + print on @param typed_submachines list of all typed machine instances of + this machine @param m the machine **) +val pp_file: Format.formatter -> (ident * ((tag * Types.t) list * machine_t)) list + * ((machine_t option * ident list) * machine_t) -> unit diff --git a/src/backends/Ada/ada_backend_ads.ml b/src/backends/Ada/ada_backend_ads.ml index 4a45191f..3b74f2bc 100644 --- a/src/backends/Ada/ada_backend_ads.ml +++ b/src/backends/Ada/ada_backend_ads.ml @@ -9,6 +9,7 @@ (* *) (********************************************************************) +open Utils open Format open Machine_code_types open Lustre_types @@ -17,241 +18,248 @@ open Ada_printer open Ada_backend_common (** Functions printing the .ads file **) -module Main = struct - let rec init f = function i when i < 0 -> [] | i -> f i :: init f (i - 1) - (*should be replaced by the init of list from ocaml std lib*) - let suffixOld = "_old" +let rec init f = function i when i < 0 -> [] | i -> f i :: init f (i - 1) +(*should be replaced by the init of list from ocaml std lib*) - let suffixNew = "_new" +let suffixOld = "_old" - let pp_invariant_name fmt = fprintf fmt "inv" +let suffixNew = "_new" - let pp_transition_name fmt = fprintf fmt "transition" +let pp_invariant_name fmt = fprintf fmt "inv" - let pp_init_name fmt = fprintf fmt "init" +let pp_transition_name fmt = fprintf fmt "transition" - let pp_state_name_predicate suffix fmt = - fprintf fmt "%t%s" pp_state_name suffix +let pp_init_name fmt = fprintf fmt "init" - let pp_axiomatize_package_name fmt = fprintf fmt "axiomatize" +let pp_state_name_predicate suffix fmt = + fprintf fmt "%t%s" pp_state_name suffix - (** Print the expression function representing the transition predicate. - @param fmt the formater to print on **) - let pp_init_predicate fmt () = - let new_state = - AdaIn, pp_state_name_predicate suffixNew, pp_state_type, None - in - pp_predicate pp_init_name [ [ new_state ] ] true fmt None +let pp_axiomatize_package_name fmt = fprintf fmt "axiomatize" - (** Print the expression function representing the transition predicate. - @param fmt the formater to print on @param machine the machine **) - let pp_transition_predicate fmt (_, m) = - let old_state = - AdaIn, pp_state_name_predicate suffixOld, pp_state_type, None - in - let new_state = - AdaIn, pp_state_name_predicate suffixNew, pp_state_type, None - in - let inputs = build_pp_var_decl_step_input AdaIn None m in - let outputs = build_pp_var_decl_step_output AdaIn None m in - pp_predicate pp_transition_name - ([ [ old_state; new_state ] ] @ inputs @ outputs) - true fmt None +(** Print the expression function representing the transition predicate. + @param fmt the formater to print on **) +let pp_init_predicate fmt () = + let new_state = + AdaIn, pp_state_name_predicate suffixNew, pp_state_type, None + in + pp_predicate pp_init_name [ [ new_state ] ] true fmt None - let pp_invariant_predicate fmt () = - pp_predicate pp_invariant_name - [ [ build_pp_state_decl AdaIn None ] ] - true fmt None +(** Print the expression function representing the transition predicate. + @param fmt the formater to print on @param machine the machine **) +let pp_transition_predicate fmt (_, m) = + let old_state = + AdaIn, pp_state_name_predicate suffixOld, pp_state_type, None + in + let new_state = + AdaIn, pp_state_name_predicate suffixNew, pp_state_type, None + in + let inputs = build_pp_var_decl_step_input AdaIn None m in + let outputs = build_pp_var_decl_step_output AdaIn None m in + pp_predicate pp_transition_name + ([ [ old_state; new_state ] ] @ inputs @ outputs) + true fmt None - (** Print a new statement instantiating a generic package. @param fmt the - formater to print on @param substitutions the instanciation substitution - @param machine the machine to instanciate **) - let pp_new_package fmt (substitutions, machine) = - let pp_name = pp_package_name machine in - let pp_new_name = pp_package_name_with_polymorphic substitutions machine in - let instanciations = - List.map - (fun (id, typ) -> pp_polymorphic_type id, fun fmt -> pp_type fmt typ) - substitutions - in - pp_package_instanciation pp_new_name pp_name fmt instanciations +let pp_invariant_predicate fmt () = + pp_predicate pp_invariant_name + [ [ build_pp_state_decl AdaIn None ] ] + true fmt None - (** Remove duplicates from a list according to a given predicate. @param eq - the predicate defining equality @param l the list to parse **) - let remove_duplicates eq l = - let aux l x = if List.exists (eq x) l then l else x :: l in - List.fold_left aux [] l +(** Print a new statement instantiating a generic package. @param fmt the + formater to print on @param substitutions the instanciation substitution + @param machine the machine to instanciate **) +let pp_new_package fmt (substitutions, machine) = + let pp_name = pp_package_name machine in + let pp_new_name = pp_package_name_with_polymorphic substitutions machine in + let instanciations = + List.map + (fun (id, typ) -> pp_polymorphic_type id, fun fmt -> pp_type fmt typ) + substitutions + in + pp_package_instanciation pp_new_name pp_name fmt instanciations - (** Compare two typed machines. **) - let eq_typed_machine (subst1, machine1) (subst2, machine2) = - String.equal machine1.mname.node_id machine2.mname.node_id - && List.for_all2 (fun a b -> pp_eq_type (snd a) (snd b)) subst1 subst2 +(** Remove duplicates from a list according to a given predicate. @param eq + the predicate defining equality @param l the list to parse **) +let remove_duplicates eq l = + let aux l x = if List.exists (eq x) l then l else x :: l in + List.fold_left aux [] l - (** Print the package declaration(ads) of a machine. It requires the list of - all typed instance. A typed submachine is a (ident, typed_machine) with - - ident: the name - typed_machine: a (substitution, machine) with - machine: - the submachine struct - substitution the instanciation of all its - polymorphic types. @param fmt the formater to print on @param - typed_submachines list of all typed submachines of this machine @param m - the machine **) - let pp_file fmt (typed_submachines, ((m_spec_opt, guarantees), m)) = - let typed_machines = snd (List.split typed_submachines) in - let typed_machines_set = - remove_duplicates eq_typed_machine typed_machines - in +(** Compare two typed machines. **) +let eq_typed_machine (subst1, machine1) (subst2, machine2) = + String.equal machine1.mname.node_id machine2.mname.node_id + && List.for_all2 (fun a b -> pp_eq_type (snd a) (snd b)) subst1 subst2 - let machines_to_import = - List.map pp_package_name (snd (List.split typed_machines_set)) - in +(** Print the package declaration(ads) of a machine. It requires the list of + all typed instance. A typed submachine is a (ident, typed_machine) with - + ident: the name - typed_machine: a (substitution, machine) with - machine: + the submachine struct - substitution the instanciation of all its + polymorphic types. @param fmt the formater to print on @param + typed_submachines list of all typed submachines of this machine @param m + the machine **) +let pp_file fmt (typed_submachines, ((m_spec_opt, guarantees), m)) = + let typed_machines = snd (List.split typed_submachines) in + let typed_machines_set = + remove_duplicates eq_typed_machine typed_machines + in - let polymorphic_types = find_all_polymorphic_type m in + let machines_to_import = + List.map pp_package_name (snd (List.split typed_machines_set)) + in - let typed_machines_to_instanciate = - List.filter (fun (l, _) -> l != []) typed_machines_set - in + let polymorphic_types = find_all_polymorphic_type m in - let typed_instances = - List.filter is_submachine_statefull typed_submachines - in + let typed_machines_to_instanciate = + List.filter (fun (l, _) -> l != []) typed_machines_set + in - let memories = - match m_spec_opt with - | None -> - [] - | Some m -> - List.map - (fun x -> - pp_var_decl - (build_pp_var_decl AdaNoMode (Some (true, false, [], [])) x)) - m.mmemory - in - let ghost_private = memories in - (* Commented since not used. Could be reinjected in the code let vars_spec = - match m_spec_opt with | None -> [] | Some m_spec -> List.map - (build_pp_var_decl AdaNoMode (Some (true, false, [], []))) - (m_spec.mmemory) in *) - let vars = List.map (build_pp_var_decl AdaNoMode None) m.mmemory in - let states = + let typed_instances = + List.filter is_submachine_statefull typed_submachines + in + + let memories = + match m_spec_opt with + | None -> + [] + | Some m -> List.map - (build_pp_state_decl_from_subinstance AdaNoMode None) - typed_instances - in - let var_lists = - (if states = [] then [] else [ states ]) - @ if vars = [] then [] else [ vars ] - in + (fun x -> + pp_var_decl + (build_pp_var_decl AdaNoMode (Some (true, false, [], [])) x)) + m.mmemory + in + let ghost_private = memories in + (* Commented since not used. Could be reinjected in the code let vars_spec = + match m_spec_opt with | None -> [] | Some m_spec -> List.map + (build_pp_var_decl AdaNoMode (Some (true, false, [], []))) + (m_spec.mmemory) in *) + let vars = List.map (build_pp_var_decl AdaNoMode None) m.mmemory in + let states = + List.map + (build_pp_state_decl_from_subinstance AdaNoMode None) + typed_instances + in + let var_lists = + (if states = [] then [] else [ states ]) + @ if vars = [] then [] else [ vars ] + in - let pp_ifstatefull fmt pp = - if is_machine_statefull m then fprintf fmt "%t" pp else fprintf fmt "" - in + let pp_ifstatefull fmt pp = + if is_machine_statefull m then fprintf fmt "%t" pp else fprintf fmt "" + in - let pp_state_decl_and_reset fmt = - let init fmt = - pp_call fmt - ( pp_access pp_axiomatize_package_name pp_init_name, - [ [ pp_state_name ] ] ) - in - let contract = Some (false, false, [], [ init ]) in - fprintf fmt "%t;@,@,%a;@,@," - (*Declare the state type*) - (pp_type_decl pp_state_type AdaPrivate) - (*Declare the reset procedure*) - (pp_procedure pp_reset_procedure_name (build_pp_arg_reset m) contract) - AdaNoContent + let pp_state_decl_and_reset fmt = + let init fmt = + pp_call fmt + ( pp_access pp_axiomatize_package_name pp_init_name, + [ [ pp_state_name ] ] ) in + let contract = Some (false, false, [], [ init ]) in + fprintf fmt "%t;@,@,%a;@,@," + (*Declare the state type*) + (pp_type_decl pp_state_type AdaPrivate) + (*Declare the reset procedure*) + (pp_procedure pp_reset_procedure_name (build_pp_arg_reset m) contract) + AdaNoContent + in - let pp_private_section fmt = - fprintf fmt "@,private@,@,%a%t%a%t%a" - (*Instantiate the polymorphic type that need to be instantiated*) - (Utils.fprintf_list ~sep:";@," pp_new_package) - typed_machines_to_instanciate - (Utils.pp_final_char_if_non_empty ";@,@," typed_machines_to_instanciate) - (*Define the state type*) - pp_ifstatefull - (fun fmt -> pp_record pp_state_type fmt var_lists) - (Utils.pp_final_char_if_non_empty ";@,@," ghost_private) - (Utils.fprintf_list ~sep:";@," (fun fmt pp -> pp fmt)) - ghost_private - in + let pp_private_section fmt = + fprintf fmt "@,private@,@,%a%a%a" + (*Instantiate the polymorphic type that need to be instantiated*) + (pp_print_list + ~pp_sep:pp_print_semicolon + ~pp_epilogue:(fun fmt () -> fprintf fmt ";@,@,") + pp_new_package) + typed_machines_to_instanciate + (*Define the state type*) + pp_ifstatefull + (fun fmt -> pp_record pp_state_type fmt var_lists) + (pp_print_list + ~pp_sep:pp_print_semicolon + ~pp_prologue:(fun fmt () -> fprintf fmt ";@,@,") + (fun fmt pp -> pp fmt)) + ghost_private + in - let pp_content fmt = - let pp_contract_opt = - let pp_var x fmt = pp_clean_ada_identifier fmt x in - let guarantee_post_conditions = List.map pp_var guarantees in - let state_pre_conditions, state_post_conditions = - if is_machine_statefull m then - let input = List.map pp_var_name m.mstep.step_inputs in - let output = List.map pp_var_name m.mstep.step_outputs in - let args = - [ [ pp_old pp_state_name; pp_state_name ] ] - @ (if input != [] then [ input ] else []) - @ if output != [] then [ output ] else [] - in - let transition fmt = - pp_call fmt - (pp_access pp_axiomatize_package_name pp_transition_name, args) - in - let invariant fmt = - pp_call fmt - ( pp_access pp_axiomatize_package_name pp_invariant_name, - [ [ pp_state_name ] ] ) - in - [ invariant ], [ transition; invariant ] - else [], [] - in - let post_conditions = - state_post_conditions @ guarantee_post_conditions - in - let pre_conditions = state_pre_conditions in - if post_conditions = [] && pre_conditions = [] then None - else Some (false, false, pre_conditions, post_conditions) + let pp_content fmt = + let pp_contract_opt = + let pp_var x fmt = pp_clean_ada_identifier fmt x in + let guarantee_post_conditions = List.map pp_var guarantees in + let state_pre_conditions, state_post_conditions = + if is_machine_statefull m then + let input = List.map pp_var_name m.mstep.step_inputs in + let output = List.map pp_var_name m.mstep.step_outputs in + let args = + [ [ pp_old pp_state_name; pp_state_name ] ] + @ (if input != [] then [ input ] else []) + @ if output != [] then [ output ] else [] + in + let transition fmt = + pp_call fmt + (pp_access pp_axiomatize_package_name pp_transition_name, args) + in + let invariant fmt = + pp_call fmt + ( pp_access pp_axiomatize_package_name pp_invariant_name, + [ [ pp_state_name ] ] ) + in + [ invariant ], [ transition; invariant ] + else [], [] in - let pp_guarantee name = - pp_var_decl - ( AdaNoMode, - (fun fmt -> pp_clean_ada_identifier fmt name), - pp_boolean_type, - Some (true, false, [], []) ) + let post_conditions = + state_post_conditions @ guarantee_post_conditions in - let ghost_public = List.map pp_guarantee guarantees in - fprintf fmt "@,%a%t%a%a%a@,@,%a;@,@,%t" - (Utils.fprintf_list ~sep:";@," (fun fmt pp -> pp fmt)) - ghost_public - (Utils.pp_final_char_if_non_empty ";@,@," ghost_public) - pp_ifstatefull pp_state_decl_and_reset - (*Declare the step procedure*) - (pp_procedure pp_step_procedure_name (build_pp_arg_step m) - pp_contract_opt) - AdaNoContent pp_ifstatefull - (fun fmt -> fprintf fmt ";@,") - (pp_package pp_axiomatize_package_name [] false) - (fun fmt -> - fprintf fmt - "pragma Annotate (GNATProve, External_Axiomatization);@,\ - @,\ - %a;@,\ - %a;@,\ - %a" - (*Declare the init predicate*) - pp_init_predicate () - (*Declare the transition predicate*) - pp_transition_predicate (m_spec_opt, m) - (*Declare the invariant predicate*) - pp_invariant_predicate ()) - (*Print the private section*) - pp_private_section + let pre_conditions = state_pre_conditions in + if post_conditions = [] && pre_conditions = [] then None + else Some (false, false, pre_conditions, post_conditions) + in + let pp_guarantee name = + pp_var_decl + ( AdaNoMode, + (fun fmt -> pp_clean_ada_identifier fmt name), + pp_boolean_type, + Some (true, false, [], []) ) in + let ghost_public = List.map pp_guarantee guarantees in + fprintf fmt "@,%a%a%a%a@,@,%a;@,@,%t" + (pp_print_list + ~pp_sep:pp_print_semicolon + ~pp_epilogue:(fun fmt () -> fprintf fmt ";@,@,") + (fun fmt pp -> pp fmt)) + ghost_public + pp_ifstatefull pp_state_decl_and_reset + (*Declare the step procedure*) + (pp_procedure pp_step_procedure_name (build_pp_arg_step m) + pp_contract_opt) + AdaNoContent pp_ifstatefull + (fun fmt -> fprintf fmt ";@,") + (pp_package pp_axiomatize_package_name [] false) + (fun fmt -> + fprintf fmt + "pragma Annotate (GNATProve, External_Axiomatization);@,\ + @,\ + %a;@,\ + %a;@,\ + %a" + (*Declare the init predicate*) + pp_init_predicate () + (*Declare the transition predicate*) + pp_transition_predicate (m_spec_opt, m) + (*Declare the invariant predicate*) + pp_invariant_predicate ()) + (*Print the private section*) + pp_private_section + in - let pp_poly_type id = pp_type_decl (pp_polymorphic_type id) AdaPrivate in - let pp_generics = List.map pp_poly_type polymorphic_types in + let pp_poly_type id = pp_type_decl (pp_polymorphic_type id) AdaPrivate in + let pp_generics = List.map pp_poly_type polymorphic_types in - fprintf fmt "@[<v>%a%t%a;@]@." - (* Include all the subinstance package*) - (Utils.fprintf_list ~sep:";@," (pp_with AdaNoVisibility)) - machines_to_import - (Utils.pp_final_char_if_non_empty ";@,@," machines_to_import) - (*Begin the package*) - (pp_package (pp_package_name m) pp_generics false) - pp_content -end + fprintf fmt "@[<v>%a%a;@]@." + (* Include all the subinstance package*) + (pp_print_list + ~pp_sep:pp_print_semicolon + ~pp_epilogue:(fun fmt () -> fprintf fmt ";@,@,") + (pp_with AdaNoVisibility)) + machines_to_import + (*Begin the package*) + (pp_package (pp_package_name m) pp_generics false) + pp_content diff --git a/src/backends/Ada/ada_backend_ads.mli b/src/backends/Ada/ada_backend_ads.mli index e69de29b..90b11e4a 100644 --- a/src/backends/Ada/ada_backend_ads.mli +++ b/src/backends/Ada/ada_backend_ads.mli @@ -0,0 +1,12 @@ +open Utils +open Machine_code_types + +(** Print the package declaration(ads) of a machine. It requires the list of + all typed instance. A typed submachine is a (ident, typed_machine) with - + ident: the name - typed_machine: a (substitution, machine) with - machine: + the submachine struct - substitution the instanciation of all its + polymorphic types. @param fmt the formater to print on @param + typed_submachines list of all typed submachines of this machine @param m + the machine **) +val pp_file: Format.formatter -> (ident * ((tag * Types.t) list * machine_t)) list + * ((machine_t option * ident list) * machine_t) -> unit diff --git a/src/backends/Ada/ada_backend_common.ml b/src/backends/Ada/ada_backend_common.ml index fa2f1b88..daff6d65 100644 --- a/src/backends/Ada/ada_backend_common.ml +++ b/src/backends/Ada/ada_backend_common.ml @@ -1,3 +1,4 @@ +open Utils open Format open Machine_code_types open Lustre_types @@ -73,68 +74,71 @@ let pp_package_name machine fmt = (** Print a type. @param fmt the formater to print on @param type the type **) let pp_type fmt typ = - match (Types.repr typ).Types.tdesc with - | Types.Tbasic Types.Basic.Tint -> + let open Types in + let t = repr typ in + if is_bool_type t then + pp_boolean_type fmt + else if is_int_type t then pp_integer_type fmt - | Types.Tbasic Types.Basic.Treal -> + else if is_real_type t then pp_float_type fmt - | Types.Tbasic Types.Basic.Tbool -> - pp_boolean_type fmt - | Types.Tunivar -> - pp_polymorphic_type typ.Types.tid fmt - | Types.Tbasic _ -> - eprintf "Tbasic@."; - assert false (*TODO*) - | Types.Tconst _ -> - eprintf "Tconst@."; - assert false (*TODO*) - | Types.Tclock _ -> - eprintf "Tclock@."; - assert false (*TODO*) - | Types.Tarrow _ -> - eprintf "Tarrow@."; - assert false (*TODO*) - | Types.Ttuple l -> - eprintf "Ttuple %a @." (Utils.fprintf_list ~sep:" " Types.print_ty) l; - assert false (*TODO*) - | Types.Tenum _ -> - eprintf "Tenum@."; - assert false (*TODO*) - | Types.Tstruct _ -> - eprintf "Tstruct@."; - assert false (*TODO*) - | Types.Tarray _ -> - eprintf "Tarray@."; - assert false (*TODO*) - | Types.Tstatic _ -> - eprintf "Tstatic@."; - assert false (*TODO*) - | Types.Tlink _ -> - eprintf "Tlink@."; - assert false (*TODO*) - | Types.Tvar -> - eprintf "Tvar@."; - assert false + else match t.tdesc with + | Tunivar -> + pp_polymorphic_type typ.tid fmt + | Tbasic _ -> + eprintf "Tbasic@."; + assert false (*TODO*) + | Tconst _ -> + eprintf "Tconst@."; + assert false (*TODO*) + | Tclock _ -> + eprintf "Tclock@."; + assert false (*TODO*) + | Tarrow _ -> + eprintf "Tarrow@."; + assert false (*TODO*) + | Ttuple l -> + eprintf "Ttuple %a @." (pp_print_list print_ty) l; + assert false (*TODO*) + | Tenum _ -> + eprintf "Tenum@."; + assert false (*TODO*) + | Tstruct _ -> + eprintf "Tstruct@."; + assert false (*TODO*) + | Tarray _ -> + eprintf "Tarray@."; + assert false (*TODO*) + | Tstatic _ -> + eprintf "Tstatic@."; + assert false (*TODO*) + | Tlink _ -> + eprintf "Tlink@."; + assert false (*TODO*) + | Tvar -> + eprintf "Tvar@."; + assert false (*TODO*) (*| _ -> eprintf "Type error : %a@." Types.print_ty typ; assert false *) (** Return a default ada constant for a given type. @param cst_typ the constant type **) -let default_ada_cst cst_typ = - match cst_typ with - | Types.Basic.Tint -> +let default_ada_cst t = + let open Types in + if is_bool_type t then + Const_tag tag_false + else if is_int_type t then Const_int 0 - | Types.Basic.Treal -> + else if is_real_type t then Const_real Real.zero - | Types.Basic.Tbool -> - Const_tag tag_false - | _ -> + else assert false (** Make a default value from a given type. @param typ the type **) let mk_default_value typ = - match (Types.repr typ).Types.tdesc with - | Types.Tbasic t -> + let t = Types.repr typ in + match t.Types.tdesc with + | Types.Tbasic _ -> mk_val (Cst (default_ada_cst t)) typ | _ -> assert false @@ -156,9 +160,12 @@ let pp_package_name_with_polymorphic substitution machine fmt = (fun poly1 (poly2, _) -> poly1 = poly2) polymorphic_types substituion); let instantiated_types = snd (List.split substitution) in - fprintf fmt "%t%t%a" (pp_package_name machine) - (Utils.pp_final_char_if_non_empty "_" instantiated_types) - (Utils.fprintf_list ~sep:"_" pp_type) + fprintf fmt "%t%a" + (pp_package_name machine) + (pp_print_list + ~pp_prologue:(fun fmt () -> pp_print_string fmt "_") + ~pp_sep:(fun fmt () -> pp_print_string fmt "_") + pp_type) instantiated_types (** Print the name of a variable. @param fmt the formater to print on @param id diff --git a/src/backends/Ada/ada_backend_common.mli b/src/backends/Ada/ada_backend_common.mli index 426b3e48..a193ba56 100644 --- a/src/backends/Ada/ada_backend_common.mli +++ b/src/backends/Ada/ada_backend_common.mli @@ -29,16 +29,16 @@ val pp_var : (string * printer) list -> formatter -> var_decl -> unit val pp_value : (string * printer) list -> formatter -> value_t -> unit -val pp_type : formatter -> type_expr -> unit +val pp_type : formatter -> Types.t -> unit val pp_var_type : formatter -> var_decl -> unit val pp_package_name : machine_t -> printer val pp_package_name_with_polymorphic : - (int * Types.type_expr) list -> machine_t -> printer + (int * Types.t) list -> machine_t -> printer -val mk_default_value : type_expr -> value_t +val mk_default_value : Types.t -> value_t val build_pp_var_decl : parameter_mode -> ada_with -> var_decl -> ada_var_decl @@ -57,7 +57,7 @@ val build_pp_arg_reset : machine_t -> ada_var_decl list list val build_pp_state_decl_from_subinstance : parameter_mode -> ada_with -> - string * ((int * Types.type_expr) list * Machine_code_types.machine_t) -> + string * ((int * Types.t) list * Machine_code_types.machine_t) -> ada_var_decl val build_pp_state_decl : parameter_mode -> ada_with -> ada_var_decl diff --git a/src/backends/Ada/ada_backend_wrapper.ml b/src/backends/Ada/ada_backend_wrapper.ml index 0caa505d..3194e73f 100644 --- a/src/backends/Ada/ada_backend_wrapper.ml +++ b/src/backends/Ada/ada_backend_wrapper.ml @@ -9,6 +9,7 @@ (* *) (********************************************************************) +open Utils open Format open Machine_code_types open Lustre_types @@ -17,33 +18,32 @@ open Misc_lustre_function open Ada_printer open Ada_backend_common -module Main = struct - let build_text_io_package_local typ = - AdaLocalPackage - ( (fun fmt -> fprintf fmt "%s_IO" typ), - (fun fmt -> fprintf fmt "Ada.Text_IO.%s_IO" typ), - [ ((fun fmt -> fprintf fmt "Num"), fun fmt -> fprintf fmt "%s" typ) ] ) +let build_text_io_package_local typ = + AdaLocalPackage + ( (fun fmt -> fprintf fmt "%s_IO" typ), + (fun fmt -> fprintf fmt "Ada.Text_IO.%s_IO" typ), + [ ((fun fmt -> fprintf fmt "Num"), fun fmt -> fprintf fmt "%s" typ) ] ) - (** Print the main file calling in a loop the step function of the main - machine. @param fmt the formater to print on @param machine the main - machine **) - let pp_main_adb fmt machine = - let statefull = is_machine_statefull machine in +(** Print the main file calling in a loop the step function of the main + machine. @param fmt the formater to print on @param machine the main + machine **) +let pp_main_adb fmt machine = + let statefull = is_machine_statefull machine in - let pp_package = pp_package_name_with_polymorphic [] machine in + let pp_package = pp_package_name_with_polymorphic [] machine in - (* Dependances *) - let text_io = "Ada.Text_IO" in + (* Dependances *) + let text_io = "Ada.Text_IO" in - (* Locals *) - let locals = + (* Locals *) + let locals = + [ [ - [ - build_text_io_package_local "Integer"; - build_text_io_package_local "Float"; - ]; - ] - @ (if statefull then + build_text_io_package_local "Integer"; + build_text_io_package_local "Float"; + ]; + ] + @ (if statefull then [ [ AdaLocalVar @@ -51,171 +51,163 @@ module Main = struct (asprintf "%t" pp_state_name, ([], machine))); ]; ] - else []) - @ (if machine.mstep.step_inputs != [] then + else []) + @ (if machine.mstep.step_inputs != [] then [ List.map (build_pp_var_decl_local None) machine.mstep.step_inputs ] - else []) - @ - if machine.mstep.step_outputs != [] then - [ List.map (build_pp_var_decl_local None) machine.mstep.step_outputs ] - else [] - in - - (* Stream instructions *) - let get_basic var = - match (Types.repr var.var_type).Types.tdesc with - | Types.Tbasic x -> - x - | _ -> - assert false - in - let pp_read fmt var = - match get_basic var with - | Types.Basic.Tbool -> - fprintf fmt "%t := Integer'Value(Ada.Text_IO.Get_Line) /= 0" - (pp_var_name var) - | _ -> - fprintf fmt "%t := %a'Value(Ada.Text_IO.Get_Line)" (pp_var_name var) - pp_var_type var - in - let pp_write fmt var = - match get_basic var with - | Types.Basic.Tbool -> - fprintf fmt - "Ada.Text_IO.Put_Line(\"'%t': '\" & (if %t then \"1\" else \"0\") & \ - \"' \")" - (pp_var_name var) (pp_var_name var) - | Types.Basic.Tint -> - fprintf fmt - "Ada.Text_IO.Put(\"'%t': '\");@,\ - Integer_IO.Put(%t);@,\ - Ada.Text_IO.Put_Line(\"' \")" (pp_var_name var) (pp_var_name var) - | Types.Basic.Treal -> - fprintf fmt - "Ada.Text_IO.Put(\"'%t': '\");@,\ - Float_IO.Put(%t, Fore=>0, Aft=> 15, Exp => 0);@,\ - Ada.Text_IO.Put_Line(\"' \")" (pp_var_name var) (pp_var_name var) - | Types.Basic.Tstring | Types.Basic.Trat -> - assert false - (* Could not be the top level inputs *) - in - - (* Loop instructions *) - let pp_loop fmt = - let args = - pp_state_name - :: - List.map pp_var_name - (machine.mstep.step_inputs @ machine.mstep.step_outputs) - in + else []) + @ + if machine.mstep.step_outputs != [] then + [ List.map (build_pp_var_decl_local None) machine.mstep.step_outputs ] + else [] + in + + (* Stream instructions *) + let get_type var = Types.repr var.var_type in + let pp_read fmt var = + if Types.is_bool_type (get_type var) then + fprintf fmt "%t := Integer'Value(Ada.Text_IO.Get_Line) /= 0" + (pp_var_name var) + else + fprintf fmt "%t := %a'Value(Ada.Text_IO.Get_Line)" (pp_var_name var) + pp_var_type var + in + let pp_write fmt var = + let t = get_type var in + if Types.is_bool_type t then + fprintf fmt + "Ada.Text_IO.Put_Line(\"'%t': '\" & (if %t then \"1\" else \"0\") & \ + \"' \")" + (pp_var_name var) (pp_var_name var) + else if Types.is_int_type t then fprintf fmt - "while not Ada.Text_IO.End_Of_File loop@,\ - \ @[<v>%a;@,\ - %a;@,\ - %a;@]@,\ - end loop" - (Utils.fprintf_list ~sep:";@," pp_read) - machine.mstep.step_inputs pp_call - (pp_package_access (pp_package, pp_step_procedure_name), [ args ]) - (Utils.fprintf_list ~sep:";@," pp_write) - machine.mstep.step_outputs + "Ada.Text_IO.Put(\"'%t': '\");@,\ + Integer_IO.Put(%t);@,\ + Ada.Text_IO.Put_Line(\"' \")" (pp_var_name var) (pp_var_name var) + else if Types.is_real_type t then + fprintf fmt + "Ada.Text_IO.Put(\"'%t': '\");@,\ + Float_IO.Put(%t, Fore=>0, Aft=> 15, Exp => 0);@,\ + Ada.Text_IO.Put_Line(\"' \")" (pp_var_name var) (pp_var_name var) + else + assert false + (* Could not be the top level inputs *) + in + + (* Loop instructions *) + let pp_loop fmt = + let args = + pp_state_name + :: + List.map pp_var_name + (machine.mstep.step_inputs @ machine.mstep.step_outputs) in - - (* Print the file *) - let instrs = - (if statefull then + fprintf fmt + "while not Ada.Text_IO.End_Of_File loop@,\ + \ @[<v>%a;@,\ + %a;@,\ + %a;@]@,\ + end loop" + (pp_print_list ~pp_sep:pp_print_semicolon pp_read) + machine.mstep.step_inputs pp_call + (pp_package_access (pp_package, pp_step_procedure_name), [ args ]) + (pp_print_list ~pp_sep:pp_print_semicolon pp_write) + machine.mstep.step_outputs + in + + (* Print the file *) + let instrs = + (if statefull then [ (fun fmt -> - pp_call fmt - ( pp_package_access (pp_package, pp_reset_procedure_name), - [ [ pp_state_name ] ] )); + pp_call fmt + ( pp_package_access (pp_package, pp_reset_procedure_name), + [ [ pp_state_name ] ] )); ] - else []) - @ [ pp_loop ] - in - fprintf fmt "@[<v>%a;@,%a;@,@,%a;@]" (pp_with AdaPrivate) (pp_str text_io) - (pp_with AdaPrivate) (pp_package_name machine) - (pp_procedure pp_main_procedure_name [] None) - (AdaProcedureContent (locals, instrs)) - - (** Print the name of the ada project configuration file. @param fmt the - formater to print on @param main_machine the machine associated to the - main node **) - let pp_project_configuration_name fmt basename = fprintf fmt "%s.adc" basename - - (** Print the project configuration file. @param fmt the formater to print on - **) - let pp_project_configuration_file fmt = fprintf fmt "pragma SPARK_Mode (On);" - - (** Print the name of the ada project file. @param base_name name of the - lustre file @param fmt the formater to print on **) - let pp_project_name basename fmt = fprintf fmt "%s.gpr" basename - - let pp_for_single name arg fmt = fprintf fmt "for %s use \"%s\"" name arg - - let pp_for name args fmt = - fprintf fmt "for %s use (@[%a@])" name - (Utils.fprintf_list ~sep:",@ " (fun fmt arg -> fprintf fmt "\"%s\"" arg)) - args - - let pp_content fmt lines = - fprintf fmt " @[<v>%a%t@]" - (Utils.fprintf_list ~sep:";@," (fun fmt pp -> fprintf fmt "%t" pp)) - lines - (Utils.pp_final_char_if_non_empty ";" lines) - - let pp_package name lines fmt = - fprintf fmt "package %s is@,%a@,end %s" name pp_content lines name - - (** Print the gpr project file, if there is a machine in machine_opt then an - executable project is made else it is a library. @param fmt the formater - to print on @param machine_opt the main machine option **) - let pp_project_file machines basename fmt machine_opt = - let adbs = - List.map (asprintf "%a" (pp_machine_filename "adb")) machines - @ - match machine_opt with - | None -> - [] - | Some m -> - [ asprintf "%a" pp_main_filename m ] - in - let project_name = - basename ^ if machine_opt = None then "_lib" else "_exe" - in - fprintf fmt "%sproject %s is@,%a@,end %s;" - (if machine_opt = None then "library " else "") - project_name pp_content - ((match machine_opt with - | None -> + else []) + @ [ pp_loop ] + in + fprintf fmt "@[<v>%a;@,%a;@,@,%a;@]" (pp_with AdaPrivate) (pp_str text_io) + (pp_with AdaPrivate) (pp_package_name machine) + (pp_procedure pp_main_procedure_name [] None) + (AdaProcedureContent (locals, instrs)) + +(** Print the name of the ada project configuration file. @param fmt the + formater to print on @param main_machine the machine associated to the + main node **) +let pp_project_configuration_name fmt basename = fprintf fmt "%s.adc" basename + +(** Print the project configuration file. @param fmt the formater to print on + **) +let pp_project_configuration_file fmt = fprintf fmt "pragma SPARK_Mode (On);" + +(** Print the name of the ada project file. @param base_name name of the + lustre file @param fmt the formater to print on **) +let pp_project_name basename fmt = fprintf fmt "%s.gpr" basename + +let pp_for_single name arg fmt = fprintf fmt "for %s use \"%s\"" name arg + +let pp_for name args fmt = + fprintf fmt "for %s use (@[%a@])" name + (pp_comma_list (fun fmt arg -> fprintf fmt "\"%s\"" arg)) + args + +let pp_content fmt lines = + fprintf fmt " @[<v>%a%a@]" + (pp_print_list ~pp_sep:pp_print_semicolon (fun fmt pp -> fprintf fmt "%t" pp)) + lines + (if lines = [] then pp_print_nothing else pp_print_semicolon) () + +let pp_package name lines fmt = + fprintf fmt "package %s is@,%a@,end %s" name pp_content lines name + +(** Print the gpr project file, if there is a machine in machine_opt then an + executable project is made else it is a library. @param fmt the formater + to print on @param machine_opt the main machine option **) +let pp_project_file machines basename fmt machine_opt = + let adbs = + List.map (asprintf "%a" (pp_machine_filename "adb")) machines + @ + match machine_opt with + | None -> + [] + | Some m -> + [ asprintf "%a" pp_main_filename m ] + in + let project_name = + basename ^ if machine_opt = None then "_lib" else "_exe" + in + fprintf fmt "%sproject %s is@,%a@,end %s;" + (if machine_opt = None then "library " else "") + project_name pp_content + ((match machine_opt with + | None -> + [ + pp_for_single "Library_Name" basename; + pp_for_single "Library_Dir" "lib"; + ] + | Some _ -> + [ + pp_for "Main" [ asprintf "%t" pp_main_procedure_name ]; + pp_for_single "Exec_Dir" "bin"; + ]) + @ [ + pp_for_single "Object_Dir" "obj"; + pp_for "Source_Files" adbs; + pp_package "Builder" [ - pp_for_single "Library_Name" basename; - pp_for_single "Library_Dir" "lib"; - ] - | Some _ -> + pp_for_single "Global_Configuration_Pragmas" + (asprintf "%a" pp_project_configuration_name basename); + ]; + pp_package "Prove" [ - pp_for "Main" [ asprintf "%t" pp_main_procedure_name ]; - pp_for_single "Exec_Dir" "bin"; - ]) - @ [ - pp_for_single "Object_Dir" "obj"; - pp_for "Source_Files" adbs; - pp_package "Builder" - [ - pp_for_single "Global_Configuration_Pragmas" - (asprintf "%a" pp_project_configuration_name basename); - ]; - pp_package "Prove" - [ - pp_for "Switches" - [ - "--mode=prove"; - "--report=statistics"; - "--proof=per_check"; - "--warnings=continue"; - ]; - pp_for_single "Proof_Dir" (asprintf "proof"); - ]; - ]) - project_name -end + pp_for "Switches" + [ + "--mode=prove"; + "--report=statistics"; + "--proof=per_check"; + "--warnings=continue"; + ]; + pp_for_single "Proof_Dir" (asprintf "proof"); + ]; + ]) + project_name diff --git a/src/backends/Ada/ada_backend_wrapper.mli b/src/backends/Ada/ada_backend_wrapper.mli index e69de29b..db8a9481 100644 --- a/src/backends/Ada/ada_backend_wrapper.mli +++ b/src/backends/Ada/ada_backend_wrapper.mli @@ -0,0 +1,26 @@ +open Utils +open Format +open Machine_code_types + +(** Print the main file calling in a loop the step function of the main + machine. @param fmt the formater to print on @param machine the main + machine **) +val pp_main_adb: formatter -> machine_t -> unit + +(** Print the name of the ada project file. @param base_name name of the + lustre file @param fmt the formater to print on **) +val pp_project_name: string -> formatter -> unit + +(** Print the gpr project file, if there is a machine in machine_opt then an + executable project is made else it is a library. @param fmt the formater + to print on @param machine_opt the main machine option **) +val pp_project_file: machine_t list -> string -> formatter -> machine_t option -> unit + +(** Print the name of the ada project configuration file. @param fmt the + formater to print on @param main_machine the machine associated to the + main node **) +val pp_project_configuration_name: formatter -> string -> unit + +(** Print the project configuration file. @param fmt the formater to print on + **) +val pp_project_configuration_file: formatter -> unit diff --git a/src/backends/Ada/ada_printer.ml b/src/backends/Ada/ada_printer.ml index b6f40235..3443fa9f 100644 --- a/src/backends/Ada/ada_printer.ml +++ b/src/backends/Ada/ada_printer.ml @@ -1,3 +1,4 @@ +open Utils open Format (** Represent the possible mode for a type of a procedure parameter **) @@ -78,28 +79,32 @@ let pp_float_type fmt = fprintf fmt "Float" (** Print the boolean type name. @param fmt the formater to print on **) let pp_boolean_type fmt = fprintf fmt "Boolean" -let pp_group ~sep pp_list fmt = +let pp_group ~pp_sep pp_list fmt = assert (pp_list != []); - fprintf fmt "@[%a@]" (Utils.fprintf_list ~sep (fun fmt pp -> pp fmt)) pp_list + fprintf fmt "@[%a@]" (pp_print_list ~pp_sep (fun fmt pp -> pp fmt)) pp_list -let pp_args ~sep fmt = function +let pp_args ~pp_sep fmt = function | [] -> fprintf fmt "" | args -> fprintf fmt " (@[<v>%a)@]" - (Utils.fprintf_list ~sep (fun fmt pp -> pp fmt)) + (pp_print_list ~pp_sep (fun fmt pp -> pp fmt)) args let pp_block fmt pp_item_list = - fprintf fmt "%t@[<v>%a@]%t" - (Utils.pp_final_char_if_non_empty " " pp_item_list) - (Utils.fprintf_list ~sep:";@," (fun fmt pp -> pp fmt)) + pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue:(fun fmt () -> pp_print_string fmt " ") + ~pp_epilogue:pp_print_semicolon + ~pp_sep:pp_print_semicolon (fun fmt pp -> pp fmt) + fmt pp_item_list - (Utils.pp_final_char_if_non_empty ";@," pp_item_list) -let pp_and l fmt = fprintf fmt "(%t)" (pp_group ~sep:"@ and then " l) +let pp_and l fmt = + fprintf fmt "(%t)" (pp_group ~pp_sep:(fun fmt () -> fprintf fmt "@ and then ") l) -let pp_or l fmt = fprintf fmt "(%t)" (pp_group ~sep:"@ or " l) +let pp_or l fmt = + fprintf fmt "(%t)" (pp_group ~pp_sep:(fun fmt () -> fprintf fmt "@ or ") l) let pp_ada_with fmt = function | None -> @@ -117,8 +122,8 @@ let pp_ada_with fmt = function let pp_import fmt = if not import then fprintf fmt "" else - fprintf fmt " Import%t" - (Utils.pp_final_char_if_non_empty ",@," contract) + fprintf fmt " Import%a" + (if contract = [] then pp_print_nothing else pp_print_comma) () in let pp_aspect aspect fmt pps = if pps = [] then fprintf fmt "" @@ -184,23 +189,23 @@ and pp_content pp_name fmt = function fprintf fmt " is@, @[<v 2>(%t)@]" pp_content | AdaProcedureContent (local_list, pp_instr_list) -> fprintf fmt " is@,%abegin@,%aend %t" pp_block - (List.map (fun l -> pp_group ~sep:";@;" (List.map pp_local l)) local_list) + (List.map (fun l -> pp_group ~pp_sep:pp_print_semicolon (List.map pp_local l)) local_list) pp_block pp_instr_list pp_name | AdaRecord var_list -> assert (var_list != []); let pp_lists = apply_var_decl_lists var_list in fprintf fmt " is@, @[<v>record@, @[<v>%a@]@,end record@]" pp_block - (List.map (pp_group ~sep:";@;") pp_lists) + (List.map (pp_group ~pp_sep:pp_print_semicolon) pp_lists) | AdaPackageInstanciation (pp_name, instanciations) -> - fprintf fmt " is new %t%a" pp_name (pp_args ~sep:",@,") + fprintf fmt " is new %t%a" pp_name (pp_args ~pp_sep:pp_print_comma) (List.map pp_generic_instanciation instanciations) and pp_def fmt (pp_generics, kind_def, pp_name, args, pp_type_opt, content, pp_with_opt) = let pp_arg_lists = apply_var_decl_lists args in fprintf fmt "%a%a %t%a%a%a%a" pp_generic pp_generics pp_kind_def kind_def - pp_name (pp_args ~sep:";@,") - (List.map (pp_group ~sep:";@,") pp_arg_lists) + pp_name (pp_args ~pp_sep:pp_print_semicolon) + (List.map (pp_group ~pp_sep:pp_print_semicolon) pp_arg_lists) (pp_opt "return") pp_type_opt (pp_content pp_name) content pp_ada_with pp_with_opt @@ -387,8 +392,8 @@ let pp_oneline_comment fmt s = fprintf fmt "-- %s@," s let pp_call fmt (pp_name, args) = - fprintf fmt "%t%a" pp_name (pp_args ~sep:",@ ") - (List.map (pp_group ~sep:",@,") args) + fprintf fmt "%t%a" pp_name (pp_args ~pp_sep:pp_print_comma) + (List.map (pp_group ~pp_sep:pp_print_comma) args) (** Print the complete name of variable. @param m the machine to check if it is memory @param fmt the formater to print on @param var the variable **) diff --git a/src/backends/Ada/misc_lustre_function.mli b/src/backends/Ada/misc_lustre_function.mli index e69de29b..74a4f7df 100644 --- a/src/backends/Ada/misc_lustre_function.mli +++ b/src/backends/Ada/misc_lustre_function.mli @@ -0,0 +1,41 @@ +open Utils +open Machine_code_types + +val is_machine_statefull: machine_t -> bool +val is_arrow: machine_t -> bool + +(** Find all polymorphic type : Types.Tunivar in a machine. @param machine the + machine @return a list of id corresponding to polymorphic type **) +val find_all_polymorphic_type: machine_t -> int list + +(** Test if two types are the same. @param typ1 the first type @param typ2 the + second type **) +val pp_eq_type: Types.t -> Types.t -> bool + +(** Check if a submachine is statefull. @param submachine a submachine @return + true if the submachine is statefull **) +val is_submachine_statefull: 'a * ('b * machine_t) -> bool + +(** Extract from a machine the instance corresponding to the identifier, assume + that the identifier exists in the instances of the machine. + + @param identifier the instance identifier @param machine a machine @return + the instance of machine.minstances corresponding to identifier **) +val get_instance: 'a -> ('a * 'b) list -> 'b + +val build_if: 'a -> ident -> 'b -> ('c * 'b) list -> bool * 'a * 'b * 'b option + +(** Extract from a machine list the one corresponding to the given instance. + assume that the machine is in the list. @param machines list of all machines + @param instance instance of a machine @return the machine corresponding to + hte given instance **) +val get_machine: machine_t list -> 'a * (Lustre_types.top_decl * 'b) -> machine_t + +(** Extract from a subinstance that can have polymorphic type the instantiation + of all its polymorphic type instanciation for a given machine. It searches + the step calls and extract a substitution for all polymorphic type from it. + @param machine the machine which instantiate the subinstance @param ident + the identifier of the instance which permits to find the step call @param + submachine the machine corresponding to the subinstance @return the + correspondance between polymorphic type id and their instantiation **) +val get_substitution: machine_t -> ident -> machine_t -> (int * Types.t) list diff --git a/src/backends/Ada/misc_printer.mli b/src/backends/Ada/misc_printer.mli index df403db0..1fc5de74 100644 --- a/src/backends/Ada/misc_printer.mli +++ b/src/backends/Ada/misc_printer.mli @@ -1 +1,10 @@ -type printer = Format.formatter -> unit +open Format + +type printer = formatter -> unit + +val pp_str: string -> printer + +(** Print a filename by lowercasing the base and appending an extension. @param + extension the extension to append to the package name @param fmt the + formatter @param pp_name the file base name printer **) +val pp_filename: string -> formatter -> printer -> unit diff --git a/src/backends/C/c_backend.ml b/src/backends/C/c_backend.ml index f3008056..622d69c7 100644 --- a/src/backends/C/c_backend.ml +++ b/src/backends/C/c_backend.ml @@ -32,8 +32,8 @@ let with_main_node machines node f = | None -> let open Error in Global.main_node := node; - Format.eprintf "Code generation error: %a@." pp_error_msg Main_not_found; - raise (Error (Location.dummy_loc, Main_not_found)) + Format.eprintf "Code generation error: %a@." pp Main_not_found; + raise (Error (Location.dummy, Main_not_found)) | Some m -> f m @@ -100,19 +100,18 @@ let gen_files (* close_out makefile_out *) let print_c_header basename = + let open Options in let header_m = - match !Options.spec with - | "no" -> - C_backend_header.((module EmptyMod : MODIFIERS_HDR)) - | "acsl" -> - C_backend_header.((module C_backend_spec.HdrMod : MODIFIERS_HDR)) - | "c" -> + match !spec with + | SpecNo -> + C_backend_header.(module EmptyMod : MODIFIERS_HDR) + | SpecACSL -> + C_backend_header.(module C_backend_spec.HdrMod : MODIFIERS_HDR) + | SpecC -> assert false (* not implemented yet *) - | _ -> - assert false in - let module Header = C_backend_header.Main ((val header_m)) in - let destname = !Options.dest_dir ^ "/" ^ basename in + let module Header = C_backend_header.Main (val header_m) in + let destname = !dest_dir ^ "/" ^ basename in (* Generating H file *) let lusic = Lusic.read_lusic destname ".lusic" in let header_file = destname ^ ".h" in @@ -122,22 +121,21 @@ let print_c_header basename = let translate_to_c generate_c_header basename prog machines dependencies = let header_m, source_m, source_main_m, makefile_m = - match !Options.spec with - | "no" -> + let open Options in + match !spec with + | SpecNo -> ( C_backend_header.((module EmptyMod : MODIFIERS_HDR)), C_backend_src.((module EmptyMod : MODIFIERS_SRC)), C_backend_main.((module EmptyMod : MODIFIERS_MAINSRC)), C_backend_makefile.((module EmptyMod : MODIFIERS_MKF)) ) - | "acsl" -> + | SpecACSL -> let open C_backend_spec in ( C_backend_header.((module HdrMod : MODIFIERS_HDR)), C_backend_src.((module SrcMod : MODIFIERS_SRC)), C_backend_main.((module EmptyMod : MODIFIERS_MAINSRC)), C_backend_makefile.((module MakefileMod : MODIFIERS_MKF)) ) - | "c" -> + | SpecC -> assert false (* not implemented yet *) - | _ -> - assert false in let module Header = C_backend_header.Main ((val header_m)) in let module Source = C_backend_src.Main ((val source_m)) in diff --git a/src/backends/C/c_backend.mli b/src/backends/C/c_backend.mli index e69de29b..b358eb0e 100644 --- a/src/backends/C/c_backend.mli +++ b/src/backends/C/c_backend.mli @@ -0,0 +1,6 @@ +open Lustre_types +open Machine_code_types + +val translate_to_c: bool -> string -> program_t -> machine_t list -> dep_t list -> unit + +val print_c_header: string -> unit diff --git a/src/backends/C/c_backend_common.ml b/src/backends/C/c_backend_common.ml index 454f2bff..b6d782e8 100644 --- a/src/backends/C/c_backend_common.ml +++ b/src/backends/C/c_backend_common.ml @@ -9,7 +9,8 @@ (* *) (********************************************************************) -open Utils.Format +open Utils +open Format open Lustre_types open Corelang open Machine_code_types @@ -88,8 +89,8 @@ let mk_call_var_decl loc id = { var_id = id; var_orig = false; - var_dec_type = mktyp Location.dummy_loc Tydec_any; - var_dec_clock = mkclock Location.dummy_loc Ckdec_any; + var_dec_type = mktyp Location.dummy Tydec_any; + var_dec_clock = mkclock Location.dummy Ckdec_any; var_dec_const = false; var_dec_value = None; var_parent_nodeid = None; @@ -237,7 +238,7 @@ let pp_c_basic_type_desc t_desc = (* Not a basic C type. Do not handle arrays or pointers *) let pp_basic_c_type ?(pp_c_basic_type_desc = pp_c_basic_type_desc) - ?(var_opt = None) fmt t = + ?var_opt fmt t = match var_opt with | Some v when Machine_types.is_exportable v -> Machine_types.pp_c_var_type fmt v @@ -248,7 +249,7 @@ let pp_c_type ?pp_c_basic_type_desc ?var_opt var_id fmt t = let rec aux t pp_suffix = if is_basic_c_type t then fprintf fmt "%a %s%a" - (pp_basic_c_type ?pp_c_basic_type_desc ~var_opt) + (pp_basic_c_type ?pp_c_basic_type_desc ?var_opt) t var_id pp_suffix () else let open Types in @@ -512,8 +513,10 @@ type loop_index = LVar of ident | LInt of int ref | LAcc of value_t (Access (v, Cst (Const_int !r))) q | _ , LVar i :: q -> value_offsets (Access (v, Var i)) q *) (* Computes the list of nested loop variables together with their dimension - bounds. - LInt r stands for loop expansion (no loop variable, but int loop - index) - LVar v stands for loop variable v *) + bounds. + * - LInt r stands for loop expansion (no loop variable, but int loop + index) + * - LVar v stands for loop variable v *) let rec mk_loop_variables m ty depth = match (Types.repr ty).Types.tdesc, depth with | Types.Tarray (d, ty'), 0 -> @@ -592,7 +595,7 @@ let rec pp_value_suffix ?(indirect = true) m self var_type loop_vars pp_var fmt in match loop_vars, value.value_desc with | (x, LAcc i) :: q, _ when is_const_index i -> - let r = ref (Dimension.size_const_dimension (dimension_of_value i)) in + let r = ref (Dimension.size_const (dimension_of_value i)) in pp_value_suffix ~indirect m self var_type ((x, LInt r) :: q) pp_var fmt value | (_, LInt r) :: q, Cst (Const_array cl) -> @@ -664,7 +667,7 @@ let rec pp_value_suffix ?(indirect = true) m self var_type loop_vars pp_var fmt * pp_c_decl_struct_var * fmt m.mmemory *) -let print_machine_struct ?(ghost = false) fmt m = +let pp_machine_struct ?(ghost = false) fmt m = if not (fst (Machine_code_common.get_stateless_status m)) then (* Define struct *) fprintf fmt "@[<v 2>%a {@,_Bool _reset;%a%a@]@,};" @@ -693,20 +696,20 @@ let print_machine_struct ?(ghost = false) fmt m = (* Prototype Printing functions *) (********************************************************************************************) -let print_global_init_prototype fmt baseNAME = +let pp_global_init_prototype fmt baseNAME = fprintf fmt "void %a ()" pp_global_init_name baseNAME -let print_global_clear_prototype fmt baseNAME = +let pp_global_clear_prototype fmt baseNAME = fprintf fmt "void %a ()" pp_global_clear_name baseNAME -let print_alloc_prototype fmt (name, static) = +let pp_alloc_prototype fmt (name, static) = fprintf fmt "%a * %a %a" (pp_machine_memtype_name ~ghost:false) name pp_machine_alloc_name name (pp_print_parenthesized pp_c_decl_input_var) static -let print_dealloc_prototype fmt name = +let pp_dealloc_prototype fmt name = fprintf fmt "void %a (%a * _alloc)" pp_machine_dealloc_name name (pp_machine_memtype_name ~ghost:false) name @@ -783,9 +786,9 @@ module Protos (Mod : MODIFIERS_GHOST_PROTO) = struct outputs end -let print_import_prototype fmt dep = fprintf fmt "#include \"%s.h\"" dep.name +let pp_import_prototype fmt dep = fprintf fmt "#include \"%s.h\"" dep.name -let print_import_alloc_prototype fmt dep = +let pp_import_alloc_prototype fmt dep = if dep.is_stateful then fprintf fmt "#include \"%s_alloc.h\"" dep.name let pp_c_var m self pp_var fmt var = @@ -858,7 +861,7 @@ let pp_file file_suffix fmt (typ, arg) = file_suffix typ arg file_suffix let pp_put_var fmt file_suffix name var_type var_id = - let pp_file = pp_print_file ("out" ^ file_suffix) in + let pp_file = pp_file ("out" ^ file_suffix) in let unclocked_t = Types.unclock_type var_type in fprintf fmt "@[<v>%a@]" (fun fmt () -> @@ -937,7 +940,7 @@ let pp_assign m self pp_var fmt (var, value) = | (d, LInt r) :: q -> (*eprintf "pp_aux %a %d@." Dimension.pp_dimension d (!r);*) let typ' = Types.array_element_type typ in - let szl = Utils.enumerate (Dimension.size_const_dimension d) in + let szl = Utils.enumerate (Dimension.size_const d) in fprintf fmt "@[<v 2>{@,%a@]@,}" (pp_print_list (fun fmt i -> r := i; diff --git a/src/backends/C/c_backend_common.mli b/src/backends/C/c_backend_common.mli index 98fb6dc2..bd7c9abc 100644 --- a/src/backends/C/c_backend_common.mli +++ b/src/backends/C/c_backend_common.mli @@ -1,5 +1,146 @@ open Utils +open Format +open Lustre_types +open Machine_code_types -val pp_file_decl: Format.formatter -> ident -> int -> unit -val pp_file_open: Format.formatter -> ident -> int -> string -val pp_put_var: Format.formatter -> string -> ident -> Types.t -> ident -> unit +val pp_file_decl: formatter -> ident -> int -> unit +val pp_file_open: formatter -> ident -> int -> string +val pp_put_var: formatter -> string -> ident -> Types.t -> ident -> unit +val pp_ptr: formatter -> ident -> unit +val pp_machine_set_reset_name: formatter -> ident -> unit +val pp_machine_clear_reset_name: formatter -> ident -> unit +val pp_machine_init_name: formatter -> ident -> unit +val pp_machine_clear_name: formatter -> ident -> unit +val pp_machine_step_name: formatter -> ident -> unit +val pp_machine_alloc_name: formatter -> ident -> unit +val pp_machine_static_alloc_name: formatter -> ident -> unit +val pp_machine_dealloc_name: formatter -> ident -> unit +val pp_global_init_name: formatter -> ident -> unit +val pp_global_clear_name: formatter -> ident -> unit +val pp_machine_static_declare_name: formatter -> ident -> unit +val pp_machine_static_link_name: formatter -> ident -> unit +val pp_global_init_prototype: formatter -> ident -> unit +val pp_global_clear_prototype: formatter -> ident -> unit +val pp_alloc_prototype: formatter -> ident * var_decl list -> unit +val pp_dealloc_prototype: formatter -> ident -> unit +val pp_import_prototype: formatter -> dep_t -> unit +val pp_import_alloc_prototype: formatter -> dep_t -> unit +val pp_c_var_read: ?test_output:bool -> machine_t -> formatter -> var_decl -> unit +val pp_c_var_write: machine_t -> formatter -> var_decl -> unit +val pp_c_var: machine_t -> ident -> (formatter -> var_decl -> unit) -> formatter -> var_decl -> unit +val pp_c_dimension: formatter -> Dimension.t -> unit +val pp_label: formatter -> label -> unit +val pp_c_tag: formatter -> label -> unit +val pp_reset_assign: ident -> formatter -> bool -> unit +val pp_assign: machine_t -> ident -> (formatter -> var_decl -> unit) -> formatter -> var_decl * value_t -> unit +val pp_c_type: ?pp_c_basic_type_desc:(Types.t -> string) -> ?var_opt:var_decl -> + ident -> formatter -> Types.t -> unit +val pp_basic_c_type: ?pp_c_basic_type_desc:(Types.t -> string) -> ?var_opt:var_decl -> formatter -> Types.t -> unit +val pp_machine_memtype_name: ?ghost:bool -> formatter -> ident -> unit +val pp_array_suffix: formatter -> ident list -> unit +val pp_print_version: formatter -> unit -> unit +val pp_machine_struct: ?ghost:bool -> formatter -> machine_t -> unit +val pp_reset_flag: ?indirect:bool -> (formatter -> 'a -> unit) -> formatter -> 'a -> unit +val pp_reset_flag': ?indirect:bool -> formatter -> ident -> unit +val pp_machine_decl: ?ghost:bool -> (formatter -> 'a -> unit) -> formatter -> ident * 'a -> unit +val pp_machine_decl': ?ghost:bool -> formatter -> ident * ident -> unit +val pp_file: ident -> formatter -> ident * ident -> unit +val pp_basic_lib_fun: bool -> ident -> (formatter -> 'a -> unit) -> formatter -> 'a list -> unit +val pp_c_decl_input_var: formatter -> var_decl -> unit + +(* Prints a value expression [v], with internal function calls only. [pp_var] is + a printer for variables (typically [pp_c_var_read]), but an offset suffix may + be added for array variables *) +val pp_c_val: machine_t -> ident -> (formatter -> var_decl -> unit) -> formatter -> value_t -> unit + + (* Prints a constant value *) +val pp_c_const: formatter -> constant -> unit + +(* Declaration of a local/mem variable: - if it's an array/matrix/etc, its + size(s) should be known in order to statically allocate memory, so we print + the full type *) +val pp_c_decl_local_var: ?pp_c_basic_type_desc:(Types.t -> string) -> machine_t -> formatter -> var_decl -> unit + +(* type directed initialization: useless wrt the lustre compilation model, + except for MPFR injection, where values are dynamically allocated *) +val pp_initialize: machine_t -> ident -> (formatter -> var_decl -> unit) -> formatter -> var_decl -> unit + +(* type directed clear: useless wrt the lustre compilation model, except for + MPFR injection, where values are dynamically allocated *) +val pp_clear: machine_t -> ident -> (formatter -> var_decl -> unit) -> formatter -> var_decl -> unit + +val mk_call_var_decl: Location.t -> ident -> var_decl + +val pp_c_basic_type_desc: Types.t -> string + +val has_c_prototype: ident -> dep_t list -> bool + +val reset_label: label + +type loop_index = LVar of ident | LInt of int ref | LAcc of value_t + +val mk_loop_var: machine_t -> unit -> ident + +(* Computes the list of nested loop variables together with their dimension + bounds. + * - LInt r stands for loop expansion (no loop variable, but int loop + index) + * - LVar v stands for loop variable v *) +val mk_loop_variables: machine_t -> Types.t -> int -> (Dimension.t * loop_index) list + +val reset_loop_counter: unit -> unit + +val reorder_loop_variables: (Dimension.t * loop_index) list -> (Dimension.t * loop_index) list + + (* Prints a [value] of type [var_type] indexed by the suffix list [loop_vars] *) +val pp_value_suffix: ?indirect:bool -> machine_t -> ident -> Types.t -> + (Dimension.t * loop_index) list -> (formatter -> var_decl -> unit) -> formatter -> value_t -> unit + +(* Generation of a non-clashing name for the self memory variable (for step and + reset functions) *) +val mk_self: machine_t -> ident +val mk_mem: machine_t -> ident +val mk_mem_in: machine_t -> ident +val mk_mem_out: machine_t -> ident +val mk_mem_reset: machine_t -> ident + +(* Generation of a non-clashing name for the attribute variable of static + allocation macro *) +val mk_attribute: machine_t -> ident + +(* Generation of a non-clashing name for the instance variable of static + allocation macro *) +val mk_instance: machine_t -> ident + +val mpfr_vars: var_decl list -> var_decl list +val mpfr_consts: const_desc list -> const_desc list + +val reset_flag_name: string + +val file_to_module_name: string -> string + +val protect_filename: string -> string + +(* Computes the depth to which multi-dimension array assignments should be + expanded. It equals the maximum number of nested static array constructions + accessible from root [v]. *) +val expansion_depth: value_t -> int + +module type MODIFIERS_GHOST_PROTO = sig + val pp_ghost_parameters : + ?cut:bool -> + formatter -> + (string * (formatter -> string -> unit)) list -> + unit +end + +module EmptyGhostProto : MODIFIERS_GHOST_PROTO + +module Protos (Mod : MODIFIERS_GHOST_PROTO): sig + val print_stateless_prototype: formatter -> ident * var_decl list * var_decl list -> unit + val print_clear_reset_prototype: ident -> ident -> formatter -> ident * var_decl list -> unit + val print_set_reset_prototype: ident -> ident -> formatter -> ident * var_decl list -> unit + val print_step_prototype: ident -> ident -> formatter -> ident * var_decl list * var_decl list -> unit + val print_init_prototype: ident -> formatter -> ident * var_decl list -> unit + val print_clear_prototype: ident -> formatter -> ident * var_decl list -> unit +end diff --git a/src/backends/C/c_backend_header.ml b/src/backends/C/c_backend_header.ml index 6343c0aa..64255452 100644 --- a/src/backends/C/c_backend_header.ml +++ b/src/backends/C/c_backend_header.ml @@ -16,6 +16,8 @@ open Machine_code_types open Machine_code_common open C_backend_common +module Mpfr = Lustrec_mpfr + (********************************************************************************************) (* Header Printing functions *) (********************************************************************************************) @@ -23,7 +25,7 @@ open C_backend_common module type MODIFIERS_HDR = sig module GhostProto : MODIFIERS_GHOST_PROTO - val print_machine_decl_prefix : Format.formatter -> machine_t -> unit + val print_machine_decl_prefix : formatter -> machine_t -> unit val pp_import_arrow : formatter -> unit -> unit end @@ -174,9 +176,9 @@ functor print_static_link_macro macro print_static_alloc_macro macro else (* Dynamic allocation *) - fprintf fmt "extern %a;@,extern %a" print_alloc_prototype + fprintf fmt "extern %a;@,extern %a" pp_alloc_prototype (m.mname.node_id, m.mstatic) - print_dealloc_prototype m.mname.node_id + pp_dealloc_prototype m.mname.node_id let print_machine_struct_top_decl_from_header fmt tdecl = let inode = imported_node_of_top tdecl in @@ -187,7 +189,7 @@ functor let print_stateless_C_prototype fmt (name, inputs, outputs) = let output = match outputs with [ hd ] -> hd | _ -> assert false in fprintf fmt "%a %s %a" - (pp_basic_c_type ~pp_c_basic_type_desc ~var_opt:None) + (fun x -> pp_basic_c_type ~pp_c_basic_type_desc x) output.var_type name (pp_print_parenthesized pp_c_decl_input_var) inputs @@ -317,7 +319,7 @@ functor (* Print the svn version number and the supported C standard (C90 or C99) *) pp_print_version () baseNAME baseNAME (* Import the header *) basename - print_import_prototype + pp_import_prototype { local = true; name = basename; @@ -327,12 +329,12 @@ functor (* Print dependencies *) (pp_print_list ~pp_open_box:pp_open_vbox0 ~pp_prologue:(pp_print_endcut "/* Import dependencies */") - print_import_alloc_prototype ~pp_epilogue:pp_print_cutcut) + pp_import_alloc_prototype ~pp_epilogue:pp_print_cutcut) dependencies (* Print the struct definitions of all machines. *) (pp_print_list ~pp_open_box:pp_open_vbox0 ~pp_prologue:(pp_print_endcut "/* Struct definitions */") - ~pp_sep:pp_print_cutcut print_machine_struct + ~pp_sep:pp_print_cutcut pp_machine_struct ~pp_epilogue:pp_print_cutcut) machines (* Print the prototypes of all machines *) @@ -372,7 +374,7 @@ functor ~pp_prologue:(pp_print_endcut "/* Import dependencies */") (fun fmt dep -> let local, name = dependency_of_top dep in - print_import_prototype fmt + pp_import_prototype fmt { local; name; @@ -404,7 +406,7 @@ functor /* Global clear declaration */@,\ extern %a;@,\ @," - print_global_init_prototype baseNAME print_global_clear_prototype + pp_global_init_prototype baseNAME pp_global_clear_prototype baseNAME else pp_print_nothing) () diff --git a/src/backends/C/c_backend_header.mli b/src/backends/C/c_backend_header.mli index e69de29b..fb1395fe 100644 --- a/src/backends/C/c_backend_header.mli +++ b/src/backends/C/c_backend_header.mli @@ -0,0 +1,17 @@ +open Format +open Lustre_types +open Machine_code_types +open C_backend_common + +module type MODIFIERS_HDR = sig + module GhostProto : MODIFIERS_GHOST_PROTO + val print_machine_decl_prefix: formatter -> machine_t -> unit + val pp_import_arrow: formatter -> unit -> unit +end + +module EmptyMod : MODIFIERS_HDR + +module Main (Mod : MODIFIERS_HDR) : sig + val print_header_from_header: formatter -> string -> top_decl list -> unit + val print_alloc_header: formatter -> string -> machine_t list -> dep_t list -> unit +end diff --git a/src/backends/C/c_backend_main.ml b/src/backends/C/c_backend_main.ml index c0fd5904..b9ad438a 100644 --- a/src/backends/C/c_backend_main.ml +++ b/src/backends/C/c_backend_main.ml @@ -16,6 +16,8 @@ open Utils.Format open C_backend_common open Utils +module Mpfr = Lustrec_mpfr + module type MODIFIERS_MAINSRC = sig end module EmptyMod = struct end @@ -37,7 +39,7 @@ functor let print_put_output fmt id o' o = let suff = string_of_int (id + 1) in - print_put_var fmt suff o'.var_id o.var_type o.var_id + pp_put_var fmt suff o'.var_id o.var_type o.var_id let print_main_inout_declaration fmt m = fprintf fmt @@ -133,7 +135,7 @@ functor outputs let print_get_input fmt id v' v = - let pp_file = pp_print_file ("in" ^ string_of_int (id + 1)) in + let pp_file = pp_file ("in" ^ string_of_int (id + 1)) in let unclocked_t = Types.unclock_type v.var_type in fprintf fmt "@[<v>%a@]" (fun fmt () -> @@ -156,8 +158,8 @@ functor pp_file ("f", v.var_id) else ( Global.main_node := !Options.main_node; - eprintf "Code generation error: %a%a@." Error.pp_error_msg - Error.Main_wrong_kind Location.pp_loc v'.var_loc; + eprintf "Code generation error: %a%a@." Error.pp + Error.Main_wrong_kind Location.pp v'.var_loc; raise (Error.Error (v'.var_loc, Error.Main_wrong_kind)))) () @@ -318,7 +320,7 @@ functor @,\ %a@,\ %a\n\ - \ @]@." print_main_header () print_import_alloc_prototype + \ @]@." print_main_header () pp_import_alloc_prototype { local = true; name = basename; diff --git a/src/backends/C/c_backend_main.mli b/src/backends/C/c_backend_main.mli index e69de29b..82313865 100644 --- a/src/backends/C/c_backend_main.mli +++ b/src/backends/C/c_backend_main.mli @@ -0,0 +1,11 @@ +open Format +open Lustre_types +open Machine_code_types + +module type MODIFIERS_MAINSRC = sig end + +module EmptyMod: MODIFIERS_MAINSRC + +module Main (Mod : MODIFIERS_MAINSRC) : sig + val print_main_c: formatter -> machine_t -> string -> program_t -> machine_t list -> dep_t list -> unit +end diff --git a/src/backends/C/c_backend_makefile.ml b/src/backends/C/c_backend_makefile.ml index 717d686b..1235e7b3 100644 --- a/src/backends/C/c_backend_makefile.ml +++ b/src/backends/C/c_backend_makefile.ml @@ -9,15 +9,16 @@ (* *) (********************************************************************) +open Utils open Format open Lustre_types let pp_dep fmt dep = - Format.fprintf fmt "%b, %s, {%a}, %b" dep.local dep.name Printers.pp_prog + fprintf fmt "%b, %s, {%a}, %b" 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 + fprintf fmt "@[<v 0>%a@ @]" (pp_comma_list pp_dep) deps let header_has_code header = List.exists @@ -50,10 +51,10 @@ let lib_dependencies deps = [] deps let fprintf_dependencies fmt (deps : dep_t list) = - (* Format.eprintf "Deps: %a@." pp_deps dep; *) + (* eprintf "Deps: %a@." pp_deps dep; *) let compiled_deps = compiled_dependencies deps in - (* Format.eprintf "Compiled Deps: %a@." pp_deps compiled_dep; *) + (* eprintf "Compiled Deps: %a@." pp_deps compiled_dep; *) List.iter (fun s -> Log.report ~level:1 (fun fmt -> fprintf fmt "Adding dependency: %s@." s); @@ -69,7 +70,7 @@ let fprintf_dependencies fmt (deps : dep_t list) = module type MODIFIERS_MKF = sig (* dep was (bool * ident * top_decl list) *) - val other_targets : Format.formatter -> string -> string -> dep_t list -> unit + val other_targets : formatter -> string -> string -> dep_t list -> unit end module EmptyMod : MODIFIERS_MKF = struct @@ -118,12 +119,11 @@ functor fprintf fmt "\t${GCC} -I${INC} -I. -c %s_main.c@." basename; fprintf_dependencies fmt dependencies; fprintf fmt "\t${GCC} -o ${BINNAME} io_frontend.o %a %s.o %s_main.o %a@." - (Utils.fprintf_list ~sep:" " (fun fmt dep -> - Format.fprintf fmt "%s.o" dep.name)) + (pp_print_list (fun fmt dep -> fprintf fmt "%s.o" dep.name)) (compiled_dependencies dependencies) basename (* library .o *) basename (* main function . o *) - (Utils.fprintf_list ~sep:" " (fun fmt lib -> fprintf fmt "-l%s" lib)) + (pp_print_list (fun fmt lib -> fprintf fmt "-l%s" lib)) (lib_dependencies dependencies); fprintf fmt "@."; fprintf fmt "clean:@."; diff --git a/src/backends/C/c_backend_makefile.mli b/src/backends/C/c_backend_makefile.mli index e69de29b..a178afd8 100644 --- a/src/backends/C/c_backend_makefile.mli +++ b/src/backends/C/c_backend_makefile.mli @@ -0,0 +1,17 @@ +open Utils +open Format +open Lustre_types + +module type MODIFIERS_MKF = sig + val other_targets : formatter -> string -> string -> dep_t list -> unit +end + +module EmptyMod : MODIFIERS_MKF + +module Main (Mod : MODIFIERS_MKF) : sig + val print_makefile: string -> string -> dep_t list -> formatter -> unit +end + +val fprintf_dependencies: formatter -> dep_t list -> unit +val compiled_dependencies: dep_t list -> dep_t list +val lib_dependencies: dep_t list -> ident list diff --git a/src/backends/C/c_backend_mauve.ml b/src/backends/C/c_backend_mauve.ml index 860a6c07..b6e4829e 100644 --- a/src/backends/C/c_backend_mauve.ml +++ b/src/backends/C/c_backend_mauve.ml @@ -26,7 +26,7 @@ let fsm_name node = node ^ "FSM" let print_mauve_header fmt basename = fprintf fmt "#include \"mauve/runtime.hpp\"@."; - print_import_alloc_prototype fmt + pp_import_alloc_prototype fmt { local = true; name = basename; content = []; is_stateful = true } (* assuming it is stateful*); pp_print_newline fmt (); diff --git a/src/backends/C/c_backend_mauve.mli b/src/backends/C/c_backend_mauve.mli index e69de29b..7680b24f 100644 --- a/src/backends/C/c_backend_mauve.mli +++ b/src/backends/C/c_backend_mauve.mli @@ -0,0 +1,7 @@ +open Format +open Machine_code_types + +val print_mauve_header: formatter -> string -> unit +val print_mauve_shell: formatter -> machine_t -> unit +val print_mauve_core: formatter -> machine_t -> unit +val print_mauve_fsm: formatter -> machine_t -> unit diff --git a/src/backends/C/c_backend_spec.ml b/src/backends/C/c_backend_spec.ml index 8143ff47..9d55cbd7 100644 --- a/src/backends/C/c_backend_spec.ml +++ b/src/backends/C/c_backend_spec.ml @@ -17,6 +17,8 @@ open Corelang open Spec_types open Machine_code_common +module Mpfr = Lustrec_mpfr + (**************************************************************************) (* Printing spec for c *) @@ -508,7 +510,7 @@ let pp_memory_pack_def m fmt mp = ((mp, (name, mem), (name, self)), mp.mpformula) let print_machine_ghost_struct fmt m = - pp_acsl (pp_ghost (print_machine_struct ~ghost:true)) fmt m + pp_acsl (pp_ghost (pp_machine_struct ~ghost:true)) fmt m let pp_memory_pack_defs fmt m = if not (fst (get_stateless_status m)) then @@ -900,14 +902,13 @@ module MakefileMod = struct "\t${GCC} -Wno-attributes -o %s_main_eacsl io_frontend.o %a %s \ %s_main_eacsl.o %a@." basename - (Utils.fprintf_list ~sep:" " (fun fmt dep -> - Format.fprintf fmt "%s.o" dep.name)) + (pp_print_list (fun fmt dep -> fprintf fmt "%s.o" dep.name)) (C_backend_makefile.compiled_dependencies dependencies) ("${FRAMACEACSL}/e_acsl.c " ^ "${FRAMACEACSL}/memory_model/e_acsl_bittree.c " ^ "${FRAMACEACSL}/memory_model/e_acsl_mmodel.c") basename - (Utils.fprintf_list ~sep:" " (fun fmt lib -> fprintf fmt "-l%s" lib)) + (pp_print_list (fun fmt lib -> fprintf fmt "-l%s" lib)) (C_backend_makefile.lib_dependencies dependencies); fprintf fmt "@." end diff --git a/src/backends/C/c_backend_src.ml b/src/backends/C/c_backend_src.ml index 8e9fa4f0..091eb15b 100644 --- a/src/backends/C/c_backend_src.ml +++ b/src/backends/C/c_backend_src.ml @@ -9,13 +9,16 @@ (* *) (********************************************************************) -open Utils.Format +open Utils +open Format open Lustre_types open Machine_code_types open Corelang open Machine_code_common open C_backend_common +module Mpfr = Lustrec_mpfr + module type MODIFIERS_SRC = sig module GhostProto : MODIFIERS_GHOST_PROTO @@ -129,7 +132,7 @@ functor (if is_arrow_reset then fun fmt -> fprintf fmt "%s_reset" else pp_machine_name) name - (pp_comma_list ~pp_eol:pp_print_comma Dimension.pp_dimension) + (pp_comma_list ~pp_eol:pp_print_comma Dimension.pp) static self (pp_print_option (fun fmt -> fprintf fmt "->%s")) inst @@ -328,7 +331,7 @@ functor let print_alloc_instance fmt (i, (m, static)) = fprintf fmt "_alloc->%s = %a %a;" i pp_machine_alloc_name (node_name m) - (pp_print_parenthesized Dimension.pp_dimension) + (pp_print_parenthesized Dimension.pp) static let print_dealloc_instance fmt (i, (m, _)) = @@ -350,11 +353,11 @@ functor let base_type = Types.array_base_type vdecl.var_type in let size_types = Types.array_type_multi_dimension vdecl.var_type in let size_type = - Dimension.multi_dimension_product vdecl.var_loc size_types + Dimension.multi_product vdecl.var_loc size_types in fprintf fmt "_alloc->_reg.%s = (%a*) malloc((%a)*sizeof(%a));@,assert(_alloc->%s);" - vdecl.var_id (pp_c_type "") base_type Dimension.pp_dimension size_type + vdecl.var_id (pp_c_type "") base_type Dimension.pp size_type (pp_c_type "") base_type vdecl.var_id let print_dealloc_array fmt vdecl = @@ -418,7 +421,7 @@ functor * (Utils.pp_newline_if_non_empty m.minit) *) let pp_c_check m self fmt (loc, check) = - fprintf fmt "@[<v>%a@,assert (%a);@]" Location.pp_c_loc loc + fprintf fmt "@[<v>%a@,assert (%a);@]" Location.pp_c loc (pp_c_val m self (pp_c_var_read m)) check @@ -458,7 +461,7 @@ functor let node_of_machine m = { top_decl_desc = Node m.mname; - top_decl_loc = Location.dummy_loc; + top_decl_loc = Location.dummy; top_decl_owner = ""; top_decl_itf = false; } @@ -624,7 +627,7 @@ functor let rec aux indices value fmt typ = if Types.is_array_type typ then let dim = Types.array_type_dimension typ in - let szl = Utils.enumerate (Dimension.size_const_dimension dim) in + let szl = Utils.enumerate (Dimension.size_const dim) in let typ' = Types.array_element_type typ in let value = match value with Const_array ca -> List.nth ca | _ -> assert false @@ -688,7 +691,7 @@ functor }@,\ return;@]@,\ }" - print_global_init_prototype baseNAME + pp_global_init_prototype baseNAME (pp_c_basic_type_desc Type_predef.type_bool) (* constants *) (pp_print_list ~pp_prologue:pp_print_cut @@ -709,7 +712,7 @@ functor }@,\ return;@]@,\ }" - print_global_clear_prototype baseNAME + pp_global_clear_prototype baseNAME (pp_c_basic_type_desc Type_predef.type_bool) (* constants *) (pp_print_list ~pp_prologue:pp_print_cut @@ -723,9 +726,9 @@ functor if not !Options.static_mem then (* Alloc functions, only if non static mode *) fprintf fmt "@[<v 2>%a {@,%a%a@]@,}@,@[<v 2>%a {@,%a%a@]@,@," - print_alloc_prototype + pp_alloc_prototype (m.mname.node_id, m.mstatic) - print_alloc_const m print_alloc_code m print_dealloc_prototype + print_alloc_const m print_alloc_code m pp_dealloc_prototype m.mname.node_id print_alloc_const m print_dealloc_code m let print_mpfr_code self fmt m = @@ -775,12 +778,12 @@ functor let print_extern_alloc_prototype fmt ind = let static = List.filter (fun v -> v.var_dec_const) ind.nodei_inputs in - fprintf fmt "extern %a;@,extern %a;" print_alloc_prototype - (ind.nodei_id, static) print_dealloc_prototype ind.nodei_id + fprintf fmt "extern %a;@,extern %a;" pp_alloc_prototype + (ind.nodei_id, static) pp_dealloc_prototype ind.nodei_id let print_lib_c source_fmt basename prog machines dependencies = fprintf source_fmt "@[<v>%a%a@,@,%a@,%a%a%a%a%a%a%a@]@." - print_import_standard () print_import_prototype + print_import_standard () pp_import_prototype { local = true; name = basename; @@ -793,7 +796,7 @@ functor (* Print dependencies *) (pp_print_list ~pp_open_box:pp_open_vbox0 ~pp_prologue:(pp_print_endcut "/* Import dependencies */") - print_import_prototype ~pp_epilogue:pp_print_cutcut) + pp_import_prototype ~pp_epilogue:pp_print_cutcut) dependencies (* Print consts *) (pp_print_list ~pp_open_box:pp_open_vbox0 @@ -836,16 +839,16 @@ functor ~pp_prologue: (pp_print_endcut "/* Node allocation function prototypes */") ~pp_sep:pp_print_cutcut (fun fmt m -> - fprintf fmt "%a;@,%a;" print_alloc_prototype + fprintf fmt "%a;@,%a;" pp_alloc_prototype (m.mname.node_id, m.mstatic) - print_dealloc_prototype m.mname.node_id)) + pp_dealloc_prototype m.mname.node_id)) machines else pp_print_nothing) () (* Print the struct definitions of all machines. *) (pp_print_list ~pp_open_box:pp_open_vbox0 ~pp_prologue:(pp_print_endcut "/* Struct definitions */") - ~pp_sep:pp_print_cutcut print_machine_struct + ~pp_sep:pp_print_cutcut pp_machine_struct ~pp_epilogue:pp_print_cutcut) machines (* Print the spec predicates *) Mod.pp_predicates machines (* Print nodes one by one (in the previous order) *) diff --git a/src/backends/C/c_backend_src.mli b/src/backends/C/c_backend_src.mli index e69de29b..93cfc84c 100644 --- a/src/backends/C/c_backend_src.mli +++ b/src/backends/C/c_backend_src.mli @@ -0,0 +1,29 @@ +open Utils +open Format +open Lustre_types +open Machine_code_types +open C_backend_common + +module type MODIFIERS_SRC = sig + module GhostProto : MODIFIERS_GHOST_PROTO + + val pp_predicates : formatter -> machine_t list -> unit + + val pp_set_reset_spec : formatter -> ident -> ident -> machine_t -> unit + + val pp_clear_reset_spec : formatter -> ident -> ident -> machine_t -> unit + + val pp_step_spec : + formatter -> machine_t list -> ident -> ident -> machine_t -> unit + + val pp_step_instr_spec : + machine_t -> ident -> ident -> formatter -> instr_t -> unit + + val pp_ghost_parameter : ident -> formatter -> ident option -> unit +end + +module EmptyMod : MODIFIERS_SRC + +module Main (Mod : MODIFIERS_SRC) : sig + val print_lib_c: formatter -> string -> program_t -> machine_t list -> dep_t list -> unit +end diff --git a/src/backends/EMF/EMF_backend.ml b/src/backends/EMF/EMF_backend.ml index 27440e16..64513a81 100644 --- a/src/backends/EMF/EMF_backend.ml +++ b/src/backends/EMF/EMF_backend.ml @@ -98,7 +98,9 @@ *) +open Utils open Lustre_types +open Corelang open Machine_code_types open Machine_code_common open Format @@ -108,8 +110,6 @@ exception Unhandled of string module ISet = Utils.ISet -let fprintf_list = Utils.fprintf_list - (**********************************************) (* Utility functions: arrow and lustre expr *) (**********************************************) @@ -170,7 +170,8 @@ let get_instr_id fmt i = fprintf fmt "branch_%i" !branch_cpt | MStep (outs, id, _) -> print_protect fmt (fun fmt -> - fprintf fmt "%a_%s" (fprintf_list ~sep:"_" pp_var_name) outs id) + fprintf fmt "%a_%s" (pp_print_list ~pp_sep:(fun fmt () -> pp_print_string fmt "_") + pp_var_name) outs id) | _ -> () (* No name *) @@ -212,7 +213,7 @@ and branch_instr_vars m i = lhs, if is_stateful && is_resetable_fun i.lustre_eq then let reset_var = - let loc = Location.dummy_loc in + let loc = Location.dummy in Corelang.mkvar_decl loc ( reset_name f, Corelang.mktyp loc Tydec_bool, @@ -334,7 +335,7 @@ let rec pp_emf_instr m fmt i = fprintf fmt "\"guard\": %a,@ " (pp_emf_cst_or_var m) g; (* it has to be a variable or a constant *) fprintf fmt "\"outputs\": [%a],@ " - (fprintf_list ~sep:", " pp_var_string) + (pp_comma_list pp_var_string) (ISet.elements outputs); fprintf fmt "\"inputs\": [%a],@ " pp_emf_vars_decl (* @@ -343,7 +344,7 @@ let rec pp_emf_instr m fmt i = remove guard's variable from inputs *) (VSet.elements inputs); fprintf fmt "@[<v 2>\"branches\": {@ @[<v 0>%a@]@]@ }" - (fprintf_list ~sep:",@ " (fun fmt (tag, instrs_tag) -> + (pp_comma_list (fun fmt (tag, instrs_tag) -> let branch_all_lhs, _, branch_inputs = branch_block_vars m instrs_tag in @@ -377,7 +378,7 @@ let rec pp_emf_instr m fmt i = (fun fmt -> pp_print_string fmt node_f.node_id) f; fprintf fmt "\"lhs\": [@[%a@]],@ \"args\": [@[%a@]]" - (fprintf_list ~sep:",@ " (fun fmt v -> + (pp_comma_list (fun fmt v -> fprintf fmt "\"%a\"" pp_var_name v)) outputs (pp_emf_cst_or_var_list m) inputs; if is_stateful then @@ -398,12 +399,12 @@ let rec pp_emf_instr m fmt i = fprintf fmt "@]@]@ }" and pp_emf_instrs m fmt instrs = - fprintf_list ~sep:",@ " (pp_emf_instr m) fmt instrs + pp_comma_list (pp_emf_instr m) fmt instrs let pp_emf_annot cpt fmt (key, ee) = let _ = fprintf fmt "\"ann%i\": { @[<hov 0>\"key\": [%a],@ \"eexpr\": %a@] }" !cpt - (fprintf_list ~sep:"," (fun fmt s -> fprintf fmt "\"%s\"" s)) + (pp_comma_list (fun fmt s -> fprintf fmt "\"%s\"" s)) key pp_emf_eexpr ee in incr cpt @@ -442,10 +443,10 @@ let pp_emf_spec fmt spec = fprintf fmt "@] }" let pp_emf_annots cpt fmt annots = - fprintf_list ~sep:",@ " (pp_emf_annot cpt) fmt annots.annots + pp_comma_list (pp_emf_annot cpt) fmt annots.annots let pp_emf_annots_list cpt fmt annots_list = - fprintf_list ~sep:",@ " (pp_emf_annots cpt) fmt annots_list + pp_comma_list (pp_emf_annots cpt) fmt annots_list (* let pp_emf_contract fmt nd = * let c = Printers.node_as_contract nd in @@ -523,7 +524,7 @@ let pp_emf_imported_node fmt top = (****************************************************) let pp_meta fmt basename = fprintf fmt "\"meta\": @[<v 0>{@ "; - Utils.fprintf_list ~sep:",@ " + Format.pp_comma_list (fun fmt (k, v) -> fprintf fmt "\"%s\": \"%s\"" k v) fmt [ @@ -550,7 +551,7 @@ let translate fmt basename prog machines = fprintf fmt "}@],@ "; fprintf fmt "\"nodes\": @[<v 0>{@ "; (* Previous alternative: mapping normalized lustre to EMF: - fprintf_list ~sep:",@ " pp_decl fmt prog; *) + pp_comma_list pp_decl fmt prog; *) pp_emf_list pp_machine fmt machines; fprintf fmt "}@]@ }"; fprintf fmt "@]@ }" diff --git a/src/backends/EMF/EMF_backend.mli b/src/backends/EMF/EMF_backend.mli index e69de29b..f1c2927b 100644 --- a/src/backends/EMF/EMF_backend.mli +++ b/src/backends/EMF/EMF_backend.mli @@ -0,0 +1 @@ +val translate: Format.formatter -> string -> Lustre_types.program_t -> Machine_code_types.machine_t list -> unit diff --git a/src/backends/EMF/EMF_common.ml b/src/backends/EMF/EMF_common.ml index c820d6b2..33ce3c76 100644 --- a/src/backends/EMF/EMF_common.ml +++ b/src/backends/EMF/EMF_common.ml @@ -1,6 +1,7 @@ +open Utils open Lustre_types +open Corelang open Machine_code_types -module VSet = Corelang.VSet open Format open Machine_code_common @@ -92,8 +93,7 @@ let rec pp_emf_dim fmt dim_expr = fprintf fmt "\"kind\": \"ident\",@ \"value\": \"%s\"" s | Dappl (f, args) -> fprintf fmt "\"kind\": \"fun\",@ \"id\": \"%s\",@ \"args\": [@[%a@]]" f - (Utils.fprintf_list ~sep:",@ " pp_emf_dim) - args + (pp_comma_list pp_emf_dim) args | Dite (i, t, e) -> fprintf fmt "\"kind\": \"ite\",@ \"guard\": \"%a\",@ \"then\": %a,@ \"else\": %a" @@ -137,13 +137,13 @@ let rec pp_concrete_type dec_t infered_t fmt = prefix of the lustre file. They shall not be associated to variables *) | Tydec_array (dim, e) -> let inf_base = - match infered_t.Typing.tdesc with - | Typing.Tarray (_, t) -> + match infered_t.Types.tdesc with + | Types.Tarray (_, t) -> t | _ -> (* returing something useless, hoping that the concrete datatype will return something usefull *) - Typing.new_var () + Types.new_var () in fprintf fmt "{ \"kind\": \"array\", \"base_type\": %t, \"dim\": %a }" (pp_concrete_type e inf_base) @@ -232,7 +232,7 @@ let pp_emf_list ?(eol : ('a, formatter, unit) Stdlib.format = "") pp fmt l = () | _ -> fprintf fmt "@["; - Utils.fprintf_list ~sep:",@ " pp fmt l; + pp_comma_list pp fmt l; fprintf fmt "@]%(%)" eol (* Print the variable declaration *) @@ -330,7 +330,7 @@ let rec pp_emf_cst_or_var m fmt v = assert false and pp_emf_cst_or_var_list m = - Utils.fprintf_list ~sep:",@ " (pp_emf_cst_or_var m) + pp_comma_list (pp_emf_cst_or_var m) (* Printer lustre expr and eexpr *) @@ -349,7 +349,7 @@ let rec pp_emf_expr fmt e = fprintf fmt "@]}" | Expr_tuple el -> fprintf fmt "[@[<hov 0>%a@ @]]" - (Utils.fprintf_list ~sep:",@ " pp_emf_expr) + (pp_comma_list pp_emf_expr) el (* Missing these | Expr_ite of expr * expr * expr | Expr_arrow of expr * expr | Expr_fby of expr * expr | Expr_array of expr list | Expr_access of expr * @@ -394,7 +394,7 @@ let pp_emf_eexpr fmt ee = () | Some name -> Format.fprintf fmt "\"name\": \"%s\",@ " name) - (Utils.fprintf_list ~sep:"; " Printers.pp_quantifiers) + (pp_print_list ~pp_sep:pp_print_semicolon Printers.pp_quantifiers) ee.eexpr_quantifiers pp_emf_expr ee.eexpr_qfexpr let pp_emf_eexprs = pp_emf_list pp_emf_eexpr @@ -411,10 +411,10 @@ let pp_emf_stmt fmt stmt = assert false | Eq eq -> fprintf fmt "@[ @[<v 2>\"%a\": {@ " - (Utils.fprintf_list ~sep:"_" pp_print_string) + (pp_print_list ~pp_sep:(fun fmt () -> pp_print_string fmt "_") pp_print_string) eq.eq_lhs; fprintf fmt "\"lhs\": [%a],@ " - (Utils.fprintf_list ~sep:", " (fun fmt vid -> fprintf fmt "\"%s\"" vid)) + (pp_comma_list (fun fmt vid -> fprintf fmt "\"%s\"" vid)) eq.eq_lhs; fprintf fmt "\"rhs\": %a,@ " pp_emf_expr eq.eq_rhs; fprintf fmt "@]@]@ }" @@ -439,11 +439,10 @@ let rec pp_emf_typ_dec fmt tydef_dec = fprintf fmt "\"kind\": \"alias\",@ \"value\": \"%s\"" c | Tydec_enum el -> fprintf fmt "\"kind\": \"enum\",@ \"elements\": [%a]" - (Utils.fprintf_list ~sep:", " (fun fmt e -> fprintf fmt "\"%s\"" e)) - el + (pp_comma_list (fun fmt e -> fprintf fmt "\"%s\"" e)) el | Tydec_struct s -> fprintf fmt "\"kind\": \"struct\",@ \"fields\": [%a]" - (Utils.fprintf_list ~sep:", " (fun fmt (id, typ) -> + (pp_comma_list (fun fmt (id, typ) -> fprintf fmt "\"%s\": %a" id pp_emf_typ_dec typ)) s | Tydec_array (dim, typ) -> diff --git a/src/backends/EMF/EMF_common.mli b/src/backends/EMF/EMF_common.mli index e69de29b..15779482 100644 --- a/src/backends/EMF/EMF_common.mli +++ b/src/backends/EMF/EMF_common.mli @@ -0,0 +1,24 @@ +open Utils +open Lustre_types +open Machine_code_types +open Format + +val pp_emf_cst_or_var_list: machine_t -> formatter -> value_t list -> unit +val pp_emf_cst_or_var: machine_t -> formatter -> value_t -> unit +val pp_var_name: formatter -> var_decl -> unit +val print_protect: formatter -> (formatter -> unit) -> unit +val pp_var_string: formatter -> ident -> unit +val pp_emf_vars_decl: formatter -> var_decl list -> unit +val pp_tag_id: formatter -> ident -> unit +val pp_emf_expr: formatter -> expr -> unit +val pp_emf_eexpr: formatter -> eexpr -> unit +val pp_emf_eexprs: formatter -> eexpr list -> unit +val pp_emf_list: ?eol:(unit, formatter, unit) Stdlib.format -> (formatter -> 'a -> unit) -> formatter -> 'a list -> unit +val pp_emf_typedef: formatter -> Lustre_types.top_decl -> unit +val pp_emf_top_const: formatter -> Lustre_types.top_decl -> unit + +val reset_name: ident -> ident + +val get_expr_vars: value_t -> Corelang.VSet.t + +val is_imported_node: ident -> machine_t -> bool diff --git a/src/backends/EMF/EMF_library_calls.ml b/src/backends/EMF/EMF_library_calls.ml index 788f4553..4e765698 100644 --- a/src/backends/EMF/EMF_library_calls.ml +++ b/src/backends/EMF/EMF_library_calls.ml @@ -3,6 +3,7 @@ moment, modular compilation of multiple lustre sources as one output JSON is not considered. *) +open Utils open Lustre_types open Machine_code_types open Format @@ -18,8 +19,7 @@ let pp_call fmt m f outputs inputs = "\"kind\": \"functioncall\",@ \"name\": \"%s\",@ \"library\": \"%s\",@ " name lib; fprintf fmt "\"lhs\": [@[%a@]],@ \"args\": [@[%a@]]" - (Utils.fprintf_list ~sep:",@ " (fun fmt v -> - fprintf fmt "\"%a\"" Printers.pp_var_name v)) + (pp_comma_list (fun fmt v -> fprintf fmt "\"%a\"" Printers.pp_var_name v)) outputs (pp_emf_cst_or_var_list m) inputs | _ -> Format.eprintf "Calls to function %s in library %s are not handled yet.@." diff --git a/src/backends/EMF/EMF_library_calls.mli b/src/backends/EMF/EMF_library_calls.mli index e69de29b..f5d0b3c4 100644 --- a/src/backends/EMF/EMF_library_calls.mli +++ b/src/backends/EMF/EMF_library_calls.mli @@ -0,0 +1,2 @@ +val pp_call: Format.formatter -> Machine_code_types.machine_t -> Utils.ident -> + Lustre_types.var_decl list -> Machine_code_types.value_t list -> unit diff --git a/src/backends/Horn/horn_backend.ml b/src/backends/Horn/horn_backend.ml index 50625633..d596f801 100644 --- a/src/backends/Horn/horn_backend.ml +++ b/src/backends/Horn/horn_backend.ml @@ -59,7 +59,7 @@ let print_type_definitions fmt = | Tydec_enum tl -> incr cpt_type; fprintf fmt "(declare-datatypes () ((%s %a)));@.@." var - (Utils.fprintf_list ~sep:" " pp_print_string) + (pp_print_list pp_print_string) tl | _ -> assert false) diff --git a/src/backends/Horn/horn_backend.mli b/src/backends/Horn/horn_backend.mli index e69de29b..b1788f5e 100644 --- a/src/backends/Horn/horn_backend.mli +++ b/src/backends/Horn/horn_backend.mli @@ -0,0 +1 @@ +val translate: Format.formatter -> Lustre_types.program_t -> Machine_code_types.machine_t list -> unit diff --git a/src/backends/Horn/horn_backend_collecting_sem.ml b/src/backends/Horn/horn_backend_collecting_sem.ml index 059c0ae4..fae985b1 100644 --- a/src/backends/Horn/horn_backend_collecting_sem.ml +++ b/src/backends/Horn/horn_backend_collecting_sem.ml @@ -14,6 +14,7 @@ This is a modified version that handle reset *) +open Utils open Format open Lustre_types open Machine_code_types @@ -45,7 +46,7 @@ let collecting_semantics machines fmt node machine = in fprintf fmt "(declare-rel MAIN (%a))@." - (Utils.fprintf_list ~sep:" " pp_type) + (pp_print_list pp_type) (List.map (fun v -> v.var_type) main_memory_next); (* Init case *) @@ -59,11 +60,11 @@ let collecting_semantics machines fmt node machine = fprintf fmt "@[<v 2>(rule (=> @ (and @[<v 0>"; fprintf fmt "INIT_STATE@ "; fprintf fmt "(@[<v 0>%a %a@])" step_name node - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) (step_vars_m_x machines machine); fprintf fmt "@]@ )@ "; fprintf fmt "(MAIN %a)@]@.))@.@." - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) main_memory_next) else let reset_name, step_name = pp_machine_reset_name, pp_machine_step_name in @@ -73,15 +74,15 @@ let collecting_semantics machines fmt node machine = fprintf fmt "@[<v 2>(rule (=> @ (and @[<v 0>"; fprintf fmt "INIT_STATE@ "; fprintf fmt "(@[<v 0>%a %a@])@ " reset_name node - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) (reset_vars machines machine); fprintf fmt "(@[<v 0>%a %a@])" step_name node - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) (step_vars_m_x machines machine); fprintf fmt "@]@ )@ "; fprintf fmt "(MAIN %a)@]@.))@.@." - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) main_memory_next in @@ -91,16 +92,16 @@ let collecting_semantics machines fmt node machine = in fprintf fmt "; Inductive def@."; - (Utils.fprintf_list ~sep:" " (fun fmt v -> fprintf fmt "%a@." pp_decl_var v)) + (pp_print_list (fun fmt v -> fprintf fmt "%a@." pp_decl_var v)) fmt main_output_dummy; fprintf fmt "@[<v 2>(rule (=> @ (and @[<v 0>(MAIN %a)@ (@[<v 0>%a %a@])@]@ )@ (MAIN \ %a)@]@.))@.@." - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) main_memory_current step_name node - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) (step_vars machines machine) - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) main_memory_next let check_prop machines fmt machine = @@ -115,7 +116,7 @@ let check_prop machines fmt machine = fprintf fmt "@[<v 2>(rule (=> @ (and @[<v 0>(not %a)@ (MAIN %a)@])@ ERR))@." (pp_conj (pp_horn_var machine)) main_output - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) main_memory_next; if !Options.horn_query then fprintf fmt "(query ERR)@." @@ -157,7 +158,7 @@ let cex_computation machines fmt node machine = in fprintf fmt "(declare-rel CEX (Int %a))@.@." - (Utils.fprintf_list ~sep:" " pp_type) + (pp_print_list pp_type) (List.map (fun v -> v.var_type) cex_memory_next); fprintf fmt "; Initial set: Reset(c,m) + One Step(m,x) @."; @@ -166,31 +167,31 @@ let cex_computation machines fmt node machine = fprintf fmt "@[<v 2>(rule (=> @ (and @[<v 0>"; fprintf fmt "INIT_STATE_CEX@ "; fprintf fmt "(@[<v 0>%a %a@])@ " reset_name node - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) (reset_vars machines machine); fprintf fmt "(@[<v 0>%a %a@])" step_name node - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) (step_vars_m_x machines machine); fprintf fmt "@]@ )@ "; fprintf fmt "(CEX 0 %a)@]@.))@.@." - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) cex_memory_next; fprintf fmt "; Inductive def@."; (* Declare dummy inputs. Outputs should have been declared previously with collecting sem *) - (Utils.fprintf_list ~sep:" " (fun fmt v -> fprintf fmt "%a@." pp_decl_var v)) + (pp_print_list (fun fmt v -> fprintf fmt "%a@." pp_decl_var v)) fmt cex_input_dummy; fprintf fmt "(declare-var cexcpt Int)@."; fprintf fmt "@[<v 2>(rule (=> @ (and @[<v 0>(CEX cexcpt %a)@ (@[<v 0>%a %a@])@]@ )@ \ (CEX (+ 1 cexcpt) %a)@]@.))@.@." - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) cex_memory_current step_name node - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) (step_vars machines machine) - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) cex_memory_next let get_cex machines fmt machine = @@ -211,7 +212,7 @@ let get_cex machines fmt machine = "@[<v 2>(rule (=> @ (and @[<v 0>(not %a)@ (CEX cexcpt %a)@])@ CEXTRACE))@." (pp_conj (pp_horn_var machine)) cex_output - (Utils.fprintf_list ~sep:" " (pp_horn_var machine)) + (pp_print_list (pp_horn_var machine)) cex_memory_next; fprintf fmt "(query CEXTRACE)@." diff --git a/src/backends/Horn/horn_backend_collecting_sem.mli b/src/backends/Horn/horn_backend_collecting_sem.mli index e69de29b..7d975275 100644 --- a/src/backends/Horn/horn_backend_collecting_sem.mli +++ b/src/backends/Horn/horn_backend_collecting_sem.mli @@ -0,0 +1,7 @@ +open Utils +open Machine_code_types + +val cex_computation: machine_t list -> Format.formatter -> ident -> machine_t -> unit +val get_cex: machine_t list -> Format.formatter -> machine_t -> unit +val collecting_semantics: machine_t list -> Format.formatter -> ident -> machine_t -> unit +val check_prop: machine_t list -> Format.formatter -> machine_t -> unit diff --git a/src/backends/Horn/horn_backend_common.ml b/src/backends/Horn/horn_backend_common.ml index 60efc7c2..3e0ff669 100644 --- a/src/backends/Horn/horn_backend_common.ml +++ b/src/backends/Horn/horn_backend_common.ml @@ -9,6 +9,7 @@ (* *) (********************************************************************) +open Utils open Format open Lustre_types open Machine_code_types @@ -60,7 +61,7 @@ let pp_conj pp fmt l = | [ x ] -> pp fmt x | _ -> - fprintf fmt "(and @[<v 0>%a@]@ )" (Utils.fprintf_list ~sep:"@ " pp) l + fprintf fmt "(and @[<v 0>%a@]@ )" (pp_print_list pp) l (********************************************************************************************) (* Workaround to prevent the use of declared keywords as node name *) diff --git a/src/backends/Horn/horn_backend_common.mli b/src/backends/Horn/horn_backend_common.mli index e69de29b..268b2841 100644 --- a/src/backends/Horn/horn_backend_common.mli +++ b/src/backends/Horn/horn_backend_common.mli @@ -0,0 +1,37 @@ +open Utils +open Format +open Lustre_types +open Machine_code_types + +val rename_machine_list: ident -> var_decl list -> var_decl list +val get_machine: machine_t list -> ident -> machine_t + +val full_memory_vars: ?without_arrow:bool -> machine_t list -> machine_t -> var_decl list + +val rename_machine: ident -> var_decl -> var_decl +val rename_current: var_decl -> var_decl +val rename_mid: var_decl -> var_decl +val rename_next: var_decl -> var_decl +val rename_current_list: var_decl list -> var_decl list +val rename_mid_list: var_decl list -> var_decl list +val rename_next_list: var_decl list -> var_decl list + +val concat: string -> ident -> ident + +val arrow_vars: machine_t list -> machine_t -> var_decl list +val reset_vars: machine_t list -> machine_t -> var_decl list +val step_vars: machine_t list -> machine_t -> var_decl list +val step_vars_m_x: machine_t list -> machine_t -> var_decl list +val local_memory_vars: machine_t -> var_decl list +val inout_vars: machine_t -> var_decl list + +val pp_type: formatter -> Types.t -> unit +val pp_machine_reset_name: formatter -> ident -> unit +val pp_machine_step_name: formatter -> ident -> unit +val pp_machine_stateless_name: formatter -> ident -> unit +val pp_conj: (formatter -> 'a -> unit) -> formatter -> 'a list -> unit +val pp_decl_var: formatter -> var_decl -> unit + +val registered_keywords: ident list + +val protect_kwd: ident -> ident diff --git a/src/backends/Horn/horn_backend_printers.ml b/src/backends/Horn/horn_backend_printers.ml index 1e06099f..7a98efce 100644 --- a/src/backends/Horn/horn_backend_printers.ml +++ b/src/backends/Horn/horn_backend_printers.ml @@ -14,6 +14,7 @@ This is a modified version that handle reset *) +open Utils open Format open Lustre_types open Machine_code_types @@ -218,7 +219,7 @@ let pp_instance_reset machines m fmt i = in fprintf fmt "(%a @[<v 0>%a)@]" pp_machine_reset_name (node_name n) - (Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (rename_machine_list (concat m.mname.node_id i) (rename_current_list (full_memory_vars machines target_machine)) @ rename_machine_list (concat m.mname.node_id i) @@ -261,23 +262,20 @@ let pp_instance_call machines reset_instances m fmt i inputs outputs = fprintf fmt "(= %a false)" (pp_horn_var m) mem_x; fprintf fmt ")@]" | _ -> - fprintf fmt "(%a @[<v 0>%a%t%a%t%a)@]" pp_machine_step_name (node_name n) - (Utils.fprintf_list ~sep:"@ " (pp_horn_val m self (pp_horn_var m))) - inputs - (Utils.pp_final_char_if_non_empty "@ " inputs) - (Utils.fprintf_list ~sep:"@ " (pp_horn_val m self (pp_horn_var m))) + fprintf fmt "(%a @[<v 0>%a%a%a)@]" pp_machine_step_name (node_name n) + (pp_print_list ~pp_epilogue:pp_print_cut + (pp_horn_val m self (pp_horn_var m))) inputs + (pp_print_list ~pp_epilogue:pp_print_cut + (pp_horn_val m self (pp_horn_var m))) (List.map (fun v -> mk_val (Var v) v.var_type) outputs) - (Utils.pp_final_char_if_non_empty "@ " outputs) - (Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) - (mid_mems @ next_mems) + (pp_print_list (pp_horn_var m)) (mid_mems @ next_mems) with Not_found -> (* stateless node instance *) let n, _ = List.assoc i m.mcalls in - fprintf fmt "(%a @[<v 0>%a%t%a)@]" pp_machine_stateless_name (node_name n) - (Utils.fprintf_list ~sep:"@ " (pp_horn_val m self (pp_horn_var m))) - inputs - (Utils.pp_final_char_if_non_empty "@ " inputs) - (Utils.fprintf_list ~sep:"@ " (pp_horn_val m self (pp_horn_var m))) + fprintf fmt "(%a @[<v 0>%a%a)@]" pp_machine_stateless_name (node_name n) + (pp_print_list ~pp_epilogue:pp_print_cut + (pp_horn_val m self (pp_horn_var m))) inputs + (pp_print_list (pp_horn_val m self (pp_horn_var m))) (List.map (fun v -> mk_val (Var v) v.var_type) outputs) (* Print the instruction and update the set of reset instances *) @@ -370,7 +368,7 @@ let pp_machine_reset machines fmt m = fprintf fmt "@[<v 5>(and @ "; (* print "x_m = x_c" for each local memory *) - (Utils.fprintf_list ~sep:"@ " (fun fmt v -> + (pp_print_list (fun fmt v -> fprintf fmt "(= %a %a)" (pp_horn_var m) (rename_mid v) (pp_horn_var m) (rename_current v))) fmt locals; @@ -378,14 +376,14 @@ let pp_machine_reset machines fmt m = (* print "child_reset ( associated vars _ {c,m} )" for each subnode. Special treatment for _arrow: _first = true *) - (Utils.fprintf_list ~sep:"@ " (fun fmt (id, (n, _)) -> + (pp_print_list (fun fmt (id, (n, _)) -> let name = node_name n in if name = "_arrow" then fprintf fmt "(= %s._arrow._first_m true)" (concat m.mname.node_id id) else let machine_n = get_machine machines name in fprintf fmt "(%s_reset @[<hov 0>%a@])" name - (Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (rename_machine_list (concat m.mname.node_id id) (reset_vars machines machine_n)))) @@ -405,7 +403,7 @@ let print_machine machines fmt m = fprintf fmt "; %s@." m.mname.node_id; (* Printing variables *) - Utils.fprintf_list ~sep:"@." pp_decl_var fmt + pp_print_list ~pp_open_box:pp_open_vbox0 pp_decl_var fmt (inout_vars m @ rename_current_list (full_memory_vars machines m) @ rename_mid_list (full_memory_vars machines m) @@ -417,7 +415,7 @@ let print_machine machines fmt m = (* Declaring single predicate *) fprintf fmt "(declare-rel %a (%a))@." pp_machine_stateless_name m.mname.node_id - (Utils.fprintf_list ~sep:" " pp_type) + (pp_print_list pp_type) (List.map (fun v -> v.var_type) (inout_vars m)); match m.mstep.step_asserts with @@ -430,7 +428,7 @@ let print_machine machines fmt m = (* No reset info for stateless nodes *) m fmt m.mstep.step_instrs); fprintf fmt "@ (%a @[<v 0>%a)@]@]@.))@.@." pp_machine_stateless_name m.mname.node_id - (Utils.fprintf_list ~sep:" " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (inout_vars m) | assertsl -> let pp_val = @@ -443,17 +441,17 @@ let print_machine machines fmt m = ignore (pp_machine_instrs machines [] m fmt m.mstep.step_instrs); fprintf fmt "@. %a)@ (%a @[<v 0>%a)@]@]@.))@.@." (pp_conj pp_val) assertsl pp_machine_stateless_name m.mname.node_id - (Utils.fprintf_list ~sep:" " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (step_vars machines m)) else ( (* Declaring predicate *) fprintf fmt "(declare-rel %a (%a))@." pp_machine_reset_name m.mname.node_id - (Utils.fprintf_list ~sep:" " pp_type) + (pp_print_list pp_type) (List.map (fun v -> v.var_type) (reset_vars machines m)); fprintf fmt "(declare-rel %a (%a))@." pp_machine_step_name m.mname.node_id - (Utils.fprintf_list ~sep:" " pp_type) + (pp_print_list pp_type) (List.map (fun v -> v.var_type) (step_vars machines m)); pp_print_newline fmt (); @@ -462,7 +460,7 @@ let print_machine machines fmt m = fprintf fmt "@[<v 2>(rule (=> @ %a@ (%a @[<v 0>%a)@]@]@.))@.@." (pp_machine_reset machines) m pp_machine_reset_name m.mname.node_id - (Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (reset_vars machines m); match m.mstep.step_asserts with @@ -473,7 +471,7 @@ let print_machine machines fmt m = ignore (pp_machine_instrs machines [] m fmt m.mstep.step_instrs); fprintf fmt "@ (%a @[<v 0>%a)@]@]@.))@.@." pp_machine_step_name m.mname.node_id - (Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (step_vars machines m) | assertsl -> let pp_val = @@ -487,7 +485,7 @@ let print_machine machines fmt m = ignore (pp_machine_instrs machines [] m fmt m.mstep.step_instrs); fprintf fmt "@. %a)@ (%a @[<v 0>%a)@]@]@.))@.@." (pp_conj pp_val) assertsl pp_machine_step_name m.mname.node_id - (Utils.fprintf_list ~sep:" " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (step_vars machines m))) let mk_flags arity = @@ -527,11 +525,11 @@ let print_sfunction machines fmt m = (* Check if there is annotation for s-function *) if m.mannot != [] then Format.fprintf fmt "; @[%a@]@]@\n" - (Utils.fprintf_list ~sep:"@ " Printers.pp_s_function) + (pp_print_list Printers.pp_s_function) m.mannot; (* Printing variables *) - Utils.fprintf_list ~sep:"@." pp_decl_var fmt + pp_print_list ~pp_open_box:pp_open_vbox0 pp_decl_var fmt (step_vars machines m @ rename_machine_list m.mname.node_id m.mstep.step_locals); Format.pp_print_newline fmt (); @@ -541,27 +539,27 @@ let print_sfunction machines fmt m = (* Declaring single predicate *) Format.fprintf fmt "(declare-rel %a (%a))@." pp_machine_stateless_name m.mname.node_id - (Utils.fprintf_list ~sep:" " pp_type) + (pp_print_list pp_type) (List.map (fun v -> v.var_type) (reset_vars machines m)); Format.pp_print_newline fmt (); (* Rule for single predicate *) let str_flags = sf_name ^ " " ^ mk_flags (int_of_string flags) in Format.fprintf fmt "@[<v 2>(rule (=> @ (%s %a) (%a %a)@]@.))@.@." str_flags - (Utils.fprintf_list ~sep:" " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (reset_vars machines m) pp_machine_stateless_name m.mname.node_id - (Utils.fprintf_list ~sep:" " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (reset_vars machines m)) else ( (* Declaring predicate *) Format.fprintf fmt "(declare-rel %a (%a))@." pp_machine_reset_name m.mname.node_id - (Utils.fprintf_list ~sep:" " pp_type) + (pp_print_list pp_type) (List.map (fun v -> v.var_type) (inout_vars m)); Format.fprintf fmt "(declare-rel %a (%a))@." pp_machine_step_name m.mname.node_id - (Utils.fprintf_list ~sep:" " pp_type) + (pp_print_list pp_type) (List.map (fun v -> v.var_type) (step_vars machines m)); Format.pp_print_newline fmt (); @@ -573,7 +571,7 @@ let print_sfunction machines fmt m = ignore (pp_machine_instrs machines [] m fmt m.mstep.step_instrs); fprintf fmt "@ (%a @[<v 0>%a)@]@]@.))@.@." pp_machine_step_name m.mname.node_id - (Utils.fprintf_list ~sep:"@ " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (step_vars machines m) | assertsl -> let pp_val = @@ -587,7 +585,7 @@ let print_sfunction machines fmt m = ignore (pp_machine_instrs machines [] m fmt m.mstep.step_instrs); fprintf fmt "@. %a)(%a @[<v 0>%a)@]@]@.))@.@." (pp_conj pp_val) assertsl pp_machine_step_name m.mname.node_id - (Utils.fprintf_list ~sep:" " (pp_horn_var m)) + (pp_print_list (pp_horn_var m)) (step_vars machines m))) (**************** XML printing functions *************) @@ -606,9 +604,9 @@ let rec pp_xml_expr fmt expr = | Expr_array a -> fprintf fmt "[%a]" pp_xml_tuple a | Expr_access (a, d) -> - fprintf fmt "%a[%a]" pp_xml_expr a Dimension.pp_dimension d + fprintf fmt "%a[%a]" pp_xml_expr a Dimension.pp d | Expr_power (a, d) -> - fprintf fmt "(%a^%a)" pp_xml_expr a Dimension.pp_dimension d + fprintf fmt "(%a^%a)" pp_xml_expr a Dimension.pp d | Expr_tuple el -> fprintf fmt "(%a)" pp_xml_tuple el | Expr_ite (c, t, e) -> @@ -628,11 +626,11 @@ let rec pp_xml_expr fmt expr = | Expr_appl (id, e, r) -> pp_xml_app fmt id e r) -and pp_xml_tuple fmt el = Utils.fprintf_list ~sep:"," pp_xml_expr fmt el +and pp_xml_tuple fmt el = pp_comma_list pp_xml_expr fmt el and pp_xml_handler fmt (t, h) = fprintf fmt "(%s -> %a)" t pp_xml_expr h -and pp_xml_handlers fmt hl = Utils.fprintf_list ~sep:" " pp_xml_handler fmt hl +and pp_xml_handlers fmt hl = pp_print_list pp_xml_handler fmt hl and pp_xml_app fmt id e r = match r with @@ -684,7 +682,7 @@ and pp_xml_call fmt id e = and pp_xml_eexpr fmt e = fprintf fmt "%a%t %a" - (Utils.fprintf_list ~sep:"; " Printers.pp_quantifiers) + (pp_print_list ~pp_sep:pp_print_semicolon Printers.pp_quantifiers) e.eexpr_quantifiers (fun fmt -> match e.eexpr_quantifiers with [] -> () | _ -> fprintf fmt ";") @@ -709,11 +707,12 @@ and pp_xml_s_function fmt expr_ann = Format.pp_print_string fmt x | _ -> Format.fprintf fmt "%a" - (Utils.fprintf_list ~sep:"/" Format.pp_print_string) + (pp_print_list ~pp_sep:(fun fmt () -> pp_print_string fmt "/") + pp_print_string) kwds) pp_xml_sf_value ee in - Utils.fprintf_list ~sep:"@ " pp_xml_annot fmt expr_ann.annots + pp_print_list pp_xml_annot fmt expr_ann.annots and pp_xml_expr_annot fmt expr_ann = let pp_xml_annot fmt (kwds, ee) = @@ -726,11 +725,12 @@ and pp_xml_expr_annot fmt expr_ann = Format.pp_print_string fmt x | _ -> Format.fprintf fmt "/%a/" - (Utils.fprintf_list ~sep:"/" Format.pp_print_string) + (pp_print_list ~pp_sep:(fun fmt () -> pp_print_string fmt "/") + pp_print_string) kwds) pp_xml_eexpr ee in - Utils.fprintf_list ~sep:"@ " pp_xml_annot fmt expr_ann.annots + pp_print_list pp_xml_annot fmt expr_ann.annots (* Local Variables: *) (* compile-command:"make -C ../../.." *) diff --git a/src/backends/Horn/horn_backend_printers.mli b/src/backends/Horn/horn_backend_printers.mli index e69de29b..cefca734 100644 --- a/src/backends/Horn/horn_backend_printers.mli +++ b/src/backends/Horn/horn_backend_printers.mli @@ -0,0 +1,8 @@ +open Format +open Lustre_types +open Machine_code_types + +val pp_horn_var: machine_t -> formatter -> var_decl -> unit +val pp_xml_expr: formatter -> expr -> unit +val print_sfunction: machine_t list -> formatter -> machine_t -> unit +val print_machine: machine_t list -> formatter -> machine_t -> unit diff --git a/src/backends/Horn/horn_backend_traces.ml b/src/backends/Horn/horn_backend_traces.ml index 6c26620b..c2c606b2 100644 --- a/src/backends/Horn/horn_backend_traces.ml +++ b/src/backends/Horn/horn_backend_traces.ml @@ -14,6 +14,7 @@ This is a modified version that handle reset *) +open Utils open Format open Lustre_types open Corelang @@ -22,8 +23,7 @@ open Horn_backend_common open Horn_backend_printers let pp_traces = - Utils.fprintf_list ~sep:", " (fun fmt (v, e) -> - Format.fprintf fmt "%s -> %a" v Printers.pp_expr e) + pp_comma_list (fun fmt (v, e) -> fprintf fmt "%s -> %a" v Printers.pp_expr e) (* Compute memories associated to each machine *) let compute_mems machines m = @@ -51,7 +51,7 @@ let machines_traces machines = let filtered = List.filter (fun (kwds, _) -> kwds = [ "traceability" ]) all_annots in - (* List.iter (Format.eprintf "Annots: %a@." Printers.pp_expr_annot) + (* List.iter (eprintf "Annots: %a@." Printers.pp_expr_annot) (m.mannot); *) let content = List.map snd filtered in (* Elements are supposed to be a pair (tuple): variable, expression *) @@ -68,7 +68,7 @@ let machines_traces machines = assert false) content in - (* Format.eprintf "Build traces: %a@." pp_traces traces; *) + (* eprintf "Build traces: %a@." pp_traces traces; *) m, traces) machines @@ -90,7 +90,7 @@ let memories_old machines m = (* eprintf "Unable to found variable %a in traces (%a)@." Printers.pp_var v * pp_traces traces; *) p, - mkexpr Location.dummy_loc (Expr_ident v.var_id) )) + mkexpr Location.dummy (Expr_ident v.var_id) )) (compute_mems machines m) let memories_next machines m = @@ -117,10 +117,10 @@ let memories_next machines m = false) m.mname.node_stmts with _ -> - Format.eprintf + eprintf "Unable to find definition of %s in stmts %a@.prefix=%a@.@?" var_id Printers.pp_node_stmts m.mname.node_stmts - (Utils.fprintf_list ~sep:"," (fun fmt (id, n) -> + (pp_comma_list (fun fmt (id, n) -> fprintf fmt "(%s,%s)" id n.mname.node_id)) (List.rev prefix); @@ -140,23 +140,24 @@ let memories_next machines m = prefix, def | _ -> eprintf "Mem Failure: (prefix: %a, eexpr: %a)@.@?" - (Utils.fprintf_list ~sep:"," (fun fmt (id, n) -> + (pp_comma_list (fun fmt (id, n) -> fprintf fmt "(%s,%s)" id n.mname.node_id)) (List.rev prefix) Printers.pp_expr ee; assert false) (memories_old machines m) let pp_prefix_rev fmt prefix = - Utils.fprintf_list ~sep:"." + pp_print_list ~pp_sep:(fun fmt () -> pp_print_string fmt ".") (fun fmt (id, n) -> fprintf fmt "(%s,%s)" id n.mname.node_id) fmt (List.rev prefix) let traces_file fmt machines = + let pp_l = pp_print_list ~pp_sep:(fun fmt () -> pp_print_string fmt " | ") in fprintf fmt "<?xml version=\"1.0\"?>@."; fprintf fmt "<Traces xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">@."; fprintf fmt "@[<v 5>@ %a@ @]@." - (Utils.fprintf_list ~sep:"@ " (fun fmt m -> + (pp_print_list (fun fmt m -> let pp_var = pp_horn_var m in let memories_old = memories_old machines m in let memories_next = memories_next machines m in @@ -171,61 +172,45 @@ let traces_file fmt machines = rename_machine_list m.mname.node_id m.mstep.step_outputs in fprintf fmt "<input name=\"%a\" type=\"%a\">%a</input>@ " - (Utils.fprintf_list ~sep:" | " (pp_horn_var m)) - input_vars - (Utils.fprintf_list ~sep:" | " (fun fmt id -> - pp_type fmt id.var_type)) - input_vars - (Utils.fprintf_list ~sep:" | " (pp_horn_var m)) - m.mstep.step_inputs; + (pp_l (pp_horn_var m)) input_vars + (pp_l (fun fmt id -> pp_type fmt id.var_type)) input_vars + (pp_l (pp_horn_var m)) m.mstep.step_inputs; fprintf fmt "<output name=\"%a\" type=\"%a\">%a</output>@ " - (Utils.fprintf_list ~sep:" | " pp_var) - output_vars - (Utils.fprintf_list ~sep:" | " (fun fmt id -> - pp_type fmt id.var_type)) - output_vars - (Utils.fprintf_list ~sep:" | " pp_var) - m.mstep.step_outputs; + (pp_l pp_var) output_vars + (pp_l (fun fmt id -> pp_type fmt id.var_type)) output_vars + (pp_l pp_var) m.mstep.step_outputs; let local_vars = try full_memory_vars ~without_arrow:true machines m with Not_found -> - Format.eprintf "machine %s@.@?" m.mname.node_id; + eprintf "machine %s@.@?" m.mname.node_id; assert false in let init_local_vars = rename_next_list local_vars in let step_local_vars = rename_current_list local_vars in fprintf fmt "<localInit name=\"%a\" type=\"%a\">%t%a</localInit>@ " - (Utils.fprintf_list ~sep:" | " pp_var) - init_local_vars - (Utils.fprintf_list ~sep:" | " (fun fmt id -> - pp_type fmt id.var_type)) + (pp_l pp_var) init_local_vars + (pp_l (fun fmt id -> pp_type fmt id.var_type)) init_local_vars (fun fmt -> match memories_next with [] -> () | _ -> fprintf fmt "") - (Utils.fprintf_list ~sep:" | " (fun fmt (_, ee) -> - fprintf fmt "%a" pp_xml_expr ee)) + (pp_l (fun fmt (_, ee) -> fprintf fmt "%a" pp_xml_expr ee)) memories_next; fprintf fmt "<localStep name=\"%a\" type=\"%a\">%t%a</localStep>@ " - (Utils.fprintf_list ~sep:" | " pp_var) - step_local_vars - (Utils.fprintf_list ~sep:" | " (fun fmt id -> - pp_type fmt id.var_type)) - step_local_vars + (pp_l pp_var) step_local_vars + (pp_l (fun fmt id -> pp_type fmt id.var_type)) step_local_vars (fun fmt -> match memories_old with [] -> () | _ -> fprintf fmt "") - (Utils.fprintf_list ~sep:" | " (fun fmt (_, ee) -> - fprintf fmt "(%a)" pp_xml_expr ee)) + (pp_l (fun fmt (_, ee) -> fprintf fmt "(%a)" pp_xml_expr ee)) memories_old; let arrow_vars = arrow_vars machines m in let arrow_vars_curr = rename_current_list arrow_vars and arrow_vars_mid = rename_mid_list arrow_vars and arrow_vars_next = rename_next_list arrow_vars in - Utils.fprintf_list ~sep:"@ " - (fun fmt v -> fprintf fmt "<reset name=\"%a\"/>" pp_var v) + pp_print_list (fun fmt v -> fprintf fmt "<reset name=\"%a\"/>" pp_var v) fmt (arrow_vars_curr @ arrow_vars_mid @ arrow_vars_next); fprintf fmt "@]@ </Node>")) diff --git a/src/backends/Horn/horn_backend_traces.mli b/src/backends/Horn/horn_backend_traces.mli index e69de29b..d17ec562 100644 --- a/src/backends/Horn/horn_backend_traces.mli +++ b/src/backends/Horn/horn_backend_traces.mli @@ -0,0 +1 @@ +val traces_file: Format.formatter -> Machine_code_types.machine_t list -> unit diff --git a/src/backends/backends.mli b/src/backends/backends.mli index 80fcce8c..ec0b6e10 100644 --- a/src/backends/backends.mli +++ b/src/backends/backends.mli @@ -1,3 +1,4 @@ val setup: unit -> unit val is_functional: unit -> bool val join_guards: bool ref +val get_normalization_params: unit -> Normalization.param_t diff --git a/src/basic_library.mli b/src/basic_library.mli index 2727025c..f5fd8f4e 100644 --- a/src/basic_library.mli +++ b/src/basic_library.mli @@ -10,6 +10,7 @@ val is_internal_fun: ident -> Types.t list -> bool val is_expr_internal_fun: Lustre_types.expr -> bool val is_value_internal_fun: Machine_code_types.value_t -> bool val is_stateless_fun: ident -> bool +val is_numeric_operator: ident -> bool val type_env: Types.t Env.t val clock_env: Clocks.t Env.t diff --git a/src/causality.ml b/src/causality.ml index 643f4fc4..a23f9800 100644 --- a/src/causality.ml +++ b/src/causality.ml @@ -692,17 +692,15 @@ let pp_dep_graph fmt g = let pp_error fmt err = match err with | NodeCycle trace -> - Format.fprintf fmt "Causality error, cyclic node calls:@ @[<v 0>%a@]@ " - (fprintf_list ~sep:",@ " Format.pp_print_string) - trace + Format.(fprintf fmt "Causality error, cyclic node calls:@ @[<v 0>%a@]@ " + (pp_comma_list Format.pp_print_string) trace) | DataCycle traces -> - Format.fprintf fmt - "Causality error, cyclic data dependencies:@ @[<v 0>%a@]@ " - (fprintf_list ~sep:";@ " (fun fmt trace -> - Format.fprintf fmt "@[<v 0>{%a}@]" - (fprintf_list ~sep:",@ " Format.pp_print_string) - trace)) - traces + Format.(fprintf fmt + "Causality error, cyclic data dependencies:@ @[<v 0>%a@]@ " + (pp_print_list ~pp_sep:pp_print_semicolon (fun fmt trace -> + fprintf fmt "@[<v 0>{%a}@]" + (pp_comma_list Format.pp_print_string) trace)) + traces) (* Merges elements of graph [g2] into graph [g1] *) let merge_with g1 g2 = diff --git a/src/causality.mli b/src/causality.mli index cebaffce..a520a169 100644 --- a/src/causality.mli +++ b/src/causality.mli @@ -10,9 +10,14 @@ exception Error of error val pp_error: Format.formatter -> error -> unit +val world: ident + module NodeDep: sig val dependence_graph: program_t -> IdentDepGraph.t val filter_static_inputs: var_decl list -> expr list -> Dimension.t list + val compute_generic_calls: program_t -> unit + val get_callee: expr -> (ident * expr list) option + val get_calls: (ident -> bool) -> node_desc -> expr list end (* Look for cycles in a dependency graph *) @@ -32,9 +37,14 @@ module ExprDep: sig val mk_instance_var: ident -> ident val is_instance_var: ident -> bool val is_ghost_var: ident -> bool + val is_read_var: ident -> bool val undo_instance_var: ident -> ident + val undo_read_var: ident -> ident val node_eq_equiv: node_desc -> (ident, ident) Hashtbl.t val node_input_variables: node_desc -> ISet.t + val node_local_variables: node_desc -> ISet.t + val node_output_variables: node_desc -> ISet.t + val node_memory_variables: node_desc -> ISet.t end (* Module used to compute static disjunction of variables based upon their @@ -46,7 +56,11 @@ module Disjunction: sig order, maybe removing shorter branches *) type disjoint_map = (ident, CISet.t) Hashtbl.t + val pp_ciset: Format.formatter -> CISet.t -> unit + val clock_disjoint_map: var_decl list -> disjoint_map + + val pp_disjoint_map: Format.formatter -> disjoint_map -> unit end (* Tests whether [v] is a root of graph [g], i.e. a source *) diff --git a/src/checks/access.ml b/src/checks/access.ml index f0b58fa9..36fa1e0c 100644 --- a/src/checks/access.ml +++ b/src/checks/access.ml @@ -28,9 +28,9 @@ open Corelang module ConstraintModule = struct (* bool dimension module *) - type t = Dimension.dim_expr + type t = Dimension.t - let equal d1 d2 = Dimension.is_eq_dimension d1 d2 + let equal d1 d2 = Dimension.equal d1 d2 let compare d1 d2 = if equal d1 d2 then 0 else compare d1.Dimension.dim_id d2.Dimension.dim_id diff --git a/src/checks/access.mli b/src/checks/access.mli index e69de29b..b17b3877 100644 --- a/src/checks/access.mli +++ b/src/checks/access.mli @@ -0,0 +1 @@ +val check_prog: Lustre_types.program_t -> unit diff --git a/src/checks/algebraicLoop.ml b/src/checks/algebraicLoop.ml index 2a7dd242..07de6846 100644 --- a/src/checks/algebraicLoop.ml +++ b/src/checks/algebraicLoop.ml @@ -77,10 +77,10 @@ end resolution*) let pp_resolution fmt resolution = - fprintf_list ~sep:"@ " - (fun fmt (eq, _) -> - Format.fprintf fmt "inlining: %a" Printers.pp_node_eq eq) - fmt resolution + Format.(pp_print_list + (fun fmt (eq, _) -> + fprintf fmt "inlining: %a" Printers.pp_node_eq eq) + fmt resolution) let al_is_solved (_, als) = List.for_all (fun (_, _, status) -> status) als @@ -132,11 +132,11 @@ let is_expr_inlined nd expr = assert false) let pp_calls nd fmt calls = - Format.fprintf fmt "@[<v 0>%a@]" - (fprintf_list ~sep:"@ " (fun fmt (funid, expr, _) -> - Format.fprintf fmt "%s: %i (inlined:%b)" funid expr.expr_tag - (is_expr_inlined nd expr))) - calls + Format.(fprintf fmt "@[<v 0>%a@]" + (pp_print_list (fun fmt (funid, expr, _) -> + fprintf fmt "%s: %i (inlined:%b)" funid expr.expr_tag + (is_expr_inlined nd expr))) + calls) (* Inline the provided expression *) let inline_expr node expr = @@ -354,10 +354,10 @@ let pp_al nd fmt (partition, calls, _) = let open Format in fprintf fmt "@[<v 0>"; fprintf fmt "variables in the alg. loop: @[<hov 0>%a@]@ " - (fprintf_list ~sep:",@ " pp_print_string) + (pp_comma_list pp_print_string) partition; fprintf fmt "@ involved node calls: @[<v 0>%a@]@ " - (fprintf_list ~sep:",@ " (fun fmt ((funid, expr, _), status) -> + (pp_comma_list (fun fmt ((funid, expr, _), status) -> fprintf fmt "%s" funid; if status && is_expr_inlined nd expr then fprintf fmt " (inlining it solves the alg. loop)")) @@ -372,7 +372,7 @@ let pp_al nd fmt (partition, calls, _) = let pp_report fmt report = let open Format in - fprintf_list ~sep:"@." + pp_print_list ~pp_open_box:pp_open_vbox0 (fun _ (nd, als) -> let top = Corelang.node_from_name nd.node_id in let pp = @@ -385,8 +385,7 @@ let pp_report fmt report = in pp top.top_decl_loc (fun fmt -> fprintf fmt "algebraic loop in node %s: {@[<v 0>%a@]}" nd.node_id - (fprintf_list ~sep:"@ " (pp_al nd)) - als)) + (pp_print_list (pp_al nd)) als)) fmt report; fprintf fmt "@." @@ -406,7 +405,7 @@ let analyze cpt prog = (* TODO create a report *) (* Printing the report on stderr *) Format.eprintf "%a" pp_report report; - raise (Error.Error (Location.dummy_loc, Error.AlgebraicLoop))) + raise (Error.Error (Location.dummy, Error.AlgebraicLoop))) in (* Printing the report on stderr *) Format.eprintf "%a" pp_report report; diff --git a/src/checks/algebraicLoop.mli b/src/checks/algebraicLoop.mli index e69de29b..ea154812 100644 --- a/src/checks/algebraicLoop.mli +++ b/src/checks/algebraicLoop.mli @@ -0,0 +1,4 @@ +open Utils +open Lustre_types + +val analyze: program_t -> program_t * Scheduling_type.schedule_report IMap.t diff --git a/src/clock_calculus.mli b/src/clock_calculus.mli index 2a57b425..130c0735 100644 --- a/src/clock_calculus.mli +++ b/src/clock_calculus.mli @@ -7,3 +7,5 @@ val compute_root_clock: Clocks.t -> Clocks.t val clock_prog: Clocks.t Env.t -> program_t -> Clocks.t Env.t val check_env_compat: top_decl list -> Clocks.t Env.t -> Clocks.t Env.t -> unit + +val uneval_prog_generics: program_t -> unit diff --git a/src/clocks.mli b/src/clocks.mli index 63f8688a..d7a19be6 100644 --- a/src/clocks.mli +++ b/src/clocks.mli @@ -45,7 +45,10 @@ type error = | Carrier_extrusion of t * carrier_expr | Clock_extrusion of t * t +(* Nice pretty-printing. Simplifies expressions before printing them. Non-linear + complexity. *) val pp: Format.formatter -> t -> unit + val pp_suffix: Format.formatter -> t -> unit val new_var: bool -> t @@ -86,6 +89,9 @@ val get_carrier_name: t -> carrier_expr option val equal: t -> t -> bool +(* Disjunction relation between variables based upon their static clocks. *) +val disjoint: t -> t -> bool + val const_of_carrier: carrier_expr -> ident val pp_error: Format.formatter -> error -> unit diff --git a/src/compiler_common.mli b/src/compiler_common.mli index 89d9d3d0..d0bf8196 100644 --- a/src/compiler_common.mli +++ b/src/compiler_common.mli @@ -11,3 +11,16 @@ val check_compatibility: program_t * Types.t Env.t * Clocks.t Env.t -> val update_vdecl_parents_prog: program_t -> unit val expand_automata: program_t -> program_t + +(* Process each node/imported node and introduce the associated contract node *) +val resolve_contracts: program_t -> program_t + +val force_stateful_decls: program_t -> unit + +val check_stateless_decls: program_t -> unit + +val type_decls: Types.t Env.t -> program_t -> Types.t Env.t + +val clock_decls: Clocks.t Env.t -> program_t -> Clocks.t Env.t + +val create_dest_dir: unit -> unit diff --git a/src/compiler_stages.ml b/src/compiler_stages.ml index b3bb823b..93092726 100644 --- a/src/compiler_stages.ml +++ b/src/compiler_stages.ml @@ -93,9 +93,9 @@ let stage1 params prog dirname basename extension = Global.main_node := main_node; try ignore (Corelang.node_from_name main_node) with Not_found -> - Format.eprintf "Code generation error: %a@." Error.pp_error_msg + Format.eprintf "Code generation error: %a@." Error.pp Error.Main_not_found; - raise (Error.Error (Location.dummy_loc, Error.Main_not_found))) + raise (Error.Error (Location.dummy, Error.Main_not_found))) in (* Perform inlining before any analysis *) @@ -249,9 +249,10 @@ let stage2 params prog = (* printing code *) let stage3 prog machine_code dependencies basename extension = + let open Options in let basename = Filename.basename basename in - match !Options.output, extension with - | "C", ".lus" -> + match !output, extension with + | OutC, ".lus" -> Log.report ~level:1 (fun fmt -> fprintf fmt ".. C code generation@,"); C_backend.translate_to_c !generate_c_header (* alloc_header_file source_lib_file source_main_file makefile_file *) @@ -260,11 +261,11 @@ let stage3 prog machine_code dependencies basename extension = ACSL annotations generation@,"); ACSL_backend.translate_to_acsl (* alloc_header_file source_lib_file source_main_file makefile_file *) basename prog machine_code dependencies end *) - | "C", _ -> + | OutC, _ -> C_backend.print_c_header basename; Log.report ~level:1 (fun fmt -> fprintf fmt ".. no C code generation for lusi@,") - | "java", _ -> + | OutJava, _ -> Format.eprintf "internal error: sorry, but not yet supported !"; assert false (*let source_file = basename ^ ".java" in Log.report ~level:1 (fun fmt -> @@ -273,11 +274,11 @@ let stage3 prog machine_code dependencies basename extension = Log.report ~level:1 (fun fmt -> fprintf fmt ".. java code generation@,@?"); Java_backend.translate_to_java source_fmt basename normalized_prog machine_code;*) - | "Ada", _ -> + | OutAda, _ -> Log.report ~level:1 (fun fmt -> fprintf fmt ".. Ada code generation@."); Ada_backend.translate_to_ada basename (Machine_code_common.arrow_machine :: machine_code) - | "horn", _ -> + | OutHorn, _ -> let destname = !Options.dest_dir ^ "/" ^ basename in let source_file = destname ^ ".smt2" in (* Could be changed *) @@ -294,7 +295,7 @@ let stage3 prog machine_code dependencies basename extension = let fmt = formatter_of_out_channel traces_out in Log.report ~level:1 (fun fmt -> fprintf fmt ".. tracing info@,"); Horn_backend_traces.traces_file fmt machine_code) - | "lustre", _ -> + | OutLustre, _ -> let destname = !Options.dest_dir ^ "/" ^ basename in let source_file = destname ^ ".lustrec" ^ extension in (* Could be changed *) @@ -306,7 +307,7 @@ let stage3 prog machine_code dependencies basename extension = Format.fprintf fmt "@.@?"; (* Lustre_backend.translate fmt basename normalized_prog machine_code *) () - | "emf", _ -> + | OutEMF, _ -> let destname = !Options.dest_dir ^ "/" ^ basename in let source_file = destname ^ ".json" in (* Could be changed *) @@ -314,5 +315,3 @@ let stage3 prog machine_code dependencies basename extension = let fmt = formatter_of_out_channel source_out in EMF_backend.translate fmt basename prog machine_code; () - | _ -> - assert false diff --git a/src/inliner.mli b/src/inliner.mli index e69de29b..53902b18 100644 --- a/src/inliner.mli +++ b/src/inliner.mli @@ -0,0 +1,7 @@ +open Utils +open Lustre_types + +val global_inline: program_t -> program_t +val local_inline: program_t -> program_t + +val keyword: ident list diff --git a/src/machine_code_common.mli b/src/machine_code_common.mli index ae2ba454..2434f8e1 100644 --- a/src/machine_code_common.mli +++ b/src/machine_code_common.mli @@ -111,6 +111,8 @@ val join_guards_list : val machine_vars : machine_t -> var_decl list +val get_machine: machine_t list -> ident -> machine_t + module PrintSpec : sig val pp_spec : machine_t -> diff --git a/src/optimize_machine.mli b/src/optimize_machine.mli index e69de29b..4f02cf59 100644 --- a/src/optimize_machine.mli +++ b/src/optimize_machine.mli @@ -0,0 +1,16 @@ +open Utils +open Lustre_types +open Machine_code_types + +(* This functions produces an optimzed prog * machines It 1- eliminates common + sub-expressions (TODO how is this different from normalization?) 2- inline + constants and eliminate duplicated variables 3- try to reuse variables + whenever possible + + When item (2) identified eliminated variables, the initial prog is modified, + its normalized recomputed, as well as its scheduling, before regenerating the + machines. + + The function returns both the (possibly updated) prog as well as the machines *) +val optimize: Normalization.param_t -> program_t -> Scheduling_type.schedule_report IMap.t -> + machine_t list -> program_t * machine_t list diff --git a/src/optimize_prog.mli b/src/optimize_prog.mli index e69de29b..3b481a78 100644 --- a/src/optimize_prog.mli +++ b/src/optimize_prog.mli @@ -0,0 +1,3 @@ +open Lustre_types + +val prog_unfold_consts: program_t -> program_t diff --git a/src/options.ml b/src/options.ml index e19289a8..7b96237e 100644 --- a/src/options.ml +++ b/src/options.ml @@ -37,6 +37,7 @@ let spec = ref SpecNo type option_output = | OutC | OutAda + | OutJava | OutEMF | OutHorn | OutLustre @@ -47,6 +48,7 @@ let pp_output fmt = Format.pp_print_string fmt (match !output with | OutC -> "C" | OutAda -> "Ada" + | OutJava -> "Java" | OutEMF -> "EMF" | OutHorn -> "Horn" | OutLustre -> "Lustre") diff --git a/src/options.mli b/src/options.mli index 9a9d5206..80d63d3b 100644 --- a/src/options.mli +++ b/src/options.mli @@ -16,6 +16,7 @@ val spec: option_spec ref type option_output = | OutC | OutAda + | OutJava | OutEMF | OutHorn | OutLustre @@ -76,3 +77,7 @@ val nb_mutants: int ref val gen_mcdc: bool ref val no_mutation_suffix: bool ref + +val compile_header: bool ref + +val track_exceptions: bool ref diff --git a/src/options_management.mli b/src/options_management.mli index 9447f369..625d7fc8 100644 --- a/src/options_management.mli +++ b/src/options_management.mli @@ -4,3 +4,5 @@ val plugin_opt: string * (unit -> unit) * (Format.formatter -> unit) * val name_dependency: ('a * string) -> string -> string val get_witness_dir: string -> string + +val verifier_opt: string * (unit -> unit) * (string * Arg.spec * string) list -> (string * Arg.spec * string) list diff --git a/src/plugins/mpfr/lustrec_mpfr.mli b/src/plugins/mpfr/lustrec_mpfr.mli index 60f43087..c055cae8 100644 --- a/src/plugins/mpfr/lustrec_mpfr.mli +++ b/src/plugins/mpfr/lustrec_mpfr.mli @@ -1 +1,19 @@ +open Utils +open Format +open Lustre_types +open Machine_code_types + val unfoldable_value: Machine_code_types.value_t -> bool +val inject_prog: program_t -> program_t + +val mpfr_t: string + +val mpfr_rnd: unit -> string +val mpfr_prec: unit -> int + +val is_homomorphic_fun: ident -> bool + +val pp_inject_init: (formatter -> 'a -> unit) -> formatter -> 'a -> unit +val pp_inject_clear: (formatter -> 'a -> unit) -> formatter -> 'a -> unit +val pp_inject_assign: (formatter -> value_t -> unit) -> formatter -> value_t * value_t -> unit +val pp_inject_real: (formatter -> 'a -> unit) -> (formatter -> 'b -> unit) -> formatter -> 'a * 'b -> unit diff --git a/src/plugins/plugins.mli b/src/plugins/plugins.mli index 093db4ae..5e9c3d2a 100644 --- a/src/plugins/plugins.mli +++ b/src/plugins/plugins.mli @@ -2,3 +2,8 @@ open Utils open Lustre_types val inline_annots: (ident -> ident) -> expr_annot list -> expr_annot list + +val check_force_stateful: unit -> bool + +val c_backend_main_loop_body_prefix: string -> string -> Format.formatter -> unit -> unit +val c_backend_main_loop_body_suffix: Format.formatter -> unit -> unit diff --git a/src/printers.mli b/src/printers.mli index 6d4f55c4..5328d2c9 100644 --- a/src/printers.mli +++ b/src/printers.mli @@ -6,12 +6,17 @@ val pp_eexpr: formatter -> eexpr -> unit val pp_node: formatter -> node_desc -> unit val pp_const: formatter -> constant -> unit val pp_var: formatter -> var_decl -> unit +val pp_var_name: formatter -> var_decl -> unit val pp_node_eq: formatter -> eq -> unit val pp_node_eqs: formatter -> eq list -> unit +val pp_node_stmts: formatter -> statement list -> unit val pp_spec: formatter -> contract_desc -> unit val pp_expr_annot: formatter -> expr_annot -> unit +val pp_s_function: formatter -> expr_annot -> unit val pp_short_decl: formatter -> top_decl -> unit val pp_const_decl: formatter -> const_desc -> unit val pp_var_type_dec_desc: formatter -> type_dec_desc -> unit val pp_typedef: formatter -> typedef_desc -> unit val pp_prog: formatter -> program_t -> unit +val pp_prog_short: formatter -> program_t -> unit +val pp_quantifiers: formatter -> quantifier_type * var_decl list -> unit diff --git a/src/scheduling.mli b/src/scheduling.mli index 8d7a6128..998bd942 100644 --- a/src/scheduling.mli +++ b/src/scheduling.mli @@ -1,9 +1,16 @@ open Utils +open Format open Lustre_types open Scheduling_type +val schedule_node: node_desc -> schedule_report val schedule_prog: program_t -> program_t * schedule_report IMap.t val remove_prog_inlined_locals: 'a IMap.t IMap.t -> schedule_report IMap.t -> schedule_report IMap.t val compute_prog_reuse_table: schedule_report IMap.t -> (ident, var_decl) Hashtbl.t IMap.t val sort_equations_from_schedule: eq list -> ident list list -> eq list * ident list + +val pp_warning_unused: formatter -> schedule_report IMap.t -> unit +val pp_schedule: formatter -> schedule_report IMap.t -> unit +val pp_fanin_table: formatter -> schedule_report IMap.t -> unit +val pp_dep_graph: formatter -> schedule_report IMap.t -> unit diff --git a/src/spec.mli b/src/spec.mli index e69de29b..ed915864 100644 --- a/src/spec.mli +++ b/src/spec.mli @@ -0,0 +1,3 @@ +open Lustre_types + +val enforce_spec_prog: program_t -> program_t diff --git a/src/tools/stateflow/common/activeStates.ml b/src/tools/stateflow/common/activeStates.ml index 48fb21b2..5a27430b 100644 --- a/src/tools/stateflow/common/activeStates.ml +++ b/src/tools/stateflow/common/activeStates.ml @@ -1,3 +1,4 @@ +open Utils open Basetypes (* Module to manipulate set of active states. @@ -13,10 +14,7 @@ module Vars = struct end) let pp_set fmt rho = - Format.fprintf fmt "@[<v 0>%a@ @]" - (Utils.fprintf_list ~sep:"@ " (fun fmt p -> - Format.fprintf fmt "%a" pp_path p)) - (elements rho) + Format.(fprintf fmt "@[<v 0>%a@ @]" (pp_print_list pp_path) (elements rho)) end module Env = struct @@ -37,8 +35,7 @@ module Env = struct let keys a = fold (fun key _ -> Vars.add key) a Vars.empty let pp_env fmt rho = - Format.fprintf fmt "@[<v 0>%a@ @]" - (Utils.fprintf_list ~sep:"@ " (fun fmt (p, b) -> - Format.fprintf fmt "%a -> %b" pp_path p b)) - (bindings rho) + Format.(fprintf fmt "@[<v 0>%a@ @]" + (pp_print_list (fun fmt (p, b) -> fprintf fmt "%a -> %b" pp_path p b)) + (bindings rho)) end diff --git a/src/tools/stateflow/common/activeStates.mli b/src/tools/stateflow/common/activeStates.mli new file mode 100644 index 00000000..e5b95131 --- /dev/null +++ b/src/tools/stateflow/common/activeStates.mli @@ -0,0 +1,7 @@ +module Vars: Set.S with type elt = Basetypes.path_t + +module Env: sig + include Map.S with type key = Basetypes.path_t + + val from_set: Vars.t -> 'a -> 'a t +end diff --git a/src/tools/stateflow/common/basetypes.ml b/src/tools/stateflow/common/basetypes.ml index 3f082709..3eb1af45 100644 --- a/src/tools/stateflow/common/basetypes.ml +++ b/src/tools/stateflow/common/basetypes.ml @@ -33,7 +33,8 @@ let pp_state_name = Format.pp_print_string let pp_junction_name = Format.pp_print_string -let pp_path fmt p = Utils.fprintf_list ~sep:"." pp_state_name fmt p +let pp_path fmt p = + Utils.Format.pp_print_list ~pp_sep:(fun fmt () -> Format.pp_print_string fmt ".") pp_state_name fmt p let pp_event fmt e = match e with diff --git a/src/tools/stateflow/common/basetypes.mli b/src/tools/stateflow/common/basetypes.mli new file mode 100644 index 00000000..286a40b2 --- /dev/null +++ b/src/tools/stateflow/common/basetypes.mli @@ -0,0 +1,77 @@ +type state_name_t = string + +type junction_name_t = string + +type path_t = state_name_t list + +type event_base_t = string + +type event_t = event_base_t option + +type user_variable_name_t = string + +(* Connected to lustrec types *) +type base_action_t = { + defs : Lustre_types.statement list; + ainputs : Lustre_types.var_decl list; + aoutputs : Lustre_types.var_decl list; + avariables : Lustre_types.var_decl list; (* ident: string; *) +} + +type base_condition_t = { + expr : Lustre_types.expr; + cinputs : Lustre_types.var_decl list; + coutputs : Lustre_types.var_decl list; + cvariables : Lustre_types.var_decl list; +} + +val pp_state_name: Format.formatter -> state_name_t -> unit +val pp_junction_name: Format.formatter -> junction_name_t -> unit +val pp_path: Format.formatter -> path_t -> unit + +type frontier_t = Loose | Strict + +type _ call_t = + | Ecall : (path_t * path_t * frontier_t) call_t + | Dcall : path_t call_t + | Xcall : (path_t * frontier_t) call_t + +(* Conditions are either (1) simple strings, (2) the active status of a state or + (3) occurence of an event. They can be combined (conjunction, negation) *) +module type ConditionType = sig + type t + + val cquote : base_condition_t -> t + + val tru : t + + val active : path_t -> t + + val event : event_t -> t + + val ( && ) : t -> t -> t + + val neg : t -> t + + val pp_cond : Format.formatter -> t -> unit +end + +module Condition: ConditionType + +module type ActionType = sig + type t + + val nil : t + + val aquote : base_action_t -> t + + val open_path : path_t -> t + + val close_path : path_t -> t + + val call : 'c call_t -> 'c -> t + + val pp_act : Format.formatter -> t -> unit +end + +module Action: ActionType diff --git a/src/tools/stateflow/common/datatype.ml b/src/tools/stateflow/common/datatype.ml index 458702ee..8d730162 100644 --- a/src/tools/stateflow/common/datatype.ml +++ b/src/tools/stateflow/common/datatype.ml @@ -1,3 +1,4 @@ +open Utils open Basetypes (* open ActiveEnv *) @@ -119,20 +120,20 @@ module SF = struct t.condition_act Action.pp_act t.transition_act pp_dest t.dest let pp_transitions fmt l = - Format.fprintf fmt "@[<hov 0>[@[<hov 0>%a@]@ ]@]" - (Utils.fprintf_list ~sep:";@ " pp_trans) - l + Format.(fprintf fmt "@[<hov 0>[@[<hov 0>%a@]@ ]@]" + (pp_print_list ~pp_sep:pp_print_semicolon pp_trans) + l) let pp_comp fmt c = match c with | Or (_T, _S) -> - Format.fprintf fmt "Or(%a, {%a})" pp_transitions _T - (Utils.fprintf_list ~sep:"; " pp_state_name) - _S + Format.(fprintf fmt "Or(%a, {%a})" pp_transitions _T + (pp_print_list ~pp_sep:pp_print_semicolon pp_state_name) + _S) | And _S -> - Format.fprintf fmt "And({%a})" - (Utils.fprintf_list ~sep:"; " pp_state_name) - _S + Format.(fprintf fmt "And({%a})" + (pp_print_list ~pp_sep:pp_print_semicolon pp_state_name) + _S) let pp_state_actions fmt sa = Format.fprintf fmt "@[<hov 0>(%a,@ %a,@ %a)@]" Action.pp_act sa.entry_act @@ -144,25 +145,23 @@ module SF = struct pp_transitions s.inner_trans pp_comp s.internal_composition let pp_src pp_sffunction fmt src = - Format.fprintf fmt "@[<v>%a@ @]" - (Utils.fprintf_list ~sep:"@ @ " (fun fmt src -> - match src with - | State (p, def) -> - Format.fprintf fmt "%a: %a" pp_path p pp_state def - | Junction (s, tl) -> - Format.fprintf fmt "%a: %a" pp_state_name s pp_transitions tl - | SFFunction p -> - pp_sffunction fmt p)) - src + Format.(fprintf fmt "@[<v>%a@ @]" + (pp_print_list ~pp_sep:pp_print_cutcut (fun fmt src -> + match src with + | State (p, def) -> + Format.fprintf fmt "%a: %a" pp_path p pp_state def + | Junction (s, tl) -> + Format.fprintf fmt "%a: %a" pp_state_name s pp_transitions tl + | SFFunction p -> + pp_sffunction fmt p)) + src) let rec pp_sffunction fmt (Program (name, component_list, _)) = Format.fprintf fmt "SFFunction name: %s@ %a@ " name (pp_src pp_sffunction) component_list let pp_vars fmt src = - Format.fprintf fmt "@[<v>%a@ @]" - (Utils.fprintf_list ~sep:"@ " Printers.pp_var) - src + Format.(fprintf fmt "@[<v>%a@ @]" (pp_print_list Printers.pp_var) src) let pp_prog fmt (Program (name, component_list, vars)) = Format.fprintf fmt "Main node name: %s@ %a@ %a@" name (pp_src pp_sffunction) diff --git a/src/tools/stateflow/common/datatype.mli b/src/tools/stateflow/common/datatype.mli new file mode 100644 index 00000000..1aa9830e --- /dev/null +++ b/src/tools/stateflow/common/datatype.mli @@ -0,0 +1,53 @@ +open Basetypes + +(* Type definitions of a model *) + +type destination_t = DPath of path_t | DJunction of junction_name_t + +type trans_t = { + event : event_t; + condition : Condition.t; + condition_act : Action.t; + transition_act : Action.t; + dest : destination_t; +} + +type transitions_t = trans_t list + +type composition_t = + | Or of transitions_t * state_name_t list + | And of state_name_t list + +type state_actions_t = { + entry_act : Action.t; + during_act : Action.t; + exit_act : Action.t; +} + +type state_def_t = { + state_actions : state_actions_t; + outer_trans : transitions_t; + inner_trans : transitions_t; + internal_composition : composition_t; +} + +type 'prog_t src_components_t = + | State of path_t * state_def_t + | Junction of junction_name_t * transitions_t + | SFFunction of 'prog_t + +type prog_t = + | Program of + state_name_t + * prog_t src_components_t list + * (Lustre_types.var_decl * Lustre_types.expr) list + +type trace_t = event_t list + +module type MODEL_T = sig + val name : string + + val model : prog_t + + val traces : trace_t list +end diff --git a/src/tools/stateflow/json-parser/json_parser.mli b/src/tools/stateflow/json-parser/json_parser.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/json-parser/main_parse_json_file.mli b/src/tools/stateflow/json-parser/main_parse_json_file.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/json-parser/test_json_parser_variables.mli b/src/tools/stateflow/json-parser/test_json_parser_variables.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/models/model_medium.mli b/src/tools/stateflow/models/model_medium.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/models/model_simple.mli b/src/tools/stateflow/models/model_simple.mli new file mode 100644 index 00000000..62e4c0f5 --- /dev/null +++ b/src/tools/stateflow/models/model_simple.mli @@ -0,0 +1,7 @@ +open Datatype + +val name : string + +val model : prog_t + +val traces : trace_t list diff --git a/src/tools/stateflow/models/model_stopwatch.mli b/src/tools/stateflow/models/model_stopwatch.mli new file mode 100644 index 00000000..62e4c0f5 --- /dev/null +++ b/src/tools/stateflow/models/model_stopwatch.mli @@ -0,0 +1,7 @@ +open Datatype + +val name : string + +val model : prog_t + +val traces : trace_t list diff --git a/src/tools/stateflow/semantics/cPS.mli b/src/tools/stateflow/semantics/cPS.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/semantics/cPS_ccode_generator.mli b/src/tools/stateflow/semantics/cPS_ccode_generator.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/semantics/cPS_evaluator.mli b/src/tools/stateflow/semantics/cPS_evaluator.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/semantics/cPS_interpreter.mli b/src/tools/stateflow/semantics/cPS_interpreter.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/semantics/cPS_lustre_generator.mli b/src/tools/stateflow/semantics/cPS_lustre_generator.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/semantics/cPS_transformer.mli b/src/tools/stateflow/semantics/cPS_transformer.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/tools/stateflow/semantics/theta.mli b/src/tools/stateflow/semantics/theta.mli new file mode 100644 index 00000000..e69de29b diff --git a/src/type_predef.mli b/src/type_predef.mli index a8d57a57..23f8c8aa 100644 --- a/src/type_predef.mli +++ b/src/type_predef.mli @@ -30,3 +30,5 @@ val type_bin_bool_op: Types.t val type_bin_comp_op: Types.t val type_unary_bool_op: Types.t val type_tuple: Types.t list -> Types.t +val type_arrow: Types.t -> Types.t -> Types.t +val type_array: Dimension.t -> Types.t -> Types.t diff --git a/src/typing.mli b/src/typing.mli index d0b2a9aa..f9201a10 100644 --- a/src/typing.mli +++ b/src/typing.mli @@ -26,3 +26,9 @@ val type_prog: Types.t Env.t -> program_t -> Types.t Env.t val check_typedef_compat: top_decl list -> unit val check_env_compat: top_decl list -> Types.t Env.t -> Types.t Env.t -> unit + +val uneval_prog_generics: program_t -> unit + +(* Equality on ground types only *) +(* Should be used between local variables which must have a ground type *) +val eq_ground: Types.t -> Types.t -> bool diff --git a/src/utils/dimension.ml b/src/utils/dimension.ml index ceed2413..2a65b415 100644 --- a/src/utils/dimension.ml +++ b/src/utils/dimension.ml @@ -86,14 +86,14 @@ let rec pp fmt dim = | Dunivar -> fprintf fmt "'%s" (Utils.name_of_dimension dim.dim_id) -let rec multi_dimension_product loc dim_list = +let rec multi_product loc dim_list = match dim_list with | [] -> mkdim_int loc 1 | [ d ] -> d | d :: q -> - mkdim_appl loc "*" [ d; multi_dimension_product loc q ] + mkdim_appl loc "*" [ d; multi_product loc q ] (* Builds a dimension expr representing 0<=d *) let check_bound loc d = mkdim_appl loc "<=" [ mkdim_int loc 0; d ] @@ -136,7 +136,7 @@ let size_const dim = | Dbool b -> if b then 1 else 0 | _ -> - Format.eprintf "internal error: size_const_dimension %a@." pp dim; + Format.eprintf "internal error: size_const %a@." pp dim; assert false let rec is_polymorphic dim = diff --git a/src/utils/dimension.mli b/src/utils/dimension.mli index e99526ad..45c9fda4 100644 --- a/src/utils/dimension.mli +++ b/src/utils/dimension.mli @@ -44,3 +44,8 @@ val expr_replace_expr: (ident -> t) -> t -> t val rename: (ident -> ident) -> (ident -> ident) -> t -> t val size_const: t -> int + +val check_bound: Location.t -> t -> t +val check_access: Location.t -> t -> t -> t + +val multi_product: Location.t -> t list -> t diff --git a/src/utils/location.ml b/src/utils/location.ml index b3ed097c..4461b78c 100644 --- a/src/utils/location.ml +++ b/src/utils/location.ml @@ -54,7 +54,7 @@ let loc_line (s, _e) = s.pos_lnum let pp fmt loc = if loc = dummy then () else Format.fprintf fmt "%s" (Lex.range loc) -let pp_c_loc fmt (s, _e) = +let pp_c fmt (s, _e) = let filename = s.pos_fname in let line = s.pos_lnum in Format.fprintf fmt "#line %i \"%s\"" line filename diff --git a/src/utils/location.mli b/src/utils/location.mli index c2857c00..e461dd88 100644 --- a/src/utils/location.mli +++ b/src/utils/location.mli @@ -3,6 +3,7 @@ type filename = string val dummy: t val pp: Format.formatter -> t -> unit +val pp_c: Format.formatter -> t -> unit val get_module: unit -> filename val curr: Lexing.lexbuf -> t val shift: t -> t -> t diff --git a/src/utils/utils.ml b/src/utils/utils.ml index 5713cb22..d87a776b 100644 --- a/src/utils/utils.ml +++ b/src/utils/utils.ml @@ -357,22 +357,22 @@ module Format = struct let pp_comma_list = pp_print_list ~pp_sep:pp_print_comma let pp_print_list_i ?pp_prologue ?pp_epilogue ?pp_op ?pp_cl ?pp_open_box - ?pp_eol ?pp_sep pp_v = + ?pp_eol ?pp_nil ?pp_sep pp_v = let i = ref 0 in pp_print_list ?pp_prologue ?pp_epilogue ?pp_op ?pp_cl ?pp_open_box ?pp_eol - ?pp_sep (fun fmt x -> + ?pp_nil ?pp_sep (fun fmt x -> pp_v fmt !i x; incr i) let pp_print_list2 ?pp_prologue ?pp_epilogue ?pp_op ?pp_cl ?pp_open_box - ?pp_eol ?pp_sep pp_v fmt (l1, l2) = + ?pp_eol ?pp_nil ?pp_sep pp_v fmt (l1, l2) = pp_print_list ?pp_prologue ?pp_epilogue ?pp_op ?pp_cl ?pp_open_box ?pp_eol - ?pp_sep pp_v fmt (List.combine l1 l2) + ?pp_nil ?pp_sep pp_v fmt (List.combine l1 l2) let pp_print_list_i2 ?pp_prologue ?pp_epilogue ?pp_op ?pp_cl ?pp_open_box - ?pp_eol ?pp_sep pp_v fmt (l1, l2) = + ?pp_eol ?pp_nil ?pp_sep pp_v fmt (l1, l2) = pp_print_list_i ?pp_prologue ?pp_epilogue ?pp_op ?pp_cl ?pp_open_box ?pp_eol - ?pp_sep + ?pp_nil ?pp_sep (fun fmt i (x1, x2) -> pp_v fmt i x1 x2) fmt (List.combine l1 l2) diff --git a/src/utils/utils.mli b/src/utils/utils.mli index d738d586..b7a8c729 100644 --- a/src/utils/utils.mli +++ b/src/utils/utils.mli @@ -4,6 +4,8 @@ type tag = int module IMap: sig include Map.S with type key = ident val pp: ?comment:string -> (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a t -> unit + val diff: 'a t -> 'a t -> 'a t + val of_list: (key * 'a) list -> 'a t end module ISet: sig @@ -13,10 +15,16 @@ end module Format: sig include module type of Format + val with_out_file: string -> (formatter -> unit) -> unit + val pp_print_comma: formatter -> unit -> unit + val pp_print_comma': formatter -> unit -> unit val pp_print_semicolon: formatter -> unit -> unit + val pp_print_semicolon': formatter -> unit -> unit + val pp_print_cpar: formatter -> unit -> unit val pp_open_vbox0: formatter -> unit -> unit val pp_print_cutcut: formatter -> unit -> unit val pp_print_nothing: formatter -> 'a -> unit + val pp_print_endcut: string -> formatter -> unit -> unit val pp_print_list: ?pp_prologue:(formatter -> unit -> unit) -> ?pp_epilogue:(formatter -> unit -> unit) -> @@ -27,6 +35,26 @@ module Format: sig ?pp_nil:(formatter -> unit -> unit) -> ?pp_sep:(formatter -> unit -> unit) -> (formatter -> 'a -> unit) -> formatter -> 'a list -> unit + val pp_print_list_i: + ?pp_prologue:(formatter -> unit -> unit) -> + ?pp_epilogue:(formatter -> unit -> unit) -> + ?pp_op:(formatter -> unit -> unit) -> + ?pp_cl:(formatter -> unit -> unit) -> + ?pp_open_box:(formatter -> unit -> unit) -> + ?pp_eol:(formatter -> unit -> unit) -> + ?pp_nil:(formatter -> unit -> unit) -> + ?pp_sep:(formatter -> unit -> unit) -> + (formatter -> int -> 'a -> unit) -> formatter -> 'a list -> unit + val pp_print_list_i2: + ?pp_prologue:(formatter -> unit -> unit) -> + ?pp_epilogue:(formatter -> unit -> unit) -> + ?pp_op:(formatter -> unit -> unit) -> + ?pp_cl:(formatter -> unit -> unit) -> + ?pp_open_box:(formatter -> unit -> unit) -> + ?pp_eol:(formatter -> unit -> unit) -> + ?pp_nil:(formatter -> unit -> unit) -> + ?pp_sep:(formatter -> unit -> unit) -> + (formatter -> int -> 'a -> 'b -> unit) -> formatter -> 'a list * 'b list -> unit val pp_comma_list: ?pp_prologue:(formatter -> unit -> unit) -> ?pp_epilogue:(formatter -> unit -> unit) -> @@ -52,6 +80,22 @@ module Format: sig ?pp_eol:(formatter -> unit -> unit) -> ?pp_nil:(formatter -> unit -> unit) -> (formatter -> 'a -> unit) -> formatter -> 'a list -> unit + val pp_print_braced: + ?pp_sep:(formatter -> unit -> unit) -> + ?pp_prologue:(formatter -> unit -> unit) -> + ?pp_epilogue:(formatter -> unit -> unit) -> + ?pp_open_box:(formatter -> unit -> unit) -> + ?pp_eol:(formatter -> unit -> unit) -> + ?pp_nil:(formatter -> unit -> unit) -> + (formatter -> 'a -> unit) -> formatter -> 'a list -> unit + val pp_print_braced': + ?pp_sep:(formatter -> unit -> unit) -> + ?pp_prologue:(formatter -> unit -> unit) -> + ?pp_epilogue:(formatter -> unit -> unit) -> + ?pp_open_box:(formatter -> unit -> unit) -> + ?pp_eol:(formatter -> unit -> unit) -> + ?pp_nil:(formatter -> unit -> unit) -> + (formatter -> 'a -> unit) -> formatter -> 'a list -> unit end module IdentDepGraph: Graph.Sig.I with type V.t = ident @@ -59,6 +103,18 @@ module TopologicalDepGraph: sig val fold : (ident -> 'a -> 'a) -> IdentDepGraph.t -> 'a -> 'a val iter : (ident -> unit) -> IdentDepGraph.t -> unit end +module Bfs: sig + (* val iter : (ident -> unit) -> IdentDepGraph.t -> unit *) + val iter_component : (ident -> unit) -> IdentDepGraph.t -> ident -> unit + + (* val fold : (G.V.t -> 'a -> 'a) -> 'a -> G.t -> 'a + * val fold_component : (G.V.t -> 'a -> 'a) -> 'a -> G.t -> G.V.t -> 'a + * + * type iterator + * val start : G.t -> iterator + * val step : iterator -> iterator + * val get : iterator -> G.V.t *) +end val name_of_dimension: tag -> ident @@ -91,3 +147,7 @@ val repeat: int -> ('a -> 'a) -> 'a -> 'a val add_cons: 'a -> 'a list -> 'a list val enumerate: int -> int list + +val duplicate: 'a -> int -> 'a list + +val list_union: 'a list -> 'a list -> 'a list diff --git a/src/verifierList.mli b/src/verifierList.mli index e69de29b..483bc7b1 100644 --- a/src/verifierList.mli +++ b/src/verifierList.mli @@ -0,0 +1 @@ +val verifiers: unit -> (module VerifierType.S) list -- GitLab