let pretty_print (prog_name, main) =
let get_spaces n =
if n <= 0 then "" else String.make n ' '
in
let string_of_var v =
(string_of_type v.var_type) ^ " " ^ v.var_name
in
let string_of_nature = function
| Varb -> "var"
| Cst -> "cst"
| Funct -> "fun"
| Unknown_nature -> "???"
in
let rec string_of_statement d st =
get_spaces d ^
(
match st.stt_value with
| Assign(v, e) ->
string_of_expression v ^ " := " ^ string_of_expression e
| Proc(v, el) ->
v.var_name ^ " (" ^ String.concat " " (List.map string_of_expression el) ^ ")"
| Compound stts ->
string_of_statements d stts
| If (e, s1, s2) ->
"if " ^ string_of_expression e ^ " then\n" ^ string_of_statement (d + 2) s1 ^ get_spaces d ^ "else\n" ^ string_of_statement (d + 2) s2
| Delete e ->
"delete " ^ string_of_expression e
| Return e ->
"return " ^ string_of_expression e
| While (e, s) ->
"while " ^ string_of_expression e ^ "\n" ^ string_of_statement (d + 2) s
| Noop -> "NOP"
) ^ "\n"
and string_of_statements d stts =
String.concat "" (List.map (string_of_statement (d + 4)) stts)
in
let rec string_of_value d = function
| Constant c -> string_of_expression c
| Variable -> "<var>"
| Function f ->
"<fun>\n" ^ string_of_block (d + 2) f.func_value
| Type t -> "<type : " ^ (string_of_type t) ^ ">"
and string_of_block d block =
(fold_env
(fun n v s ->
s ^
get_spaces d ^ (string_of_nature v.def_nature) ^ " " ^ (string_of_type v.def_type) ^ " " ^ v.def_name ^ " = " ^ (string_of_value d v.def_value) ^ "\n"
) "" block.block_env
) ^ (string_of_statements d block.block_stts)
in
prog_name ^ "\n" ^ (String.make (String.length prog_name) '=') ^ "\n\n" ^ (string_of_block 0 main)