246 lines
7.9 KiB
OCaml
246 lines
7.9 KiB
OCaml
(***********************************************************************)
|
|
(* *)
|
|
(* Caml Special Light *)
|
|
(* *)
|
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
|
(* *)
|
|
(* Copyright 1995 Institut National de Recherche en Informatique et *)
|
|
(* Automatique. Distributed only by permission. *)
|
|
(* *)
|
|
(***********************************************************************)
|
|
|
|
(* $Id$ *)
|
|
|
|
(* Pretty-printing of C-- code *)
|
|
|
|
open Format
|
|
open Cmm
|
|
|
|
let machtype_component = function
|
|
Addr -> print_string "addr"
|
|
| Int -> print_string "int"
|
|
| Float -> print_string "float"
|
|
|
|
let machtype mty =
|
|
match Array.length mty with
|
|
0 -> print_string "unit"
|
|
| n -> machtype_component mty.(0);
|
|
for i = 1 to n-1 do
|
|
print_string "*"; machtype_component mty.(i)
|
|
done
|
|
|
|
let comparison = function
|
|
Ceq -> print_string "=="
|
|
| Cne -> print_string "!="
|
|
| Clt -> print_string "<"
|
|
| Cle -> print_string "<="
|
|
| Cgt -> print_string ">"
|
|
| Cge -> print_string ">="
|
|
|
|
let chunk = function
|
|
Byte_unsigned -> print_string "unsigned byte"
|
|
| Byte_signed -> print_string "signed byte"
|
|
| Sixteen_unsigned -> print_string "unsigned half"
|
|
| Sixteen_signed -> print_string "signed half"
|
|
| Word -> ()
|
|
|
|
let operation = function
|
|
Capply ty -> print_string "app"
|
|
| Cextcall(lbl, ty, alloc) ->
|
|
print_string "extcall \""; print_string lbl; print_string "\""
|
|
| Cproj(ofs, len) ->
|
|
print_string "proj "; print_int ofs;
|
|
if len > 1 then begin print_string "-"; print_int (ofs + len - 1) end
|
|
| Cload mty -> print_string "load"
|
|
| Cloadchunk c -> print_string "load "; chunk c
|
|
| Calloc -> print_string "alloc"
|
|
| Cstore -> print_string "store"
|
|
| Cstorechunk c -> print_string "store "; chunk c
|
|
| Caddi -> print_string "+"
|
|
| Csubi -> print_string "-"
|
|
| Cmuli -> print_string "*"
|
|
| Cdivi -> print_string "/"
|
|
| Cmodi -> print_string "mod"
|
|
| Cand -> print_string "and"
|
|
| Cor -> print_string "or"
|
|
| Cxor -> print_string "xor"
|
|
| Clsl -> print_string "<<"
|
|
| Clsr -> print_string ">>u"
|
|
| Casr -> print_string ">>s"
|
|
| Ccmpi c -> comparison c
|
|
| Cadda -> print_string "+a"
|
|
| Csuba -> print_string "-a"
|
|
| Ccmpa c -> comparison c; print_string "a"
|
|
| Caddf -> print_string "+f"
|
|
| Csubf -> print_string "-f"
|
|
| Cmulf -> print_string "*f"
|
|
| Cdivf -> print_string "/f"
|
|
| Cfloatofint -> print_string "floatofint"
|
|
| Cintoffloat -> print_string "intoffloat"
|
|
| Ccmpf c -> comparison c; print_string "f"
|
|
| Craise -> print_string "raise"
|
|
| Ccheckbound -> print_string "checkbound"
|
|
|
|
let rec expression = function
|
|
Cconst_int n -> print_int n
|
|
| Cconst_float s -> print_string s
|
|
| Cconst_symbol s -> print_string "\""; print_string s; print_string "\""
|
|
| Cconst_pointer n -> print_int n; print_string "a"
|
|
| Cvar id -> Ident.print id
|
|
| Clet(id, def, (Clet(_, _, _) as body)) ->
|
|
open_hovbox 2;
|
|
print_string "(let"; print_space();
|
|
open_hovbox 1;
|
|
print_string "(";
|
|
open_hovbox 2;
|
|
Ident.print id; print_space(); expression def;
|
|
close_box();
|
|
let rec letdef = function
|
|
Clet(id, def, body) ->
|
|
print_space();
|
|
open_hovbox 2;
|
|
Ident.print id; print_space(); expression def;
|
|
close_box();
|
|
letdef body
|
|
| exp ->
|
|
print_string ")"; close_box();
|
|
print_space(); sequence exp
|
|
in letdef body;
|
|
print_string ")"; close_box()
|
|
| Clet(id, def, body) ->
|
|
open_hovbox 2;
|
|
print_string "(let"; print_space();
|
|
open_hovbox 2;
|
|
Ident.print id; print_space(); expression def;
|
|
close_box(); print_space();
|
|
sequence body;
|
|
print_string ")"; close_box()
|
|
| Cassign(id, exp) ->
|
|
open_hovbox 2;
|
|
print_string "(assign ";
|
|
open_hovbox 2;
|
|
Ident.print id; print_space(); expression exp;
|
|
close_box();
|
|
print_string ")"; close_box()
|
|
| Ctuple el ->
|
|
open_hovbox 1;
|
|
print_string "[";
|
|
let first = ref true in
|
|
List.iter
|
|
(fun e ->
|
|
if !first then first := false else print_space();
|
|
expression e)
|
|
el;
|
|
print_string "]";
|
|
close_box()
|
|
| Cop(op, el) ->
|
|
open_hovbox 2;
|
|
print_string "("; operation op;
|
|
List.iter (fun e -> print_space(); expression e) el;
|
|
begin match op with
|
|
Capply mty -> print_space(); machtype mty
|
|
| Cextcall(_, mty, _) -> print_space(); machtype mty
|
|
| Cload mty -> print_space(); machtype mty
|
|
| _ -> ()
|
|
end;
|
|
print_string ")";
|
|
close_box()
|
|
| Csequence(e1, e2) ->
|
|
open_hovbox 2;
|
|
print_string "(seq "; print_space();
|
|
sequence e1; print_space();
|
|
sequence e2; print_string ")"; close_box()
|
|
| Cifthenelse(e1, e2, e3) ->
|
|
open_hovbox 2;
|
|
print_string "(if";
|
|
print_space(); expression e1;
|
|
print_space(); expression e2;
|
|
print_space(); expression e3;
|
|
print_string ")"; close_box()
|
|
| Cswitch(e1, index, cases) ->
|
|
open_vbox 0;
|
|
open_hovbox 2;
|
|
print_string "(switch"; print_space(); expression e1; print_space();
|
|
close_box();
|
|
for i = 0 to Array.length cases - 1 do
|
|
print_space();
|
|
open_hovbox 2;
|
|
for j = 0 to Array.length index - 1 do
|
|
if index.(j) = i then begin
|
|
print_string "case "; print_int j; print_string ":"; print_space()
|
|
end
|
|
done;
|
|
sequence cases.(i);
|
|
close_box()
|
|
done;
|
|
close_box()
|
|
| Cloop e ->
|
|
open_hovbox 2;
|
|
print_string "(loop";
|
|
print_space(); sequence e;
|
|
print_string ")"; close_box()
|
|
| Ccatch(e1, e2) ->
|
|
open_hovbox 2;
|
|
print_string "(catch";
|
|
print_space(); sequence e1;
|
|
print_break 1 (-2); print_string "with";
|
|
print_space(); sequence e2;
|
|
print_string ")"; close_box()
|
|
| Cexit ->
|
|
print_string "exit"
|
|
| Ctrywith(e1, id, e2) ->
|
|
open_hovbox 2;
|
|
print_string "(try";
|
|
print_space(); sequence e1;
|
|
print_break 1 (-2); print_string "with "; Ident.print id;
|
|
print_space(); sequence e2;
|
|
print_string ")"; close_box()
|
|
|
|
and sequence = function
|
|
Csequence(e1, e2) ->
|
|
sequence e1; print_space(); sequence e2
|
|
| e ->
|
|
expression e
|
|
|
|
let fundecl f =
|
|
open_hovbox 1;
|
|
print_string "(function "; print_string f.fun_name; print_break 1 4;
|
|
open_hovbox 1;
|
|
print_string "(";
|
|
let first = ref true in
|
|
List.iter
|
|
(fun (id, ty) ->
|
|
if !first then first := false else print_space();
|
|
Ident.print id; print_string ": "; machtype ty)
|
|
f.fun_args;
|
|
print_string ")"; close_box(); print_space();
|
|
open_hovbox 0;
|
|
sequence f.fun_body;
|
|
print_string ")";
|
|
close_box(); close_box(); print_newline()
|
|
|
|
let data_item = function
|
|
Cdefine_symbol s -> print_string "\""; print_string s; print_string "\":"
|
|
| Cdefine_label l -> print_string "L"; print_int l; print_string ":"
|
|
| Cint8 n -> print_string "byte "; print_int n
|
|
| Cint16 n -> print_string "half "; print_int n
|
|
| Cint n -> print_string "int "; print_int n
|
|
| Cintlit s -> print_string "intlit "; print_string s
|
|
| Cfloat f -> print_string "float "; print_string f
|
|
| Csymbol_address s ->
|
|
print_string "addr \""; print_string s; print_string "\""
|
|
| Clabel_address l -> print_string "addr L"; print_int l
|
|
| Cstring s -> print_string "string \""; print_string s; print_string "\""
|
|
| Cskip n -> print_string "skip "; print_int n
|
|
| Calign n -> print_string "align "; print_int n
|
|
|
|
let data dl =
|
|
open_hvbox 1;
|
|
print_string "(data";
|
|
List.iter (fun d -> print_space(); data_item d) dl;
|
|
print_string ")"; close_box()
|
|
|
|
let phrase = function
|
|
Cfunction f -> fundecl f
|
|
| Cdata dl -> data dl
|