G3dNatsImpl.mesa
Copyright Ó 1985, 1992 by Xerox Corporation. All rights reserved.
Glassner, February 19, 1991 10:43 am PST
Jules Bloomenthal August 26, 1992 3:25 pm PDT
DIRECTORY G2dBasic, G3dBasic, G3dNats, Real, Rope;
G3dNatsImpl: CEDAR MONITOR
IMPORTS G2dBasic, Real
EXPORTS G3dNats
~ BEGIN
Imported Types
ROPE:       TYPE ~ Rope.ROPE;
IntegerPairSequence:  TYPE ~ G2dBasic.IntegerPairSequence;
IntegerPairSequenceRep: TYPE ~ G2dBasic.IntegerPairSequenceRep;
NatSequence:     TYPE ~ G2dBasic.NatSequence;
NatSequenceRep:    TYPE ~ G2dBasic.NatSequenceRep;
BoolSequence:    TYPE ~ G3dBasic.BoolSequence;
BoolSequenceRep:   TYPE ~ G3dBasic.BoolSequenceRep;
NatTable:      TYPE ~ G3dNats.NatTable;
NatTableRep:     TYPE ~ G3dNats.NatTableRep;
Error:      PUBLIC SIGNAL [reason: ROPE] = CODE;
NatSequence Support
NewNatSequence3: PUBLIC PROC [v0, v1, v2: INT] RETURNS [nats: NatSequence] ~ {
nats ¬ NEW[NatSequenceRep[3]];
nats.length ¬ 3;
nats[0] ¬ v0;
nats[1] ¬ v1;
nats[2] ¬ v2;
};
EqualNatSequences: PUBLIC PROC [s1, s2: NatSequence] RETURNS [BOOL] ~ {
Return TRUE iff the two surfaces are the same
match: BoolSequence ¬ NEW[BoolSequenceRep[s1.length]];
match.length ¬ s1.length;
IF s1=NIL OR s2=NIL THEN RETURN [FALSE];
IF s1.length # s2.length THEN RETURN [FALSE];
FOR i: INT IN [0 .. s1.length) DO
match[i] ¬ FALSE;
FOR j: INT IN [0 .. s2.length) DO
IF s2[j] = s1[i] THEN { match[i] ¬ TRUE; EXIT; };
ENDLOOP;
ENDLOOP;
FOR i: INT IN [0 .. match.length) DO
IF NOT match[i] THEN RETURN[FALSE];
ENDLOOP;
RETURN[TRUE];
};
GetCommonElementInNatSequences: PUBLIC PROC [n1, n2: NatSequence] RETURNS [INT ¬ -1] ~ {
dumb n2 test, but I only expect these to be three long anyway. Return -1 if none shared.
IF n1=NIL OR n2=NIL THEN RETURN;
FOR i: INT IN [0 .. n1.length) DO
FOR j: INT IN [0 .. n2.length) DO
IF n1[i] = n2[j] THEN RETURN [n1[i]];
ENDLOOP;
ENDLOOP;
};
GetNatSequenceIndex: PUBLIC PROC [nats: NatSequence, nat: NAT] RETURNS [INT ¬ -1] ~ {
return index into sequence where nat appears, else -1
IF nats=NIL THEN RETURN;
FOR i: INT IN [0 .. nats.length) DO
IF nats[i] = nat THEN RETURN[i];
ENDLOOP;
};
ReplaceNatInSequence: PUBLIC PROC[n: NatSequence, old, new: NAT]RETURNS[r: NatSequence]~{
r ¬ NIL;
IF n=NIL THEN RETURN;
FOR i: INT IN [0 .. n.length) DO
IF n[i] # old
THEN r ¬ G2dBasic.AddToNatSequence[r, n[i]]
ELSE r ¬ G2dBasic.AddToNatSequence[r, new];
ENDLOOP;
};
RemoveNatInSequence: PUBLIC PROC[n: NatSequence, old: NAT] RETURNS [r: NatSequence ¬ NIL ]~{
IF n=NIL THEN RETURN;
FOR i: INT IN [0 .. n.length) DO
IF n[i] # old THEN r ¬ G2dBasic.AddToNatSequence[r, n[i]]
ENDLOOP;
};
GetUniqueElement: PUBLIC PROC [ns: NatSequence] RETURNS [unique: INT ¬ -1] ~ {
returns the single unrepeated element in ns
IF ns=NIL THEN RETURN;
FOR i: INT IN [0 .. ns.length) DO
repeat: BOOL ¬ FALSE;
FOR j: INT IN [0 .. ns.length) DO
IF (i#j) AND (ns[i]=ns[j]) THEN repeat¬TRUE;
ENDLOOP;
IF NOT repeat THEN
IF unique < 0
THEN unique ¬ ns[i]
ELSE Error["no single unique element"]
ENDLOOP;
};
GetRepeatedElement: PUBLIC PROC [ns: NatSequence] RETURNS [INT ¬ -1] ~ {
IF ns=NIL THEN RETURN;
FOR i: INT IN [0 .. ns.length) DO
FOR j: INT IN [0 .. ns.length) DO
IF (i#j) AND (ns[i]=ns[j]) THEN RETURN[ns[i]];
ENDLOOP;
ENDLOOP;
};
GetElementNotShared: PUBLIC PROC [v: NAT, ns: NatSequence] RETURNS [unique: INT ¬ -1] ~ {
returns that single element in n1 that is not v
IF ns=NIL THEN RETURN;
FOR i: INT IN [0 .. ns.length) DO
IF ns[i] # v THEN
IF unique < 0 THEN unique ¬ ns[i]
ELSE Error["repeated unique vertex"];
ENDLOOP;
};
NatInSequence: PUBLIC PROC [nat: NAT, seq: NatSequence] RETURNS [BOOL] ~ {
test if this nat is in this sequence
IF seq=NIL THEN RETURN [FALSE];
FOR i: INT IN [0 .. seq.length) DO IF seq[i]=nat THEN RETURN [TRUE]; ENDLOOP;
RETURN[FALSE];
};
NatSequenceLength: PUBLIC PROC [seq: NatSequence] RETURNS [INT] ~ {
IF seq = NIL THEN RETURN[0] ELSE RETURN [seq.length];
};
NatTable Sequences
CopyNatTable: PUBLIC PROC [nats: NatTable]
RETURNS [NatTable] ~ {
copy: NatTable ¬ NIL;
IF nats # NIL THEN {
copy ¬ NEW[NatTableRep[nats.length]];
copy.length ¬ nats.length;
FOR n: NAT IN [0..nats.length) DO copy[n] ¬ nats[n]; ENDLOOP;
};
RETURN[copy];
};
AddToNatTable: PUBLIC PROC [nats: NatTable, nat: NatSequence]
RETURNS [NatTable] ~ {
IF nats = NIL THEN nats ¬ NEW[NatTableRep[1]];
IF nats.length = nats.maxLength THEN nats ¬ LengthenNatTable[nats];
nats[nats.length] ¬ nat;
nats.length ¬ nats.length+1;
RETURN[nats];
};
LengthenNatTable: PUBLIC PROC [nats: NatTable, amount: REAL ¬ 1.3] RETURNS [new: NatTable] ~ {
newLength: CARDINAL ¬ Real.Ceiling[amount*nats.maxLength];
newLength ¬ MAX[newLength, 3];
new ¬ NEW[NatTableRep[newLength]];
FOR i: NAT IN [0..nats.length) DO new[i] ¬ nats[i]; ENDLOOP;
new.length ¬ nats.length;
};
Scratch Pool
scratchNats: ARRAY [0..10) OF NatSequence ¬ ALL[NIL];
scratchIntegerPairs: ARRAY [0..10) OF IntegerPairSequence ¬ ALL[NIL];
ObtainScratchNats: PUBLIC ENTRY PROC [length: INTEGER] RETURNS [NatSequence] ~ {
FOR i: NAT IN [0..10) DO
scratch: NatSequence ¬ scratchNats[i];
IF scratch = NIL OR scratch.maxLength < CARDINAL[length] THEN LOOP;
scratchNats[i] ¬ NIL;
RETURN[scratch];
ENDLOOP;
RETURN[NEW[NatSequenceRep[length]]];
};
ReleaseScratchNats: PUBLIC ENTRY PROC [scratch: NatSequence] ~ {
FOR i: INTEGER IN [0..10) DO
IF scratchNats[i] # NIL AND scratch.maxLength <= scratchNats[i].maxLength THEN LOOP;
scratchNats[i] ¬ scratch;
RETURN;
ENDLOOP;
};
ObtainScratchIntegerPairs: PUBLIC ENTRY PROC [length: INTEGER]
RETURNS [IntegerPairSequence]
~ {
FOR i: NAT IN [0..10) DO
scratch: IntegerPairSequence ¬ scratchIntegerPairs[i];
IF scratch = NIL OR scratch.maxLength < CARDINAL[length] THEN LOOP;
scratchIntegerPairs[i] ¬ NIL;
RETURN[scratch];
ENDLOOP;
RETURN[NEW[IntegerPairSequenceRep[length]]];
};
ReleaseScratchIntegerPairs: PUBLIC ENTRY PROC [scratch: IntegerPairSequence] ~ {
FOR i: INTEGER IN [0..10) DO
IF scratchIntegerPairs[i] # NIL AND scratch.maxLength <= scratchIntegerPairs[i].maxLength
THEN LOOP;
scratchIntegerPairs[i] ¬ scratch;
RETURN;
ENDLOOP;
};
END.