(** This module provides a function to print [LIN] programs. *) let n_spaces n = String.make n ' ' let print_global n (x, size) = Printf.sprintf "%s\"%s\" [%d]" (n_spaces n) x size let print_globals eformat n globs = Eformat.printf eformat "%sglobals:\n" (n_spaces n) ; List.iter (fun g -> Eformat.printf eformat "%s\n" (print_global (n+2) g)) globs let print_reg = I8051.print_register let print_a = print_reg I8051.a let print_statement = function | LIN.St_goto lbl -> "goto " ^ lbl | LIN.St_label lbl -> lbl ^ ":" | LIN.St_comment s -> Printf.sprintf "*** %s ***" s | LIN.St_cost cost_lbl -> Printf.sprintf "emit %s" cost_lbl | LIN.St_int (dstr, i) -> Printf.sprintf "imm %s, %d" (print_reg dstr) i | LIN.St_pop -> Printf.sprintf "pop %s" print_a | LIN.St_push -> Printf.sprintf "push %s" print_a | LIN.St_addr id -> Printf.sprintf "addr DPTR, %s" id | LIN.St_from_acc dstr -> Printf.sprintf "move %s, %s" (print_reg dstr) print_a | LIN.St_to_acc srcr -> Printf.sprintf "move %s, %s" print_a (print_reg srcr) | LIN.St_opaccs opaccs -> Printf.sprintf "%s %s, %s" (I8051.print_opaccs opaccs) print_a (print_reg I8051.b) | LIN.St_op1 op1 -> Printf.sprintf "%s %s" (I8051.print_op1 op1) print_a | LIN.St_op2 (op2, srcr) -> Printf.sprintf "%s %s, %s" (I8051.print_op2 op2) print_a (print_reg srcr) | LIN.St_clear_carry -> "clear CARRY" | LIN.St_set_carry -> "set CARRY" | LIN.St_load -> Printf.sprintf "movex %s, @DPTR" print_a | LIN.St_store -> Printf.sprintf "movex @DPTR, %s" print_a | LIN.St_call_id f -> Printf.sprintf "call \"%s\"" f | LIN.St_call_ptr -> Printf.sprintf "call_ptr DPTR" | LIN.St_condacc lbl_true -> Printf.sprintf "branch %s <> 0, %s" print_a lbl_true | LIN.St_return -> "return" let print_code eformat n c = let f stmt = Eformat.printf eformat "\n%s%s" (n_spaces n) (print_statement stmt) in List.iter f c let print_internal_decl eformat n f def = Eformat.printf eformat "%s\"%s\"\n\n" (n_spaces n) f ; print_code eformat (n+2) def let print_external_decl eformat n f def = Eformat.printf eformat "%sextern \"%s\": %s\n" (n_spaces n) f (Primitive.print_sig def.AST.ef_sig) let print_fun_decl eformat n (f, def) = match def with | LIN.F_int def -> print_internal_decl eformat n f def | LIN.F_ext def -> print_external_decl eformat n f def let print_fun_decls eformat n functs = List.iter (fun f -> print_fun_decl eformat n f ; Eformat.printf eformat "\n\n") functs let print_program p = let eformat = Eformat.create () in Eformat.printf eformat "program:\n\n\n" ; print_globals eformat 2 p.LIN.vars ; Eformat.printf eformat "\n\n" ; print_fun_decls eformat 2 p.LIN.functs ; Eformat.get eformat