lustrec / src / backends / C / c_backend_spec.ml @ 01c7d5e1
History | View | Annotate | Download (7.75 KB)
1 | d4107cf2 | ploc | open Format |
---|---|---|---|
2 | open LustreSpec |
||
3 | open Machine_code |
||
4 | open C_backend_common |
||
5 | 01c7d5e1 | ploc | open Utils |
6 | d4107cf2 | ploc | |
7 | 13eb21df | ploc | (**************************************************************************) |
8 | (* Printing spec for c *) |
||
9 | |||
10 | (**************************************************************************) |
||
11 | 01c7d5e1 | ploc | (* OLD STUFF ??? |
12 | |||
13 | 13eb21df | ploc | |
14 | cefc3744 | ploc | let pp_acsl_type var fmt t = |
15 | let rec aux t pp_suffix = |
||
16 | match (Types.repr t).Types.tdesc with |
||
17 | | Types.Tclock t' -> aux t' pp_suffix |
||
18 | | Types.Tbool -> fprintf fmt "int %s%a" var pp_suffix () |
||
19 | | Types.Treal -> fprintf fmt "real %s%a" var pp_suffix () |
||
20 | | Types.Tint -> fprintf fmt "int %s%a" var pp_suffix () |
||
21 | | Types.Tarray (d, t') -> |
||
22 | let pp_suffix' fmt () = fprintf fmt "%a[%a]" pp_suffix () pp_c_dimension d in |
||
23 | aux t' pp_suffix' |
||
24 | (* | Types.Tstatic (_, t') -> fprintf fmt "const "; aux t' pp_suffix *) |
||
25 | (* | Types.Tconst ty -> fprintf fmt "%s %s" ty var *) |
||
26 | (* | Types.Tarrow (_, _) -> fprintf fmt "void (\*%s)()" var *) |
||
27 | | _ -> eprintf "internal error: pp_acsl_type %a@." Types.print_ty t; assert false |
||
28 | in aux t (fun fmt () -> ()) |
||
29 | |||
30 | let pp_acsl_var_decl fmt id = |
||
31 | pp_acsl_type id.var_id fmt id.var_type |
||
32 | |||
33 | 13eb21df | ploc | |
34 | let pp_econst fmt c = |
||
35 | match c with |
||
36 | | EConst_int i -> pp_print_int fmt i |
||
37 | | EConst_real r -> pp_print_string fmt r |
||
38 | | EConst_float r -> pp_print_float fmt r |
||
39 | | EConst_bool b -> pp_print_bool fmt b |
||
40 | | EConst_string s -> pp_print_string fmt ("\"" ^ s ^ "\"") |
||
41 | |||
42 | let rec pp_eexpr is_output fmt eexpr = |
||
43 | let pp_eexpr = pp_eexpr is_output in |
||
44 | match eexpr.eexpr_desc with |
||
45 | | EExpr_const c -> pp_econst fmt c |
||
46 | | EExpr_ident id -> |
||
47 | if is_output id then pp_print_string fmt ("*" ^ id) else pp_print_string fmt id |
||
48 | | EExpr_tuple el -> Utils.fprintf_list ~sep:"," pp_eexpr fmt el |
||
49 | | EExpr_arrow (e1, e2) -> fprintf fmt "%a -> %a" pp_eexpr e1 pp_eexpr e2 |
||
50 | | EExpr_fby (e1, e2) -> fprintf fmt "%a fby %a" pp_eexpr e1 pp_eexpr e2 |
||
51 | (* | EExpr_concat (e1, e2) -> fprintf fmt "%a::%a" pp_eexpr e1 pp_eexpr e2 *) |
||
52 | (* | EExpr_tail e -> fprintf fmt "tail %a" pp_eexpr e *) |
||
53 | | EExpr_pre e -> fprintf fmt "pre %a" pp_eexpr e |
||
54 | | EExpr_when (e, id) -> fprintf fmt "%a when %s" pp_eexpr e id |
||
55 | | EExpr_merge (id, e1, e2) -> |
||
56 | fprintf fmt "merge (%s, %a, %a)" id pp_eexpr e1 pp_eexpr e2 |
||
57 | | EExpr_appl (id, e, r) -> pp_eapp is_output fmt id e r |
||
58 | | EExpr_forall (vars, e) -> fprintf fmt "forall %a; %a" Printers.pp_node_args vars pp_eexpr e |
||
59 | | EExpr_exists (vars, e) -> fprintf fmt "exists %a; %a" Printers.pp_node_args vars pp_eexpr e |
||
60 | |||
61 | |||
62 | (* | EExpr_whennot _ *) |
||
63 | (* | EExpr_uclock _ *) |
||
64 | (* | EExpr_dclock _ *) |
||
65 | (* | EExpr_phclock _ -> assert false *) |
||
66 | and pp_eapp is_output fmt id e r = |
||
67 | let pp_eexpr = pp_eexpr is_output in |
||
68 | match r with |
||
69 | | None -> |
||
70 | (match id, e.eexpr_desc with |
||
71 | | "+", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a + %a)" pp_eexpr e1 pp_eexpr e2 |
||
72 | | "uminus", _ -> fprintf fmt "(- %a)" pp_eexpr e |
||
73 | | "-", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a - %a)" pp_eexpr e1 pp_eexpr e2 |
||
74 | | "*", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a * %a)" pp_eexpr e1 pp_eexpr e2 |
||
75 | | "/", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a / %a)" pp_eexpr e1 pp_eexpr e2 |
||
76 | | "mod", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a mod %a)" pp_eexpr e1 pp_eexpr e2 |
||
77 | | "&&", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a && %a)" pp_eexpr e1 pp_eexpr e2 |
||
78 | | "||", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a || %a)" pp_eexpr e1 pp_eexpr e2 |
||
79 | | "xor", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a ^^ %a)" pp_eexpr e1 pp_eexpr e2 |
||
80 | | "impl", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a ==> %a)" pp_eexpr e1 pp_eexpr e2 |
||
81 | | "<", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a < %a)" pp_eexpr e1 pp_eexpr e2 |
||
82 | | "<=", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a <= %a)" pp_eexpr e1 pp_eexpr e2 |
||
83 | | ">", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a > %a)" pp_eexpr e1 pp_eexpr e2 |
||
84 | | ">=", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a >= %a)" pp_eexpr e1 pp_eexpr e2 |
||
85 | | "!=", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a != %a)" pp_eexpr e1 pp_eexpr e2 |
||
86 | | "=", EExpr_tuple([e1;e2]) -> fprintf fmt "(%a == %a)" pp_eexpr e1 pp_eexpr e2 |
||
87 | | "not", _ -> fprintf fmt "(! %a)" pp_eexpr e |
||
88 | | "ite", EExpr_tuple([e1;e2;e3]) -> fprintf fmt "(if %a then %a else %a)" pp_eexpr e1 pp_eexpr e2 pp_eexpr e3 |
||
89 | | _ -> fprintf fmt "%s (%a)" id pp_eexpr e) |
||
90 | | Some x -> fprintf fmt "%s (%a) every %s" id pp_eexpr e x |
||
91 | |||
92 | let pp_ensures is_output fmt e = |
||
93 | match e with |
||
94 | | EnsuresExpr e -> fprintf fmt "ensures %a;@ " (pp_eexpr is_output) e |
||
95 | | SpecObserverNode (name, args) -> fprintf fmt "observer %s (%a);@ " name (Utils.fprintf_list ~sep:", " (pp_eexpr is_output)) args |
||
96 | |||
97 | let pp_acsl_spec outputs fmt spec = |
||
98 | let is_output = fun oid -> List.exists (fun v -> v.var_id = oid) outputs in |
||
99 | let pp_eexpr = pp_eexpr is_output in |
||
100 | fprintf fmt "@[<v 2>/*@@ "; |
||
101 | Utils.fprintf_list ~sep:"" (fun fmt r -> fprintf fmt "requires %a;@ " pp_eexpr r) fmt spec.requires; |
||
102 | Utils.fprintf_list ~sep:"" (pp_ensures is_output) fmt spec.ensures; |
||
103 | fprintf fmt "@ "; |
||
104 | (* fprintf fmt "assigns *self%t%a;@ " *) |
||
105 | (* (fun fmt -> if List.length outputs > 0 then fprintf fmt ", ") *) |
||
106 | (* (fprintf_list ~sep:"," (fun fmt v -> fprintf fmt "*%s" v.var_id)) outputs; *) |
||
107 | Utils.fprintf_list ~sep:"@ " (fun fmt (name, assumes, requires) -> |
||
108 | fprintf fmt "behavior %s:@[@ %a@ %a@]" |
||
109 | name |
||
110 | (Utils.fprintf_list ~sep:"@ " (fun fmt r -> fprintf fmt "assumes %a;" pp_eexpr r)) assumes |
||
111 | (Utils.fprintf_list ~sep:"@ " (pp_ensures is_output)) requires |
||
112 | ) fmt spec.behaviors; |
||
113 | fprintf fmt "@]@ */@."; |
||
114 | () |
||
115 | |||
116 | |||
117 | |||
118 | |||
119 | let print_machine_decl_prefix fmt m = |
||
120 | (* Print specification if any *) |
||
121 | (match m.mspec with |
||
122 | | None -> () |
||
123 | | Some spec -> |
||
124 | pp_acsl_spec m.mstep.step_outputs fmt spec |
||
125 | ) |
||
126 | |||
127 | 01c7d5e1 | ploc | *) |
128 | |||
129 | d4107cf2 | ploc | (**************************************************************************) |
130 | (* MAKEFILE *) |
||
131 | (**************************************************************************) |
||
132 | |||
133 | let makefile_targets fmt basename nodename dependencies = |
||
134 | fprintf fmt "FRAMACEACSL=`frama-c -print-share-path`/e-acsl@."; |
||
135 | (* EACSL version of library file . c *) |
||
136 | fprintf fmt "%s_eacsl.c: %s.c %s.h@." basename basename basename; |
||
137 | fprintf fmt |
||
138 | "\tframa-c -e-acsl-full-mmodel -machdep x86_64 -e-acsl %s.c -then-on e-acsl -print -ocode %s_eacsl.c@." |
||
139 | basename basename; |
||
140 | fprintf fmt "@."; |
||
141 | fprintf fmt "@."; |
||
142 | |||
143 | (* EACSL version of library file . c + main .c *) |
||
144 | fprintf fmt "%s_main_eacsl.c: %s.c %s.h %s_main.c@." basename basename basename basename; |
||
145 | fprintf fmt "\tframa-c -e-acsl-full-mmodel -machdep x86_64 -e-acsl %s.c %s_main.c -then-on e-acsl -print -ocode %s_main_eacsl.i@." |
||
146 | basename basename basename; |
||
147 | (* Ugly hack to deal with eacsl bugs *) |
||
148 | fprintf fmt "\tgrep -v _fc_stdout %s_main_eacsl.i > %s_main_eacsl.c" basename basename; |
||
149 | fprintf fmt "@."; |
||
150 | fprintf fmt "@."; |
||
151 | |||
152 | (* EACSL version of binary *) |
||
153 | fprintf fmt "%s_main_eacsl: %s_main_eacsl.c@." basename basename; |
||
154 | fprintf fmt "\t${GCC} -Wno-attributes -I${INC} -I. -c %s_main_eacsl.c@." basename; (* compiling instrumented lib + main *) |
||
155 | C_backend_makefile.fprintf_dependencies fmt dependencies; |
||
156 | fprintf fmt "\t${GCC} -Wno-attributes -o %s_main_eacsl io_frontend.o %a %s %s_main_eacsl.o %a@." |
||
157 | basename |
||
158 | (Utils.fprintf_list ~sep:" " (fun fmt (s, _, _) -> Format.fprintf fmt "%s.o" s)) |
||
159 | (C_backend_makefile.compiled_dependencies dependencies) |
||
160 | ("${FRAMACEACSL}/e_acsl.c " |
||
161 | ^ "${FRAMACEACSL}/memory_model/e_acsl_bittree.c " |
||
162 | ^ "${FRAMACEACSL}/memory_model/e_acsl_mmodel.c") |
||
163 | basename |
||
164 | (Utils.fprintf_list ~sep:" " (fun fmt lib -> fprintf fmt "-l%s" lib)) |
||
165 | (C_backend_makefile.lib_dependencies dependencies) |
||
166 | ; |
||
167 | fprintf fmt "@."; |
||
168 | |||
169 | module MakefileMod = |
||
170 | struct |
||
171 | let other_targets = makefile_targets |
||
172 | |||
173 | end |
||
174 | |||
175 | 13eb21df | ploc | (* Local Variables: *) |
176 | cd670fe1 | ploc | (* compile-command:"make -C ../../.." *) |
177 | 13eb21df | ploc | (* End: *) |