LichenArray2Impl.Mesa
Last tweaked by Mike Spreitzer on September 18, 1987 1:36:20 pm PDT
DIRECTORY Basics, Convert, InterpreterOps, IO, LichenArrayStuff, LichenCollections, LichenDataOps, LichenDataStructure, LichenPairCollections, List, LRUCache, Rope;
LichenArray2Impl:
CEDAR
PROGRAM
IMPORTS Convert, LichenArrayStuff, LichenCollections, LichenDataOps, LichenDataStructure, LichenPairCollections, List, LRUCache, Rope
EXPORTS LichenArrayStuff
=
BEGIN OPEN LichenDataStructure, LichenArrayStuff, LichenDataOps, Colls:LichenCollections, PairColls:LichenPairCollections;
Abort: ERROR = CODE;
Jgi2ToLair:
PUBLIC
PROC [a: Array, phase: Nat2, j: Joint, jgi2: Nat2]
RETURNS [lair, jiir: Range2, jCount:
NAT] = {
Do1:
PROC [d: Dim]
RETURNS [jiir: Range] = {
SELECT
TRUE
FROM
jgi2[d] < j.groupingParmses[d].middle.min => RETURN [[jgi2[d], jgi2[d]+1]];
jgi2[d] >= j.groupingParmses[d].firstHigh => {
jiir.min ← jgi2[d] - j.groupingParmses[d].d;
RETURN [[jiir.min, jiir.min+1]]};
ENDCASE => RETURN [j.groupingParmses[d].middle];
};
jiir ← [Foo: Do1[Foo], Bar: Do1[Bar]];
jCount ← RangeArea[jiir];
lair ← Range2Mul[jiir, a.jointsPeriod, phase];
};
EnumJgiOfGi:
PUBLIC
PROC [a: Array, gi2: Nat2,
Consume:
PROC [d: Dim, j: Joint, side: End, jgi2, phase: Nat2]] = {
phase: Nat2;
air: Range2 = Gi2ToAir[a, gi2].air;
FOR d: Dim
IN Dim
DO
phase[d] ←
SELECT
TRUE
FROM
gi2[d] < a.groupingParmses[d].middle.min => gi2[d] MOD a.jointsPeriod[d],
gi2[d] >= a.groupingParmses[d].firstHigh => NAT[(gi2[d]-a.groupingParmses[d].d) MOD a.jointsPeriod[d]],
ENDCASE => gi2[d] - NAT[a.groupingParmses[d].middle.min];
ENDLOOP;
FOR d
j: Dim
IN Dim
DO
lairMax: Range2 = SizeRange[Nat2Tweak[a.size, dj, -1]];
j: Joint = GetArrayJoint[a, dj, phase];
FOR side: End
IN End
DO
lair: Range2 = Range2Intersection[lairMax, IF side = low THEN air ELSE Range2Off[air, ConsInt2[dj, -1, 0]]];
lf: Nat2 = [lair[Foo].min MOD a.jointsPeriod[Foo], lair[Bar].min MOD a.jointsPeriod[Bar]];
jir: Range2 = Range2Div[lair, a.jointsPeriod, lf];
Enum:
PROC [d
e: Dim,
Consume:
PROC [
NAT]] = {
mid: Range ~ [
min: MAX[jir[de].min, j.groupingParmses[de].middle.min],
maxPlusOne: MIN[jir[de].maxPlusOne, j.groupingParmses[de].middle.maxPlusOne]];
FOR jgi: INT IN [jir[de].min .. mid.min) DO Consume[jgi] ENDLOOP;
FOR jgi: INT IN [mid.maxPlusOne .. jir[de].maxPlusOne) DO Consume[jgi+j.groupingParmses[de].d] ENDLOOP;
IF mid.min < mid.maxPlusOne THEN Consume[j.groupingParmses[de].middle.min];
};
Med:
PROC [jgif:
NAT] = {
Inner: PROC [jgib: NAT] = {Consume[dj, j, side, [jgif, jgib], phase]};
Enum[Bar, Inner]};
Enum[Foo, Med];
ENDLOOP;
ENDLOOP;
};
Gi2ToAir:
PUBLIC
PROC [a: Array, gi2: Nat2]
RETURNS [air: Range2, ngii2: Nat2, ngii:
NAT] = {
Do1:
PROC [d: Dim]
RETURNS [air: Range, n:
NATURAL] = {
SELECT
TRUE
FROM
gi2[d]<a.groupingParmses[d].middle.min => RETURN [[gi2[d], gi2[d]+1], 1];
gi2[d]>=a.groupingParmses[d].firstHigh => {
air.min ← gi2[d] - a.groupingParmses[d].d;
RETURN [[air.min, air.min+1], 1]};
ENDCASE => {
f: NAT = gi2[d] - a.groupingParmses[d].middle.min;
jiir: Range = Range1Div[a.groupingParmses[d].middle, a.jointsPeriod[d], f];
RETURN [Range1Mul[jiir, a.jointsPeriod[d], f], RangeLength[jiir]];
};
};
[air[Foo], ngii2[Foo]] ← Do1[Foo];
[air[Bar], ngii2[Bar]] ← Do1[Bar];
ngii ← ngii2[Foo] * ngii2[Bar];
};
EnumerateJoints:
PUBLIC
PROC [a: Array,
Consume:
PROC [d: Dim, phase: Nat2, j: Joint]] ~ {
FOR d: Dim
IN Dim
DO
FOR
f
f:
INT
IN [0 .. a.jointsPeriod[Foo])
DO
FOR
f
b:
INT
IN [0 .. a.jointsPeriod[Bar])
DO
phase: Nat2 ~ [ff, fb];
j: Joint ~ GetArrayJoint[a, d, phase];
Consume[d, phase, j];
ENDLOOP ENDLOOP;
ENDLOOP;
};
EnumerateTies:
PUBLIC
PROC [a: Array,
Consume:
PROC [d: Dim, phase: Nat2, jgi:
NATURAL, jgi2: Nat2, j: Joint, tie: Tie]] ~ {
Refine:
PROC [d: Dim, phase: Nat2, j: Joint] ~ {
jgi: NAT ← 0;
FOR jgi
f:
NAT
IN [0 .. j.groupingParmses[Foo].sum)
DO
FOR jgi
b:
NAT
IN [0 .. j.groupingParmses[Bar].sum)
DO
jgi2: Nat2 ~ [jgif, jgib];
ties: Set--of Tie-- ~ FetchTies[j, jgi];
PassTie:
PROC [ra:
REF
ANY]
~ {Consume[d, phase, jgi, jgi2, j, NARROW[ra]]};
ties.Enumerate[PassTie];
jgi ← jgi + 1;
ENDLOOP;
ENDLOOP;
IF jgi # j.ties.length THEN ERROR;
};
EnumerateJoints[a, Refine];
};
EnumerateTiesOfGroup:
PUBLIC
PROC [a: Array, gi2: Nat2, g: Group,
Consume:
PROC [d: Dim, phase: Nat2, jgi:
NATURAL, jgi2: Nat2, j: Joint, tie: Tie, side: End]] ~ {
PerJgi:
PROC [d: Dim, j: Joint, side: End, jgi2: Nat2, phase: Nat2] ~ {
jgi: NATURAL ~ ComposeJgi[j, jgi2];
ties: Set--of Tie-- ~ FetchTies[j, jgi];
PassTie:
PROC [ra:
REF
ANY] ~ {
tie: Tie ~ NARROW[ra];
side: End;
SELECT g
FROM
tie.groups[low] => side ← low;
tie.groups[high] => side ← high;
ENDCASE => RETURN;
Consume[d, phase, jgi, jgi2, j, tie, side];
};
ties.Enumerate[PassTie];
a ← a;
};
EnumJgiOfGi[a, gi2, PerJgi];
a ← a;
};
IsIncompleteArray:
PUBLIC
PROC [ct: CellType]
RETURNS [incomplete:
BOOL] = {
a: Array = ct.asArray;
incomplete ← FALSE;
IF a = NIL THEN RETURN;
FOR d: Dim
IN Dim
DO
FOR cphase:
INT
IN [0 .. a.joints[d].length)
DO
j: Joint = NARROW[a.joints[d][cphase]];
njgi: NAT = j.groupingParmses[Foo].sum * j.groupingParmses[Bar].sum;
FOR jgi:
NAT
IN [0 .. njgi)
DO
ties: Set--of Tie-- = FetchTies[j, jgi];
TestTie:
PROC [ra:
REF
ANY] = {
tie: Tie = NARROW[ra];
IF tie.completion # NIL THEN incomplete ← TRUE;
};
ties.Enumerate[TestTie];
IF incomplete THEN RETURN;
ENDLOOP;
ENDLOOP;
ENDLOOP;
incomplete ← incomplete;
};
GroupInWireAt:
PUBLIC
PROC [a: Array, gi2: Nat2, g: Group, aw: ArrayWire, ai: ArrayIndex]
RETURNS [
BOOL] ~ {
bs: BoolSeq ~ NARROW[aw.members.Apply[g].DVal];
IF bs = NIL THEN RETURN [FALSE];
{air: Range2 ~ Gi2ToAir[a, gi2].air;
shape: Nat2 ~ RangeShape[air];
gii: Nat2 ~ Nat2Div[Int2SubN[ai, Range2Min[air]], a.jointsPeriod];
index: NAT ~ shape[Bar] * gii[Foo] + gii[Bar];
RETURN [bs[index]];
}};
HasUnusedGroups:
PROC [ct: CellType]
RETURNS [has:
BOOL] = {
ENABLE Abort => {has ← TRUE; CONTINUE};
a: Array = ct.asArray;
has ← FALSE;
IF a = NIL THEN RETURN;
FOR gif:
NAT
IN [0 .. a.groupingParmses[Foo].sum)
DO
FOR gib:
NAT
IN [0 .. a.groupingParmses[Bar].sum)
DO
gi2: Nat2 = [gif, gib];
gi: NAT = ComposeGI[a, gi2];
gs: Groupings = NARROW[a.groupingses[gi]];
PerGroup:
PROC [ra:
REF
ANY] = {
g: Group = NARROW[ra];
PerJgi:
PROC [d: Dim, j: Joint, side: End, jgi2, phase: Nat2] = {
jgi: NAT ~ ComposeJgi[j, jgi2];
IF FetchTie[j, side, jgi, g] # NIL THEN ERROR Abort[];
};
EnumJgiOfGi[a, gi2, PerJgi !Abort => GOTO Used];
ERROR Abort[];
EXITS Used => ra ← ra;
};
gs.groups.Enumerate[PerGroup];
IF has THEN RETURN;
ENDLOOP ENDLOOP;
has ← FALSE;
};
GetArrayPortForPort:
PUBLIC
PROC [act: CellType, a: Array, index: ArrayIndex, ep: Port, mayAdd:
BOOL]
RETURNS [arrayPort: Port] = {
gi: NAT = ComputeGroupingsIndex[a, index].gi;
g: Group = PortToGroup[a, gi, ep];
IF g #
NIL
THEN {
arrayPort ← GetArrayPortForGroup[act, a, index, g, FALSE];
IF arrayPort # NIL THEN RETURN;
};
IF mayAdd
THEN {
portName: SteppyName ~ List.Append[NameIndex[a, index], SteppyDescribe[ep, a.eltType.port]];
arrayPort ← FullyAddPort[[parent: act.port, names: CreateSteppyNames[LIST[portName]]]].port;
SetArrayPortForPort[a, index, ep, arrayPort];
}
ELSE arrayPort ← NIL;
};
GetArrayPortForGroup:
PUBLIC
PROC [act: CellType, a: Array, index: ArrayIndex, g: Group, mayAdd:
BOOL]
RETURNS [arrayPort: Port] = {
gi: NAT = ComputeGroupingsIndex[a, index].gi;
aw: ArrayWire = ArrayWireForGroup[a, index, gi, g, mayAdd];
PerPort:
PROC [ra:
REF
ANY] = {
IF (arrayPort ← NARROW[ra]) = NIL THEN ERROR;
};
arrayPort ← NIL;
IF aw # NIL THEN aw.ports.Enumerate[PerPort];
IF arrayPort=
NIL
AND mayAdd
THEN {
ep: Port ~ g.ports.first;
portName: SteppyName ~ List.Append[NameIndex[a, index], SteppyDescribe[ep, a.eltType.port]];
arrayPort ← FullyAddPort[[parent: act.port, names: CreateSteppyNames[LIST[portName]]]].port;
SetArrayPortForGroup[a, index, gi, g, arrayPort];
};
arrayPort ← arrayPort;
};
SetArrayPortForPort:
PUBLIC
PROC [a: Array, index: ArrayIndex, ep, ap: Port] = {
gi: NAT = ComputeGroupingsIndex[a, index].gi;
g: Group = GetGroup[a, gi, ep, TRUE];
SetArrayPortForGroup[a, index, gi, g, ap];
};
SetArrayPortForGroup:
PUBLIC
PROC [a: Array, index: ArrayIndex, gi:
NAT, g: Group, ap: Port] = {
aw: ArrayWire = ArrayWireForGroup[a, index, gi, g, TRUE];
IF NOT aw.ports.AddElt[ap] THEN ERROR;
IF NOT a.portWire.Insert[ap, aw] THEN ERROR;
};
EnumerateGroupsContainingPort:
PUBLIC
PROC [a: Array, ep: Port,
Consume:
PROC [gi2: Nat2, gi:
NATURAL, g: Group]] ~ {
FOR gi
f:
NATURAL
IN [0 .. a.groupingParmses[Foo].sum)
DO
FOR gi
b:
NATURAL
IN [0 .. a.groupingParmses[Bar].sum)
DO
gi: NATURAL ~ ComposeGI[a, [Foo: gif, Bar: gib]];
gs: Groupings ~ NARROW[a.groupingses[gi]];
g: Group ~ NARROW[gs.toGroup.Fetch[ep].val];
IF g#NIL THEN Consume[[Foo: gif, Bar: gib], gi, g];
a ← a;
ENDLOOP;
ENDLOOP;
RETURN};
EnumerateArrayWiresContainingGroup:
PUBLIC
PROC [a: Array, gi2: Nat2, gi:
NATURAL, g: Group,
Consume:
PROC [ArrayWire], addIfMissing:
BOOL] ~ {
seen: Set--of ArrayWire-- ~ Colls.CreateHashSet[];
air: Range2 ~ Gi2ToAir[a, gi2].air;
FOR f:
INT
IN [air[Foo].min .. air[Foo].maxPlusOne)
DO
FOR b:
INT
IN [air[Bar].min .. air[Bar].maxPlusOne)
DO
aw: ArrayWire ~ ArrayWireForGroup[a, [Foo: f, Bar: b], gi, g, addIfMissing];
IF seen.AddElt[aw] THEN Consume[aw];
a ← a; ENDLOOP ENDLOOP;
RETURN};
EnumerateGroupsOfArrayWire:
PUBLIC
PROC [a: Array, aw: ArrayWire,
Consume:
PROC [gi2: Nat2, gi:
NATURAL, g: Group, membership: BoolSeq
--group instance index
b isMember--]] ~ {
PerGroup:
PROC [pair: PairColls.Pair] ~ {
g: Group ~ NARROW[pair[left]];
membership: BoolSeq--group instance index b isMember-- ~ NARROW[pair[right]];
gi: NATURAL ~ ComposeGI[a, g.gi2];
Consume[g.gi2, gi, g, membership];
RETURN};
aw.members.Enumerate[PerGroup];
RETURN};
FlushArrayWires:
PUBLIC
PROC [a: Array, doomedArrayPorts: VarSet
--of port of a--] ~ {
portToAWE: VarFunction--array port b REF ArrayWireElt-- ~ PairColls.CreateHashFn[];
RememberExPort:
PROC [ra:
REF
ANY] ~ {
aw: ArrayWire ~ NARROW[ra];
awe: REF ArrayWireElt ← NIL;
IF aw.ports.Size[] # 0
THEN {
TryGroup:
PROC [pair: PairColls.Pair] ~ {
g: Group ~ NARROW[pair[left]];
bs: BoolSeq ~ NARROW[pair[right]];
air: Range2;
gii, ngii: NATURAL ← 0;
IF g.ports=NIL THEN RETURN;
[air, , ngii] ← Gi2ToAir[a, g.gi2];
FOR foo:
INT ← air[Foo].min, foo+a.jointsPeriod[Foo]
WHILE foo < air[Foo].maxPlusOne
DO
FOR bar:
INT ← air[Bar].min, bar+a.jointsPeriod[Bar]
WHILE bar < air[Bar].maxPlusOne
DO
IF bs[gii]
THEN {
awe ← NEW [ArrayWireElt ← [g, [foo, bar]]];
ERROR GotIt;
};
gii ← gii+1;
ENDLOOP ENDLOOP;
IF gii # ngii THEN ERROR;
};
aw.members.Enumerate[TryGroup !GotIt => GOTO Gotit];
{
NoteDoomedPort:
PROC [ra:
REF
ANY] ~ {
IF NOT doomedArrayPorts.AddElt[ra] THEN ERROR;
};
aw.ports.Enumerate[NoteDoomedPort];
};
EXITS
Gotit => {
NotePortAns:
PROC [ra:
REF
ANY] ~ {
IF NOT portToAWE.Store[[ra, awe]] THEN ERROR;
};
aw.ports.Enumerate[NotePortAns];
awe ← awe;
};
};
};
ExPortNewWire:
PROC [pair: PairColls.Pair] ~ {
ap: Port ~ NARROW[pair[left]];
awe: REF ArrayWireElt ~ NARROW[pair[right]];
gi: NAT ~ ComputeGroupingsIndex[a, awe.ai].gi;
aw: ArrayWire ~ ArrayWireForGroup[a, awe.ai, gi, awe.g, TRUE];
IF NOT a.portWire.Replace[ap, aw] THEN ERROR;
IF NOT aw.ports.AddElt[ap] THEN ERROR;
};
a.wires.Enumerate[RememberExPort];
a.toWire.Erase[];
a.wires.Erase[];
portToAWE.Enumerate[ExPortNewWire];
};
GotIt: ERROR = CODE;
TieSpec: TYPE = REF TieSpecPrivate;
TieSpecPrivate:
TYPE =
RECORD [
j: Joint,
jgi: NATURAL,
tie: Tie
];
tieSpecs: Colls.Space ~ NEW [Colls.SpacePrivate ← [Equal: EqualTieSpecs, Hash: HashTieSpec]];
HashTieSpec:
PROC [data, elt:
REF
ANY]
RETURNS [
CARDINAL]
--HashProc-- ~ {
ts: TieSpec ~ NARROW[elt];
RETURN [Colls.HashRefI[ts.j]+Colls.HashRefI[ts.tie]+ts.jgi];
};
EqualTieSpecs:
PROC [data, elt1, elt2:
REF
ANY]
RETURNS [
BOOL]
--EqualProc-- ~ {
ts1: TieSpec ~ NARROW[elt1];
ts2: TieSpec ~ NARROW[elt2];
RETURN [ts1^ = ts2^];
};
TrimEmptyGroups:
PUBLIC
PROC [a: Array] ~ {
doomedGroups: Set--of Group-- ~ Colls.CreateHashSet[];
doomedTies: Set--of TieSpec-- ~ Colls.CreateHashSet[tieSpecs];
KillTie:
PROC [ra:
REF
ANY] ~ {
ts: TieSpec ~ NARROW[ra];
DeleteTie[ts.j, ts.jgi, ts.tie];
};
KillGroup:
PROC [ra:
REF
ANY] ~ {
g: Group ~ NARROW[ra];
DeleteGroup[a, g];
};
FOR gi
f:
NATURAL
IN [0 .. a.groupingParmses[Foo].sum)
DO
FOR gi
b:
NATURAL
IN [0 .. a.groupingParmses[Bar].sum)
DO
gi2: Nat2 ~ [gif, gib];
gi: NATURAL ~ ComposeGI[a, gi2];
gs: Groupings ~ NARROW[a.groupingses[gi]];
ExploreFrom:
PROC [ra:
REF
ANY] ~ {
IF ~doomedGroups.HasMember[ra]
THEN {
g: Group ~ NARROW[ra];
nonempties: LIST OF Group ← NIL;
stack: LIST OF RECORD [g: Group, t: Tie] ← NIL;
cyclic: BOOL ← FALSE;
IF g.ports=
NIL
THEN {
stack ← CONS[[g, NIL], stack];
IF NOT doomedGroups.AddElt[g] THEN ERROR;
};
WHILE stack#
NIL
DO
h: Group ~ stack.first.g;
avoid: Tie ~ stack.first.t;
CrossTie:
PROC [d: Dim, phase: Nat2, jgi:
NATURAL, jgi2: Nat2, j: Joint, tie: Tie, side: End] ~ {
IF tie=NIL THEN ERROR;
IF tie#avoid
THEN {
i: Group ~ tie.groups[OtherEnd[side]];
IF tie.groups[side]#h THEN ERROR;
IF i=NIL THEN NULL
ELSE
IF i.ports=
NIL
THEN {
ts: TieSpec ~ NEW [TieSpecPrivate ← [j, jgi, tie]];
[] ← doomedTies.AddElt[ts];
IF doomedGroups.AddElt[i] THEN stack ← CONS[[i, tie], stack] ELSE cyclic ← TRUE;
}
ELSE nonempties ← CONS[i, nonempties];
};
};
stack ← stack.rest;
IF h=NIL THEN ERROR;
EnumerateTiesOfGroup[a, h.gi2, h, CrossTie];
ENDLOOP;
IF nonempties=NIL THEN NULL
ELSE IF nonempties.rest=NIL AND NOT cyclic THEN NULL
ELSE ERROR nyet;
}};
gs.groups.Enumerate[ExploreFrom];
ENDLOOP ENDLOOP;
doomedTies.Enumerate[KillTie];
doomedGroups.Enumerate[KillGroup];
};
TrimArray:
PUBLIC
PROC [a: Array] = {
FOR d: Dim
IN Dim
DO
FOR
f
f:
NAT
IN [0 .. a.jointsPeriod[Foo])
DO
FOR
f
b:
NAT
IN [0 .. a.jointsPeriod[Bar])
DO
phase: Nat2 = [ff, fb];
j: Joint = GetArrayJoint[a, d, phase];
FOR jgi:
NAT
IN [0 .. j.ties.length)
DO
ties: VarSet--of Tie-- = FetchTies[j, jgi];
PruneTie:
PROC [ra:
REF
ANY] = {
tie: Tie = NARROW[ra];
IF tie.completion = NIL AND (tie.groups[low] = NIL OR tie.groups[high] = NIL) THEN DeleteTie[j, jgi, tie];
};
ties.Enumerate[PruneTie];
ENDLOOP;
ENDLOOP ENDLOOP;
ENDLOOP;
FOR d: Dim
IN Dim
DO
FOR index:
NAT
IN [0 .. a.roles[d].length)
DO
rpd: SidedPortData ~ NARROW[a.roles[d].refs[index]];
IF rpd=NIL THEN --it's a deleted index--LOOP;
IF rpd.links # NIL AND NOT RPDNeedsLinks[a, d, rpd] THEN rpd.links ← NIL;
ENDLOOP;
ENDLOOP;
};
NameIndex:
PUBLIC
PROC [a: Array, index: ArrayIndex]
RETURNS [SteppyName] = {
SELECT
TRUE
FROM
a.size[Foo]=1 => RETURN [LIST[NewInt[index[Bar]]]];
a.size[Bar]=1 => RETURN [LIST[NewInt[index[Foo]]]];
ENDCASE => RETURN [LIST[NewInt[index[Foo]], NewInt[index[Bar]]]];
};
FmtIndex:
PUBLIC
PROC [a: Array, index: ArrayIndex]
RETURNS [asRope:
ROPE] = {
asRope ←
SELECT
TRUE
FROM
a.size[Foo]=1 => Subscript[NIL, index[Bar]],
a.size[Bar]=1 => Subscript[NIL, index[Foo]],
ENDCASE => Subscript2[NIL, index];
};
sublen: NATURAL ~ 64;
subs: ARRAY [0 .. sublen) OF ROPE ← ALL[NIL];
Subscript:
PUBLIC
PROC [base:
ROPE, index:
INT]
RETURNS [sub:
ROPE] ~ {
sub ← IF index < sublen THEN sub ← subs[index] ELSE sub ← Convert.RopeFromInt[index].Concat["/"];
IF base.Length#0 THEN sub ← base.Cat["/", sub];
RETURN};
sub2len: NATURAL ← 2050;
sub2Ps: LRUCache.Handle ← LRUCache.Create[sub2len, HashAI, EqualAI];
sub2Rs: RefSeq ← CreateRefSeq[sub2len];
s2probes, s2misses: CARD ← 0;
HashAI:
PROC [ra:
REF
ANY]
RETURNS [
CARDINAL]
--LRUCache.HashProc-- ~ {
rai: REF ArrayIndex ~ NARROW[ra];
lnF: Basics.LongNumber ~ [li[rai[Foo]]];
lnB: Basics.LongNumber ~ [li[rai[Bar]]];
ln: Basics.LongNumber ~ [lc[lnF.lo + lnF.hi*3 + lnB.lo*5 + lnB.hi*7]];
RETURN [ln.lo+ln.hi];
};
EqualAI:
PROC [r1, r2:
REF
ANY]
RETURNS [
BOOL]
--LRUCache.EqualProc-- ~ {
rai1: REF ArrayIndex ~ NARROW[r1];
rai2: REF ArrayIndex ~ NARROW[r2];
RETURN [rai1^ = rai2^]};
Subscript2:
PUBLIC
PROC [base:
ROPE, index: ArrayIndex]
RETURNS [sub:
ROPE] ~ {
rai: REF ArrayIndex ~ NEW [ArrayIndex ← index];
p: NATURAL;
news: BOOL;
[p, news, ] ← sub2Ps.Include[rai];
s2probes ← s2probes+1;
IF news
THEN {
sub2Rs[p] ← Rope.Cat[Convert.RopeFromInt[index[Foo]], "/", Convert.RopeFromInt[index[Bar]], "/"];
s2misses ← s2misses+1;
};
sub ← NARROW[sub2Rs[p]];
IF base.Length#0 THEN sub ← base.Cat["/", sub];
RETURN};
Start:
PROC ~ {
FOR index:
NATURAL
IN [0 .. sublen)
DO
subs[index] ← Convert.RopeFromInt[index].Concat["/"];
ENDLOOP;
RETURN};
Start[];
END.