DIRECTORY IP USING [Any, AnyFromInt, AnyFromReal, CheckInteger, Color, ColorFromAny, Element, ElementRep, GetMarker, Identifier, IdentifierFromAny, Integer, IntegerFromAny, IntegerFromInt, IntegerFromReal, Marker, MarkItem, MarkItemRep, MasterError, maxInteger, Operator, OperatorFromAny, Outline, OutlineFromAny, Pair, PixelArray, PixelArrayFromAny, RealFromAny, RealFromInt, State, Trajectory, TrajectoryFromAny, Transformation, TransformationFromAny, Type, TypeCode, Vector, VectorFromAny], IPBase USING []; IPStackImpl: CEDAR PROGRAM IMPORTS IP EXPORTS IP, IPBase = BEGIN OPEN IP; NewElement: PROC RETURNS[Element] ~ { RETURN[NEW[ElementRep _ []]]; }; InitializeStack: PUBLIC PROC[self: State, maxLength: Integer] ~ { self.stack _ NewElement[]; -- dummy element at base of stack, so self.stack.above always works self.count _ 0; self.maxCount _ CheckInteger[maxLength]; self.mark _ NIL; }; StackUnderflow: PROC[self: State] ~ { MasterError[$stackUnderflow, "Stack underflow."]; }; PushElement: PROC[self: State] RETURNS[Element] ~ { old: Element ~ self.stack; new: Element _ old.above; count: Integer ~ self.count; IF NOT count0 THEN MasterError[$stackUnderflow, "Tried to pop an element from an empty stack."]; self.count _ count-1; self.stack _ old.below; RETURN[old]; }; Push: PUBLIC PROC[self: State, x: Any] ~ { new: Element ~ PushElement[self]; new.type _ $ref; new.ref _ x; }; PushInteger: PUBLIC PROC[self: State, i: Integer] ~ { new: Element ~ PushElement[self]; new.type _ $int; new.int _ CheckInteger[i]; }; PushInt: PUBLIC PROC[self: State, i: INT] ~ { new: Element ~ PushElement[self]; new.type _ $int; new.int _ i; }; PushReal: PUBLIC PROC[self: State, r: REAL] ~ { new: Element ~ PushElement[self]; new.type _ $real; new.real _ r; }; PushPair: PUBLIC PROC[self: State, p: Pair] ~ { PushReal[self, p.x]; PushReal[self, p.y]; }; PushIdentifier: PUBLIC PROC[self: State, x: Identifier] ~ { IF x=NIL THEN MasterError[$nilFault, "Identifier must not be NIL."] ELSE { new: Element ~ PushElement[self]; new.type _ $ref; new.ref _ x }; }; PushVector: PUBLIC PROC[self: State, x: Vector] ~ { IF x=NIL THEN MasterError[$nilFault, "Vector must not be NIL."] ELSE { new: Element ~ PushElement[self]; new.type _ $ref; new.ref _ x }; }; PushOperator: PUBLIC PROC[self: State, x: Operator] ~ { IF x=NIL THEN MasterError[$nilFault, "Operator must not be NIL."] ELSE { new: Element ~ PushElement[self]; new.type _ $ref; new.ref _ x }; }; PushTransformation: PUBLIC PROC[self: State, x: Transformation] ~ { IF x=NIL THEN MasterError[$nilFault, "Transformation must not be NIL."] ELSE { new: Element ~ PushElement[self]; new.type _ $ref; new.ref _ x }; }; PushPixelArray: PUBLIC PROC[self: State, x: PixelArray] ~ { IF x=NIL THEN MasterError[$nilFault, "PixelArray must not be NIL."] ELSE { new: Element ~ PushElement[self]; new.type _ $ref; new.ref _ x }; }; PushColor: PUBLIC PROC[self: State, x: Color] ~ { IF x=NIL THEN MasterError[$nilFault, "Color must not be NIL."] ELSE { new: Element ~ PushElement[self]; new.type _ $ref; new.ref _ x }; }; PushTrajectory: PUBLIC PROC[self: State, x: Trajectory] ~ { IF x=NIL THEN MasterError[$nilFault, "Trajectory must not be NIL."] ELSE { new: Element ~ PushElement[self]; new.type _ $ref; new.ref _ x }; }; PushOutline: PUBLIC PROC[self: State, x: Outline] ~ { IF x=NIL THEN MasterError[$nilFault, "Outline must not be NIL."] ELSE { new: Element ~ PushElement[self]; new.type _ $ref; new.ref _ x }; }; Pop: PUBLIC PROC[self: State] RETURNS[Any] ~ { old: Element ~ PopElement[self]; SELECT old.type FROM $ref => { x: REF ~ old.ref; old.ref _ NIL; RETURN[x] }; $int => RETURN[AnyFromInt[old.int]]; $real => RETURN[AnyFromReal[old.real]]; ENDCASE => ERROR; }; PopInteger: PUBLIC PROC[self: State] RETURNS[Integer] ~ { old: Element ~ PopElement[self]; SELECT old.type FROM $ref => { x: REF ~ old.ref; old.ref _ NIL; RETURN[IntegerFromAny[x]] }; $int => RETURN[IF old.int IN[0..maxInteger] THEN old.int ELSE IntegerFromInt[old.int]]; $real => RETURN[IntegerFromReal[old.real]]; ENDCASE => ERROR; }; PopReal: PUBLIC PROC[self: State] RETURNS[REAL] ~ { old: Element ~ PopElement[self]; SELECT old.type FROM $ref => { x: REF ~ old.ref; old.ref _ NIL; RETURN[RealFromAny[x]] }; $int => RETURN[RealFromInt[old.int]]; $real => RETURN[old.real]; ENDCASE => ERROR; }; PopPair: PUBLIC PROC[self: State] RETURNS[p: Pair] ~ { p.y _ PopReal[self]; p.x _ PopReal[self]; }; PopIdentifier: PUBLIC PROC[self: State] RETURNS[Identifier] ~ { old: Element ~ PopElement[self]; x: REF _ NIL; IF old.type=$ref THEN { x _ old.ref; old.ref _ NIL }; WITH x SELECT FROM x: Identifier => RETURN[x]; ENDCASE; RETURN[IdentifierFromAny[x]]; }; PopVector: PUBLIC PROC[self: State] RETURNS[Vector] ~ { old: Element ~ PopElement[self]; x: REF _ NIL; IF old.type=$ref THEN { x _ old.ref; old.ref _ NIL }; WITH x SELECT FROM x: Vector => RETURN[x]; ENDCASE; RETURN[VectorFromAny[x]]; }; PopOperator: PUBLIC PROC[self: State] RETURNS[Operator] ~ { old: Element ~ PopElement[self]; x: REF _ NIL; IF old.type=$ref THEN { x _ old.ref; old.ref _ NIL }; WITH x SELECT FROM x: Operator => RETURN[x]; ENDCASE; RETURN[OperatorFromAny[x]]; }; PopTransformation: PUBLIC PROC[self: State] RETURNS[Transformation] ~ { old: Element ~ PopElement[self]; x: REF _ NIL; IF old.type=$ref THEN { x _ old.ref; old.ref _ NIL }; WITH x SELECT FROM x: Transformation => RETURN[x]; ENDCASE; RETURN[TransformationFromAny[x]]; }; PopPixelArray: PUBLIC PROC[self: State] RETURNS[PixelArray] ~ { old: Element ~ PopElement[self]; x: REF _ NIL; IF old.type=$ref THEN { x _ old.ref; old.ref _ NIL }; WITH x SELECT FROM x: PixelArray => RETURN[x]; ENDCASE; RETURN[PixelArrayFromAny[x]]; }; PopColor: PUBLIC PROC[self: State] RETURNS[Color] ~ { old: Element ~ PopElement[self]; x: REF _ NIL; IF old.type=$ref THEN { x _ old.ref; old.ref _ NIL }; WITH x SELECT FROM x: Color => RETURN[x]; ENDCASE; RETURN[ColorFromAny[x]]; }; PopTrajectory: PUBLIC PROC[self: State] RETURNS[Trajectory] ~ { old: Element ~ PopElement[self]; x: REF _ NIL; IF old.type=$ref THEN { x _ old.ref; old.ref _ NIL }; WITH x SELECT FROM x: Trajectory => RETURN[x]; ENDCASE; RETURN[TrajectoryFromAny[x]]; }; PopOutline: PUBLIC PROC[self: State] RETURNS[Outline] ~ { old: Element ~ PopElement[self]; x: REF _ NIL; IF old.type=$ref THEN { x _ old.ref; old.ref _ NIL }; WITH x SELECT FROM x: Outline => RETURN[x]; ENDCASE; RETURN[OutlineFromAny[x]]; }; TopType: PUBLIC PROC[self: State] RETURNS[TypeCode] ~ { top: Element ~ self.stack; count: Integer ~ self.count; IF NOT count>0 THEN MasterError[$stackUnderflow, "Tried to pop an element from an empty stack."]; SELECT top.type FROM $ref => RETURN[Type[top.ref]]; $int, $real => RETURN[$Number]; ENDCASE => ERROR; }; Discard: PUBLIC PROC[self: State] ~ { old: Element ~ PopElement[self]; SELECT old.type FROM $ref => old.ref _ NIL; $int, $real => NULL; ENDCASE => ERROR; }; Copy: PUBLIC PROC[self: State, depth: Integer] ~ { IF CheckInteger[depth]=0 THEN NULL ELSE IF self.count new.int _ this.int; $real => new.real _ this.real; $ref => new.ref _ this.ref; ENDCASE => ERROR; ENDLOOP; }; }; Roll: PUBLIC PROC[self: State, depth, moveFirst: Integer] ~ { IF CheckInteger[moveFirst]>CheckInteger[depth] THEN MasterError[$invalidArgs, "ROLL: moveFirst exceeds depth."] ELSE IF self.count0 THEN { MasterError[$unmarkFailed, "UNMARK0 found one or more elements above the top mark.", FALSE]; -- don't raise Error WHILE self.count>0 DO Discard[self] ENDLOOP; -- do mark recovery }; RemoveMark[self, marker]; }; Count: PUBLIC PROC[self: State] RETURNS[Integer] ~ { marker: Marker ~ GetMarker[self]; mark: MarkItem ~ self.mark; IF mark.marker#marker THEN MarkMismatch[]; RETURN[CheckInteger[self.count]]; }; PopToMark: PUBLIC PROC[self: State] RETURNS[Marker] ~ { mark: MarkItem ~ self.mark; WHILE self.count>0 DO Discard[self] ENDLOOP; RETURN[mark.marker]; }; ApplyPOP: PUBLIC PROC[self: State] ~ { Discard[self]; }; ApplyCOPY: PUBLIC PROC[self: State] ~ { n: Integer ~ PopInteger[self]; Copy[self: self, depth: n]; }; ApplyDUP: PUBLIC PROC[self: State] ~ { Copy[self: self, depth: 1]; }; ApplyROLL: PUBLIC PROC[self: State] ~ { moveFirst: Integer ~ PopInteger[self]; depth: Integer ~ PopInteger[self]; Roll[self: self, depth: depth, moveFirst: moveFirst]; }; ApplyEXCH: PUBLIC PROC[self: State] ~ { Roll[self: self, depth: 2, moveFirst: 1]; }; ApplyMARK: PUBLIC PROC[self: State] ~ { n: Integer ~ PopInteger[self]; Mark[self, n]; }; ApplyUNMARK: PUBLIC PROC[self: State] ~ { n: Integer ~ PopInteger[self]; Unmark[self, n]; }; ApplyUNMARK0: PUBLIC PROC[self: State] ~ { Unmark0[self]; }; ApplyCOUNT: PUBLIC PROC[self: State] ~ { n: Integer ~ Count[self]; PushInteger[self, n]; }; ApplyNOP: PUBLIC PROC[self: State] ~ { }; END. $IPStackImpl.mesa Last edited by: Doug Wyatt, March 3, 1984 3:58:25 pm PST Return the type of the top element. Equivalent to [] _ Pop[self], but avoids useless NEW. Since there is a dummy element at the base of the stack, bot cannot be NIL. ReserveChars: PROC [to: String, nChars: NAT] RETURNS [String] = { newMinLength: NAT = to.length + nChars; -- may raise PointerFault or BoundsFault IF newMinLength <= to.maxLength THEN RETURN [to]; { expandBy: NAT = MAX[16, to.maxLength, nChars]; newLength: NAT = IF expandBy > NAT.LAST-to.maxLength THEN NAT.LAST ELSE expandBy+to.maxLength; newString: String = NEW[StringRep[newLength]]; FOR i: NAT IN [0..to.length) DO newText[i] _ to[i] ENDLOOP; newText.length _ to.length; RETURN [newText]; } }; AppendChar: PROC[to: String, from: CARDINAL] RETURNS[String] ~ { IF to.length>=to.maxLength THEN to _ ReserveChars[to, 1]; to[to.length] _ from; to.length _ to.length+1; RETURN[to]; }; InlineAppendChar: PROC[to: String, from: CARDINAL] RETURNS[String] ~ INLINE { IF to.length>=to.maxLength THEN RETURN[AppendChar[to, from]]; to[to.length] _ from; to.length _ to.length+1; RETURN[to]; }; PushString: PUBLIC PROC[self: State, text: REF TEXT] ~ { offset: CARDINAL _ 0; state: {run, escape, escape2, extended, extended2} _ run; FOR i: NAT IN[0..text.length) DO b: BYTE ~ LOOPHOLE[text[i]]; SELECT state FROM run => IF b#255 THEN Append[offset+b] ELSE state _ escape; escape => IF b#255 THEN { offset _ b*256; state _ run } ELSE state _ escape2; escape2 => IF b=0 THEN state _ extended ELSE ERROR; extended => IF b#255 THEN { offset _ b*256; state _ extended2 } ELSE state _ escape; extended2 => { Append[offset+b]; state _ extended }; ENDCASE; ENDLOOP; IF NOT(state=run OR state=extended) THEN ERROR; }; PopString: PUBLIC PROC[self: State, buffer: String] RETURNS[String] ~ { }; ʘJšœ™J™šœ™Jšœ(™(—J˜šÏk ˜ JšœœÛ˜ãJšœœ˜J˜—Jšœ œ˜Jšœ˜ Jšœœ˜Jšœœœœ˜J˜šÏn œœœ ˜%Jšœœ˜J˜J˜—šžœœœ%˜AJšœÏcC˜^J˜J˜(Jšœ œ˜J˜J˜—J˜šžœœ˜%Jšœ1˜1J˜J˜—J˜šž œœœ ˜3JšœQ˜Qšœœ˜JšœO˜O—Jšœœœ:˜IJšœ œœœ˜Jšœœ˜/J˜J˜—šž œœœ ˜2Jšœ7˜7šœœ ˜JšœM˜M—Jšœ.œ˜:J˜J˜—J˜šžœœœ˜*J˜!J˜J˜J˜—šž œœœ˜5J˜!J˜+J˜J˜—šžœœœœ˜-J˜!J˜J˜J˜—šžœœœœ˜/J˜!J˜J˜J˜—šžœœœ˜/J˜)J˜J˜—šžœœœ ˜;Jšœœœ6˜CJšœD˜HJ˜J˜—šž œœœ˜3Jšœœœ2˜?JšœD˜HJ˜J˜—šž œœœ˜7Jšœœœ4˜AJšœD˜HJ˜J˜—šžœœœ$˜CJšœœœ:˜GJšœD˜HJ˜J˜—šžœœœ ˜;Jšœœœ6˜CJšœD˜HJ˜J˜—šž œœœ˜1Jšœœœ1˜>JšœD˜HJ˜J˜—šžœœœ ˜;Jšœœœ6˜CJšœD˜HJ˜J˜—šž œœœ˜5Jšœœœ3˜@JšœD˜HJ˜J˜—J˜šžœœœœ ˜.Jšœ ˜ šœ ˜Jšœ œœœ˜7Jšœœ˜$Jšœ œ˜'Jšœœ˜—J˜J˜—šž œœœœ ˜9J˜ šœ ˜Jšœ œœœ˜GJš œœœ œœ œ˜WJšœ œ˜+Jšœœ˜—J˜J˜—š žœœœœœ˜3J˜ šœ ˜Jšœ œœœ˜DJšœœ˜%Jšœ œ ˜Jšœœ˜—J˜J˜—šžœœœœ ˜6J˜)J˜J˜—šž œœœœ˜?Jšœ$œœ˜.Jšœœœ˜5Jš œœœœœ˜7Jšœ˜J˜J˜—šž œœœœ ˜7Jšœ$œœ˜.Jšœœœ˜5Jš œœœœœ˜3Jšœ˜J˜J˜—šž œœœœ˜;Jšœ$œœ˜.Jšœœœ˜5Jš œœœœœ˜5Jšœ˜J˜J˜—šžœœœœ˜GJšœ$œœ˜.Jšœœœ˜5Jš œœœœœ˜;Jšœ˜!J˜J˜—šž œœœœ˜?Jšœ$œœ˜.Jšœœœ˜5Jš œœœœœ˜7Jšœ˜J˜J˜—šžœœœœ ˜5Jšœ$œœ˜.Jšœœœ˜5Jš œœœ œœ˜2Jšœ˜J˜J˜—šž œœœœ˜?Jšœ$œœ˜.Jšœœœ˜5Jš œœœœœ˜7Jšœ˜J˜J˜—šž œœœœ ˜9Jšœ$œœ˜.Jšœœœ˜5Jš œœœœœ˜4Jšœ˜J˜J˜—J˜šžœœœœ˜7J™#Jšœ7˜7šœœ ˜JšœM˜M—šœ ˜Jšœœ˜Jšœœ ˜Jšœœ˜—J˜J˜—šžœœœ˜%Jšœ1œ™5J˜ šœ ˜Jšœœ˜Jšœœ˜Jšœœ˜—J˜J˜—šžœœœ!˜2Jšœœ˜"šœœ˜JšœB˜B—šœ˜Jšœ˜Jšœ œœ˜0šœ ˜Jšœ!˜!J˜šœ˜"J˜J˜J˜Jšœœ˜—Jšœ˜—J˜—J˜J˜—šžœœœ,˜=šœ-˜3Jšœ;˜;—šœœ˜JšœB˜B—Jš œœ œ œœ˜;šœ˜Jšœœ˜JšœŸ˜2JšœŸ*˜FJšœœ˜JšœŸ)œŸ ˜KJšœœœ˜5Jšœ Ÿ$˜/šœ œœ˜9JšœGœ™K—Jšœœœœ˜7J˜!Jšœ!˜!J˜J˜—J˜J˜—J˜šžœœœ˜.Jšœ!˜!šœ˜"J˜F—šœ˜Jšœœ6˜JJšœ#˜#Jšœ)˜)Jšœ)˜)Jšœ˜—J˜J˜—šž œœœ!˜8Jšœ˜Jšœœœ˜!Jšœ#˜#Jšœ)˜)Jšœ˜Jšœ˜J˜—šž œœ˜Jšœ[˜[J˜J˜—šžœœœ˜0Jšœ!˜!Jšœ˜Jšœœ˜*šœ˜"J˜H—Jšœœœ˜2JšœR˜VJ˜J˜—šžœœœ˜%Jšœ!˜!Jšœ˜Jšœœ˜*šœœ˜šœT˜TJšœŸ˜—JšœœœŸ˜@J˜—J˜J˜J˜—šžœœœœ ˜4Jšœ!˜!Jšœ˜Jšœœ˜*Jšœ˜!Jšœ˜J˜—šž œœœœ ˜7Jšœ˜Jšœœœ˜,Jšœ˜Jšœ˜J˜—J™šž œœœœ ™AJšœœŸ(™PJšœœœ™1šœ œœ™0šœ œ™Jšœ œœœœœœ™M—Jšœœ™.Jš œœœœœ™;J™Jšœ ™J™—J™J™—šž œœœœ ™@Jšœœ™9J™J™Jšœ™ J™J™—š žœœœœ œ™MJšœœœ™=J™J™Jšœ™ J™J™—š ž œœœœœ™8Jšœœ™Jšœ9™9šœœœ™ Jšœœœ ™šœ™Jšœœœœ™:Jšœ œœ!œ™MJš œ œœœœ™3Jšœ œœ'œ™TJšœ4™4Jšœ™—Jšœ™—Jš œœ œœœ™/J™J™—šž œœœœ ™GJ™J™—J˜šžœœœ˜&J˜J˜—šž œœœ˜'Jšœ˜Jšœ˜J˜—šžœœœ˜&Jšœ˜J˜—šž œœœ˜'Jšœ&˜&Jšœ"˜"Jšœ5˜5J˜—šž œœœ˜'Jšœ)˜)J˜—šž œœœ˜'Jšœ˜J˜J˜—šž œœœ˜)Jšœ˜J˜J˜—šž œœœ˜*J˜J˜—šž œœœ˜(Jšœ˜Jšœ˜J˜—šžœœœ˜&J˜J˜—J˜Jšœ˜—…—,œCÆ