Project

General

Profile

« Previous | Next » 

Revision 09d7b39f

Added by Guillaume DAVY about 4 years ago

Ada: Add generation of step calls and refactor prototypes and ads printing to handle staless
instance.

View differences:

src/backends/Ada/ada_backend.ml
72 72
  fprintf fmt "%a.gpr" pp_package_name main_machine
73 73

  
74 74

  
75
let get_typed_instances machines m =
76
  let submachines = List.map (get_machine machines) m.minstances in
75
let get_typed_submachines machines m =
76
  let instances = List.filter (fun (id, _) -> not (is_builtin_fun id)) m.mcalls in
77
  let submachines = List.map (get_machine machines) instances in
77 78
  List.map2
78 79
    (fun instance submachine ->
79 80
      let ident = (fst instance) in
80 81
      ident, (get_substitution m ident submachine, submachine))
81
    m.minstances submachines
82
    instances submachines
82 83

  
83 84
(** Main function of the Ada backend. It calls all the subfunction creating all
84 85
the file and fill them with Ada code representing the machines list given.
......
92 93
  let module Adb = Ada_backend_adb.Main in
93 94
  let module Wrapper = Ada_backend_wrapper.Main in
94 95

  
95
  let typed_instances_machines =
96
    List.map (get_typed_instances machines) machines in
96
  let typed_submachines =
97
    List.map (get_typed_submachines machines) machines in
97 98

  
98
  let _machines = List.combine typed_instances_machines machines in
99
  let _machines = List.combine typed_submachines machines in
99 100

  
100
  let _pp_filename ext fmt (typed_instances, machine) =
101
  let _pp_filename ext fmt (typed_submachines, machine) =
101 102
    pp_machine_filename ext fmt machine in
102 103

  
103 104
  (* Extract the main machine if there is one *)
src/backends/Ada/ada_backend_adb.ml
50 50
     @param machine a machine
51 51
     @return the instance of machine.minstances corresponding to identifier
52 52
  **)
53
  let get_instance identifier typed_instances =
53
  let get_instance identifier typed_submachines =
54 54
    try
55
      List.assoc identifier typed_instances
55
      List.assoc identifier typed_submachines
56 56
    with Not_found -> assert false
57 57

  
58
  (** Printing the reset function. call
58
  (** Printing a call to a package function
59 59

  
60
      @param typed_instances list of all typed machine instances of this machine
61
      @param machine the current machine
62
      @param instance the considered instance
60
      @param typed_submachines list of all typed machine instances of this machine
61
      @param pp_name printer for the function name
63 62
      @param fmt the formater to use
63
      @param identifier the instance identifier
64
      @param pp_args_opt optional printer for other arguments
64 65
   **)
65
  let pp_machine_reset typed_instances (machine: machine_t) fmt identifier =
66
    let (substitution, submachine) = get_instance identifier typed_instances in
67
    fprintf fmt "%a.%t(%t.%s)"
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@])"
68 81
      (pp_package_name_with_polymorphic substitution) submachine
69
      pp_reset_procedure_name
70
      pp_state_name
71
      identifier
82
      pp_name
83
      pp_state
84
      pp_opt pp_args_opt
72 85

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

  
77
      @param typed_instances list of all typed machine instances of this machine
90
      @param typed_submachines list of all typed machine instances of this machine
78 91
      @param machine the current machine
79 92
      @param fmt the formater to print on
80 93
      @param instr the instruction to print
81 94
   **)
82
  let pp_machine_instr typed_instances machine fmt instr =
95
  let pp_machine_instr typed_submachines machine fmt instr =
83 96
    match get_instr_desc instr with
84 97
      (* no reset *)
85 98
      | MNoReset _ -> ()
86 99
      (* reset  *)
87
      | MReset ident ->
88
          pp_machine_reset typed_instances machine fmt ident
100
      | MReset i ->
101
          pp_package_call typed_submachines pp_reset_procedure_name fmt (i, None)
89 102
      | MLocalAssign (ident, value) ->
90 103
          pp_basic_assign machine fmt ident value
91 104
      | MStateAssign (ident, value) ->
92 105
          pp_basic_assign machine fmt ident value
93
      | MStep ([i0], i, vl) when Basic_library.is_internal_fun i
94
                                   (List.map (fun v -> v.value_type) vl) ->
106
      | MStep ([i0], i, vl) when is_builtin_fun i ->
95 107
          let value = mk_val (Fun (i, vl)) i0.var_type in
96 108
          pp_basic_assign machine fmt i0 value
97
      | MStep (il, i, vl) -> fprintf fmt "Null"
98
      (* pp_basic_instance_call m self fmt i vl il *)
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)
99 116
      | MBranch (_, []) -> fprintf fmt "Null"
100 117

  
101 118
      (* (Format.eprintf "internal error: C_backend_src.pp_machine_instr %a@." (pp_instr m) instr; assert false) *)
......
114 131
      | MComment s  ->
115 132
        let lines = String.split_on_char '\n' s in
116 133
        fprintf fmt "%a" (Utils.fprintf_list ~sep:"" pp_oneline_comment) lines
134
      | _ -> assert false
117 135

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

  
120
   @param typed_instances list of all typed machine instances of this machine
138
   @param typed_submachines list of all typed machine instances of this machine
121 139
   @param fmt the formater to print on
122 140
   @param machine the machine
123 141
**)
124
let pp_step_definition typed_instances fmt m = pp_procedure_definition
142
let pp_step_definition typed_submachines fmt m = pp_procedure_definition
125 143
      pp_step_procedure_name
126 144
      (pp_step_prototype m)
127 145
      (pp_machine_var_decl NoMode)
128
      (pp_machine_instr typed_instances m)
146
      (pp_machine_instr typed_submachines m)
129 147
      fmt
130 148
      (m.mstep.step_locals, m.mstep.step_instrs)
131 149

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

  
134
   @param typed_instances list of all typed machine instances of this machine
152
   @param typed_submachines list of all typed machine instances of this machine
135 153
   @param fmt the formater to print on
136 154
   @param machine the machine
137 155
**)
138
let pp_reset_definition typed_instances fmt m = pp_procedure_definition
156
let pp_reset_definition typed_submachines fmt m = pp_procedure_definition
139 157
      pp_reset_procedure_name
140 158
      (pp_reset_prototype m)
141 159
      (pp_machine_var_decl NoMode)
142
      (pp_machine_instr typed_instances m)
160
      (pp_machine_instr typed_submachines m)
143 161
      fmt
144 162
      ([], m.minit)
145 163

  
......
150 168
  the machine associated to the instance and substitution the instanciation of
151 169
  all its polymorphic types.
152 170
   @param fmt the formater to print on
153
   @param typed_instances list of all typed machine instances of this machine
171
   @param typed_submachines list of all typed machine instances of this machine
154 172
   @param m the machine
155 173
**)
156
let pp_file fmt (typed_instances, machine) =
157
  fprintf fmt "%a@,  @[<v>@,%a;@,@,%a;@,@]@,%a;@."
158
    (pp_begin_package true) machine (*Begin the package*)
159
    (pp_reset_definition typed_instances) machine (*Define the reset procedure*)
160
    (pp_step_definition typed_instances) machine (*Define the step procedure*)
161
    pp_end_package machine  (*End the package*)
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
162 208

  
163 209
end
164 210

  
src/backends/Ada/ada_backend_ads.ml
38 38
   @param typed_instances list typed instances
39 39
**)
40 40
let pp_state_record_definition fmt (var_list, typed_instances) =
41
  fprintf fmt "@,  @[<v>record@,  @[<v>%a%t%a%t@]@,end record@]"
41
  fprintf fmt "@,  @[<v>record@,  @[<v>%a%t%t%a%t@]@,end record@]"
42 42
    (Utils.fprintf_list ~sep:";@;" pp_machine_subinstance_state_decl)
43 43
    typed_instances
44
    (Utils.pp_final_char_if_non_empty ";@," typed_instances)
44
    (Utils.pp_final_char_if_non_empty ";" typed_instances)
45
    (fun fmt -> if var_list!=[] && typed_instances!= [] then fprintf fmt "@,@," else fprintf fmt "")
45 46
    (Utils.fprintf_list ~sep:";@;" (pp_machine_var_decl NoMode))
46 47
    var_list
47 48
    (Utils.pp_final_char_if_non_empty ";" var_list)
......
139 140

  
140 141
(** Print the package declaration(ads) of a machine.
141 142
  It requires the list of all typed instance.
142
  A typed submachine instance is (ident, type_machine) with ident
143
  the instance name and typed_machine is (substitution, machine) with machine
144
  the machine associated to the instance and substitution the instanciation of
145
  all its polymorphic types.
143
  A typed submachine is a (ident, typed_machine) with
144
    - ident: the name 
145
    - typed_machine: a (substitution, machine) with
146
      - machine: the submachine struct
147
      - substitution the instanciation of all its polymorphic types.
146 148
   @param fmt the formater to print on
147
   @param typed_instances list of all typed machine instances of this machine
149
   @param typed_submachines list of all typed submachines of this machine
148 150
   @param m the machine
149 151
**)
150
let pp_file fmt (typed_instances, m) =
151
  let typed_machines = snd (List.split typed_instances) in
152
let pp_file fmt (typed_submachines, m) =
153
  let typed_machines = snd (List.split typed_submachines) in
152 154
  let typed_machines_set = remove_duplicates eq_typed_machine typed_machines in
153 155
  
154 156
  let machines_to_import = snd (List.split typed_machines_set) in
......
157 159
  
158 160
  let typed_machines_to_instanciate =
159 161
    List.filter (fun (l, _) -> l != []) typed_machines_set in
162

  
163
  let typed_instances = List.filter is_submachine_statefull typed_submachines in
160 164
  
161 165
  let pp_record fmt =
162 166
    pp_state_record_definition fmt (m.mmemory, typed_instances) in
167

  
168
  let pp_state_decl_and_reset fmt = fprintf fmt "%a;@,@,%t;@,@,"
169
    (*Declare the state type*)
170
    pp_private_limited_type_decl pp_state_type
171
    (*Declare the reset procedure*)
172
    (pp_reset_prototype m)
173
  in
174

  
175
  let pp_private_section fmt = fprintf fmt "@,private@,@,%a%t%a;@,"
176
    (*Instantiate the polymorphic type that need to be instantiated*)
177
    (Utils.fprintf_list ~sep:";@," pp_new_package) typed_machines_to_instanciate
178
    (Utils.pp_final_char_if_non_empty ";@,@," typed_machines_to_instanciate)
179
    (*Define the state type*)
180
    pp_type_decl (pp_state_type, pp_record)
181
  in
163 182
  
183
  let pp_ifstatefull fmt pp =
184
    if is_machine_statefull m then
185
      fprintf fmt "%t" pp
186
    else
187
      fprintf fmt ""
188
  in
164 189
  
165
  fprintf fmt "@[<v>%a%t%a%a@,  @[<v>@,%a;@,@,%t;@,@,%a;@,@,private@,@,%a%t%a;@,@]@,%a;@.@]"
190
  fprintf fmt "@[<v>%a%t%a%a@,  @[<v>@,%a%a;@,%a@]@,%a;@.@]"
166 191
    
167
    (* Include all the subinstance*)
192
    (* Include all the subinstance package*)
168 193
    (Utils.fprintf_list ~sep:";@," pp_with_machine) machines_to_import
169 194
    (Utils.pp_final_char_if_non_empty ";@,@," machines_to_import)
170 195
    
......
172 197
    
173 198
    (*Begin the package*)
174 199
    (pp_begin_package false) m
175
    
176
    (*Declare the state type*)
177
    pp_private_limited_type_decl pp_state_type
178
    
179
    (*Declare the reset procedure*)
180
    (pp_reset_prototype m)
200

  
201
    pp_ifstatefull pp_state_decl_and_reset
181 202
    
182 203
    (*Declare the step procedure*)
183 204
    pp_step_prototype_contract m
184 205
    
185
    (*Instantiate the polymorphic type that need to be instantiated*)
186
    (Utils.fprintf_list ~sep:";@," pp_new_package) typed_machines_to_instanciate
187
    (Utils.pp_final_char_if_non_empty ";@,@," typed_machines_to_instanciate)
188
    
189
    (*Define the state type*)
190
    pp_type_decl (pp_state_type, pp_record)
206
    (*Print the private section*)
207
    pp_ifstatefull pp_private_section
191 208
    
192 209
    (*End the package*)
193 210
    pp_end_package m
src/backends/Ada/ada_backend_common.ml
8 8
(** Exception for unsupported features in Ada backend **)
9 9
exception Ada_not_supported of string
10 10

  
11
(** All the pretty print functions common to the ada backend **)
11
(** All the pretty print and aux functions common to the ada backend **)
12 12

  
13 13
(* Misc pretty print functions *)
14 14

  
15
let is_machine_statefull m = not m.mname.node_dec_stateless
16

  
17
let ada_supported_funs =
18
  [("sin", ("Ada.Numerics.Elementary_Functions", "Sin"));
19
   ("cos", ("Ada.Numerics.Elementary_Functions", "Cos"));
20
   ("tan", ("Ada.Numerics.Elementary_Functions", "Tan"))]
21

  
22
let is_builtin_fun ident =
23
  List.mem ident Basic_library.internal_funs ||
24
    List.mem_assoc ident ada_supported_funs
15 25

  
16 26
(** Print a cleaned an identifier for ada exportation : Ada names must not start by an
17 27
    underscore and must not contain a double underscore
......
133 143
let pp_private_with fmt pp_pakage_name =
134 144
  fprintf fmt "private with %t" pp_pakage_name
135 145

  
146
(** Print a with statement to include a package.
147
   @param fmt the formater to print on
148
   @param name the package name
149
**)
150
let pp_with fmt name =
151
  fprintf fmt "with %s" name
152

  
136 153
(** Print a with statement to include a machine.
137 154
   @param fmt the formater to print on
138 155
   @param machine the machine
......
411 428
(** Print the prototype of a machine procedure. The first parameter is always
412 429
the state, state_modifier specify the modifier applying to it. The next
413 430
parameters are inputs and the last parameters are the outputs.
414
   @param state_mode the input/output mode for the state parameter
431
   @param state_mode_opt None if no state parameter required and some input/output mode for it else
415 432
   @param input list of the input parameter of the procedure
416 433
   @param output list of the output parameter of the procedure
417 434
   @param fmt the formater to print on
418 435
   @param name the name of the procedure
419 436
**)
420
let pp_base_prototype state_mode input output fmt pp_name =
421
  fprintf fmt "procedure %t(@[<v>%a%t@[%a@]%t@[%a@])@]"
437
let pp_base_prototype state_mode_opt input output fmt pp_name =
438
  let pp_var_decl_state fmt = match state_mode_opt with
439
    | None -> fprintf fmt ""
440
    | Some state_mode -> fprintf fmt "%a" pp_state_var_decl state_mode
441
  in
442
  fprintf fmt "procedure %t(@[<v>%t%t@[%a@]%t@[%a@])@]"
422 443
    pp_name
423
    pp_state_var_decl state_mode
424
    (Utils.pp_final_char_if_non_empty ";@," input)
444
    pp_var_decl_state
445
    (fun fmt -> if state_mode_opt != None && input!=[] then
446
      fprintf fmt ";@," else fprintf fmt "")
425 447
    (Utils.fprintf_list ~sep:";@ " (pp_machine_var_decl In)) input
426
    (Utils.pp_final_char_if_non_empty ";@," output)
448
    (fun fmt -> if (state_mode_opt != None || input!=[]) && output != [] then
449
      fprintf fmt ";@," else fprintf fmt "")
427 450
    (Utils.fprintf_list ~sep:";@ " (pp_machine_var_decl Out)) output
428 451

  
429 452
(** Print the prototype of the step procedure of a machine.
......
432 455
   @param pp_name name function printer
433 456
**)
434 457
let pp_step_prototype m fmt =
435
  pp_base_prototype InOut m.mstep.step_inputs m.mstep.step_outputs fmt pp_step_procedure_name
458
  let state_mode = if is_machine_statefull m then Some InOut else None in
459
  pp_base_prototype state_mode m.mstep.step_inputs m.mstep.step_outputs fmt pp_step_procedure_name
436 460

  
437 461
(** Print the prototype of the reset procedure of a machine.
438 462
   @param m the machine
......
440 464
   @param pp_name name function printer
441 465
**)
442 466
let pp_reset_prototype m fmt =
443
  pp_base_prototype InOut m.mstatic [] fmt pp_reset_procedure_name
467
  let state_mode = if is_machine_statefull m then Some InOut else None in
468
  pp_base_prototype state_mode m.mstatic [] fmt pp_reset_procedure_name
444 469

  
445 470
(** Print the prototype of the init procedure of a machine.
446 471
   @param m the machine
......
448 473
   @param pp_name name function printer
449 474
**)
450 475
let pp_init_prototype m fmt =
451
  pp_base_prototype Out m.mstatic [] fmt pp_init_procedure_name
476
  let state_mode = if is_machine_statefull m then Some Out else None in
477
  pp_base_prototype state_mode m.mstatic [] fmt pp_init_procedure_name
452 478

  
453 479
(** Print the prototype of the clear procedure of a machine.
454 480
   @param m the machine
......
456 482
   @param pp_name name function printer
457 483
**)
458 484
let pp_clear_prototype m fmt =
459
  pp_base_prototype InOut m.mstatic [] fmt pp_clear_procedure_name
485
  let state_mode = if is_machine_statefull m then Some InOut else None in
486
  pp_base_prototype state_mode m.mstatic [] fmt pp_clear_procedure_name
460 487

  
461 488
(** Print a one line comment with the final new line character to avoid
462 489
      commenting anything else.
......
468 495
  fprintf fmt "-- %s@," s
469 496

  
470 497
(* Functions which computes the substitution for polymorphic type *)
498

  
499

  
500
(** Check if a submachine is statefull.
501
    @param submachine a submachine
502
    @return true if the submachine is statefull
503
**)
504
let is_submachine_statefull submachine =
505
    not (snd (snd submachine)).mname.node_dec_stateless
506

  
471 507
(** Find a submachine step call in a list of instructions.
472 508
    @param ident submachine instance ident
473 509
    @param instr_list List of instruction sto search
......
719 755
      Format.fprintf fmt "(%a %s %a)" pp_value v1 "/=" pp_value v2
720 756
    | op, [v1; v2]     ->
721 757
      Format.fprintf fmt "(%a %s %a)" pp_value v1 op pp_value v2
758
    | op, [v1] when  List.mem_assoc ident ada_supported_funs ->
759
      let pkg, name = try List.assoc ident ada_supported_funs
760
        with Not_found -> assert false in
761
      let pkg = pkg^(if String.equal pkg "" then "" else ".") in
762
        Format.fprintf fmt "%s%s(%a)" pkg name pp_value v1
722 763
    | fun_name, _      ->
723 764
      (Format.eprintf "internal compilation error: basic function %s@." fun_name; assert false)
724 765

  

Also available in: Unified diff