Replace:
PUBLIC ReplaceProc = {
newParent ← (NARROW [Pipal.ObjectMethod[parent, replaceMethod], REF ReplaceProc]^)[parent, table];
};
ReplaceRecursive:
PROC [old: Pipal.Object, table: RefTab.Ref]
RETURNS [new: Pipal.Object] = {
ReplaceChildRecursive: PipalInt.EachChildProc = {
newChild: Pipal.Object ← RefTab.Fetch[table, child].val;
IF newChild#NIL THEN RETURN;
newChild ← ReplaceRecursive[child, table];
IF newChild=child THEN RETURN;
[] ← RefTab.Store[table, child, newChild];
};
new ← RefTab.Fetch[table, old].val;
IF new#NIL THEN RETURN [new];
IF NOT AnyReachable[old, table] THEN RETURN [old];
[] ← PipalInt.ObjectEnumerate[old, ReplaceChildRecursive];
new ← Replace[old, table];
[] ← RefTab.Store[table, old, new];
};
TransitiveReplace:
PUBLIC
PROC [oldRoots: Pipal.Objects, table: RefTab.Ref]
RETURNS [newRoots: Pipal.Objects] = {
reversed: Pipal.Objects ← NIL;
IF AnyReachableFromRoots[oldRoots, table] THEN RETURN [oldRoots];
WHILE oldRoots#
NIL
DO
old: Pipal.Object ← oldRoots.first;
new: Pipal.Object ← ReplaceRecursive[old, table];
oldRoots ← oldRoots.rest;
reversed ← CONS [new, reversed];
ENDLOOP;
WHILE reversed#
NIL
DO
reversed ← reversed.rest; newRoots ← CONS [reversed.first, newRoots] ENDLOOP;
};