package lutin

  1. Overview
  2. Docs

Source file luc2alice.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
(*-----------------------------------------------------------------------
** Copyright (C) - Verimag.
** This file may only be copied under the terms of the CeCill
** Public License
**-----------------------------------------------------------------------
**
** File: luc2c.ml
** Author: erwan.jahier@univ-grenoble-alpes.fr
**
** Generates C files to call Lucky from Alice.
**
*)


(* put all args in one structure  *)
type alice_args = { 
  env_name : string;
  alice_module_name : string ;
  seed : int option;
  env_in_vars : Exp.var list;
  env_out_vars : Exp.var list;
  use_sockets: bool;
  output_dir:string;
}


(********************************************************************)

(* let (cast : Type.t -> string) = function *)
(*   | Type.BoolT -> "(_bool*)" *)
(*   | Type.IntT  -> "(_int*)" *)
(*   | Type.FloatT -> "(_real*)" *)
(*   | Type.UT _ -> assert false *)
(*  *)
(*  *)
(* let (declarer_importeurs : string -> Exp.var list -> string) = *)
(* fun an vars  ->  *)
(*   let make_one_decl var = *)
(*     let vn = Var.name var in *)
(*       ("    DeclarerImporteur(DaxFlags32( Nv3BaseDeModule::cEchangeSync ),\" "^ *)
(*          an^":"^vn^":\", "^(cast (Var.typ var))^"&mCtx->_"^vn^");\n") *)
(*   in *)
(*   let items = List.map make_one_decl vars in *)
(*      "" ^ (String.concat "" items) *)
(*  *)
(* let (declarer_exporteurs : string -> Exp.var list -> string) = *)
(*   fun an vars  ->  *)
(*     let make_one_decl var =  *)
(*       let vn = Var.name var in *)
(*         ("    DeclarerExporteur(DaxFlags32( Nv3BaseDeModule::cEchangeSync ),\" "^ *)
(*            an^":"^vn^":\", "^(cast (Var.typ var))^" &mCtx->_"^vn^");\n") *)
(*     in *)
(*     let items = List.map make_one_decl vars in *)
(*       "" ^ (String.concat "" items) *)
(********************************************************************)


let (lucky_seed : int option -> string) =
  function
    | Some i -> ("lucky_set_seed("^(string_of_int i)^");\n")
    | None -> ""

(********************************************************************)


let (define_output_proc : string -> Exp.var list -> string) =
  fun n vl ->
    let f var =
      let vn = Var.name var in
      let t = Type.to_cstring  (Var.typ var) in
      ("  void  "^n^"_O_"^vn^"("^n^"_ctx* ctx, "^t^" value){ ctx->_"^vn^" = value; };\n")
    in
      (String.concat "" (List.map f vl))


(********************************************************************)
(*
** Variable names and types lists
*)

let soi = string_of_int

let (to_char: Type.t -> string) =
  function
  | Type.BoolT -> "_bool_type_char"
  | Type.IntT  -> "_int_type_char"
  | Type.FloatT -> "_real_type_char"
  | Type.UT _ -> assert false

let (gen_alice_var_tab : string -> string -> Exp.var list -> string) =
  fun _alice_name name vl ->
    let n = List.length vl in

    let f (i,acc) var = i+1,acc ^
      "  "^name^".tab[" ^ (soi i) ^ "].var_name = \"" ^ (Var.name var) ^ "\";\n" ^
      "  "^name^".tab[" ^ (soi i) ^ "].var_type = " ^ (to_char(Var.typ var)) ^ ";\n" ^
      "  "^name^".tab[" ^ (soi i) ^ "].var_adrs = &(mCtx->_" ^ (Var.name var)^ ");\n"
    in
      ("
  "^name^".size="^(soi n)^";
  "^name^".tab = new var_info["^(soi n)^"];\n" ^
         (snd (List.fold_left f (0,"") vl))) 


(********************************************************************)


let (gen_alice_stub : alice_args -> string) =
  fun args -> 
    let alice_full_name = args.alice_module_name 
    and alice_name = Filename.basename args.alice_module_name 
    and fn = args.env_name 
    and in_vars  = args.env_in_vars
    and out_vars = args.env_out_vars
    in

("
#include \""^alice_full_name^".h\"
#include \"float.h\"
#include \"Ims/ImsMessageStack.h\"

#ifdef _DEBUG
#define dbg(...) fprintf(fp, __VA_ARGS__); fflush(fp)
#else
#define dbg(...)  while(0)
#endif

int "^alice_name^"::instance_cpt=0;
structTab "^alice_name^"::inputs;
structTab "^alice_name^"::outputs;
structTab "^alice_name^"::memories;


/*  Build an instance of the Class "^alice_name^" */
"^alice_name^"::"^alice_name^"()
{  
  try 
    {
#ifdef _DEBUG
       fp = fopen(\""^fn^"-"^alice_name^".log\", \"w\");
#endif
       dbg(\"%s\\n\", \"--> "^alice_name^"\");

       instance_nb = instance_cpt++;
       mCtx = "^fn^"_new_ctx((void *) instance_nb);

      dbg(\"%s\\n\", \"<--  "^alice_name^"\");

    }
  catch (ImsMessageStack& xMessageStack)
    {
      xMessageStack.InsertErrorMessage(\"2\", \"Err\", cImsFatal, IMS_DEBUG_INFO("^
   alice_name^":Initialisation))
	<< \" Erreur lors de l'initialisation du contexte de "^fn^"\";
      throw xMessageStack;
    }

 // Inputs"
 ^ (gen_alice_var_tab alice_name "inputs" in_vars)  ^
"
   // Outputs"
 ^ (gen_alice_var_tab alice_name "outputs" out_vars) ^
"
   // Memories"
 ^ (gen_alice_var_tab alice_name "memories" []) ^
"
}

/* Remove an instance of the Class "^alice_name^" */
"^alice_name^"::~"^alice_name^"()
{
  "^fn^"_terminate(mCtx);
  delete[] inputs.tab;
  delete[] outputs.tab;
  delete[] memories.tab;
#ifdef _DEBUG
  fclose(fp);
#endif

}

/* Get a new object (for dynamic libs) */
"^alice_name^"* "^alice_name^"::Factory () 
{ 
  return new "^alice_name^"();
}

/* Initialisation */
void "^alice_name^"::Initialisation()
{
  //"^fn^"_reset_ctx(mCtx);" ^ (lucky_seed args.seed) ^ "
}

/* Step */
void "^alice_name^"::Process()
{
  dbg(\"%s\\n\", \"--> Process\");
  "^fn^"_step(mCtx" ^ (if args.use_sockets then "" else ", step_inside")^");
  dbg(\"%s\\n\", \"<-- Process\");
}

/* Terminate */
void "^alice_name^"::Terminate()
{
  "^fn^"_terminate(mCtx);
  // pourquoi ne pas faire 'delete toto' plutot que 'toto.Terminate()' ? 
  // Quand est appelé cette méthode finalement ?
}

/* Returns the Lucky input vars */
structTab* "^alice_name^"::Inputs() {
   { return  &inputs;};
}

/* Returns the Lucky output vars */
structTab* "^alice_name^"::Outputs() {
  { return  &outputs;};
}

/* Returns the Lucky output memories */
structTab* "^alice_name^"::Memories() {
   { return  &memories;};
}


")

let my_open_out fn =
  prerr_string ("Generating file " ^ fn ^ "\n"); 
  open_out fn 

let (gen_alice_stub_c : alice_args -> unit) =
  fun args -> 
    let amn = Filename.basename args.alice_module_name in
    let oc = my_open_out (Filename.concat args.output_dir (amn ^ ".cpp")) in
    let putln s = output_string oc (s^"\n") in
    putln (Util.entete "// " "");
    putln (gen_alice_stub args)


let (gen_alice_stub_h : alice_args -> unit) =
  fun args -> 
    let amn = Filename.basename args.alice_module_name in
    let oc = my_open_out (Filename.concat args.output_dir (amn ^ ".h")) in
    let amn = Filename.basename args.alice_module_name in
    let putln s = output_string oc (s^"\n") in
    let fn = args.env_name in
      putln (Util.entete "// " "");
      putln ("

#include \"AlicesCommon.h\"

#ifdef BUILD_"^amn^"
    #define "^amn^"_interface LINKER_EXPORTED
#else // BUILD_"^amn^"
    #define "^amn^"_interface LINKER_IMPORTED
#endif // BUILD_"^amn^"


#include \""^fn^".h\"

class "^amn^"_interface "^amn^";

#ifndef _real_type_char
#define _real_type_char 'd'
#endif
#ifndef _int_type_char
#define _int_type_char 'i'
#endif
#ifndef _bool_type_char
#define _bool_type_char 'b'
#endif

struct var_info {
  const char *var_name;
  char  var_type;
  void *var_adrs;
};

struct structTab {
  int size;
  var_info* tab;
};


class "^amn^"_interface "^amn^" {

  _"^fn^"_ctx * mCtx;
  static structTab inputs;
  static structTab outputs;
  static structTab memories;
  static int instance_cpt; 
  int instance_nb;

 public :      

  "^amn^"();
  ~"^amn^"();
  static "^amn^"*  Factory();
  void Initialisation();
  void Process();
  void	Terminate()   ;
  structTab* Inputs();
  structTab* Outputs();
  structTab* Memories();
};
")