Source file soc2cStack.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
open Soc2cUtil
open Soc2cIdent
open Soc
let (mem_interface_out : Soc.t -> string -> bool) =
fun soc id ->
let _,outs = soc.profile in
List.mem_assoc id outs
let (not_an_array : Data.t -> bool) = function
| Data.Array(_,_) -> false | _ -> true
let (ve_not_an_array : Soc.var_expr -> bool) =
fun v ->
match v with
| Var(_,t)
| Const(_,t)
| Field(_,_,t)
| Index(_,_,t) -> not_an_array t
| Slice(_,_,_,_,_,_) -> false
let (ve_not_a_field : Soc.var_expr -> bool) =
fun v ->
match v with
| Var(_,_)
| Const(_,_)
| Index(_,_,_)
| Slice(_,_,_,_,_,_) -> true
| Field(_,_,_t) -> false
let rec (is_soc_output : Soc.var_expr -> Soc.t -> bool) =
fun v soc ->
match v with
| Var(n,t) -> List.mem (n,t) (snd soc.profile)
| Const(_) -> false
| Index(ve,_,_t)
| Field(ve,_,_t)
| Slice(ve,_,_,_,_,_t) -> is_soc_output ve soc
let (is_soc_output_and_not_a_struct : Soc.var_expr -> Soc.t -> bool) =
fun v soc ->
match v with
| Var(n,t) -> List.mem (n,t) (snd soc.profile)
| Const(_) -> false
| Index(_ve,_,_t)
| Field(_ve,_,_t)
| Slice(_ve,_,_,_,_,_t) -> false
let rec (string_of_var_expr: Soc.t -> Soc.var_expr -> string) =
fun soc var -> match var with
| Const("true", _) -> "_true"
| Const("false", _) -> "_false"
| Const(id, _) -> id2s id
| Var ("_memory",_) -> "ctx->_memory"
| Var (id,_t) -> id2s id
| Field(f, id,_) ->
if is_soc_output_and_not_a_struct f soc
then Printf.sprintf "%s->%s" (string_of_var_expr soc f) (id2s id)
else Printf.sprintf "%s.%s" (string_of_var_expr soc f) (id2s id)
| Index(f, index,_) -> Printf.sprintf "%s[%i]" (string_of_var_expr soc f) index
| Slice(_f,_fi,_la,_st,_wi,_vt) -> assert false
let rec (gen_assign : Data.t -> string -> string -> string) =
fun t vi vo ->
let t_str = Soc2cUtil.data_type_to_c t "" in
match t with
| Data.Alias(_,t) -> gen_assign t vi vo
| Data.Enum _
| Data.Struct(_)
| Data.Bool | Data.Int | Data.Real -> Printf.sprintf " %s = %s;\n" vi vo
| Data.Alpha(_)
| Data.String
| Data.Array(_) ->
let t_str_short = Soc2cIdent.type_to_short_string t in
Printf.sprintf " _assign_%s(%s, %s, sizeof(%s));\n" t_str_short vi vo t_str
| Data.Extern (id) ->
Printf.sprintf " _assign_%s(%s, %s, sizeof(%s));\n" (id2s id) vi vo t_str
let (gen_assign_var_expr : Soc.t -> Soc.var_expr -> Soc.var_expr -> string) =
fun soc vo vi ->
match vo,vi with
| Slice _, _ | _, Slice _ -> assert false
| _,_ ->
let left = string_of_var_expr soc vo in
let left = if is_soc_output_and_not_a_struct vo soc && ve_not_an_array vo && ve_not_a_field vo
then "*"^left else left
in
let vi_str = string_of_var_expr soc vi in
let vi_str =
if is_soc_output_and_not_a_struct vi soc && ve_not_an_array vi then "*"^vi_str else vi_str
in
gen_assign (Soc.data_type_of_var_expr vo) left vi_str
let (step_name : Soc.key -> string -> string) =
fun sk sm ->
let str = Printf.sprintf "%s_%s" (Soc2cIdent.get_soc_name sk) sm in
(id2s str)
let (ctx_var : var_kind -> Soc.t -> Lv6Id.t -> string) =
fun _opt soc id ->
if mem_interface_out soc id then
Printf.sprintf "*%s" (id2s id)
else
Printf.sprintf "%s" (id2s id)
let (list_split : 'a list -> int -> 'a list * 'a list) =
fun l s ->
let rec aux s l acc =
match s,l with
| 0, _ -> List.rev acc,l
| _, x::l -> aux (s-1) l (x::acc)
| _, [] -> assert false
in
aux s l []
let _ = assert (list_split [1;2;3;4;5;6] 3 = ([1;2;3],[4;5;6]))
let (inline_soc: Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list ->
string option) =
fun soc called_soc vel_out vel_in ->
let called_soc_name,_,_ = called_soc.key in
match called_soc_name with
| "Lustre::if" ->
let c,vel_in= match vel_in with [] -> assert false | c::l -> c,l in
let s = (List.length vel_out) in
let vel_in_t, vel_in_e = list_split vel_in s in
let lt = List.map2 (gen_assign_var_expr soc) vel_out vel_in_t in
let le = List.map2 (gen_assign_var_expr soc) vel_out vel_in_e in
let ptr_indir = if is_soc_output_and_not_a_struct c soc then "*" else "" in
let str = " if ("^ ptr_indir^string_of_var_expr soc c ^" == _true) {\n "^
(String.concat " " lt)^ " } else {\n "^
(String.concat " " le)^ " }\n"
in
Some str
| _ ->
try
if
Lv6MainArgs.global_opt.Lv6MainArgs.gen_c_inline_predef
&& Soc2cPredef.is_call_supported called_soc.key
then
let vel_in_str = List.map (string_of_var_expr soc) vel_in in
let vel_in = List.map2
(fun v s -> if is_soc_output_and_not_a_struct v soc && ve_not_an_array v
then "*"^s else s) vel_in vel_in_str
in
let vel_out_str = List.map (string_of_var_expr soc) vel_out in
let vel_out = List.map2
(fun v s -> if is_soc_output_and_not_a_struct v soc && ve_not_an_array v
then "*"^s else s) vel_out vel_out_str
in
Some (Soc2cPredef.gen_call called_soc.key soc vel_out vel_in)
else
None
with Not_found ->
None
let (inlined_soc : Soc.key -> bool) =
fun key ->
let soc_name,_,_ = key in
soc_name = "Lustre::if" || Soc2cPredef.is_call_supported key
let (gen_step_call : Soc.t -> Soc.t -> Soc.var_expr list -> Soc.var_expr list ->
string -> string -> string -> string) =
fun soc called_soc vel_out vel_in _ctx sname step_arg ->
match inline_soc soc called_soc vel_out vel_in with
| Some str -> str
| None ->
let vel_in_str = List.map (string_of_var_expr soc) vel_in in
let vel_in =
List.map2 (fun v s -> if is_soc_output_and_not_a_struct v soc && ve_not_an_array v
then "*"^s else s) vel_in vel_in_str
in
let vel_out_str = List.map (string_of_var_expr soc) vel_out in
let vel_out =
List.map2
(fun v s ->
if (not (is_soc_output_and_not_a_struct v soc) && ve_not_an_array v )
then "&"^s
else s)
vel_out vel_out_str
in
let step_arg = if step_arg = "" then [] else [step_arg] in
let step_arg = String.concat "," (vel_in@vel_out@step_arg) in
let str = Printf.sprintf " %s(%s); \n" (step_name called_soc.key sname) step_arg in
str
let (typedef_of_soc : Soc.t -> string) =
fun soc ->
if inlined_soc soc.key then "" else
if SocUtils.is_memory_less soc then "" else
let ctx_name = get_ctx_name soc.key in
let ctx_name_type = ctx_name^"_type" in
let str = Printf.sprintf "/* %s */\ntypedef struct {\n" ctx_name in
let str = str ^
(match soc.memory with
| No_mem -> ""
| Mem t -> Printf.sprintf " /*Memory cell*/\n %s ;\n"
(id2s (Soc2cUtil.data_type_to_c t "_memory"))
| Mem_hidden -> ""
)
in
let str = str ^ (if soc.instances <> [] then " /*INSTANCES*/\n" else "") in
let il, _get_index = Soc2cInstances.to_array soc.instances in
let string_of_instance (sk,i) =
let n = get_ctx_name sk in
Printf.sprintf " %s_type %s_tab[%d];\n" n n i
in
let str = List.fold_left (fun acc inst -> acc^(string_of_instance inst)) str il in
let str = Printf.sprintf "%s} %s;\n\n" str ctx_name_type in
str
let (get_step_prototype : Soc.step_method -> Soc.t -> string * string * string) =
fun sm soc ->
let sname = step_name soc.key sm.name in
let inputs, outputs = soc.Soc.profile in
let inputs = SocUtils.filter_step_params sm.Soc.idx_ins inputs in
let outputs = SocUtils.filter_step_params sm.Soc.idx_outs outputs in
let to_param_decl is_an_output (_id,dt) =
match is_an_output, dt with
| true, Data.Array(_,_) -> Soc2cUtil.data_type_to_c dt "" ^"/*out*/"
| false, _ -> Soc2cUtil.data_type_to_c dt ""
| true, _ -> Soc2cUtil.data_type_to_c dt "*"
in
let to_param out (id,dt) =
match out, dt with
| true, Data.Array(_,_) -> Soc2cUtil.data_type_to_c dt id ^"/*out*/"
| false, _ -> Soc2cUtil.data_type_to_c dt id
| true, _ -> Soc2cUtil.data_type_to_c dt ("*"^id)
in
let in_params = List.map (to_param false) inputs in
let out_params = List.map (to_param true) outputs in
let in_params_decl = List.map (to_param_decl false) inputs in
let out_params_decl = List.map (to_param_decl true) outputs in
let params = String.concat "," (in_params@out_params) in
let params_decl = String.concat "," (in_params_decl@out_params_decl) in
let ctype = match inputs with
| (_,t)::_ ->
Printf.sprintf "sizeof(%s)" (Soc2cUtil.data_type_to_c t "")
| [] -> ""
in
if SocUtils.is_memory_less soc then
Printf.sprintf "void %s(%s);\n" sname params_decl,
Printf.sprintf "void %s(%s){\n" sname params,
ctype
else
let ctx = Printf.sprintf "%s_type* ctx" (get_ctx_name soc.key) in
let ctx_decl = Printf.sprintf "%s_type*" (get_ctx_name soc.key) in
Printf.sprintf "void %s(%s,%s);\n" sname params_decl ctx_decl,
Printf.sprintf "void %s(%s,%s){" sname params ctx,
ctype