ocaml/bytecomp/translclass.ml

117 lines
3.9 KiB
OCaml
Raw Normal View History

(***********************************************************************)
(* *)
(* Objective Caml *)
(* *)
(* Jerome Vouillon, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* Automatique. Distributed only by permission. *)
(* *)
(***********************************************************************)
(* $Id$ *)
open Misc
open Asttypes
open Typedtree
open Lambda
open Translobj
open Translcore
let transl_label l = Lconst (Const_base (Const_string l.Label.lab_name))
(* Instance variable initialization *)
let set_inst_var obj var id expr =
Lprim(Parraysetu (if maybe_pointer expr then Paddrarray else Pintarray),
[Lvar obj; Lvar id; transl_exp expr])
let transl_super tbl inh_methods rem =
List.fold_right
(fun (nm, id) rem ->
Llet(StrictOpt, id, Lapply (oo_prim "get_method",
[Lvar tbl; Lvar (meth nm)]),
rem))
inh_methods rem
let transl_val tbl name id rem =
Llet(StrictOpt, id, Lapply (oo_prim "get_variable",
[Lvar tbl; transl_label name]),
rem)
let transl_private_val tbl name id rem =
Llet(StrictOpt, id, Lapply (oo_prim "get_private_variable",
[Lvar tbl; transl_label name]),
rem)
let transl_vals tbl vals rem =
List.fold_right
(fun (name, id) rem -> transl_val tbl name id rem)
vals rem
let transl_field_obj obj field (obj_init, anc_id) =
match field with
Cf_inher (name, args, vals, meths) ->
let init = Ident.create "init" in
(Lsequence(Lapply(Lvar init, Lvar obj :: (List.map transl_exp args)),
obj_init),
init::anc_id)
| Cf_val (name, id, priv, Some exp) ->
(Lsequence(set_inst_var obj name id exp, obj_init),
anc_id)
| Cf_val (name, id, priv, None) ->
(obj_init, anc_id)
| Cf_meth (name, exp) ->
(obj_init, anc_id)
let transl_field_cl tbl field cl_init =
match field with
Cf_inher (name, args, vals, meths) ->
Lsequence(Lapply (oo_prim "inheritance", [Lvar tbl; transl_path name]),
transl_vals tbl vals (
transl_super tbl meths cl_init))
| Cf_val (name, id, priv, exp) ->
if priv = Private then
transl_private_val tbl name id cl_init
else
transl_val tbl name id cl_init
| Cf_meth (name, exp) ->
Lsequence(Lapply (oo_prim "set_method",
[Lvar tbl; Lvar (meth name); transl_exp exp]),
cl_init)
let transl_val_hiding tbl field cl_init =
match field with
Cf_inher _ | Cf_meth _ | Cf_val (_, _, Public, _) ->
cl_init
| Cf_val (name, id, Private, exp) ->
Lsequence(Lapply (oo_prim "hide_variable",
[Lvar tbl; transl_label name]),
cl_init)
let transl_class cl =
let obj = Ident.create "obj" in
let (field_init, anc_id) =
List.fold_right (transl_field_obj obj) cl.cl_field (Lvar obj, [])
in
let (params, body) =
List.fold_right
(fun pat (params, rem) ->
let param = name_pattern "param" [pat, ()] in
(param::params,
Matching.for_function pat.pat_loc (Lvar param) [pat, rem]))
cl.cl_args
([], field_init)
in
let obj_init = Lfunction(anc_id @ obj::params, body) in
let table = Ident.create "table" in
let cl_init =
Lfunction ([table],
List.fold_right (transl_val_hiding table) cl.cl_field
(List.fold_right (transl_field_cl table) cl.cl_field
(Lapply (oo_prim "set_initializer",
[Lvar table; obj_init]))))
in
Lapply (oo_prim "create_class", [cl_init])