StdPairCollections5.Mesa
Last tweaked by Mike Spreitzer on October 16, 1987 10:31:36 am PDT
DIRECTORY Basics, Collections, PairCollections, List, Rope;
StdPairCollections5: CEDAR PROGRAM
IMPORTS Collections, PairCollections
EXPORTS PairCollections
=
BEGIN OPEN Colls:Collections, PairColls:PairCollections, PairCollections, Collections;
Wp: PROC [pair: Pair] RETURNS [REF ANY]
~ INLINE {RETURN [NEW [Pair ← pair]]};
Np: PROC [pair: REF ANY] RETURNS [Pair]
~ INLINE {RETURN [NARROW[pair, REF Pair]^]};
Nmv: PROC [mv: MaybeValue] RETURNS [MaybePair]
~ INLINE {RETURN [IF mv.found THEN [TRUE, Np[mv.val]] ELSE noMaybePair]};
Wmp: PROC [mp: MaybePair] RETURNS [MaybeValue]
~ INLINE {RETURN [IF mp.found THEN [TRUE, Wp[mp.pair]] ELSE noMaybe]};
DefaultWiden: PUBLIC PROC [pc: PairColl] RETURNS [Collection--of REF Pair--] ~ {
RETURN [[
wideClasses
[pc.MayDuplicate]
[pc.OrderStyleOf]
[pc.MutabilityOf],
pc.Refify
]];
};
WideClasses: TYPE ~ ARRAY --mayDuplicate--BOOL OF ARRAY OrderStyle OF ARRAY Mutability OF CollectionClass;
wideClasses: REF WideClasses ~ NEW [WideClasses];
WidePrimitive: PROC [coll: Collection, op: ATOM, args: ArgList ← NIL] RETURNS [PrimitiveAnswer] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
SELECT op FROM
$IsPairColl, $QuaPairColl => RETURN [yes];
$HasMember => RETURN [IF pc.QualityOf[$HasPair]>cant THEN yes ELSE no];
$Scan, $Extremum, $Get3, $Size, $Copy, $Insulate, $ValueOf, $Freeze, $Thaw, $AddColl, $OrderingOf => RETURN [IF pc.QualityOf[op, args]>cant THEN yes ELSE no];
$RemoveColl => RETURN [IF pc.QualityOf[$RemColl]>cant THEN yes ELSE no];
$SpaceOf => RETURN [IF pc.QualityOf[$Spaces]>cant THEN yes ELSE no];
ENDCASE => RETURN [no];
};
WideHasMember: PROC [coll: Collection, elt: Value] RETURNS [BOOL] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN pc.HasPair[Np[elt]]};
WideEnumerate: PROC [coll: Collection, Consumer: PROC [elt: Value], bkwd: BOOL] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
rp: REF Pair ~ NEW [Pair];
Pass: PROC [pair: Pair] ~ {rp^ ← pair; Consumer[rp]};
pc.Enumerate[Pass, bkwd];
RETURN};
WideScan: PROC [coll: Collection, Test: Tester, bkwd: BOOL] RETURNS [MaybeValue] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
rp: REF Pair ~ NEW [Pair];
Pass: PROC [pair: Pair] RETURNS [pass: BOOL] ~ {rp^ ← pair; pass ← Test[rp]};
RETURN Wmp[pc.Scan[Pass, bkwd]]};
WideExtremum: PROC [coll: Collection, bkwd, remove: BOOL] RETURNS [MaybeValue] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN Wmp[pc.class.Extremum[pc, bkwd, remove]]};
WideGet3: PROC [coll: Collection, elt: Value] RETURNS [prev, same, next: MaybeValue] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
nPrev, nSame, nNext: MaybePair;
[nPrev, nSame, nNext] ← pc.Get3[Np[elt]];
prev ← Wmp[nPrev];
same ← Wmp[nSame];
next ← Wmp[nNext];
RETURN};
WideSize: PROC [coll: Collection, limit: LNATLNAT.LAST] RETURNS [LNAT] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN pc.Size[limit]};
WideCopy: PROC [coll: Collection] RETURNS [VarColl] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN pc.Copy.Widen.AsVar};
WideInsulate: PROC [coll: Collection] RETURNS [UWColl] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN pc.Insulate.Widen.AsUW};
WideValueOf: PROC [coll: Collection] RETURNS [ConstColl] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN pc.ValueOf.Widen.AsConst};
WideFreeze: PROC [coll: Collection] RETURNS [ConstColl] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN pc.Freeze.Widen.AsConst};
WideThaw: PROC [coll: Collection] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
pc.Thaw;
RETURN};
WideAddColl: PROC [coll, other: Collection, where: Where] RETURNS [someNew, allNew: BOOL] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
oPC: PairColl ~ PairColls.DeRef[other.AsPairColl];
fnl: BoolPair ~ pc.Functional;
dir: Direction ~ IF fnl[leftToRight] THEN leftToRight ELSE IF fnl[rightToLeft] THEN rightToLeft ELSE ERROR Cant[coll]--don't know how to compute someNew & allNew--;
pcWhere: PairColls.Where ~ WITH where SELECT FROM
x: any Where => [any[]],
x: end Where => [end[x.end]],
x: rel Where => [rel[Np[x.elt], x.reln]],
ENDCASE => ERROR;
some: NewsSetPair ~ pc.AddColl[oPC, alwaysAdd, pcWhere];
allNew ← NOT some[dir][same];
someNew ← some[dir][different] OR some[dir][new];
RETURN};
WideRemoveColl: PROC [coll, other: Collection, style: RemoveStyle] RETURNS [hadSome, hadAll: BOOL] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
oPC: PairColl ~ PairColls.DeRef[other.AsPairColl];
fnl: BoolPair ~ pc.Functional;
dir: Direction ~ IF fnl[leftToRight] THEN leftToRight ELSE IF fnl[rightToLeft] THEN rightToLeft ELSE ERROR Cant[coll]--don't know how to compute someNew & allNew--;
hadSomePair, hadAllPairs: BoolPair;
[hadSomePair, hadAllPairs] ← pc.RemColl[oPC, style];
RETURN [hadSomePair[dir], hadAllPairs[dir]]};
WideQuaPairColl: PROC [coll: Collection] RETURNS [MaybeValue] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN [[TRUE, pc.Refify]]};
WideSpaceOf: PROC [coll: Collection] RETURNS [Space] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN [WidenSpacePair[pc.Spaces]]};
WideOrderingOf: PROC [coll: Collection] RETURNS [Ordering] ~ {
pc: PairColl ~ PairColls.DeRef[coll.data];
RETURN [pc.OrderingOf.WidenOrdering]};
WidePreserveValue: PROC [coll: Collection, val: Value] RETURNS [Value] ~ {
rp: REF Pair ~ NARROW[val];
RETURN [NEW [Pair ← rp^]]};
Start: PROC ~ {
FOR mayDuplicate: BOOL IN BOOL DO FOR orderStyle: OrderStyle IN OrderStyle DO FOR mutability: Mutability IN Mutability DO
wideClasses[mayDuplicate][orderStyle][mutability] ← CreateClass[[
Primitive: WidePrimitive,
HasMember: WideHasMember,
Scan: WideScan,
Extremum: WideExtremum,
Get3: WideGet3,
Size: WideSize,
Copy: WideCopy,
Insulate: WideInsulate,
ValueOf: WideValueOf,
Freeze: WideFreeze,
Thaw: WideThaw,
AddColl: WideAddColl,
RemoveColl: WideRemoveColl,
QuaPairColl: WideQuaPairColl,
SpaceOf: WideSpaceOf,
OrderingOf: WideOrderingOf,
PreserveValue: WidePreserveValue,
mayDuplicate: mayDuplicate,
orderStyle: orderStyle,
mutability: mutability
]];
ENDLOOP ENDLOOP ENDLOOP;
RETURN};
Start[];
END.