DIRECTORY IO USING [int, PutFR1], IPInterpreter USING [Any, BoundsCheckInteger, Color, ColorFromAny, Context, Identifier, IdentifierFromAny, Integer, IntegerFromAny, IntegerFromNum, Marker, MasterError, maxInteger, nullMarker, Number, NumberFromAny, NumberRep, Operator, OperatorFromAny, Outline, OutlineFromAny, PixelArray, PixelArrayFromAny, RealFromAny, RealFromNum, Ref, StackArray, stackArraySize, StackList, StackMark, Trajectory, TrajectoryFromAny, Transformation, TransformationFromAny, Type, TypeCode, VEC, Vector, VectorFromAny]; IPStackImpl: CEDAR PROGRAM IMPORTS IO, IPInterpreter EXPORTS IPInterpreter ~ BEGIN OPEN IPInterpreter; FlushStackArray: PROC[self: Ref] ~ { FOR i: NAT IN[0..self.stackArrayCount) DO val: Number ~ NEW[NumberRep _ self.stackArray[i]]; self.stackList _ CONS[val, self.stackList]; ENDLOOP; self.stackArrayCount _ 0; }; StackOverflow: PROC [self: Ref] ~ { MasterError[code: $stackOverflow, explanation: IO.PutFR1[ "Stack overflow (maxStackLength=%g)", IO.int[self.stackCountMax]]]; }; StackUnderflow: PROC [self: Ref] ~ { MasterError[code: $stackUnderflow, explanation: "Stack underflow"]; }; MarkMismatch: PROC [self: Ref] ~ { MasterError[code: $markMismatch, explanation: "Mark on stack does not match current context."]; }; PushAny: PUBLIC PROC[self: Ref, val: Any] ~ { IF NOT self.stackCount0 THEN StackUnderflow[self]; self.stackCount _ self.stackCount-1; IF self.stackArrayCount>0 THEN { n: NumberRep ~ self.stackArray[self.stackArrayCount _ self.stackArrayCount-1]; RETURN[NEW[NumberRep _ n]]; } ELSE { top: StackList ~ self.stackList; self.stackList _ top.rest; RETURN[top.first] }; }; PopNum: PUBLIC PROC[self: Ref] RETURNS[NumberRep] ~ { IF self.stackCount>0 AND self.stackArrayCount>0 THEN { n: NumberRep ~ self.stackArray[self.stackArrayCount _ self.stackArrayCount-1]; self.stackCount _ self.stackCount-1; RETURN[n]; } ELSE RETURN[NumberFromAny[PopAny[self]]^]; }; PopBool: PUBLIC PROC[self: Ref] RETURNS[BOOL] ~ { RETURN[PopInteger[self]#0]; }; PopInteger: PUBLIC PROC[self: Ref] RETURNS[Integer] ~ { IF self.stackCount>0 AND self.stackArrayCount>0 THEN { n: NumberRep ~ self.stackArray[self.stackArrayCount _ self.stackArrayCount-1]; self.stackCount _ self.stackCount-1; WITH n: n SELECT FROM int => IF n.int IN[0..maxInteger] THEN RETURN[n.int]; ENDCASE; RETURN[IntegerFromNum[n]]; } ELSE RETURN[IntegerFromAny[PopAny[self]]]; }; PopReal: PUBLIC PROC[self: Ref] RETURNS[REAL] ~ { IF self.stackCount>0 AND self.stackArrayCount>0 THEN { n: NumberRep ~ self.stackArray[self.stackArrayCount _ self.stackArrayCount-1]; self.stackCount _ self.stackCount-1; WITH n: n SELECT FROM int => RETURN[REAL[n.int]]; real => RETURN[n.real]; ENDCASE; RETURN[RealFromNum[n]]; } ELSE RETURN[RealFromAny[PopAny[self]]]; }; PopVec: PUBLIC PROC[self: Ref] RETURNS[VEC] ~ { y: REAL ~ PopReal[self]; x: REAL ~ PopReal[self]; RETURN[[x, y]]; }; PopIdentifier: PUBLIC PROC[self: Ref] RETURNS[Identifier] ~ { x: Any ~ PopAny[self]; WITH x SELECT FROM x: Identifier => RETURN[x]; ENDCASE; RETURN[IdentifierFromAny[x]]; }; PopVector: PUBLIC PROC[self: Ref] RETURNS[Vector] ~ { x: Any ~ PopAny[self]; WITH x SELECT FROM x: Vector => RETURN[x]; ENDCASE; RETURN[VectorFromAny[x]]; }; PopOperator: PUBLIC PROC[self: Ref] RETURNS[Operator] ~ { x: Any ~ PopAny[self]; WITH x SELECT FROM x: Operator => RETURN[x]; ENDCASE; RETURN[OperatorFromAny[x]]; }; PopTransformation: PUBLIC PROC[self: Ref] RETURNS[Transformation] ~ { x: Any ~ PopAny[self]; WITH x SELECT FROM x: Transformation => RETURN[x]; ENDCASE; RETURN[TransformationFromAny[x]]; }; PopPixelArray: PUBLIC PROC[self: Ref] RETURNS[PixelArray] ~ { x: Any ~ PopAny[self]; WITH x SELECT FROM x: PixelArray => RETURN[x]; ENDCASE; RETURN[PixelArrayFromAny[x]]; }; PopColor: PUBLIC PROC[self: Ref] RETURNS[Color] ~ { x: Any ~ PopAny[self]; WITH x SELECT FROM x: Color => RETURN[x]; ENDCASE; RETURN[ColorFromAny[x]]; }; PopTrajectory: PUBLIC PROC[self: Ref] RETURNS[Trajectory] ~ { x: Any ~ PopAny[self]; WITH x SELECT FROM x: Trajectory => RETURN[x]; ENDCASE; RETURN[TrajectoryFromAny[x]]; }; PopOutline: PUBLIC PROC[self: Ref] RETURNS[Outline] ~ { x: Any ~ PopAny[self]; WITH x SELECT FROM x: Outline => RETURN[x]; ENDCASE; RETURN[OutlineFromAny[x]]; }; TopType: PUBLIC PROC[self: Ref] RETURNS[TypeCode] ~ { IF NOT self.stackCount>0 THEN StackUnderflow[self]; IF self.stackArrayCount>0 THEN RETURN[number] ELSE RETURN[Type[self.stackList.first]]; }; Pop: PUBLIC PROC[self: Ref] ~ { IF self.stackCount>0 AND self.stackArrayCount>0 THEN { self.stackCount _ self.stackCount-1; self.stackArrayCount _ self.stackArrayCount-1; } ELSE [] _ PopAny[self]; }; Copy: PUBLIC PROC[self: Ref, depth: Integer] ~ { IF NOT self.stackCount>=BoundsCheckInteger[depth] THEN StackUnderflow[self]; IF NOT (self.stackCountMax-self.stackCount)>=depth THEN StackOverflow[self]; IF depth=0 THEN RETURN; IF self.stackArrayCount>=depth AND (stackArraySize-self.stackArrayCount)>=depth THEN { n: NAT ~ depth; b: NAT ~ self.stackArrayCount-n; array: StackArray ~ self.stackArray; FOR i: NAT IN[b..b+n) DO TRUSTED{ array[i+n] _ array[i] }; ENDLOOP; self.stackArrayCount _ self.stackArrayCount+n; } ELSE { head, tail, each: StackList _ NIL; IF NOT self.stackArrayCount=0 THEN FlushStackArray[self]; each _ self.stackList; THROUGH [0..depth) DO copy: StackList ~ CONS[each.first, NIL]; IF tail=NIL THEN head _ copy ELSE tail.rest _ copy; tail _ copy; each _ each.rest; ENDLOOP; tail.rest _ self.stackList; self.stackList _ head; }; self.stackCount _ self.stackCount+depth; }; Roll: PUBLIC PROC[self: Ref, depth, moveFirst: Integer] ~ { IF NOT BoundsCheckInteger[depth]>=BoundsCheckInteger[moveFirst] THEN MasterError[$invalidArgs, "ROLL: moveFirst exceeds depth"]; IF NOT self.stackCount>=depth THEN StackUnderflow[self]; IF depth=0 OR moveFirst=0 OR moveFirst=depth THEN RETURN; IF self.stackArrayCount>=depth THEN { n: NAT ~ depth; m: NAT ~ moveFirst; b: NAT ~ self.stackArrayCount-n; a: StackArray ~ self.stackArray; Reverse: PROC[bot, top: NAT] ~ { -- reverse a[bot..top) FOR x: NAT IN[0..NAT[top-bot]/2) DO i: NAT ~ bot+x; j: NAT ~ top-1-x; temp: NumberRep ~ a[i]; TRUSTED{ a[i] _ a[j] }; TRUSTED{ a[j] _ temp }; ENDLOOP; }; Reverse[b, b+m]; Reverse[b+m, b+n]; Reverse[b, b+n]; } ELSE { k: Integer ~ depth-moveFirst; top, kth, nth, each: StackList _ NIL; IF NOT self.stackArrayCount=0 THEN FlushStackArray[self]; each _ top _ self.stackList; THROUGH [0..k) DO kth _ each; each _ each.rest ENDLOOP; self.stackList _ each; -- new top of stack THROUGH [k..depth) DO nth _ each; each _ each.rest ENDLOOP; kth.rest _ each; nth.rest _ top; }; }; Mark: PUBLIC PROC[self: Ref, n: Integer] ~ { contextMarker: Marker ~ IF self.context=NIL THEN nullMarker ELSE self.context.marker; mark: StackMark _ []; IF NOT self.stackCount>=BoundsCheckInteger[n] THEN StackUnderflow[self]; mark.count _ self.stackCount-n; -- number of elements hidden by the mark mark.marker _ contextMarker; -- marker for current context self.stackCount _ self.stackCount-mark.count; -- = n self.stackCountMax _ self.stackCountMax-mark.count; self.stackMarkList _ CONS[mark, self.stackMarkList]; }; Unmark: PUBLIC PROC[self: Ref, n: Integer] ~ { contextMarker: Marker ~ IF self.context=NIL THEN nullMarker ELSE self.context.marker; mark: StackMark ~ IF self.stackMarkList=NIL THEN [] ELSE self.stackMarkList.first; IF NOT mark.marker=contextMarker THEN MarkMismatch[self]; IF NOT self.stackCount>=BoundsCheckInteger[n] THEN StackUnderflow[self]; IF NOT self.stackCount=n THEN MasterError[$unmarkFailed, "UNMARK found no mark at the specified depth"]; self.stackCount _ self.stackCount+mark.count; self.stackCountMax _ self.stackCountMax+mark.count; self.stackMarkList _ self.stackMarkList.rest; }; Count: PUBLIC PROC[self: Ref] RETURNS[Integer] ~ { contextMarker: Marker ~ IF self.context=NIL THEN nullMarker ELSE self.context.marker; mark: StackMark ~ IF self.stackMarkList=NIL THEN [] ELSE self.stackMarkList.first; IF NOT mark.marker=contextMarker THEN MarkMismatch[self]; RETURN[BoundsCheckInteger[self.stackCount]]; }; PopToActiveMark: PUBLIC PROC[self: Ref] RETURNS[Marker] ~ { DO mark: StackMark ~ self.stackMarkList.first; WHILE self.stackCount>0 DO Pop[self] ENDLOOP; IF mark.marker=nullMarker THEN RETURN[mark.marker]; FOR context: Context _ self.context, context.caller UNTIL context=NIL DO IF context.marker=mark.marker THEN RETURN[mark.marker]; -- context still exists ENDLOOP; self.stackCount _ self.stackCount+mark.count; self.stackCountMax _ self.stackCountMax+mark.count; self.stackMarkList _ self.stackMarkList.rest; ENDLOOP; }; END. ”IPStackImpl.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Doug Wyatt, May 30, 1985 5:52:34 pm PDT Top: PUBLIC PROC[self: Ref] RETURNS[Any] ~ { IF NOT self.stackCount>0 THEN MasterError[stackUnderflow]; IF self.stackArrayCount>0 THEN RETURN[NEW[NumberRep _ self.stackArray[self.stackArrayCount-1]]] ELSE RETURN[self.stackList.first]; }; -- Avoid useless NEW[NumberRep]. Ê:˜codešœ™Kšœ Ïmœ7™BKšœ'™'—K˜šÏk ˜ Kšžœžœ˜KšœžœÊžœ˜ù—K˜KšÐbl œžœž˜Kšžœžœ˜Kšžœ˜Kšœžœžœ˜K˜šÏnœžœ˜$šžœžœžœž˜)Kšœžœ!˜2Kšœžœ˜+Kšžœ˜—Kšœ˜K˜K˜—š  œžœ˜#Kšœ/žœ/žœ˜}K˜K˜—š œžœ˜$KšœC˜CK˜K˜—š  œžœ˜"Kšœ`˜`K˜K˜—š œžœžœ˜-Kšžœžœ$žœ˜CKšžœžœžœ˜9Kšœžœ˜+Kšœ$˜$K˜K˜—š œžœžœ˜3Kšžœžœ$žœ˜CKšžœžœ%žœ˜FKšžœ0˜7Kšœ.˜.Kšœ$˜$K˜K˜—š œžœžœžœ˜/Kšœžœžœžœ˜(Kšœ˜K˜—š  œžœžœ˜5Kšœ.˜.šžœ$žœ%žœ˜TKšžœ.˜5Kšœ.˜.Kšœ$˜$K˜—Kšžœ˜Kšœ˜K˜—š œžœžœžœ˜/K˜šžœ$žœ%žœ˜TKšžœ.˜5Kšœ.˜.Kšœ$˜$K˜—Kšžœ˜Kšœ˜K˜—š œžœžœžœ˜-Kšœ-˜-Kšœ˜K˜—š œžœžœ ˜;Kšžœžœžœ3˜BKšœ˜Kšœ˜K˜—š  œžœžœ˜3Kšžœžœžœ/˜>Kšœ˜Kšœ˜K˜—š  œžœžœ˜7Kšžœžœžœ1˜@Kšœ˜Kšœ˜K˜—š œžœžœ$˜CKšžœžœžœ7˜FKšœ˜Kšœ˜K˜—š œžœžœ ˜;Kšžœžœžœ3˜BKšœ˜Kšœ˜K˜—š  œžœžœ˜1Kšžœžœžœ.˜=Kšœ˜Kšœ˜K˜—š œžœžœ ˜;Kšžœžœžœ3˜BKšœ˜Kšœ˜K˜—š  œžœžœ˜5Kšžœžœžœ0˜?Kšœ˜Kšœ˜K˜—K˜š œžœžœ žœ ˜/Kšžœžœžœ˜3Kšœ$˜$šžœžœ˜ KšœN˜NKšžœžœ˜K˜—Kšžœ?žœ˜WK˜K˜—š œžœžœ žœ˜5šžœžœžœ˜6KšœN˜NKšœ$˜$Kšžœ˜ K˜—Kšžœžœ˜*K˜K˜—š  œžœžœ žœžœ˜1Kšžœ˜Kšœ˜K˜—š  œžœžœ žœ ˜7šžœžœžœ˜6KšœN˜NKšœ$˜$šžœžœž˜Kš œžœžœžœžœ˜5Kšžœ˜—Kšžœ˜K˜—Kšžœžœ˜*K˜K˜—š  œžœžœ žœžœ˜1šžœžœžœ˜6KšœN˜NKšœ$˜$šžœžœž˜Kšœžœžœ ˜Kšœžœ ˜Kšžœ˜—Kšžœ˜K˜—Kšžœžœ˜'K˜K˜—š  œžœžœ žœžœ˜/Kšœžœžœžœ ˜AK˜K˜—š  œžœžœ žœ˜=K˜Kš žœžœžœžœžœ˜7Kšžœ˜K˜K˜—š  œžœžœ žœ ˜5K˜Kš žœžœžœžœžœ˜3Kšžœ˜K˜K˜—š  œžœžœ žœ˜9K˜Kš žœžœžœžœžœ˜5Kšžœ˜K˜K˜—š œžœžœ žœ˜EK˜Kš žœžœžœžœžœ˜;Kšžœ˜!K˜K˜—š  œžœžœ žœ˜=K˜Kš žœžœžœžœžœ˜7Kšžœ˜K˜K˜—š œžœžœ žœ ˜3K˜Kš žœžœžœ žœžœ˜2Kšžœ˜K˜K˜—š  œžœžœ žœ˜=K˜Kš žœžœžœžœžœ˜7Kšžœ˜K˜K˜—š  œžœžœ žœ ˜7K˜Kš žœžœžœžœžœ˜4Kšžœ˜K˜K˜—K˜š œžœžœ žœ ™,Kšžœžœžœ™:šžœž™Kšžœžœ6™@—Kšžœžœ™"K™K™—š œžœžœ žœ˜5Kšžœžœžœ˜3Kšžœžœžœ˜-Kšžœžœ˜(K˜K˜—š œžœžœ˜šžœžœžœ˜6KšÏc ™ Kšœ$˜$Kšœ.˜.K˜—Kšžœ˜K˜K˜—š œžœžœ˜0Kšžœžœ,žœ˜LKšžœžœ-žœ˜LKšžœ žœžœ˜šžœžœ.žœ˜VKšœžœ ˜Kšœžœ˜ Kšœ$˜$šžœžœžœ ž˜Kšžœ˜!Kšžœ˜—Kšœ.˜.K˜—šžœ˜Kšœžœ˜"Kšžœžœžœ˜9K˜šžœ ž˜Kšœžœ žœ˜(Kšžœžœžœ žœ˜3K˜Kšžœ˜—K˜2K˜—Kšœ(˜(K˜K˜—š œžœžœ*˜;Kšžœžœ:žœ<˜€Kšžœžœžœ˜8Kš žœ žœ žœžœžœ˜9šžœžœ˜%Kšœžœ ˜Kšœžœ ˜Kšœžœ˜ Kšœ ˜ š œžœ žœ¡˜7š žœžœžœžœ ž˜#Kšœžœ žœ ˜!Kšœ˜Kšžœ˜Kšžœ˜Kšžœ˜—K˜—Kšœ4˜4K˜—šžœ˜Kšœ˜Kšœ!žœ˜%Kšžœžœžœ˜9Kšœ˜Kšžœžœžœ˜7Kšœ¡˜*Kšžœ žœžœ˜;K˜ K˜—K˜K˜—K˜š œžœžœ˜,Kš œžœžœžœ žœ˜UKšœ˜Kšžœžœ(žœ˜HKšœ ¡(˜HKšœ¡˜:Kšœ.¡˜4Kšœ3˜3Kšœžœ˜4K˜K˜—š œžœžœ˜.Kš œžœžœžœ žœ˜UKš œžœžœžœžœ˜RKšžœžœžœ˜9Kšžœžœ(žœ˜HKšžœžœžœL˜iKšœ-˜-Kšœ3˜3Kšœ-˜-K˜K˜—š œžœžœ žœ ˜2Kš œžœžœžœ žœ˜UKš œžœžœžœžœ˜RKšžœžœžœ˜9Kšžœ&˜,Kšœ˜K˜—š œžœžœ žœ ˜;šžœ,˜.Kšžœžœ žœ˜-Kšžœžœžœ˜3šžœ1žœ žœž˜HKšžœžœžœ¡˜OKšžœ˜—Kšœ-˜-Kšœ3˜3Kšœ-˜-Kšžœ˜—Kšœ˜K˜—K™Kšžœ˜—…—+à;®