Project

General

Profile

Download (7.9 KB) Statistics
| Branch: | Tag: | Revision:
1
(********************************************************************)
2
(*                                                                  *)
3
(*  The LustreC compiler toolset   /  The LustreC Development Team  *)
4
(*  Copyright 2012 -    --   ONERA - CNRS - INPT - ISAE-SUPAERO     *)
5
(*                                                                  *)
6
(*  LustreC is free software, distributed WITHOUT ANY WARRANTY      *)
7
(*  under the terms of the GNU Lesser General Public License        *)
8
(*  version 2.1.                                                    *)
9
(*                                                                  *)
10
(********************************************************************)
11

    
12
open Format
13

    
14
open Machine_code_types
15
open Lustre_types
16
open Corelang
17
open Machine_code_common
18
open Ada_backend_common
19

    
20
(** Main module for generating packages bodies
21
 **)
22
module Main =
23
struct
24

    
25
  (** Printing function for basic assignement [var_name := value;].
26

    
27
      @param fmt the formater to print on
28
      @param var_name the name of the variable
29
      @param value the value to be assigned
30
   **)
31
  let pp_basic_assign m fmt var_name value =
32
    fprintf fmt "%a := %a"
33
      (pp_access_var m) var_name
34
      (pp_value m) value
35

    
36
  (** Printing function for assignement. For the moment, only use
37
      [pp_basic_assign] function.
38

    
39
      @param pp_var pretty printer for variables
40
      @param fmt the formater to print on
41
      @param var_name the name of the variable
42
      @param value the value to be assigned
43
   **)
44
  let pp_assign m pp_var fmt var_name value = pp_basic_assign m
45

    
46
  (** Extract from a machine the instance corresponding to the identifier,
47
        assume that the identifier exists in the instances of the machine.
48

    
49
     @param identifier the instance identifier
50
     @param machine a machine
51
     @return the instance of machine.minstances corresponding to identifier
52
  **)
53
  let get_instance identifier typed_submachines =
54
    try
55
      List.assoc identifier typed_submachines
56
    with Not_found -> assert false
57

    
58
  (** Printing a call to a package function
59

    
60
      @param typed_submachines list of all typed machine instances of this machine
61
      @param pp_name printer for the function name
62
      @param fmt the formater to use
63
      @param identifier the instance identifier
64
      @param pp_args_opt optional printer for other arguments
65
   **)
66
  let pp_package_call typed_submachines pp_name fmt (identifier, pp_args_opt) =
67
    let (substitution, submachine) = get_instance identifier typed_submachines in
68
    let statefull = is_machine_statefull submachine in
69
    let pp_opt fmt = function
70
        | Some pp_args when statefull -> fprintf fmt ",@,%t" pp_args
71
        | Some pp_args -> pp_args fmt
72
        | None -> fprintf fmt ""
73
    in
74
    let pp_state fmt =
75
      if statefull then
76
        fprintf fmt "%t.%s" pp_state_name identifier
77
      else
78
        fprintf fmt ""
79
    in
80
    fprintf fmt "%a.%t(@[<v>%t%a@])"
81
      (pp_package_name_with_polymorphic substitution) submachine
82
      pp_name
83
      pp_state
84
      pp_opt pp_args_opt
85

    
86
  (** Printing function for instruction. See
87
      {!type:Machine_code_types.instr_t} for more details on
88
      machine types.
89

    
90
      @param typed_submachines list of all typed machine instances of this machine
91
      @param machine the current machine
92
      @param fmt the formater to print on
93
      @param instr the instruction to print
94
   **)
95
  let pp_machine_instr typed_submachines machine fmt instr =
96
    match get_instr_desc instr with
97
      (* no reset *)
98
      | MNoReset _ -> ()
99
      (* reset  *)
100
      | MReset i ->
101
          pp_package_call typed_submachines pp_reset_procedure_name fmt (i, None)
102
      | MLocalAssign (ident, value) ->
103
          pp_basic_assign machine fmt ident value
104
      | MStateAssign (ident, value) ->
105
          pp_basic_assign machine fmt ident value
106
      | MStep ([i0], i, vl) when is_builtin_fun i ->
107
          let value = mk_val (Fun (i, vl)) i0.var_type in
108
          pp_basic_assign machine fmt i0 value
109
      | MStep (il, i, vl) when List.mem_assoc i typed_submachines ->
110
        let pp_args fmt = fprintf fmt "@[%a@]%t@[%a@]"
111
          (Utils.fprintf_list ~sep:",@ " (pp_value machine)) vl
112
          (Utils.pp_final_char_if_non_empty ",@," il)
113
          (Utils.fprintf_list ~sep:",@ " (pp_access_var machine)) il
114
        in
115
        pp_package_call typed_submachines pp_step_procedure_name fmt (i, Some pp_args)
116
      | MBranch (_, []) -> fprintf fmt "Null"
117

    
118
      (* (Format.eprintf "internal error: C_backend_src.pp_machine_instr %a@." (pp_instr m) instr; assert false) *)
119
      | MBranch (g, hl) -> fprintf fmt "Null"
120
      (* if let t = fst (List.hd hl) in t = tag_true || t = tag_false
121
       * then (\* boolean case, needs special treatment in C because truth value is not unique *\)
122
       *   (\* may disappear if we optimize code by replacing last branch test with default *\)
123
       *   let tl = try List.assoc tag_true  hl with Not_found -> [] in
124
       *   let el = try List.assoc tag_false hl with Not_found -> [] in
125
       *   pp_conditional dependencies m self fmt g tl el
126
       * else (\* enum type case *\)
127
       *   (\*let g_typ = Typing.type_const Location.dummy_loc (Const_tag (fst (List.hd hl))) in*\)
128
       *   fprintf fmt "@[<v 2>switch(%a) {@,%a@,}@]"
129
       *     (pp_c_val m self (pp_c_var_read m)) g
130
       *     (Utils.fprintf_list ~sep:"@," (pp_machine_branch dependencies m self)) hl *)
131
      | MComment s  ->
132
        let lines = String.split_on_char '\n' s in
133
        fprintf fmt "%a" (Utils.fprintf_list ~sep:"" pp_oneline_comment) lines
134
      | _ -> assert false
135

    
136
(** Print the definition of the step procedure from a machine.
137

    
138
   @param typed_submachines list of all typed machine instances of this machine
139
   @param fmt the formater to print on
140
   @param machine the machine
141
**)
142
let pp_step_definition typed_submachines fmt m = pp_procedure_definition
143
      pp_step_procedure_name
144
      (pp_step_prototype m)
145
      (pp_machine_var_decl NoMode)
146
      (pp_machine_instr typed_submachines m)
147
      fmt
148
      (m.mstep.step_locals, m.mstep.step_instrs)
149

    
150
(** Print the definition of the reset procedure from a machine.
151

    
152
   @param typed_submachines list of all typed machine instances of this machine
153
   @param fmt the formater to print on
154
   @param machine the machine
155
**)
156
let pp_reset_definition typed_submachines fmt m = pp_procedure_definition
157
      pp_reset_procedure_name
158
      (pp_reset_prototype m)
159
      (pp_machine_var_decl NoMode)
160
      (pp_machine_instr typed_submachines m)
161
      fmt
162
      ([], m.minit)
163

    
164
(** Print the package definition(ads) of a machine.
165
  It requires the list of all typed instance.
166
  A typed submachine instance is (ident, type_machine) with ident
167
  the instance name and typed_machine is (substitution, machine) with machine
168
  the machine associated to the instance and substitution the instanciation of
169
  all its polymorphic types.
170
   @param fmt the formater to print on
171
   @param typed_submachines list of all typed machine instances of this machine
172
   @param m the machine
173
**)
174
let pp_file fmt (typed_submachines, machine) =
175
  let pp_reset fmt =
176
    if is_machine_statefull machine then
177
      fprintf fmt "%a;@,@," (pp_reset_definition typed_submachines) machine
178
    else
179
      fprintf fmt ""
180
  in
181
  let aux pkgs (id, _) =
182
    try
183
      let (pkg, _) = List.assoc id ada_supported_funs in
184
      if List.mem pkg pkgs then
185
        pkgs
186
      else
187
        pkg::pkgs
188
    with Not_found -> pkgs
189
  in
190
  let packages = List.fold_left aux [] machine.mcalls in
191
  fprintf fmt "%a%t%a@,  @[<v>@,%t%a;@,@]@,%a;@."
192
    
193
    (* Include all the required packages*)
194
    (Utils.fprintf_list ~sep:";@," pp_with) packages
195
    (Utils.pp_final_char_if_non_empty ";@,@," packages)
196
    
197
    (*Begin the package*)
198
    (pp_begin_package true) machine
199
    
200
    (*Define the reset procedure*)
201
    pp_reset
202
    
203
    (*Define the step procedure*)
204
    (pp_step_definition typed_submachines) machine
205
    
206
    (*End the package*)
207
    pp_end_package machine
208

    
209
end
210

    
211
(* Local Variables: *)
212
(* compile-command: "make -C ../../.." *)
213
(* End: *)
(3-3/6)