source: src/Cminor/cminorMatitaPrinter.ml @ 1626

Last change on this file since 1626 was 1226, checked in by campbell, 8 years ago

Adjust pretty printers for change in program records, try a test of each.

File size: 12.3 KB
Line 
1open AST
2
3let next_id = ref 0
4let fresh () = let i = !next_id in next_id := i+1; i
5
6let print_signedness = function
7  | Signed -> "Signed"
8  | Unsigned -> "Unsigned"
9
10let print_type = function
11  | Sig_int (sz, sg) -> Printf.sprintf "ASTint I%d %s" (sz*8) (print_signedness sg)
12  | Sig_float (sz, _) -> Printf.sprintf "ASTfloat F%d" (sz*8)
13  | Sig_offset -> "ASTint I32 Unsigned"
14  | Sig_ptr -> "ASTptr Any"
15
16let print_ret_type = function
17  | Type_ret t -> Printf.sprintf "Some ? (%s)" (print_type t)
18  | Type_void -> "None ?"
19
20
21let print_data = function
22  (*| Data_reserve n -> Printf.sprintf "Init_space %d" n*)
23  | Data_int8 i -> Printf.sprintf "Init_int8 (repr I8 %d)" i
24  | Data_int16 i -> Printf.sprintf "Init_int16 (repr I16 %d)" i
25  | Data_int32 i -> Printf.sprintf "Init_int32 (repr I32 %d)" i
26  | Data_float32 f -> Printf.sprintf "Init_float32 %f" f
27  | Data_float64 f -> Printf.sprintf "Init_float64 %f" f
28
29let print_var n (id, sz, init) =
30  Printf.sprintf "(pair ?? (pair ?? id_%s Any) [%s])"
31    id
32    (match init with
33     | None -> Printf.sprintf "Init_space %d" (Driver.CminorMemory.concrete_size sz)
34     | Some init ->
35         (MiscPottier.string_of_list ";" print_data init))
36
37let print_vars n = MiscPottier.string_of_list ";\n" (print_var n) 
38
39let print_cmp = function
40  | AST.Cmp_eq -> "Ceq"
41  | AST.Cmp_ne -> "Cne"
42  | AST.Cmp_gt -> "Cgt"
43  | AST.Cmp_ge -> "Cge"
44  | AST.Cmp_lt -> "Clt"
45  | AST.Cmp_le -> "Cle"
46
47let print_constant ty = function
48  | AST.Cst_int i ->
49      Printf.sprintf "Ointconst I%d (repr ? %d)"
50        (match ty with Sig_int (sz, _) -> 8*sz | _ -> 32)
51        i
52  | AST.Cst_float f -> Printf.sprintf "Ofloatconst %f" f
53  | AST.Cst_addrsymbol id -> Printf.sprintf "Oaddrsymbol id_%s 0" id
54  (*| AST.Cst_stackoffset off -> Printf.sprintf "Oaddrstack (repr %d)" off*)
55  | AST.Cst_stack -> Printf.sprintf "Oaddrstack 0"
56  | AST.Cst_offset off ->
57      Printf.sprintf "Ointconst I%d (repr ? %d)"
58        (match ty with Sig_int (sz, _) -> 8*sz | _ -> 32)
59        (Driver.CminorMemory.concrete_offset off)
60  | AST.Cst_sizeof sz ->
61      Printf.sprintf "Ointconst I%d (repr ? %d)"
62        (match ty with Sig_int (sz, _) -> 8*sz | _ -> 32)
63        (Driver.CminorMemory.concrete_size sz)
64
65let print_op1 = function
66  | AST.Op_cast((_,sg),sz) -> Printf.sprintf "(Ocastint %s I%d)" (print_signedness sg) (8*sz)
67  | AST.Op_negint -> "Onegint"
68  | AST.Op_notbool -> "Onotbool"
69  | AST.Op_notint -> "Onotint"
70  | AST.Op_id -> "Oid"
71  | AST.Op_ptrofint -> "(Optrofint Any)"
72  | AST.Op_intofptr -> "(Ointofptr ?)"
73
74let print_op2 ty = function
75  | AST.Op_add -> "Oadd"
76  | AST.Op_sub -> "Osub"
77  | AST.Op_mul -> "Omul"
78  | AST.Op_div -> "Odiv"
79  | AST.Op_divu -> "Odivu"
80  | AST.Op_mod -> "Omod"
81  | AST.Op_modu -> "Omodu"
82  | AST.Op_and -> "Oand"
83  | AST.Op_or -> "Oor"
84  | AST.Op_xor -> "Oxor"
85  | AST.Op_shl -> "Oshl"
86  | AST.Op_shr -> "Oshr"
87  | AST.Op_shru -> "Oshru"
88  | AST.Op_cmp cmp -> "(Ocmp " ^ print_cmp cmp ^ ")"
89  | AST.Op_cmpu cmp -> "(Ocmpu " ^ (print_cmp cmp) ^ ")"
90  | AST.Op_addp -> "Oaddp"
91  | AST.Op_subp -> "Osubpi"
92  | AST.Op_subpp ->
93      Printf.sprintf "(Osubpp I%d)"
94        (match ty with Sig_int (sz, _) -> 8*sz | _ -> 32)
95  | AST.Op_cmpp cmp -> "(Ocmpp " ^ (print_cmp cmp) ^ ")"
96
97let rec define_expr_labels = function
98| Cminor.Expr (e,ty) -> match e with
99  | Cminor.Op1 (_, e) -> define_expr_labels e
100  | Cminor.Op2 (_, e1, e2) -> define_expr_labels e1 ^ define_expr_labels e2
101  | Cminor.Mem (_, e) -> define_expr_labels e
102  | Cminor.Cond (e1, e2, e3) ->
103      define_expr_labels e1 ^ define_expr_labels e2 ^ define_expr_labels e3 
104  | Cminor.Exp_cost (lab, e) ->
105      Printf.sprintf "definition C%s := costlabel_of_nat %d.\n%s"
106        lab (fresh ()) (define_expr_labels e)
107  | _ -> ""
108
109let print_quantity = function
110  | AST.QInt 1 -> "Mint8unsigned"
111  | AST.QInt 2 -> "Mint16unsigned"
112  | AST.QInt 4 -> "Mint32"
113  | AST.QOffset -> "Mint32"
114  | AST.QPtr -> "Mpointer Any"
115
116let typeof = function Cminor.Expr (_,ty) -> ty
117
118let rec print_expression p_id = function
119| Cminor.Expr (e,ty) -> match e with
120  | Cminor.Id id -> Printf.sprintf "Id (%s) %s" (print_type ty) (p_id id)
121  | Cminor.Cst cst -> Printf.sprintf "Cst (%s) (%s)" (print_type ty) (print_constant ty cst)
122  | Cminor.Op1 (op1, e) ->
123      Printf.sprintf "Op1 (%s) (%s) %s (%s)"
124        (print_type (typeof e)) (print_type ty)
125        (print_op1 op1) (print_expression p_id e)
126  | Cminor.Op2 (op2, e1, e2) ->
127      Printf.sprintf "Op2 (%s) (%s) (%s) %s (%s) (%s)"
128        (print_type (typeof e1)) (print_type (typeof e2)) (print_type ty)
129        (print_op2 ty op2)
130        (print_expression p_id e1)
131        (print_expression p_id e2)
132  | Cminor.Mem (q, e) ->
133      Printf.sprintf "Mem (%s) Any %s (%s)"
134        (print_type ty) (print_quantity q) (print_expression p_id e)
135  | Cminor.Cond (e1, e2, e3) ->
136      let sz,sg = match typeof e1 with Sig_int (sz, sg) -> sz,sg in
137      Printf.sprintf "Cond I%d %s (%s) (%s) (%s) (%s)"
138        (sz*8) (print_signedness sg)
139        (print_type ty)
140        (print_expression p_id e1)
141        (print_expression p_id e2)
142        (print_expression p_id e3)
143  | Cminor.Exp_cost (lab, e) ->
144      Printf.sprintf "Ecost (%s) C%s (%s)" (print_type ty) lab (print_expression p_id e)
145
146let print_arg p_id e =
147  Printf.sprintf "dp ?? (%s) (%s)" (print_type (typeof e)) (print_expression p_id e)
148
149let rec print_args p_id = 
150  MiscPottier.string_of_list "; " (print_arg p_id)
151
152
153let n_spaces n = String.make n ' '
154
155
156let print_local p_id (id,ty) =
157  Printf.sprintf "pair ?? %s (%s)" (p_id id) (print_type ty)
158
159let print_locals p_id vars =
160  (MiscPottier.string_of_list "; " (print_local p_id) vars)
161
162
163let print_table n =
164  let f (case, exit) =
165    Printf.sprintf "(pair ?? (repr ? %d) %d)" case exit
166  in
167  MiscPottier.string_of_list (";\n" ^ n_spaces n) f
168
169let rec define_labels = function
170  | Cminor.St_assign (_, e) -> define_expr_labels e
171  | Cminor.St_store (_, e1, e2) -> define_expr_labels e1 ^ define_expr_labels e2
172  | Cminor.St_call (_, _, args, _) -> String.concat "" (List.map define_expr_labels args)
173  | Cminor.St_tailcall (_, args, _) -> String.concat "" (List.map define_expr_labels args)
174  | Cminor.St_seq (s1, s2) -> define_labels s1 ^ define_labels s2
175  | Cminor.St_ifthenelse (e, s1, s2) -> define_expr_labels e ^ define_labels s1 ^ define_labels s2
176  | Cminor.St_loop s -> define_labels s
177  | Cminor.St_block s -> define_labels s
178  | Cminor.St_switch (e, _, _) -> define_expr_labels e
179  | Cminor.St_return (Some e) -> define_expr_labels e
180  | Cminor.St_label (l, s) ->
181      Printf.sprintf "definition L%s := ident_of_nat %d.\n%s"
182        l (fresh ()) (define_labels s)
183  | Cminor.St_cost (l, s) ->
184      Printf.sprintf "definition C%s := costlabel_of_nat %d.\n%s"
185        l (fresh ()) (define_labels s)
186  | _ -> ""
187
188let rec print_body p_id n = function
189  | Cminor.St_skip -> Printf.sprintf "%sSt_skip" (n_spaces n)
190  | Cminor.St_assign (id, e) ->
191      Printf.sprintf "%sSt_assign (%s) %s (%s)\n"
192        (n_spaces n) (print_type (typeof e))
193        (p_id id) (print_expression p_id e)
194  | Cminor.St_store (q, e1, e2) ->
195      Printf.sprintf "%sSt_store (%s) Any %s (%s) (%s)\n"
196        (n_spaces n)
197        (print_type (typeof e2))
198        (print_quantity q)
199        (print_expression p_id e1)
200        (print_expression p_id e2)
201(* XXX cheat horribly *)
202  | Cminor.St_call (None, Cminor.Expr (Cminor.Cst (AST.Cst_addrsymbol f),_), args, sg) ->
203      Printf.sprintf "%sSt_call (None ?) (Cst ? (Oaddrsymbol id_%s 0)) [%s]\n"
204        (n_spaces n)
205        f
206        (print_args p_id args)
207  | Cminor.St_call (Some id, Cminor.Expr (Cminor.Cst (AST.Cst_addrsymbol f),_), args, sg) ->
208      Printf.sprintf "%sSt_call (Some ? %s) (Cst ? (Oaddrsymbol id_%s 0)) [%s]\n"
209        (n_spaces n)
210        (p_id id)
211        f
212        (print_args p_id args)
213  | Cminor.St_tailcall (Cminor.Expr (Cminor.Cst (AST.Cst_addrsymbol f),_), args, sg) ->
214      Printf.sprintf "%sSt_tailcall (Cst ? (Oaddrsymbol id_%s 0)) [%s]\n"
215        (n_spaces n)
216        f
217        (print_args p_id args)
218(* XXX regular versions, but the region will be screwed up *)
219  | Cminor.St_call (None, f, args, sg) ->
220      Printf.sprintf "%sSt_call (None ?) (%s) [%s]\n"
221        (n_spaces n)
222        (print_expression p_id f)
223        (print_args p_id args)
224  | Cminor.St_call (Some id, f, args, sg) ->
225      Printf.sprintf "%sSt_call (Some ? %s) (%s) [%s]\n"
226        (n_spaces n)
227        (p_id id)
228        (print_expression p_id f)
229        (print_args p_id args)
230  | Cminor.St_tailcall (f, args, sg) ->
231      Printf.sprintf "%sSt_tailcall (%s) [%s]\n"
232        (n_spaces n)
233        (print_expression p_id f)
234        (print_args p_id args)
235  | Cminor.St_seq (s1, s2) ->
236      Printf.sprintf "%sSt_seq (\n%s%s) (\n%s%s)\n"
237        (n_spaces n)
238        (print_body p_id (n+2) s1)
239        (n_spaces n)
240        (print_body p_id n s2)
241        (n_spaces n)
242  | Cminor.St_ifthenelse (e, s1, s2) ->
243      let sz,sg = match typeof e with Sig_int (sz, sg) -> sz,sg in
244      Printf.sprintf "%sSt_ifthenelse I%d %s (%s) (\n%s%s) (\n%s%s)\n"
245        (n_spaces n)
246        (sz*8) (print_signedness sg)
247        (print_expression p_id e)
248        (print_body p_id (n+2) s1)
249        (n_spaces n)
250        (print_body p_id (n+2) s2)
251        (n_spaces n)
252  | Cminor.St_loop s ->
253      Printf.sprintf "%sSt_loop (\n%s%s)\n"
254        (n_spaces n)
255        (print_body p_id (n+2) s)
256        (n_spaces n)
257  | Cminor.St_block s ->
258      Printf.sprintf "%sSt_block (\n%s%s)\n"
259        (n_spaces n)
260        (print_body p_id (n+2) s)
261        (n_spaces n)
262  | Cminor.St_exit i ->
263      Printf.sprintf "%sSt_exit %d\n" (n_spaces n) i
264  | Cminor.St_switch (e, tbl, dflt) ->
265      let sz,sg = match typeof e with Sig_int (sz, sg) -> sz,sg in
266      Printf.sprintf "%sSt_switch I%d %s (%s) [\n%s%s] %d\n"
267        (n_spaces n)
268        (sz*8) (print_signedness sg)
269        (print_expression p_id e)
270        (n_spaces (n+2))
271        (print_table ( n+2) tbl)
272        dflt
273  | Cminor.St_return None -> Printf.sprintf "%sSt_return (None ?)\n" (n_spaces n)
274  | Cminor.St_return (Some e) ->
275      Printf.sprintf "%sSt_return (Some ? (%s))\n" (n_spaces n) (print_arg p_id e)
276  | Cminor.St_label (lbl, s) ->
277      Printf.sprintf "%sSt_label L%s (\n%s%s)\n" 
278        (n_spaces n)
279        lbl
280        (print_body p_id n s)
281        (n_spaces n)
282  | Cminor.St_goto lbl ->
283      Printf.sprintf "%sSt_goto L%s\n" (n_spaces n) lbl
284  | Cminor.St_cost (lbl, s) ->
285      Printf.sprintf "%sSt_cost C%s (\n%s%s)\n"
286        (n_spaces n) lbl (print_body p_id n s)
287        (n_spaces n)
288
289let print_ids fname vs =
290  List.fold_left (fun s (v,_) ->
291                  Printf.sprintf "%sdefinition id_%s_%s := ident_of_nat %d.\n"
292                                 s fname v (fresh ()))
293       "" vs
294
295let print_internal f_name f_def =
296  let fid = fresh () in
297  let p_id id = Printf.sprintf "id_%s_%s" f_name id in
298  Printf.sprintf "definition id_%s := ident_of_nat %d.\n%s%sdefinition f_%s := Internal ? (mk_internal_function\n  (%s)\n  [%s]\n  [%s]\n  %d (\n%s\n)).\n\n"
299    f_name
300    fid
301    (print_ids f_name (f_def.Cminor.f_vars @ f_def.Cminor.f_params))
302    (define_labels f_def.Cminor.f_body)
303    f_name
304    (print_ret_type f_def.Cminor.f_return)
305    (print_locals p_id f_def.Cminor.f_params)
306    (print_locals p_id f_def.Cminor.f_vars)
307    (Driver.CminorMemory.concrete_size f_def.Cminor.f_stacksize)
308    (print_body p_id 2 f_def.Cminor.f_body)
309
310let print_sig s =
311  Printf.sprintf "mk_signature [%s] (%s)"
312    (MiscPottier.string_of_list "; " print_type s.AST.args)
313    (match s.AST.res with AST.Type_ret t -> "Some ? " ^ print_type t
314                        | AST.Type_void  -> "None ?")
315
316
317
318let print_external f def =
319  Printf.sprintf "definition id_%s := ident_of_nat %d.\ndefinition f_%s := External internal_function (mk_external_function id_%s (%s)).\n"
320    f
321    (fresh ())
322    f
323    f
324    (print_sig def.AST.ef_sig)
325
326
327let print_funct (f_name, f_def) = match f_def with
328  | Cminor.F_int f_def -> print_internal f_name f_def
329  | Cminor.F_ext f_def -> print_external f_name f_def
330
331let print_functs = List.fold_left (fun s f -> s ^ (print_funct f)) ""
332
333
334let print_fun' n functs =
335  MiscPottier.string_of_list ";\n" (fun (f,def) ->
336    Printf.sprintf "%s(pair ?? id_%s f_%s)"
337      (n_spaces n) 
338      f
339      f)
340      functs
341
342let print_main n main =
343  Printf.sprintf "%s%s"
344    (n_spaces n)
345    (match main with Some f -> "id_" ^ f | None -> "ident_of_nat 0 (* None! *)")
346
347let define_var_id (id,_,_) =
348  Printf.sprintf "definition id_%s := ident_of_nat %d.\n" id (fresh ())
349
350let define_var_ids =
351  List.fold_left (fun s v -> s ^ (define_var_id v)) ""
352
353let print_program p =
354  Printf.sprintf "include \"Cminor/semantics.ma\".\ninclude \"common/Animation.ma\".\n\n%s\n\n%s\n\ndefinition myprog : Cminor_program :=\nmk_program ?? [%s] [\n%s\n]%s\n.\n"
355    (define_var_ids p.Cminor.vars)
356    (print_functs p.Cminor.functs)
357    (print_vars 2 p.Cminor.vars)
358    (print_fun' 2 p.Cminor.functs)
359    (print_main 2 p.Cminor.main)
360
Note: See TracBrowser for help on using the repository browser.