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 *)
|
1999-11-17 10:59:06 -08:00
|
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
|
|
(* under the terms of the Q Public License version 1.0. *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
|
|
|
(* $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
|
1999-02-24 07:21:50 -08:00
|
|
|
| Pignore
|
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
|
1999-12-06 08:59:24 -08:00
|
|
|
(* Test if the argument is a block or an immediate integer *)
|
|
|
|
| Pisint
|
2000-10-02 07:18:05 -07:00
|
|
|
(* Test if the (integer) argument is outside an interval *)
|
|
|
|
| Pisout
|
1996-04-04 07:55:29 -08:00
|
|
|
(* Bitvect operations *)
|
|
|
|
| Pbittest
|
2000-02-21 10:14:56 -08:00
|
|
|
(* Operations on boxed integers (Nativeint.t, Int32.t, Int64.t) *)
|
|
|
|
| Pbintofint of boxed_integer
|
|
|
|
| Pintofbint of boxed_integer
|
2000-03-05 11:17:54 -08:00
|
|
|
| Pcvtbint of boxed_integer (*source*) * boxed_integer (*destination*)
|
2000-02-21 10:14:56 -08:00
|
|
|
| Pnegbint of boxed_integer
|
|
|
|
| Paddbint of boxed_integer
|
|
|
|
| Psubbint of boxed_integer
|
|
|
|
| Pmulbint of boxed_integer
|
|
|
|
| Pdivbint of boxed_integer
|
|
|
|
| Pmodbint of boxed_integer
|
|
|
|
| Pandbint of boxed_integer
|
|
|
|
| Porbint of boxed_integer
|
|
|
|
| Pxorbint of boxed_integer
|
|
|
|
| Plslbint of boxed_integer
|
|
|
|
| Plsrbint of boxed_integer
|
|
|
|
| Pasrbint of boxed_integer
|
|
|
|
| Pbintcomp of boxed_integer * comparison
|
2000-02-28 07:45:50 -08:00
|
|
|
(* Operations on big arrays *)
|
|
|
|
| Pbigarrayref of int * bigarray_kind * bigarray_layout
|
|
|
|
| Pbigarrayset of int * bigarray_kind * bigarray_layout
|
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
|
|
|
|
|
2000-02-21 10:14:56 -08:00
|
|
|
and boxed_integer =
|
|
|
|
Pnativeint | Pint32 | Pint64
|
|
|
|
|
2000-02-28 07:45:50 -08:00
|
|
|
and bigarray_kind =
|
|
|
|
Pbigarray_unknown
|
|
|
|
| Pbigarray_float32 | Pbigarray_float64
|
|
|
|
| Pbigarray_sint8 | Pbigarray_uint8
|
|
|
|
| Pbigarray_sint16 | Pbigarray_uint16
|
2005-08-25 08:35:16 -07:00
|
|
|
| Pbigarray_int32 | Pbigarray_int64
|
2000-02-28 07:45:50 -08:00
|
|
|
| Pbigarray_caml_int | Pbigarray_native_int
|
2002-02-10 09:01:27 -08:00
|
|
|
| Pbigarray_complex32 | Pbigarray_complex64
|
2000-02-28 07:45:50 -08:00
|
|
|
|
|
|
|
and bigarray_layout =
|
|
|
|
Pbigarray_unknown_layout
|
|
|
|
| Pbigarray_c_layout
|
|
|
|
| Pbigarray_fortran_layout
|
|
|
|
|
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
|
2004-11-29 23:28:00 -08:00
|
|
|
| Const_immstring of string
|
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
|
|
|
|
2004-05-26 04:10:52 -07:00
|
|
|
type meth_kind = Self | Public | Cached
|
|
|
|
|
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
|
2000-10-02 07:18:05 -07:00
|
|
|
| Lstaticraise of int * lambda list
|
|
|
|
| Lstaticcatch of lambda * (int * Ident.t list) * lambda
|
1995-05-04 03:15:53 -07:00
|
|
|
| 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
|
2004-05-26 04:10:52 -07:00
|
|
|
| Lsend of meth_kind * 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;
|
2001-02-19 12:27:52 -08:00
|
|
|
sw_failaction : lambda option}
|
1996-04-04 07:55:29 -08:00
|
|
|
|
1996-11-29 10:36:42 -08:00
|
|
|
and lambda_event =
|
2005-08-25 08:35:16 -07:00
|
|
|
{ lev_loc: Location.t;
|
1996-11-29 10:36:42 -08:00
|
|
|
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
|
|
|
|
|
2004-07-13 05:19:15 -07:00
|
|
|
let rec same l1 l2 =
|
|
|
|
match (l1, l2) with
|
|
|
|
| Lvar v1, Lvar v2 ->
|
|
|
|
Ident.same v1 v2
|
|
|
|
| Lconst c1, Lconst c2 ->
|
|
|
|
c1 = c2
|
|
|
|
| Lapply(a1, bl1), Lapply(a2, bl2) ->
|
|
|
|
same a1 a2 && samelist same bl1 bl2
|
|
|
|
| Lfunction(k1, idl1, a1), Lfunction(k2, idl2, a2) ->
|
|
|
|
k1 = k2 && samelist Ident.same idl1 idl2 && same a1 a2
|
|
|
|
| Llet(k1, id1, a1, b1), Llet(k2, id2, a2, b2) ->
|
|
|
|
k1 = k2 && Ident.same id1 id2 && same a1 a2 && same b1 b2
|
|
|
|
| Lletrec (bl1, a1), Lletrec (bl2, a2) ->
|
|
|
|
samelist samebinding bl1 bl2 && same a1 a2
|
|
|
|
| Lprim(p1, al1), Lprim(p2, al2) ->
|
|
|
|
p1 = p2 && samelist same al1 al2
|
|
|
|
| Lswitch(a1, s1), Lswitch(a2, s2) ->
|
|
|
|
same a1 a2 && sameswitch s1 s2
|
|
|
|
| Lstaticraise(n1, al1), Lstaticraise(n2, al2) ->
|
|
|
|
n1 = n2 && samelist same al1 al2
|
|
|
|
| Lstaticcatch(a1, (n1, idl1), b1), Lstaticcatch(a2, (n2, idl2), b2) ->
|
|
|
|
same a1 a2 && n1 = n2 && samelist Ident.same idl1 idl2 && same b1 b2
|
|
|
|
| Ltrywith(a1, id1, b1), Ltrywith(a2, id2, b2) ->
|
|
|
|
same a1 a2 && Ident.same id1 id2 && same b1 b2
|
|
|
|
| Lifthenelse(a1, b1, c1), Lifthenelse(a2, b2, c2) ->
|
|
|
|
same a1 a2 && same b1 b2 && same c1 c2
|
|
|
|
| Lsequence(a1, b1), Lsequence(a2, b2) ->
|
|
|
|
same a1 a2 && same b1 b2
|
|
|
|
| Lwhile(a1, b1), Lwhile(a2, b2) ->
|
|
|
|
same a1 a2 && same b1 b2
|
|
|
|
| Lfor(id1, a1, b1, df1, c1), Lfor(id2, a2, b2, df2, c2) ->
|
|
|
|
Ident.same id1 id2 && same a1 a2 &&
|
|
|
|
same b1 b2 && df1 = df2 && same c1 c2
|
|
|
|
| Lassign(id1, a1), Lassign(id2, a2) ->
|
|
|
|
Ident.same id1 id2 && same a1 a2
|
|
|
|
| Lsend(k1, a1, b1, cl1), Lsend(k2, a2, b2, cl2) ->
|
|
|
|
k1 = k2 && same a1 a2 && same b1 b2 && samelist same cl1 cl2
|
|
|
|
| Levent(a1, ev1), Levent(a2, ev2) ->
|
2005-08-25 08:35:16 -07:00
|
|
|
same a1 a2 && ev1.lev_loc = ev2.lev_loc
|
2004-07-13 05:19:15 -07:00
|
|
|
| Lifused(id1, a1), Lifused(id2, a2) ->
|
|
|
|
Ident.same id1 id2 && same a1 a2
|
|
|
|
| _, _ ->
|
|
|
|
false
|
|
|
|
|
|
|
|
and samebinding (id1, c1) (id2, c2) =
|
|
|
|
Ident.same id1 id2 && same c1 c2
|
|
|
|
|
|
|
|
and sameswitch sw1 sw2 =
|
|
|
|
let samecase (n1, a1) (n2, a2) = n1 = n2 && same a1 a2 in
|
|
|
|
sw1.sw_numconsts = sw2.sw_numconsts &&
|
|
|
|
sw1.sw_numblocks = sw2.sw_numblocks &&
|
|
|
|
samelist samecase sw1.sw_consts sw2.sw_consts &&
|
|
|
|
samelist samecase sw1.sw_blocks sw2.sw_blocks &&
|
|
|
|
(match (sw1.sw_failaction, sw2.sw_failaction) with
|
|
|
|
| (None, None) -> true
|
|
|
|
| (Some a1, Some a2) -> same a1 a2
|
|
|
|
| _ -> false)
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
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
|
|
|
|
|
2005-04-03 21:09:12 -07:00
|
|
|
let rec iter f = function
|
|
|
|
Lvar _
|
|
|
|
| Lconst _ -> ()
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lapply(fn, args) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f fn; List.iter f args
|
1996-10-22 06:36:59 -07:00
|
|
|
| Lfunction(kind, params, body) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f body
|
1995-12-15 02:18:29 -08:00
|
|
|
| Llet(str, id, arg, body) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f arg; f body
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lletrec(decl, body) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f body;
|
|
|
|
List.iter (fun (id, exp) -> f exp) decl
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lprim(p, args) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
List.iter f args
|
1996-04-04 07:55:29 -08:00
|
|
|
| Lswitch(arg, sw) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f arg;
|
|
|
|
List.iter (fun (key, case) -> f case) sw.sw_consts;
|
|
|
|
List.iter (fun (key, case) -> f case) sw.sw_blocks;
|
2001-02-19 12:27:52 -08:00
|
|
|
begin match sw.sw_failaction with
|
|
|
|
| None -> ()
|
2005-04-03 21:09:12 -07:00
|
|
|
| Some l -> f l
|
2001-02-19 12:27:52 -08:00
|
|
|
end
|
2000-10-02 07:18:05 -07:00
|
|
|
| Lstaticraise (_,args) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
List.iter f args
|
2000-10-02 07:18:05 -07:00
|
|
|
| Lstaticcatch(e1, (_,vars), e2) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f e1; f e2
|
1995-05-04 03:15:53 -07:00
|
|
|
| Ltrywith(e1, exn, e2) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f e1; f e2
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lifthenelse(e1, e2, e3) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f e1; f e2; f e3
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lsequence(e1, e2) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f e1; f e2
|
1995-05-04 03:15:53 -07:00
|
|
|
| Lwhile(e1, e2) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f e1; f e2
|
2005-08-25 08:35:16 -07:00
|
|
|
| Lfor(v, e1, e2, dir, e3) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f e1; f e2; f e3
|
1995-11-25 07:38:43 -08:00
|
|
|
| Lassign(id, e) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f e
|
2004-05-26 04:10:52 -07:00
|
|
|
| Lsend (k, met, obj, args) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
List.iter f (met::obj::args)
|
1996-11-29 10:36:42 -08:00
|
|
|
| Levent (lam, evt) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f lam
|
1998-06-24 12:22:26 -07:00
|
|
|
| Lifused (v, e) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
f e
|
|
|
|
|
|
|
|
module IdentSet =
|
|
|
|
Set.Make(struct
|
|
|
|
type t = Ident.t
|
|
|
|
let compare = compare
|
|
|
|
end)
|
|
|
|
|
|
|
|
let free_ids get l =
|
|
|
|
let fv = ref IdentSet.empty in
|
|
|
|
let rec free l =
|
|
|
|
iter free l;
|
|
|
|
fv := List.fold_right IdentSet.add (get l) !fv;
|
|
|
|
match l with
|
|
|
|
Lfunction(kind, params, body) ->
|
|
|
|
List.iter (fun param -> fv := IdentSet.remove param !fv) params
|
|
|
|
| Llet(str, id, arg, body) ->
|
|
|
|
fv := IdentSet.remove id !fv
|
|
|
|
| Lletrec(decl, body) ->
|
|
|
|
List.iter (fun (id, exp) -> fv := IdentSet.remove id !fv) decl
|
|
|
|
| Lstaticcatch(e1, (_,vars), e2) ->
|
2005-08-25 08:35:16 -07:00
|
|
|
List.iter (fun id -> fv := IdentSet.remove id !fv) vars
|
2005-04-03 21:09:12 -07:00
|
|
|
| Ltrywith(e1, exn, e2) ->
|
|
|
|
fv := IdentSet.remove exn !fv
|
2005-08-25 08:35:16 -07:00
|
|
|
| Lfor(v, e1, e2, dir, e3) ->
|
2005-04-03 21:09:12 -07:00
|
|
|
fv := IdentSet.remove v !fv
|
|
|
|
| Lassign(id, e) ->
|
|
|
|
fv := IdentSet.add id !fv
|
|
|
|
| Lvar _ | Lconst _ | Lapply _
|
|
|
|
| Lprim _ | Lswitch _ | Lstaticraise _
|
|
|
|
| Lifthenelse _ | Lsequence _ | Lwhile _
|
|
|
|
| Lsend _ | Levent _ | Lifused _ -> ()
|
|
|
|
in free l; !fv
|
|
|
|
|
|
|
|
let free_variables l =
|
|
|
|
free_ids (function Lvar id -> [id] | _ -> []) l
|
|
|
|
|
|
|
|
let free_methods l =
|
|
|
|
free_ids (function Lsend(Self, Lvar meth, obj, _) -> [meth] | _ -> []) l
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
(* Check if an action has a "when" guard *)
|
2001-02-19 12:27:52 -08:00
|
|
|
let raise_count = ref 0
|
|
|
|
|
|
|
|
let next_raise_count () =
|
|
|
|
incr raise_count ;
|
|
|
|
!raise_count
|
|
|
|
|
|
|
|
(* Anticipated staticraise, for guards *)
|
|
|
|
let staticfail = Lstaticraise (0,[])
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
let rec is_guarded = function
|
2001-02-19 12:27:52 -08:00
|
|
|
| Lifthenelse( cond, body, Lstaticraise (0,[])) -> 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
|
|
|
|
|
2001-02-19 12:27:52 -08:00
|
|
|
let rec patch_guarded patch = function
|
|
|
|
| Lifthenelse (cond, body, Lstaticraise (0,[])) ->
|
|
|
|
Lifthenelse (cond, body, patch)
|
|
|
|
| Llet(str, id, lam, body) ->
|
|
|
|
Llet (str, id, lam, patch_guarded patch body)
|
|
|
|
| Levent(lam, ev) ->
|
|
|
|
Levent (patch_guarded patch lam, ev)
|
|
|
|
| _ -> fatal_error "Lambda.patch_guarded"
|
|
|
|
|
1999-02-04 02:31:16 -08:00
|
|
|
(* Translate an access path *)
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
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"
|
1999-02-04 02:31:16 -08:00
|
|
|
|
|
|
|
(* Compile a sequence of expressions *)
|
|
|
|
|
|
|
|
let rec make_sequence fn = function
|
|
|
|
[] -> lambda_unit
|
|
|
|
| [x] -> fn x
|
|
|
|
| x::rem ->
|
|
|
|
let lam = fn x in Lsequence(lam, make_sequence fn rem)
|
|
|
|
|
|
|
|
(* Apply a substitution to a lambda-term.
|
|
|
|
Assumes that the bound variables of the lambda-term do not
|
|
|
|
belong to the domain of the substitution.
|
|
|
|
Assumes that the image of the substitution is out of reach
|
|
|
|
of the bound variables of the lambda-term (no capture). *)
|
|
|
|
|
|
|
|
let subst_lambda s lam =
|
|
|
|
let rec subst = function
|
|
|
|
Lvar id as l ->
|
|
|
|
begin try Ident.find_same id s with Not_found -> l end
|
|
|
|
| Lconst sc as l -> l
|
|
|
|
| Lapply(fn, args) -> Lapply(subst fn, List.map subst args)
|
|
|
|
| Lfunction(kind, params, body) -> Lfunction(kind, params, subst body)
|
|
|
|
| Llet(str, id, arg, body) -> Llet(str, id, subst arg, subst body)
|
|
|
|
| Lletrec(decl, body) -> Lletrec(List.map subst_decl decl, subst body)
|
|
|
|
| Lprim(p, args) -> Lprim(p, List.map subst args)
|
|
|
|
| Lswitch(arg, sw) ->
|
|
|
|
Lswitch(subst arg,
|
|
|
|
{sw with sw_consts = List.map subst_case sw.sw_consts;
|
2001-02-19 12:27:52 -08:00
|
|
|
sw_blocks = List.map subst_case sw.sw_blocks;
|
|
|
|
sw_failaction =
|
|
|
|
match sw.sw_failaction with
|
|
|
|
| None -> None
|
|
|
|
| Some l -> Some (subst l)})
|
2005-08-25 08:35:16 -07:00
|
|
|
|
2001-02-19 12:27:52 -08:00
|
|
|
| Lstaticraise (i,args) -> Lstaticraise (i, List.map subst args)
|
2000-08-11 12:58:52 -07:00
|
|
|
| Lstaticcatch(e1, io, e2) -> Lstaticcatch(subst e1, io, subst e2)
|
1999-02-04 02:31:16 -08:00
|
|
|
| Ltrywith(e1, exn, e2) -> Ltrywith(subst e1, exn, subst e2)
|
|
|
|
| Lifthenelse(e1, e2, e3) -> Lifthenelse(subst e1, subst e2, subst e3)
|
|
|
|
| Lsequence(e1, e2) -> Lsequence(subst e1, subst e2)
|
|
|
|
| Lwhile(e1, e2) -> Lwhile(subst e1, subst e2)
|
2005-08-25 08:35:16 -07:00
|
|
|
| Lfor(v, e1, e2, dir, e3) -> Lfor(v, subst e1, subst e2, dir, subst e3)
|
1999-02-04 02:31:16 -08:00
|
|
|
| Lassign(id, e) -> Lassign(id, subst e)
|
2004-05-26 04:10:52 -07:00
|
|
|
| Lsend (k, met, obj, args) ->
|
|
|
|
Lsend (k, subst met, subst obj, List.map subst args)
|
1999-02-04 02:31:16 -08:00
|
|
|
| Levent (lam, evt) -> Levent (subst lam, evt)
|
|
|
|
| Lifused (v, e) -> Lifused (v, subst e)
|
|
|
|
and subst_decl (id, exp) = (id, subst exp)
|
|
|
|
and subst_case (key, case) = (key, subst case)
|
|
|
|
in subst lam
|
2000-10-02 07:18:05 -07:00
|
|
|
|
|
|
|
|
|
|
|
(* To let-bind expressions to variables *)
|
|
|
|
|
|
|
|
let bind str var exp body =
|
|
|
|
match exp with
|
|
|
|
Lvar var' when Ident.same var var' -> body
|
|
|
|
| _ -> Llet(str, var, exp, body)
|
|
|
|
|
|
|
|
and commute_comparison = function
|
|
|
|
| Ceq -> Ceq| Cneq -> Cneq
|
|
|
|
| Clt -> Cgt | Cle -> Cge
|
|
|
|
| Cgt -> Clt | Cge -> Cle
|
|
|
|
|
|
|
|
and negate_comparison = function
|
|
|
|
| Ceq -> Cneq| Cneq -> Ceq
|
|
|
|
| Clt -> Cge | Cle -> Cgt
|
|
|
|
| Cgt -> Cle | Cge -> Clt
|
|
|
|
|
|
|
|
|