Commit 52ee871a authored by POTTIER Francois's avatar POTTIER Francois

Deal with recursive and nonrecursive definitions at the same time.

parent d19a7258
......@@ -15,14 +15,24 @@ type ('bn, 'term) abs =
(* -------------------------------------------------------------------------- *)
(* A definition is a binding form of the form [let x = t in u].
The name [x] is in scope in [u], but not in [t].
The terms [t] and [u] need not belong to the same syntactic category. *)
(* A definition is a binding form of the form [let (rec) x = t in u]. The name
[x] is in scope in [u]. It is in scope in [t] if the definition is marked
recursive; otherwise, it is not. The terms [t] and [u] need not belong to the
same syntactic category. *)
type recursive =
| NonRecursive
| Recursive
type ('bn, 't, 'u) def =
'bn * 't * 'u
recursive * 'bn * 't * 'u
(* This type is isomorphic to ['t * ('bn, 'u) abs]. *)
let choose recursive env env' =
match recursive with
| NonRecursive ->
env
| Recursive ->
env'
(* -------------------------------------------------------------------------- *)
......@@ -73,11 +83,11 @@ class virtual ['self] map = object (self : 'self)
('env -> 't1 -> 't2) ->
('env -> 'u1 -> 'u2) ->
'env -> ('bn1, 't1, 'u1) def -> ('bn2, 't2, 'u2) def
= fun _ f g env (x1, t1, u1) ->
= fun _ f g env (recursive, x1, t1, u1) ->
let x2, env' = self#extend x1 env in
let t2 = f env t1 in
let t2 = f (choose recursive env env') t1 in
let u2 = g env' u1 in
x2, t2, u2
recursive, x2, t2, u2
end
......@@ -109,14 +119,14 @@ class virtual ['self] endo = object (self : 'self)
('env -> 't -> 't) ->
('env -> 'u -> 'u) ->
'env -> ('bn, 't, 'u) def -> ('bn, 't, 'u) def
= fun _ f g env ((x1, t1, u1) as this) ->
= fun _ f g env ((recursive, x1, t1, u1) as this) ->
let x2, env' = self#extend x1 env in
let t2 = f env t1 in
let t2 = f (choose recursive env env') t1 in
let u2 = g env' u1 in
if x1 == x2 && t1 == t2 && u1 == u2 then
this
else
x2, t2, u2
recursive, x2, t2, u2
end
......@@ -148,9 +158,9 @@ class virtual ['self] reduce = object (self : 'self)
('env -> 't -> 'z) ->
('env -> 'u -> 'z) ->
'env -> ('bn, 't, 'u) def -> 'z
= fun _ f g env (x, t, u) ->
= fun _ f g env (recursive, x, t, u) ->
let env' = self#extend x env in
let zt = f env t in
let zt = f (choose recursive env env') t in
let zu = self#restrict x (g env' u) in
self#plus zt zu
......@@ -193,11 +203,12 @@ class virtual ['self] map2 = object (self : 'self)
('env -> 't1 -> 't2 -> 't3) ->
('env -> 'u1 -> 'u2 -> 'u3) ->
'env -> ('bn1, 't1, 'u1) def -> ('bn2, 't2, 'u2) def -> ('bn3, 't3, 'u3) def
= fun _ f g env (x1, t1, u1) (x2, t2, u2) ->
= fun _ f g env (recursive1, x1, t1, u1) (recursive2, x2, t2, u2) ->
if recursive1 <> recursive2 then VisitorsRuntime.fail();
let x3, env' = self#extend x1 x2 env in
let t3 = f env t1 t2 in
let t3 = f (choose recursive1 env env') t1 t2 in
let u3 = g env' u1 u2 in
x3, t3, u3
recursive1, x3, t3, u3
end
......@@ -229,9 +240,10 @@ class virtual ['self] reduce2 = object (self : 'self)
('env -> 't1 -> 't2 -> 'z) ->
('env -> 'u1 -> 'u2 -> 'z) ->
'env -> ('bn1, 't1, 'u1) def -> ('bn2, 't2, 'u2) def -> 'z
= fun _ f g env (x1, t1, u1) (x2, t2, u2) ->
= fun _ f g env (recursive1, x1, t1, u1) (recursive2, x2, t2, u2) ->
if recursive1 <> recursive2 then VisitorsRuntime.fail();
let env' = self#extend x1 x2 env in
let zt = f env t1 t2 in
let zt = f (choose recursive1 env env') t1 t2 in
let zu = self#restrict x1 x2 (g env' u1 u2) in
self#plus zt zu
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment