DIRECTORY Atom, Basics, IntStuff, PrincOps, Rope; SetBasics: CEDAR DEFINITIONS IMPORTS Basics = { LORA: TYPE ~ LIST OF REF ANY; LNAT: TYPE ~ INT--[0 .. INT.LAST]--; EINT: TYPE ~ IntStuff.EINT; lastEINT: EINT ~ IntStuff.lastEINT; IntInterval: TYPE ~ IntStuff.Interval; ROPE: TYPE ~ Rope.ROPE; LOV: TYPE ~ LIST OF Value; Error: ERROR [msg: ROPE, args: LOV]; Value: TYPE ~ RECORD [SELECT kind: ValueKind FROM no => [fill: INT _ 0], --the fill is not meaningful, it's just there to make all the variants have the same length, which makes the compiler a little happier. There should never be a no Value with fill other than 0. a => [a: REF ANY], i => [i: INT], ENDCASE]; ValueKind: TYPE ~ {no, a, i}; NotAValue: TYPE ~ Value[no]; RefAnyValue: TYPE ~ Value[a]; IntValue: TYPE ~ Value[i]; noValue: NotAValue ~ [no[]]; AV: PROC [a: REF ANY] RETURNS [RefAnyValue] ~ INLINE {RETURN [[a[a]]]}; IV: PROC [i: INT] RETURNS [IntValue] ~ INLINE {RETURN [[i[i]]]}; VA: PROC [v: Value] RETURNS [REF ANY] ~ TRUSTED INLINE {RETURN [WITH v SELECT FROM a => a, ENDCASE => Error[narrowFault, LIST[v]]]}; VI: PROC [v: Value] RETURNS [INT] ~ TRUSTED INLINE {RETURN [WITH v SELECT FROM i => i, ENDCASE => Error[narrowFault, LIST[v]]]}; narrowFault: READONLY ROPE; notFound: READONLY ROPE; MaybeValue: TYPE ~ RECORD [found: BOOL, it: Value]; noMaybe: MaybeValue ~ [FALSE, noValue]; Val: PROC [mv: MaybeValue] RETURNS [Value] ~ INLINE {RETURN [IF mv.found THEN mv.it ELSE Error[notFound, NIL]]}; DVal: PROC [mv: MaybeValue, ifNotFound: Value] RETURNS [Value] ~ INLINE {RETURN [IF mv.found THEN mv.it ELSE ifNotFound]}; MA: PROC [mv: MaybeValue] RETURNS [REF ANY] ~ TRUSTED INLINE {RETURN [IF mv.found THEN WITH mv.it SELECT FROM a => a, ENDCASE => Error[narrowFault, LIST[mv.it]] ELSE Error[notFound, NIL]]}; MDA: PROC [mv: MaybeValue, ifNotFound: REF ANY _ NIL] RETURNS [REF ANY] ~ TRUSTED INLINE {RETURN [IF mv.found THEN WITH mv.it SELECT FROM a => a, ENDCASE => Error[narrowFault, LIST[mv.it]] ELSE ifNotFound]}; MI: PROC [mv: MaybeValue] RETURNS [INT] ~ TRUSTED INLINE {RETURN [IF mv.found THEN WITH mv.it SELECT FROM i => i, ENDCASE => Error[narrowFault, LIST[mv.it]] ELSE Error[notFound, NIL]]}; MDI: PROC [mv: MaybeValue, ifNotFound: INT] RETURNS [INT] ~ TRUSTED INLINE {RETURN [IF mv.found THEN WITH mv.it SELECT FROM i => i, ENDCASE => Error[narrowFault, LIST[mv.it]] ELSE ifNotFound]}; Space: TYPE ~ REF SpacePrivate; basic: READONLY Space; refs, ints, spaceSpace: READONLY Space; ropes: READONLY ARRAY --case matters--BOOL OF Space; SContains: PROC [s: Space, v: Value] RETURNS [BOOL] ~ INLINE {RETURN s.Contains[s.data, v]}; SEqual: PROC [s: Space, v1, v2: Value] RETURNS [BOOL] ~ INLINE {RETURN s.Equal[s.data, v1, v2]}; SHash: PROC [s: Space, v: Value] RETURNS [CARDINAL] ~ INLINE {RETURN s.Hash[s.data, v]}; SCompare: PROC [s: Space, v1, v2: Value] RETURNS [Comparison] ~ INLINE {RETURN s.Compare[s.data, v1, v2]}; SMin: PROC [s: Space, e1, e2: Value] RETURNS [Value] ~ INLINE {RETURN [IF s.Compare[s.data, e1, e2] <= equal THEN e1 ELSE e2]}; SMax: PROC [s: Space, e1, e2: Value] RETURNS [Value] ~ INLINE {RETURN [IF s.Compare[s.data, e1, e2] >= equal THEN e1 ELSE e2]}; Interval: TYPE ~ ARRAY End OF NoingValue; End: TYPE ~ {min, max}; NoingValue: TYPE ~ Value _ noValue; IEmpty: PROC [s: Space, i: Interval] RETURNS [BOOL] ~ INLINE {RETURN [i[min]#noValue AND i[max]#noValue AND s.SCompare[i[min], i[max]]=greater]}; IContains: PROC [s: Space, i: Interval, v: Value] RETURNS [BOOL] ~ INLINE {RETURN [(i[min]=noValue OR s.SCompare[i[min], v]<=equal) AND (i[max]=noValue OR s.SCompare[v, i[max]]<=equal)]}; MBI: PROC [s: Space, i1, i2: Interval] RETURNS [Interval] ~ INLINE {RETURN[[ min: IF i1[min]=noValue OR i2[min]=noValue THEN noValue ELSE s.SMin[i1[min], i2[min]], max: IF i1[max]=noValue OR i2[max]=noValue THEN noValue ELSE s.SMax[i1[max], i2[max]]]]}; IIntersection: PROC [s: Space, i1, i2: Interval] RETURNS [Interval] ~ INLINE {RETURN[[ min: IF i1[min]=noValue THEN i2[min] ELSE IF i2[min]=noValue THEN i1[min] ELSE s.SMax[i1[min], i2[min]], max: IF i1[max]=noValue THEN i2[max] ELSE IF i2[max]=noValue THEN i1[max] ELSE s.SMin[i1[max], i2[max]]]]}; BoundsOfVals: PROC [s: Space, v1, v2: Value] RETURNS [Interval] ~ INLINE {RETURN[IF s.SCompare[v1, v2]<=equal THEN [v1, v2] ELSE [v2, v1]]}; IIntify: PROC [i: Interval] RETURNS [IntInterval] ~ INLINE {RETURN [[ min: IF i[min]=noValue THEN INT.FIRST ELSE i[min].VI, max: IF i[max]=noValue THEN INT.LAST ELSE i[max].VI]]}; IValify: PROC [i: IntInterval] RETURNS [Interval] ~ INLINE {RETURN [[[i[i.min]], [i[i.max]]]]}; SpacePrivate: TYPE ~ MONITORED RECORD [ Contains: TestProc, Equal: EqualProc, Hash: HashProc, Compare: CompareProc, name: ROPE _, other: Atom.PropList _ NIL, --the canonical expansion slot data: REF ANY ]; TestProc: TYPE ~ PROC [data: REF ANY, v: Value] RETURNS [BOOL]; EqualProc: TYPE ~ PROC [data: REF ANY, v1, v2: Value] RETURNS [BOOL]; HashProc: TYPE ~ PROC [data: REF ANY, v: Value] RETURNS [CARDINAL]; CompareProc: TYPE ~ PROC [data: REF ANY, v1, v2: Value] RETURNS [Comparison]; HashIntI: PROC [INT] RETURNS [CARDINAL] ~ TRUSTED MACHINE CODE { PrincOps.zXOR }; HashRefI: PROC [REF ANY] RETURNS [CARDINAL] ~ TRUSTED MACHINE CODE { PrincOps.zXOR }; CompareIntI: PROC [a, b: INT] RETURNS [Comparison] ~ Basics.CompareInt; CompareRefI: PROC [a, b: REF ANY] RETURNS [Comparison] ~ TRUSTED INLINE {RETURN [Basics.CompareInt[LOOPHOLE[a], LOOPHOLE[b]]]}; UpdateSpaceOther: PROC [s: Space, Update: PROC [Atom.PropList] RETURNS [Atom.PropList]]; --total--Comparison: TYPE ~ Basics.Comparison; RevComp: ARRAY Comparison OF Comparison ~ [equal: equal, less: greater, greater: less]; --total--Order: TYPE ~ RECORD [ Compare: CompareProc, data: REF ANY]; OCompare: PROC [o: Order, v1, v2: Value] RETURNS [Comparison] ~ INLINE {RETURN o.Compare[o.data, v1, v2]}; ReverseOrder: PROC [o: Order] RETURNS [ro: Order]; ComposeOrders: PROC [mso, lso: Order] RETURNS [Order]; SpaceOrder: PROC [space: Space] RETURNS [Order] ~ INLINE {RETURN [[space.Compare, space.data]]}; OrderList: TYPE ~ LIST OF Order; LexLOV: PROC [prefix, repeat: OrderList] RETURNS [Order]; LexLORA: PROC [prefix, repeat: OrderList] RETURNS [Order]; PartialComparison: TYPE ~ MACHINE DEPENDENT {less(0), equal(1), greater(2), notrel(3)}; RevPComp: ARRAY PartialComparison OF PartialComparison ~ [less: greater, equal: equal, greater: less, notrel: notrel]; Partialify: ARRAY Comparison OF PartialComparison ~ [less: less, equal: equal, greater: greater]; Totalify: ARRAY PartialComparison[less..greater] OF Comparison ~ [less: less, equal: equal, greater: greater]; RevPartialify: ARRAY Comparison OF PartialComparison ~ [less: greater, equal: equal, greater: less]; Squash: ARRAY PartialComparison OF Comparison ~ [less: less, equal: equal, greater: greater, notrel: equal]; Unrel: ARRAY Comparison OF PartialComparison ~ [less: notrel, equal: equal, greater: notrel]; ParitialCompareProc: TYPE ~ PROC [data: REF ANY, v1, v2: Value] RETURNS [PartialComparison]; PartialCompareIntI: PROC [a, b: INT] RETURNS [PartialComparison] ~ LOOPHOLE[Basics.CompareInt]; PartialCompareRefI: PROC [a, b: REF ANY] RETURNS [PartialComparison] ~ TRUSTED INLINE {RETURN [PartialCompareIntI[LOOPHOLE[a], LOOPHOLE[b]]]}; RelOrder: TYPE ~ {no, fwd, bwd}; RelPCompare: PROC [ro: RelOrder, space: Space, v1, v2: Value] RETURNS [PartialComparison] ~ INLINE {SELECT ro FROM no => RETURN [IF space.SEqual[v1, v2] THEN equal ELSE notrel]; fwd => RETURN [Partialify[space.SCompare[v1, v2]]]; bwd => RETURN [Partialify[space.SCompare[v2, v1]]]; ENDCASE => ERROR}; RelCompare: PROC [ro: RelOrder, space: Space, v1, v2: Value] RETURNS [Comparison] ~ INLINE {SELECT ro FROM no => RETURN [equal]; fwd => RETURN space.SCompare[v1, v2]; bwd => RETURN space.SCompare[v2, v1]; ENDCASE => ERROR}; RelativizeComparison: PROC [ro: RelOrder, c: Comparison] RETURNS [PartialComparison] ~ INLINE {RETURN [SELECT ro FROM no => Unrel[c], fwd => Partialify[c], bwd => RevPartialify[c], ENDCASE => ERROR]}; ReverseRelOrder: ARRAY RelOrder OF RelOrder ~ [no, bwd, fwd]; ReverseRO: PROC [ro: RelOrder] RETURNS [RelOrder] ~ INLINE {RETURN [ReverseRelOrder[ro]]}; }. –SetBasics.Mesa Last tweaked by Mike Spreitzer on December 10, 1987 11:56:58 am PST Some basic stuff For random objections to calls. Values MaybeValues A MaybeValue is a BOOLEAN and a Value; it is the result of a procedure that might return a Value, or might return nothing. We define a TYPE for it for client convencience: Cedar's type conformance rules are such that there's nothing a client can write to which the return record of a procedure can be assigned, so we have to have a TYPE of our own that packages up all the return arguments of a procedure if we want clients to be able to assign the entire results of a procedure call to one variable. If there's really a Value here, return it; otherwise, Error[notFound]. If there's really a Value here return it; otherwise return a given default value. Val composed with VA. Spaces A Space tells how to interpret Values as `value's. Each space implements membership testing (not every Value is in every space), hashing, and a total ordering. Each space also has a name. treats REF ANY as address, INT as integer. Intervals Inclusive. An interval is relative to a space. An extremum of noValue means the appropriate extremal value of the space. Implementing Spaces The only thing that may vary is the other, and that must accessed through the monitor entry procedures below. Ordering If o says a before b, ro says b before a. If mso (most significant ordering) doesn't say equal, that's it; otherwise consult lso. Returns an ordering on LOVs. The first elements are compared with prefix.first; if not equal, that's it. Otherwise the second elements are compared with prefix.rest.first; if not equal, that's it. Otherwise continue, until either prefix or one of the LOVs is exhausted. If one of the LOVs is exhausted, return: equal if the other is, less or greater if the other isn't (dependening on whether the empty one was the first or second argument). If prefix is exhausted before both lists, pick up with repeat. If repeat is exhausted before both lists, use it over again. Like LexLOV, except that the ordering is on LORAs. Relative Orders An RelOrder specifies a partial ordering among values, relative to the ordering of a space. fwd means the same ordering as the space's; bwd means the reversal of that ordering; no means space-equal values are considered equal, and all other pairs are considered unrelated. A perversion that considers two unrelated elements to be equal. Κ – "cedar" style˜codešœ™K™C—K˜KšΟk œ(˜1K˜šΟn œœ ˜Kšœ˜Kšœ˜—head™Kš œœœœœœ˜KšœœΟcœ˜$Kšœœ œ˜Kšœ œ˜#Kšœ œ˜&Kšœœœ˜Kšœœœœ˜K˜šžœœœœ˜$K™——™šœœœœ˜1Kšœ œŸΑ˜ΨKšœ œœ˜Kšœ œ˜Kšœ˜ —K˜Kšœ œ˜K˜Kšœ œ ˜Kšœ œ ˜Kšœ œ ˜K˜Kšœ˜š œœœœœ˜+Kšœœœ ˜—šœœœœ ˜$Kšœœœ ˜—K˜š œœ œœœ˜%Kšœœœœœœœ œœ˜^—šœœ œœ˜!Kšœœœœœœœ œœ˜^—K˜Kšœ œœ˜Kšœ œœ˜—™ Ibody™υK˜Kšœ œœ œ ˜3Kšœœ ˜'K˜šžœœœ˜*K™FKš œœœœ œœœ˜E—šžœœ%œ˜>K™QKš œœœœ œœ˜;—š œœœœœ˜+K™Kšœœœœœ œœœœ œœ œœ˜‘—šœœœœœœœœ˜GKšœœœœœ œœœœ œœ œ˜‡—šœœœœ˜'Kšœœœœœ œœœœ œœ œœ˜‘—š œœœœœ˜9Kšœœœœœ œœœœ œœ œ˜‡——™M™½K˜Kšœœœ˜šœœ˜K™*—Kšœœ˜'Kš œœœŸœœ˜4K˜šž œœœœ˜3Kšœœœ˜(—šžœœœœ˜5Kšœœœ˜*—šžœœœœ˜3Kšœœœ˜$—šžœœœ ˜=Kšœœœ˜,—šžœœœ˜4Kš œœœœ$œœ˜J—šžœœœ˜4Kš œœœœ$œœ˜J——™ Kšœ œœœ ˜)Kšœœ˜šœ œ˜#K™z—K˜šžœœœœ˜3Kš œœœœœ&˜]—K˜šž œœ#œœ˜@Kš œœœœœœ!˜z—K˜šœœœ ˜9šœœœ˜Kš œœœœ œ˜VKš œœœœ œ˜Y——K˜šž œœœ ˜Cšœœœ˜Kš œœœ œœœ œ˜hKš œœœ œœœ œ˜k——K˜šž œœœ ˜?Kš œœœœœ œ ˜L—K˜šžœœœ˜1šœœœ˜Kš œœœœœœœ˜5Kš œœœœœœœ˜7——K˜šžœœœ ˜1Kšœœœ˜-——™šœœ œœ˜'Kšžœ ˜Kšžœ ˜Kšžœ ˜Kšžœ˜Kšœœ˜ KšœœŸ˜:Kšœœ˜ K˜Kšœ$ΟeœD™m—K˜Kš œ œœœœ œœ˜?Kš œ œœœœœœ˜EKš œ œœœœ œœ˜CKš œ œœœœœ˜MK˜š žœœœœœ˜'Kšœœœœ˜)—š žœœœœœœ˜+Kšœœœœ˜)—K˜šž œœœœ ˜2Kšœ˜—š ž œœœœœ ˜6Kš œœœœœœ˜H—K˜Kš žœœ žœœœ˜X—™KšŸ œ œ˜.K˜Kšžœœ œ;˜WK˜šŸ œœœ˜Kšžœ˜Kšœœœ˜—K˜šžœœœ ˜=Kšœœœ˜,—K˜šž œœ œ ˜2Kšœ œ œ™)—K˜šž œœœ ˜6Kš œ œΟzœ‘œ ‘œ9 œ™W—K˜šž œœœ˜/Kšœœœ ˜0—K˜Kšœ œœœ˜ šžœœœ ˜9KšœC  œL œ= œL œ œ œa œ. œ œ3™»—K˜šžœœœ ˜:K™2—K˜Kšœœœ œ,˜WK˜KšžœœœR˜vKšž œœ œB˜aKšžœœ"œ;˜nKšž œœ œB˜dKšžœœœJ˜lKšžœœ œC˜]K˜Kš œœœœœœ˜\K˜šžœœœœ˜@Kšœœ˜—š žœœœœœ˜DKš œœœœœœ˜I——™šœ œ˜ Kšœ] œ) œ& œ]™‘—K˜šž œœ-œ˜Yšœœœ˜Kš œœœœœ ˜>Kšœœ&˜3Kšœœ&˜3Kšœœ˜——K˜šž œœ-œ ˜QK™?šœœœ˜Kšœœ ˜Kšœœ˜%Kšœœ˜%Kšœœ˜——K˜šžœœœ˜Tšœœœœ˜ Kšœ˜Kšœ˜K˜Kšœœ˜——K˜Kšžœœ œ˜=K˜šž œœœ ˜1Kšœœœ˜(——L˜—…—ψ6ž