<> <> <> <> DIRECTORY UnsafeStorage USING [GetSystemUZone, NewUObject], RelationDefs: FROM "RelationDefs"; Relations: PROGRAM IMPORTS UnsafeStorage EXPORTS RelationDefs = BEGIN OPEN RelationDefs; UCZone: UNCOUNTED ZONE _ UnsafeStorage.GetSystemUZone[]; Allocate: PROCEDURE[nwords: CARDINAL] RETURNS[LONG POINTER] = BEGIN RETURN[UnsafeStorage.NewUObject[nwords,UCZone]]; END; Free: PROCEDURE[ptr: LONG POINTER] ={ IF ptr#NIL THEN UCZone.FREE[@ptr]; }; CreateRelation: PUBLIC PROCEDURE RETURNS [relation: Relation] = BEGIN relation _ Allocate[SIZE[RelationHead]]; relation.first _ NIL; END; AddPair: PUBLIC PROCEDURE [relation: Relation, left, right: CARDINAL] = BEGIN pair: LONG POINTER TO Pair _ Allocate[SIZE[Pair]]; pair.left _ left; pair.right _ right; pair.link _ relation.first; relation.first _ pair; END; Left: PUBLIC PROCEDURE[relation: Relation, right: CARDINAL] RETURNS [left: CARDINAL] = BEGIN IsRight: PROCEDURE [leftPart, rightPart: CARDINAL] = BEGIN IF right=rightPart THEN left_leftPart; END; left_notFound; ForAllPairs[relation, IsRight]; END; Right: PUBLIC PROCEDURE[relation: Relation, left: CARDINAL] RETURNS [right: CARDINAL] = BEGIN IsLeft: PROCEDURE [leftPart, rightPart: CARDINAL] = BEGIN IF left=leftPart THEN right_rightPart; END; right_notFound; ForAllPairs[relation, IsLeft]; END; ForAllPairs: PUBLIC PROCEDURE[relation: Relation, do: PROCEDURE[leftPart, rightPart: CARDINAL]] = BEGIN pair: LONG POINTER TO Pair _ NIL; FOR pair _ relation.first, pair.link UNTIL pair=NIL DO do[pair.left, pair.right] ENDLOOP; END; DestroyRelation: PUBLIC PROCEDURE[relation: Relation] = BEGIN pair, next: LONG POINTER TO Pair _ NIL; FOR pair _ relation.first, next UNTIL pair=NIL DO next _ pair.link; Free[pair]; ENDLOOP; Free[relation]; END; END.