2011-01-20 23:05:18 +01:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Heptagon *)
|
|
|
|
(* *)
|
|
|
|
(* Author : Marc Pouzet *)
|
|
|
|
(* Organization : Demons, LRI, University of Paris-Sud, Orsay *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
|
|
|
(* Java printer *)
|
|
|
|
|
|
|
|
open Java
|
|
|
|
open Pp_tools
|
|
|
|
open Format
|
2011-02-07 14:24:17 +01:00
|
|
|
open Misc
|
2011-01-20 23:05:18 +01:00
|
|
|
|
2011-02-07 14:24:17 +01:00
|
|
|
let class_name = Global_printer.print_qualname
|
|
|
|
let bare_class_name = Global_printer.print_shortname
|
2011-01-20 23:05:18 +01:00
|
|
|
let obj_ident = Global_printer.print_ident
|
|
|
|
let constructor_name = Global_printer.print_qualname
|
|
|
|
let bare_constructor_name = Global_printer.print_shortname
|
|
|
|
let method_name = pp_print_string
|
|
|
|
let field_name = pp_print_string
|
|
|
|
let field_ident = Global_printer.print_ident
|
|
|
|
let var_ident = Global_printer.print_ident
|
|
|
|
let const_name = Global_printer.print_qualname
|
|
|
|
|
2011-02-07 14:24:17 +01:00
|
|
|
let protection ff = function
|
|
|
|
| Ppublic -> fprintf ff "public "
|
|
|
|
| Pprotected -> fprintf ff "protected "
|
|
|
|
| Pprivate -> fprintf ff "private "
|
|
|
|
| Ppackage -> ()
|
|
|
|
|
|
|
|
let static ff s = if s then fprintf ff "static " else ()
|
|
|
|
|
|
|
|
let final ff f = if f then fprintf ff "final " else ()
|
|
|
|
|
2011-03-29 20:43:55 +02:00
|
|
|
let rec _ty news ff t = match t with
|
2011-01-20 23:05:18 +01:00
|
|
|
| Tbool -> fprintf ff "boolean"
|
|
|
|
| Tint -> fprintf ff "int"
|
|
|
|
| Tfloat -> fprintf ff "float"
|
|
|
|
| Tclass n -> class_name ff n
|
2011-03-29 20:43:55 +02:00
|
|
|
| Tgeneric (n, ty_l) ->
|
|
|
|
if news
|
|
|
|
then fprintf ff "%a" class_name n
|
|
|
|
else fprintf ff "%a<@[%a@]>" class_name n (print_list_r ty """,""") ty_l
|
|
|
|
| Tarray (t,s) -> if news then fprintf ff "%a[%a]" new_ty t exp s else fprintf ff "%a[]" ty t
|
2011-01-20 23:05:18 +01:00
|
|
|
| Tunit -> pp_print_string ff "void"
|
|
|
|
|
2011-03-29 20:43:55 +02:00
|
|
|
and new_ty ff t = _ty true ff t
|
2011-01-20 23:05:18 +01:00
|
|
|
|
2011-02-07 14:24:17 +01:00
|
|
|
and ty ff t = _ty false ff t
|
2011-01-20 23:05:18 +01:00
|
|
|
|
2011-02-07 14:24:17 +01:00
|
|
|
and var_dec init ff vd =
|
|
|
|
if init then
|
|
|
|
fprintf ff "%a %a = %a" ty vd.vd_type var_ident vd.vd_ident exp (Java.default_value vd.vd_type)
|
|
|
|
else
|
|
|
|
fprintf ff "%a %a" ty vd.vd_type var_ident vd.vd_ident
|
2011-01-20 23:05:18 +01:00
|
|
|
|
2011-02-07 14:24:17 +01:00
|
|
|
and vd_list s1 s2 s3 ff vd_l = match vd_l with
|
|
|
|
| [] -> ()
|
|
|
|
| _ -> fprintf ff "@[<v>%a@]@\n" (print_list_r (var_dec true) s1 s2 s3) vd_l
|
2011-01-20 23:05:18 +01:00
|
|
|
|
2011-02-07 14:24:17 +01:00
|
|
|
and field ff f =
|
2011-02-07 16:06:52 +01:00
|
|
|
fprintf ff "@[<2>%a%a%a%a %a%a@]"
|
2011-01-20 23:05:18 +01:00
|
|
|
protection f.f_protection
|
|
|
|
static f.f_static
|
|
|
|
final f.f_final
|
|
|
|
ty f.f_type
|
2011-02-07 14:24:17 +01:00
|
|
|
field_ident f.f_ident
|
2011-01-24 16:07:26 +01:00
|
|
|
(print_opt2 exp " = ") f.f_value
|
2011-01-20 23:05:18 +01:00
|
|
|
|
|
|
|
and exp ff = function
|
2011-02-14 15:21:57 +01:00
|
|
|
| Ethis -> fprintf ff "this"
|
2011-01-20 23:05:18 +01:00
|
|
|
| Eval p -> pattern ff p
|
2011-02-07 14:24:17 +01:00
|
|
|
| Efun (f,e_l) -> op ff (f, e_l)
|
|
|
|
| Emethod_call (o,m,e_l) -> fprintf ff "%a.%a%a" exp o method_name m args e_l
|
2011-03-29 20:43:55 +02:00
|
|
|
| Enew (c,e_l) -> fprintf ff "new %a%a" new_ty c args e_l
|
2011-02-07 14:24:17 +01:00
|
|
|
| Enew_array (t,e_l) ->
|
|
|
|
(match e_l with
|
2011-03-29 20:43:55 +02:00
|
|
|
| [] -> fprintf ff "new %a" new_ty t
|
2011-02-07 14:24:17 +01:00
|
|
|
| _ -> fprintf ff "new %a@[<2>%a@]" ty t (print_list_r exp "{"",""}") e_l )
|
2011-01-20 23:05:18 +01:00
|
|
|
| Evoid -> ()
|
2011-03-21 14:30:19 +01:00
|
|
|
| Ecast (t,e) -> fprintf ff "(%a)(%a)" ty t exp e
|
2011-01-20 23:05:18 +01:00
|
|
|
| Svar c -> const_name ff c
|
|
|
|
| Sint i -> pp_print_int ff i
|
|
|
|
| Sfloat f -> pp_print_float ff f
|
|
|
|
| Sbool b -> pp_print_bool ff b
|
|
|
|
| Sconstructor c -> constructor_name ff c
|
2011-02-14 15:21:57 +01:00
|
|
|
| Sstring s -> fprintf ff "\"%s\"" s
|
2011-02-07 14:24:17 +01:00
|
|
|
| Snull -> fprintf ff "null"
|
|
|
|
|
|
|
|
and op ff (f, e_l) =
|
|
|
|
let javaop = function
|
|
|
|
| "=" -> "=="
|
|
|
|
| "<>" -> "!="
|
|
|
|
| "or" -> "||"
|
|
|
|
| "&" -> "&&"
|
|
|
|
| "*." -> "*"
|
|
|
|
| "/." -> "/"
|
|
|
|
| "+." -> "+"
|
|
|
|
| "-." -> "-"
|
|
|
|
| op -> op
|
|
|
|
in
|
|
|
|
match Names.modul f with
|
|
|
|
| Names.Pervasives ->
|
|
|
|
(match Names.shortname f with
|
|
|
|
|("+" | "-" | "*" | "/"
|
2011-02-14 15:21:57 +01:00
|
|
|
|"+." | "-." | "*." | "/."
|
|
|
|
| "=" | "<>" | "<" | "<="
|
|
|
|
| ">" | ">=" | "&" | "or") as n ->
|
|
|
|
let e1,e2 = Misc.assert_2 e_l in
|
|
|
|
fprintf ff "(@[%a@ %s %a@])" exp e1 (javaop n) exp e2
|
2011-02-07 14:24:17 +01:00
|
|
|
| "not" ->
|
|
|
|
let e = Misc.assert_1 e_l in
|
|
|
|
fprintf ff "!%a" exp e
|
|
|
|
| "~-" ->
|
|
|
|
let e = Misc.assert_1 e_l in
|
|
|
|
fprintf ff "-%a" exp e
|
2011-04-28 15:20:21 +02:00
|
|
|
| "assert" ->
|
|
|
|
let e = Misc.assert_1 e_l in
|
|
|
|
fprintf ff "assert(%a)" exp e
|
2011-03-29 20:43:55 +02:00
|
|
|
| s -> fprintf ff "jeptagon.Pervasives.%s%a" s args e_l)
|
|
|
|
(* TODO java deal with this correctly
|
2011-02-14 15:21:57 +01:00
|
|
|
bug when using Pervasives.ggg in the code but works when using ggg directly *)
|
2011-02-07 14:24:17 +01:00
|
|
|
| _ -> fprintf ff "%a%a" Global_printer.print_qualname f args e_l
|
2011-01-20 23:05:18 +01:00
|
|
|
|
2011-01-24 16:07:26 +01:00
|
|
|
and args ff e_l = fprintf ff "@[(%a)@]" (print_list_r exp """,""") e_l
|
2011-01-20 23:05:18 +01:00
|
|
|
|
|
|
|
and pattern ff = function
|
|
|
|
| Pfield (p,f) -> fprintf ff "%a.%a" pattern p field_name f
|
|
|
|
| Pvar v -> var_ident ff v
|
2011-02-07 14:24:17 +01:00
|
|
|
| Pclass c -> class_name ff c
|
2011-01-20 23:05:18 +01:00
|
|
|
| Parray_elem (p,e) -> fprintf ff "%a[%a]" pattern p exp e
|
|
|
|
| Pthis f -> fprintf ff "this.%a" field_ident f
|
|
|
|
|
|
|
|
let rec block ff b =
|
2011-02-07 14:24:17 +01:00
|
|
|
fprintf ff "%a%a"
|
2011-01-20 23:05:18 +01:00
|
|
|
(vd_list """;"";") b.b_locals
|
2011-02-14 15:21:57 +01:00
|
|
|
(print_list_r act """""") b.b_body
|
2011-01-20 23:05:18 +01:00
|
|
|
|
2011-02-14 15:21:57 +01:00
|
|
|
(*
|
2011-02-07 14:24:17 +01:00
|
|
|
and switch_hack ff c_b_l =
|
2011-03-29 20:43:55 +02:00
|
|
|
fprintf ff "@[<hv 2> default :
|
|
|
|
\\Dead code. Hack to prevent \"may not be initialized\" java error.@ %a@ break;@]"
|
2011-02-07 14:24:17 +01:00
|
|
|
block (c_b_l |> List.hd |> snd)
|
2011-02-14 15:21:57 +01:00
|
|
|
*)
|
2011-02-07 14:24:17 +01:00
|
|
|
|
2011-01-20 23:05:18 +01:00
|
|
|
and act ff = function
|
2011-02-14 15:21:57 +01:00
|
|
|
| Anewvar (vd,e) -> fprintf ff "@[<4>%a =@ %a;@]" (var_dec false) vd exp e
|
|
|
|
| Aassgn (p,e) -> fprintf ff "@[<4>%a =@ %a;@]" pattern p exp e
|
2011-04-28 15:20:21 +02:00
|
|
|
| Aexp e -> fprintf ff "@[%a@];" exp e
|
2011-01-20 23:05:18 +01:00
|
|
|
| Aswitch (e, c_b_l) ->
|
2011-03-29 20:43:55 +02:00
|
|
|
let pcb ff (c,b) =
|
|
|
|
fprintf ff "@[<v4>case %a:@ %a@ break;@]" bare_constructor_name c block b in
|
2011-02-07 14:24:17 +01:00
|
|
|
(* let switch_hack ff c_b_l = (* TODO java : better thing to do ? *)
|
|
|
|
fprintf ff "@[<2>default ://Dead code. Hack to prevent \
|
2011-03-29 20:43:55 +02:00
|
|
|
\"may not be initialized\"
|
|
|
|
java error.@ %a@ break;@]" block (c_b_l |> List.hd |> snd)
|
2011-02-07 14:24:17 +01:00
|
|
|
in*)
|
2011-01-20 23:05:18 +01:00
|
|
|
fprintf ff "@[<v4>switch (%a) {@ %a@]@\n}"
|
|
|
|
exp e
|
|
|
|
(print_list_r pcb """""") c_b_l
|
|
|
|
| Aif (e,bt) ->
|
2011-02-14 15:21:57 +01:00
|
|
|
fprintf ff "@[<v 4>if (%a) {@ %a }@]" exp e block bt
|
2011-01-20 23:05:18 +01:00
|
|
|
| Aifelse (e,bt,bf) ->
|
2011-02-14 15:21:57 +01:00
|
|
|
fprintf ff "@[<v>@[<v4>if (%a) {@ %a@]@ @[<v4>} else {@ %a@]@ }@]"
|
2011-01-20 23:05:18 +01:00
|
|
|
exp e
|
|
|
|
block bt
|
|
|
|
block bf
|
2011-02-14 15:21:57 +01:00
|
|
|
| Ablock b -> if (List.length b.b_body > 0) then fprintf ff "@[<v>@[<v4>{@ %a@]@ }@]" block b
|
2011-01-20 23:05:18 +01:00
|
|
|
| Afor (x, i1, i2, b) ->
|
2011-02-14 15:21:57 +01:00
|
|
|
fprintf ff "@[<hv>@[<hv 4>for (%a = %a; %a<%a; %a++) {@ %a@]@ }@]"
|
2011-02-07 14:24:17 +01:00
|
|
|
(var_dec false) x
|
|
|
|
exp i1
|
|
|
|
var_ident x.vd_ident
|
|
|
|
exp i2
|
|
|
|
var_ident x.vd_ident
|
|
|
|
block b
|
2011-02-14 15:21:57 +01:00
|
|
|
| Areturn e -> fprintf ff "return %a;" exp e
|
2011-01-20 23:05:18 +01:00
|
|
|
|
|
|
|
let methode ff m =
|
2011-02-14 15:21:57 +01:00
|
|
|
fprintf ff "@[<v4>%a%a%a %a @[<4>(%a)@] @[%a@]{@ %a@]@\n}"
|
2011-01-20 23:05:18 +01:00
|
|
|
protection m.m_protection
|
|
|
|
static m.m_static
|
|
|
|
ty m.m_returns
|
|
|
|
method_name m.m_name
|
2011-02-07 14:24:17 +01:00
|
|
|
(print_list_r (var_dec false) """,""") m.m_args
|
2011-02-07 16:06:52 +01:00
|
|
|
(print_list_r class_name "throws "","" ") m.m_throws
|
2011-01-24 16:07:26 +01:00
|
|
|
block m.m_body
|
|
|
|
|
|
|
|
let constructor ff m =
|
2011-02-14 15:21:57 +01:00
|
|
|
fprintf ff "@[<v4>%a%a @[<4>(%a)@] {@\n%a@]@\n}"
|
2011-01-24 16:07:26 +01:00
|
|
|
protection m.m_protection
|
|
|
|
method_name m.m_name
|
2011-02-07 14:24:17 +01:00
|
|
|
(print_list_r (var_dec false) """,""") m.m_args
|
2011-01-20 23:05:18 +01:00
|
|
|
block m.m_body
|
|
|
|
|
|
|
|
let rec class_desc ff cd =
|
|
|
|
fprintf ff "@[<v>%a@ %a@ %a@ %a@]"
|
|
|
|
(print_list_r field """;"";") cd.cd_fields
|
|
|
|
(print_list_r classe """""") cd.cd_classs
|
2011-01-24 16:07:26 +01:00
|
|
|
(print_list constructor """""") cd.cd_constructors
|
|
|
|
(print_list methode """""") cd.cd_methodes
|
2011-01-20 23:05:18 +01:00
|
|
|
|
|
|
|
and classe ff c = match c.c_kind with
|
|
|
|
| Cenum c_l ->
|
2011-02-14 15:21:57 +01:00
|
|
|
fprintf ff "@\n@[<4>%a%aenum %a {@\n%a@]@\n}"
|
2011-01-20 23:05:18 +01:00
|
|
|
protection c.c_protection
|
|
|
|
static c.c_static
|
2011-02-07 14:24:17 +01:00
|
|
|
bare_class_name c.c_name
|
2011-01-20 23:05:18 +01:00
|
|
|
(print_list_r bare_constructor_name """,""") c_l
|
|
|
|
| Cgeneric cd ->
|
2011-02-14 15:21:57 +01:00
|
|
|
fprintf ff "@\n@[<4>%a%aclass %a @[<h>%a@]{@\n%a@]@\n}"
|
2011-01-20 23:05:18 +01:00
|
|
|
protection c.c_protection
|
|
|
|
static c.c_static
|
2011-02-07 14:24:17 +01:00
|
|
|
bare_class_name c.c_name
|
|
|
|
(print_list_r class_name "implements "",""") c.c_implements
|
2011-01-20 23:05:18 +01:00
|
|
|
class_desc cd
|
|
|
|
|
2011-02-07 14:24:17 +01:00
|
|
|
let output_classe base_dir c =
|
|
|
|
let { Names.name = file_name; Names.qual = package } = c.c_name in
|
2011-01-20 23:05:18 +01:00
|
|
|
let file_name = file_name ^ ".java" in
|
2011-02-07 14:24:17 +01:00
|
|
|
let package_dirs = Misc.split_string (Names.modul_to_string package) "." in
|
|
|
|
let create_dir base_dir dir =
|
|
|
|
let dir = Filename.concat base_dir dir in
|
|
|
|
Compiler_utils.ensure_dir dir;
|
|
|
|
dir
|
|
|
|
in
|
|
|
|
let dir = List.fold_left create_dir base_dir package_dirs in
|
2011-01-20 23:05:18 +01:00
|
|
|
let oc = open_out (Filename.concat dir file_name) in
|
|
|
|
let ff = Format.formatter_of_out_channel oc in
|
2011-02-07 14:24:17 +01:00
|
|
|
pp_set_margin ff 120;
|
|
|
|
fprintf ff "package %a;@\n@[<v>%a@]@\n%a@."
|
2011-02-14 15:21:57 +01:00
|
|
|
Global_printer.print_full_modul package
|
2011-02-07 14:24:17 +01:00
|
|
|
(print_list_r (fun ff n -> fprintf ff "import %a" class_name n) """;"";") c.c_imports
|
|
|
|
classe c;
|
2011-01-20 23:05:18 +01:00
|
|
|
close_out oc
|
|
|
|
|
2011-01-24 16:07:26 +01:00
|
|
|
let output_program dir (p:Java.program) =
|
|
|
|
List.iter (output_classe dir) p
|
|
|
|
|