1995-08-09 08:06:35 -07:00
|
|
|
(***********************************************************************)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Objective Caml *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* Automatique. Distributed only by permission. *)
|
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
|
|
|
(* $Id$ *)
|
|
|
|
|
1995-08-23 04:55:54 -07:00
|
|
|
open Misc
|
1995-05-04 03:15:53 -07:00
|
|
|
open Path
|
|
|
|
open Asttypes
|
|
|
|
|
|
|
|
type primitive =
|
|
|
|
Pidentity
|
1995-07-27 10:40:34 -07:00
|
|
|
(* Globals *)
|
1995-05-04 03:15:53 -07:00
|
|
|
| Pgetglobal of Ident.t
|
|
|
|
| Psetglobal of Ident.t
|
1995-07-27 10:40:34 -07:00
|
|
|
(* Operations on heap blocks *)
|
1995-11-09 05:22:16 -08:00
|
|
|
| Pmakeblock of int * mutable_flag
|
1995-05-04 03:15:53 -07:00
|
|
|
| Pfield of int
|
1995-07-10 02:48:27 -07:00
|
|
|
| Psetfield of int * bool
|
1995-07-27 10:40:34 -07:00
|
|
|
| Pfloatfield of int
|
|
|
|
| Psetfloatfield of int
|
|
|
|
(* External call *)
|
|
|
|
| Pccall of Primitive.description
|
|
|
|
(* Exceptions *)
|
1995-05-04 03:15:53 -07:00
|
|
|
| Praise
|
1995-07-27 10:40:34 -07:00
|
|
|
(* Boolean operations *)
|
1995-05-04 03:15:53 -07:00
|
|
|
| Psequand | Psequor | Pnot
|
1995-07-27 10:40:34 -07:00
|
|
|
(* Integer operations *)
|
1995-05-04 03:15:53 -07:00
|
|
|
| Pnegint | Paddint | Psubint | Pmulint | Pdivint | Pmodint
|
|
|
|
| Pandint | Porint | Pxorint
|
|
|
|
| Plslint | Plsrint | Pasrint
|
1995-06-18 07:44:56 -07:00
|
|
|
| Pintcomp of comparison
|
1995-05-04 03:15:53 -07:00
|
|
|
| Poffsetint of int
|
|
|
|
| Poffsetref of int
|
1995-07-27 10:40:34 -07:00
|
|
|
(* Float operations *)
|
1995-07-11 01:53:14 -07:00
|
|
|
| Pintoffloat | Pfloatofint
|
1996-03-07 05:45:57 -08:00
|
|
|
| Pnegfloat | Pabsfloat
|
|
|
|
| Paddfloat | Psubfloat | Pmulfloat | Pdivfloat
|
1995-06-18 07:44:56 -07:00
|
|
|
| Pfloatcomp of comparison
|
1995-07-27 10:40:34 -07:00
|
|
|
(* String operations *)
|
|
|
|
| Pstringlength | Pstringrefu | Pstringsetu | Pstringrefs | Pstringsets
|
|
|
|
(* Array operations *)
|
|
|
|
| Pmakearray of array_kind
|
|
|
|
| Parraylength of array_kind
|
|
|
|
| Parrayrefu of array_kind
|
|
|
|
| Parraysetu of array_kind
|
|
|
|
| Parrayrefs of array_kind
|
|
|
|
| Parraysets of array_kind
|
1996-04-04 07:55:29 -08:00
|
|
|
(* Bitvect operations *)
|
|
|
|
| Pbittest
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
and comparison =
|
|
|
|
Ceq | Cneq | Clt | Cgt | Cle | Cge
|
|
|
|
|
1995-07-27 10:40:34 -07:00
|
|
|
and array_kind =
|
|
|
|
Pgenarray | Paddrarray | Pintarray | Pfloatarray
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
type structured_constant =
|
|
|
|
Const_base of constant
|
1995-07-02 09:45:21 -07:00
|
|
|
| Const_pointer of int
|
1995-07-27 10:40:34 -07:00
|
|
|
| Const_block of int * structured_constant list
|
|
|
|
| Const_float_array of string list
|
1995-05-04 03:15:53 -07:00
|
|
|
|
1996-10-22 06:36:59 -07:00
|
|
|
type function_kind = Curried | Tupled
|
|
|
|
|
1998-04-30 05:12:28 -07:00
|
|
|
type let_kind = Strict | Alias | StrictOpt | Variable
|
1996-04-22 04:15:41 -07:00
|
|
|
|
|
|
|
type shared_code = (int * int) list
|
1995-12-15 02:18:29 -08:00
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
type lambda =
|
|
|
|
Lvar of Ident.t
|
|
|
|
| Lconst of structured_constant
|
|
|
|
| Lapply of lambda * lambda list
|
1996-10-22 06:36:59 -07:00
|
|
|
| Lfunction of function_kind * Ident.t list * lambda
|
1995-12-15 02:18:29 -08:00
|
|
|
| Llet of let_kind * Ident.t * lambda * lambda
|
1995-07-02 09:45:21 -07:00
|
|
|
| Lletrec of (Ident.t * lambda) list * lambda
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lprim of primitive * lambda list
|
1996-04-04 07:55:29 -08:00
|
|
|
| Lswitch of lambda * lambda_switch
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lstaticfail
|
|
|
|
| Lcatch of lambda * lambda
|
|
|
|
| Ltrywith of lambda * Ident.t * lambda
|
|
|
|
| Lifthenelse of lambda * lambda * lambda
|
|
|
|
| Lsequence of lambda * lambda
|
|
|
|
| Lwhile of lambda * lambda
|
|
|
|
| Lfor of Ident.t * lambda * lambda * direction_flag * lambda
|
1995-11-25 07:38:43 -08:00
|
|
|
| Lassign of Ident.t * lambda
|
1996-04-22 04:15:41 -07:00
|
|
|
| Lsend of lambda * lambda * lambda list
|
1996-11-29 10:36:42 -08:00
|
|
|
| Levent of lambda * lambda_event
|
1998-06-24 12:22:26 -07:00
|
|
|
| Lifused of Ident.t * lambda
|
1995-05-04 03:15:53 -07:00
|
|
|
|
1996-04-04 07:55:29 -08:00
|
|
|
and lambda_switch =
|
|
|
|
{ sw_numconsts: int;
|
|
|
|
sw_consts: (int * lambda) list;
|
|
|
|
sw_numblocks: int;
|
|
|
|
sw_blocks: (int * lambda) list;
|
|
|
|
sw_checked: bool }
|
|
|
|
|
1996-11-29 10:36:42 -08:00
|
|
|
and lambda_event =
|
|
|
|
{ lev_loc: int;
|
|
|
|
lev_kind: lambda_event_kind;
|
1997-03-27 12:53:30 -08:00
|
|
|
lev_repr: int ref option;
|
1996-11-29 10:36:42 -08:00
|
|
|
lev_env: Env.summary }
|
|
|
|
|
|
|
|
and lambda_event_kind =
|
|
|
|
Lev_before
|
|
|
|
| Lev_after of Types.type_expr
|
1997-03-27 12:53:30 -08:00
|
|
|
| Lev_function
|
1996-11-29 10:36:42 -08:00
|
|
|
|
1996-01-09 01:47:53 -08:00
|
|
|
let const_unit = Const_pointer 0
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let lambda_unit = Lconst const_unit
|
|
|
|
|
|
|
|
let name_lambda arg fn =
|
|
|
|
match arg with
|
|
|
|
Lvar id -> fn id
|
1996-04-22 04:15:41 -07:00
|
|
|
| _ -> let id = Ident.create "let" in Llet(Strict, id, arg, fn id)
|
1995-05-04 03:15:53 -07:00
|
|
|
|
1995-07-02 09:45:21 -07:00
|
|
|
let name_lambda_list args fn =
|
|
|
|
let rec name_list names = function
|
|
|
|
[] -> fn (List.rev names)
|
|
|
|
| (Lvar id as arg) :: rem ->
|
|
|
|
name_list (arg :: names) rem
|
|
|
|
| arg :: rem ->
|
1996-04-22 04:15:41 -07:00
|
|
|
let id = Ident.create "let" in
|
1995-12-15 02:18:29 -08:00
|
|
|
Llet(Strict, id, arg, name_list (Lvar id :: names) rem) in
|
1995-07-02 09:45:21 -07:00
|
|
|
name_list [] args
|
|
|
|
|
1995-05-30 06:36:40 -07:00
|
|
|
module IdentSet =
|
|
|
|
Set.Make(struct
|
|
|
|
type t = Ident.t
|
|
|
|
let compare = compare
|
|
|
|
end)
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
let free_variables l =
|
1995-05-30 06:36:40 -07:00
|
|
|
let fv = ref IdentSet.empty in
|
1995-05-04 03:15:53 -07:00
|
|
|
let rec freevars = function
|
|
|
|
Lvar id ->
|
1995-05-30 06:36:40 -07:00
|
|
|
fv := IdentSet.add id !fv
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lconst sc -> ()
|
|
|
|
| Lapply(fn, args) ->
|
|
|
|
freevars fn; List.iter freevars args
|
1996-10-22 06:36:59 -07:00
|
|
|
| Lfunction(kind, params, body) ->
|
1995-12-19 02:19:12 -08:00
|
|
|
freevars body;
|
|
|
|
List.iter (fun param -> fv := IdentSet.remove param !fv) params
|
1995-12-15 02:18:29 -08:00
|
|
|
| Llet(str, id, arg, body) ->
|
1995-05-30 06:36:40 -07:00
|
|
|
freevars arg; freevars body; fv := IdentSet.remove id !fv
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lletrec(decl, body) ->
|
|
|
|
freevars body;
|
1995-07-02 09:45:21 -07:00
|
|
|
List.iter (fun (id, exp) -> freevars exp) decl;
|
|
|
|
List.iter (fun (id, exp) -> fv := IdentSet.remove id !fv) decl
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lprim(p, args) ->
|
|
|
|
List.iter freevars args
|
1996-04-04 07:55:29 -08:00
|
|
|
| Lswitch(arg, sw) ->
|
1995-06-18 07:44:56 -07:00
|
|
|
freevars arg;
|
1996-04-04 07:55:29 -08:00
|
|
|
List.iter (fun (key, case) -> freevars case) sw.sw_consts;
|
|
|
|
List.iter (fun (key, case) -> freevars case) sw.sw_blocks
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lstaticfail -> ()
|
|
|
|
| Lcatch(e1, e2) ->
|
|
|
|
freevars e1; freevars e2
|
|
|
|
| Ltrywith(e1, exn, e2) ->
|
1995-05-30 06:36:40 -07:00
|
|
|
freevars e1; freevars e2; fv := IdentSet.remove exn !fv
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lifthenelse(e1, e2, e3) ->
|
|
|
|
freevars e1; freevars e2; freevars e3
|
|
|
|
| Lsequence(e1, e2) ->
|
|
|
|
freevars e1; freevars e2
|
|
|
|
| Lwhile(e1, e2) ->
|
|
|
|
freevars e1; freevars e2
|
|
|
|
| Lfor(v, e1, e2, dir, e3) ->
|
1995-05-30 06:36:40 -07:00
|
|
|
freevars e1; freevars e2; freevars e3; fv := IdentSet.remove v !fv
|
1995-11-25 07:38:43 -08:00
|
|
|
| Lassign(id, e) ->
|
|
|
|
fv := IdentSet.add id !fv; freevars e
|
1996-04-22 04:15:41 -07:00
|
|
|
| Lsend (met, obj, args) ->
|
|
|
|
List.iter freevars (met::obj::args)
|
1996-11-29 10:36:42 -08:00
|
|
|
| Levent (lam, evt) ->
|
|
|
|
freevars lam
|
1998-06-24 12:22:26 -07:00
|
|
|
| Lifused (v, e) ->
|
|
|
|
freevars e
|
1995-07-02 09:45:21 -07:00
|
|
|
in freevars l; !fv
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
(* Check if an action has a "when" guard *)
|
|
|
|
|
|
|
|
let rec is_guarded = function
|
|
|
|
Lifthenelse(cond, body, Lstaticfail) -> true
|
1995-12-15 02:18:29 -08:00
|
|
|
| Llet(str, id, lam, body) -> is_guarded body
|
1997-02-19 08:08:05 -08:00
|
|
|
| Levent(lam, ev) -> is_guarded lam
|
1995-05-04 03:15:53 -07:00
|
|
|
| _ -> false
|
|
|
|
|
|
|
|
let rec transl_path = function
|
|
|
|
Pident id ->
|
|
|
|
if Ident.global id then Lprim(Pgetglobal id, []) else Lvar id
|
|
|
|
| Pdot(p, s, pos) ->
|
|
|
|
Lprim(Pfield pos, [transl_path p])
|
1995-08-23 04:55:54 -07:00
|
|
|
| Papply(p1, p2) ->
|
|
|
|
fatal_error "Lambda.transl_path"
|