ocaml/bytecomp/printlambda.ml

283 lines
11 KiB
OCaml
Raw Normal View History

(***********************************************************************)
(* *)
(* Objective Caml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* en Automatique. All rights reserved. This file is distributed *)
(* under the terms of the Q Public License version 1.0. *)
(* *)
(***********************************************************************)
(* $Id$ *)
open Format
open Asttypes
open Primitive
open Types
open Lambda
let rec struct_const ppf = function
| Const_base(Const_int n) -> fprintf ppf "%i" n
| Const_base(Const_char c) ->
fprintf ppf "'%s'" (Char.escaped c)
| Const_base(Const_string s) ->
fprintf ppf "\"%s\"" (String.escaped s)
| Const_base(Const_float s) ->
fprintf ppf "%s" s
| Const_pointer n -> fprintf ppf "%ia" n
| Const_block(tag, []) ->
fprintf ppf "[%i]" tag
| Const_block(tag, sc1::scl) ->
let sconsts ppf scl =
List.iter (fun sc -> fprintf ppf "@ %a" struct_const sc) scl in
fprintf ppf "@[<1>[%i:@ @[%a%a@]]@]" tag struct_const sc1 sconsts scl
| Const_float_array [] ->
fprintf ppf "[| |]"
| Const_float_array (f1 :: fl) ->
let floats ppf fl =
List.iter (fun f -> fprintf ppf "@ %s" f) fl in
fprintf ppf "@[<1[|@[%s%a@]|]@]" f1 floats fl
let print_id ppf id = Ident.print id
let boxed_integer_name = function
| Pnativeint -> "nativeint"
| Pint32 -> "int32"
| Pint64 -> "int64"
let print_boxed_integer name ppf bi =
fprintf ppf "%s_%s" (boxed_integer_name bi) name
let print_boxed_integer_conversion ppf bi1 bi2 =
fprintf ppf "%s_of_%s" (boxed_integer_name bi2) (boxed_integer_name bi1)
let boxed_integer_mark name = function
| Pnativeint -> Printf.sprintf "Nativeint.%s" name
| Pint32 -> Printf.sprintf "Int32.%s" name
| Pint64 -> Printf.sprintf "Int64.%s" name
let print_boxed_integer name ppf bi =
fprintf ppf "%s" (boxed_integer_mark name bi);;
let print_bigarray name kind ppf layout =
fprintf ppf "Bigarray.%s[%s,%s]"
name
(match kind with
| Pbigarray_unknown -> "generic"
| Pbigarray_float32 -> "float32"
| Pbigarray_float64 -> "float64"
| Pbigarray_sint8 -> "sint8"
| Pbigarray_uint8 -> "uint8"
| Pbigarray_sint16 -> "sint16"
| Pbigarray_uint16 -> "uint16"
| Pbigarray_int32 -> "int32"
| Pbigarray_int64 -> "int64"
| Pbigarray_caml_int -> "camlint"
| Pbigarray_native_int -> "nativeint")
(match layout with
| Pbigarray_unknown_layout -> "unknown"
| Pbigarray_c_layout -> "C"
| Pbigarray_fortran_layout -> "Fortran")
let primitive ppf = function
| Pidentity -> fprintf ppf "id"
| Pignore -> fprintf ppf "ignore"
| Pgetglobal id -> fprintf ppf "global %a" print_id id
| Psetglobal id -> fprintf ppf "setglobal %a" print_id id
| Pmakeblock(tag, Immutable) -> fprintf ppf "makeblock %i" tag
| Pmakeblock(tag, Mutable) -> fprintf ppf "makemutable %i" tag
| Pfield n -> fprintf ppf "field %i" n
| Psetfield(n, ptr) ->
let instr = if ptr then "setfield_ptr " else "setfield_imm " in
fprintf ppf "%s%i" instr n
| Pfloatfield n -> fprintf ppf "floatfield %i" n
| Psetfloatfield n -> fprintf ppf "setfloatfield %i" n
| Pccall p -> fprintf ppf "%s" p.prim_name
| Praise -> fprintf ppf "raise"
| Psequand -> fprintf ppf "&&"
| Psequor -> fprintf ppf "||"
| Pnot -> fprintf ppf "not"
| Pnegint -> fprintf ppf "~"
| Paddint -> fprintf ppf "+"
| Psubint -> fprintf ppf "-"
| Pmulint -> fprintf ppf "*"
| Pdivint -> fprintf ppf "/"
| Pmodint -> fprintf ppf "mod"
| Pandint -> fprintf ppf "and"
| Porint -> fprintf ppf "or"
| Pxorint -> fprintf ppf "xor"
| Plslint -> fprintf ppf "lsl"
| Plsrint -> fprintf ppf "lsr"
| Pasrint -> fprintf ppf "asr"
| Pintcomp(Ceq) -> fprintf ppf "=="
| Pintcomp(Cneq) -> fprintf ppf "!="
| Pintcomp(Clt) -> fprintf ppf "<"
| Pintcomp(Cle) -> fprintf ppf "<="
| Pintcomp(Cgt) -> fprintf ppf ">"
| Pintcomp(Cge) -> fprintf ppf ">="
| Poffsetint n -> fprintf ppf "%i+" n
| Poffsetref n -> fprintf ppf "+:=%i"n
| Pintoffloat -> fprintf ppf "int_of_float"
| Pfloatofint -> fprintf ppf "float_of_int"
| Pnegfloat -> fprintf ppf "~."
| Pabsfloat -> fprintf ppf "abs."
| Paddfloat -> fprintf ppf "+."
| Psubfloat -> fprintf ppf "-."
| Pmulfloat -> fprintf ppf "*."
| Pdivfloat -> fprintf ppf "/."
| Pfloatcomp(Ceq) -> fprintf ppf "==."
| Pfloatcomp(Cneq) -> fprintf ppf "!=."
| Pfloatcomp(Clt) -> fprintf ppf "<."
| Pfloatcomp(Cle) -> fprintf ppf "<=."
| Pfloatcomp(Cgt) -> fprintf ppf ">."
| Pfloatcomp(Cge) -> fprintf ppf ">=."
| Pstringlength -> fprintf ppf "string.length"
| Pstringrefu -> fprintf ppf "string.unsafe_get"
| Pstringsetu -> fprintf ppf "string.unsafe_set"
| Pstringrefs -> fprintf ppf "string.get"
| Pstringsets -> fprintf ppf "string.set"
| Parraylength _ -> fprintf ppf "array.length"
| Pmakearray _ -> fprintf ppf "makearray "
| Parrayrefu _ -> fprintf ppf "array.unsafe_get"
| Parraysetu _ -> fprintf ppf "array.unsafe_set"
| Parrayrefs _ -> fprintf ppf "array.get"
| Parraysets _ -> fprintf ppf "array.set"
| Pisint -> fprintf ppf "isint"
| Pbittest -> fprintf ppf "testbit"
| Pbintofint bi -> print_boxed_integer "of_int" ppf bi
| Pintofbint bi -> print_boxed_integer "to_int" ppf bi
| Pcvtbint (bi1, bi2) -> print_boxed_integer_conversion ppf bi1 bi2
| Pnegbint bi -> print_boxed_integer "neg" ppf bi
| Paddbint bi -> print_boxed_integer "add" ppf bi
| Psubbint bi -> print_boxed_integer "sub" ppf bi
| Pmulbint bi -> print_boxed_integer "mul" ppf bi
| Pdivbint bi -> print_boxed_integer "div" ppf bi
| Pmodbint bi -> print_boxed_integer "mod" ppf bi
| Pandbint bi -> print_boxed_integer "and" ppf bi
| Porbint bi -> print_boxed_integer "or" ppf bi
| Pxorbint bi -> print_boxed_integer "xor" ppf bi
| Plslbint bi -> print_boxed_integer "lsl" ppf bi
| Plsrbint bi -> print_boxed_integer "lsr" ppf bi
| Pasrbint bi -> print_boxed_integer "asr" ppf bi
| Pbintcomp(bi, Ceq) -> print_boxed_integer "==" ppf bi
| Pbintcomp(bi, Cneq) -> print_boxed_integer "!=" ppf bi
| Pbintcomp(bi, Clt) -> print_boxed_integer "<" ppf bi
| Pbintcomp(bi, Cgt) -> print_boxed_integer ">" ppf bi
| Pbintcomp(bi, Cle) -> print_boxed_integer "<=" ppf bi
| Pbintcomp(bi, Cge) -> print_boxed_integer ">=" ppf bi
| Pbigarrayref(n, kind, layout) -> print_bigarray "get" kind ppf layout
| Pbigarrayset(n, kind, layout) -> print_bigarray "set" kind ppf layout
let rec lam ppf = function
| Lvar id ->
print_id ppf id
| Lconst cst ->
struct_const ppf cst
| Lapply(lfun, largs) ->
let lams ppf largs =
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in
fprintf ppf "@[<2>(apply@ %a%a)@]" lam lfun lams largs
| Lfunction(kind, params, body) ->
let pr_params ppf params =
match kind with
| Curried ->
List.iter (fun param -> fprintf ppf "@ %a" print_id param) params
| Tupled ->
fprintf ppf " (";
let first = ref true in
List.iter
(fun param ->
if !first then first := false else fprintf ppf ",@ ";
print_id ppf param)
params;
fprintf ppf ")" in
fprintf ppf "@[<2>(function%a@ %a)@]" pr_params params lam body
| Llet(str, id, arg, body) ->
let rec letbody = function
| Llet(str, id, arg, body) ->
fprintf ppf "@ @[<2>%a@ %a@]" print_id id lam arg;
letbody body
| expr -> expr in
fprintf ppf "@[<2>(let@ @[<hv 1>(@[<2>%a@ %a@]" print_id id lam arg;
let expr = letbody body in
fprintf ppf ")@]@ %a)@]" lam expr
| Lletrec(id_arg_list, body) ->
let bindings ppf id_arg_list =
let spc = ref false in
List.iter
(fun (id, l) ->
if !spc then print_space() else spc := true;
fprintf ppf "@[<2>%a@ %a@]" print_id id lam l)
id_arg_list in
fprintf ppf
"@[<2>(letrec@ (@[<hv 1>%a@])@ %a)@]" bindings id_arg_list lam body
| Lprim(prim, largs) ->
let lams ppf largs =
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in
fprintf ppf "@[<2>(%a%a)@]" primitive prim lams largs
| Lswitch(larg, sw) ->
let switch ppf sw =
let spc = ref false in
List.iter
(fun (n, l) ->
if !spc then print_space() else spc := true;
fprintf ppf "@[<hv 1>case int %i:@ %a@]" n lam l)
sw.sw_consts;
List.iter
(fun (n, l) ->
if !spc then print_space() else spc := true;
fprintf ppf "@[<hv 1>case tag %i:@ %a@]" n lam l)
sw.sw_blocks in
fprintf ppf
"@[<1>(%s%a@ @[<v 0>%a@])@]"
(if sw.sw_checked then "switch-checked " else "switch ")
lam larg switch sw
| Lstaticfail ->
fprintf ppf "exit"
| Lcatch(lbody, lhandler) ->
fprintf ppf "@[<2>(catch@ %a@;<1 -1>with@ %a)@]" lam lbody lam lhandler
| Ltrywith(lbody, param, lhandler) ->
fprintf ppf "@[<2>(try@ %a@;<1 -1>with %a@ %a)@]"
lam lbody print_id param lam lhandler
| Lifthenelse(lcond, lif, lelse) ->
fprintf ppf "@[<2>(if@ %a@ %a@ %a)@]" lam lcond lam lif lam lelse
| Lsequence(l1, l2) ->
fprintf ppf "@[<2>(seq@ %a@ %a)@]" lam l1 sequence l2
| Lwhile(lcond, lbody) ->
fprintf ppf "@[<2>(while@ %a@ %a)@]" lam lcond lam lbody
| Lfor(param, lo, hi, dir, body) ->
fprintf ppf "@[<2>(for %a@ %a@ %s@ %a@ %a)@]"
print_id param lam lo
(match dir with Upto -> "to" | Downto -> "downto")
lam hi lam body
| Lassign(id, expr) ->
fprintf ppf "@[<2>(assign@ %a@ %a)@]" print_id id lam expr
| Lsend (met, obj, largs) ->
let args ppf largs =
List.iter (fun l -> fprintf ppf "@ %a" lam l) largs in
fprintf ppf "@[<2>(send@ %a@ %a%a)@]" lam obj lam met args largs
| Levent(expr, ev) ->
let kind =
match ev.lev_kind with
| Lev_before -> "before"
| Lev_after _ -> "after"
| Lev_function -> "funct-body" in
fprintf ppf "@[<2>(%s %i@ %a)@]" kind ev.lev_loc lam expr
| Lifused(id, expr) ->
fprintf ppf "@[<2>(ifused@ %a@ %a)@]" print_id id lam expr
and sequence ppf = function
| Lsequence(l1, l2) ->
fprintf ppf "%a@ %a" sequence l1 sequence l2
| Llet(str, id, arg, body) ->
fprintf ppf "@[<2>let@ %a@ %a@]@ %a" print_id id lam arg sequence body
| l ->
lam ppf l
let structured_constant = struct_const
let lambda = lam