DIRECTORY PS; PSStackImpl: CEDAR PROGRAM IMPORTS PS EXPORTS PS ~ BEGIN OPEN PS; Stack: TYPE ~ REF StackRep; StackRep: PUBLIC TYPE ~ RECORD [ count: ArrayIndex, size: ArrayIndex, array: ArrayRef ]; PushAny: PUBLIC PROC [self: Root, x: Any] ~ { stack: Stack ~ self.stack; IF NOT stack.count0 THEN ERROR Error[stackunderflow]; stack.count _ stack.count-1; RETURN [stack.array[stack.count]]; }; TopType: PUBLIC PROC [self: Root] RETURNS [TypeCode] ~ { stack: Stack ~ self.stack; IF NOT stack.count>0 THEN ERROR Error[stackunderflow]; RETURN [stack.array[stack.count-1].val.type]; }; Copy: PUBLIC PROC [self: Root, n: INT] ~ { stack: Stack ~ self.stack; IF n<0 THEN ERROR Error[rangecheck]; IF n>stack.count THEN ERROR Error[stackunderflow]; IF n>(stack.size-stack.count) THEN ERROR Error[stackoverflow]; FOR i: ArrayIndex IN [stack.count..ArrayIndex[stack.count+n]) DO stack.array[i] _ stack.array[i-n]; ENDLOOP; stack.count _ stack.count+n; }; Reverse: PROC [array: ArrayRef, m1, m2: ArrayIndex] ~ { FOR i: ArrayIndex IN[0..(m2-m1)/2) DO i1: ArrayIndex ~ m1+i; i2: ArrayIndex ~ m2-1-i; x1: Any ~ array[i1]; x2: Any ~ array[i2]; array[i1] _ x2; array[i2] _ x1; ENDLOOP; }; Roll: PUBLIC PROC [self: Root, n, j: INT] ~ { stack: Stack ~ self.stack; IF n<0 THEN ERROR Error[rangecheck]; IF n>stack.count THEN ERROR Error[stackunderflow]; IF j NOT IN [0..n) THEN { j _ j MOD n; IF j<0 THEN j _ j+n }; IF j#0 THEN { k3: ArrayIndex ~ stack.count; k2: ArrayIndex ~ k3-j; k1: ArrayIndex ~ k3-n; Reverse[stack.array, k1, k2]; Reverse[stack.array, k2, k3]; Reverse[stack.array, k1, k3]; }; }; Index: PUBLIC PROC [self: Root, n: INT] RETURNS [Any] ~ { stack: Stack ~ self.stack; IF n<0 THEN ERROR Error[rangecheck]; IF NOT n0 THEN { last: ArrayIndex ~ stack.count-1; FOR i: ArrayIndex DECREASING IN [0..last] DO IF stack.array[i].val.type=mark THEN RETURN [last-i]; ENDLOOP; }; ERROR Error[unmatchedmark]; }; PushInt: PUBLIC PROC [self: Root, int: INT] ~ { PushAny[self, [val: [executable: FALSE, variant: integer[int: int]], ref: NIL]]; }; PushReal: PUBLIC PROC [self: Root, real: REAL] ~ { PushAny[self, [val: [executable: FALSE, variant: real[real: real]], ref: NIL]]; }; PushBool: PUBLIC PROC [self: Root, bool: BOOL] ~ { PushAny[self, [val: [executable: FALSE, variant: boolean[bool: bool]], ref: NIL]]; }; PushArray: PUBLIC PROC [self: Root, array: Array] ~ { PushAny[self, AnyFromArray[array]]; }; PushString: PUBLIC PROC [self: Root, string: String] ~ { PushAny[self, AnyFromString[string]]; }; PushFile: PUBLIC PROC [self: Root, file: File] ~ { PushAny[self, AnyFromFile[file]]; }; PushDict: PUBLIC PROC [self: Root, dict: Dict] ~ { PushAny[self, AnyFromDict[dict]]; }; PushName: PUBLIC PROC [self: Root, name: Name] ~ { PushAny[self, AnyFromName[name]]; }; PopInt: PUBLIC PROC [self: Root] RETURNS [INT] ~ { x: Any ~ PopAny[self]; WITH v: x.val SELECT FROM integer => RETURN [v.int]; ENDCASE => RETURN [IntFromAny[x]]; }; PopReal: PUBLIC PROC [self: Root] RETURNS [REAL] ~ { x: Any ~ PopAny[self]; WITH v: x.val SELECT FROM integer => RETURN [REAL[v.int]]; real => RETURN [v.real]; ENDCASE => RETURN [RealFromAny[x]]; }; PopBool: PUBLIC PROC [self: Root] RETURNS [BOOL] ~ { x: Any ~ PopAny[self]; WITH v: x.val SELECT FROM boolean => RETURN [v.bool]; ENDCASE => RETURN [BoolFromAny[x]]; }; PopNum: PUBLIC PROC [self: Root] RETURNS [Num] ~ { x: Any ~ PopAny[self]; WITH v: x.val SELECT FROM integer => RETURN [[int[v.int]]]; real => RETURN [[real[v.real]]]; ENDCASE => ERROR Error[typecheck]; }; PopArray: PUBLIC PROC [self: Root] RETURNS [Array] ~ { RETURN[ArrayFromAny[PopAny[self]]]; }; PopString: PUBLIC PROC [self: Root] RETURNS [String] ~ { RETURN[StringFromAny[PopAny[self]]]; }; PopFile: PUBLIC PROC [self: Root] RETURNS [File] ~ { RETURN[FileFromAny[PopAny[self]]]; }; PopDict: PUBLIC PROC [self: Root] RETURNS [Dict] ~ { RETURN[DictFromAny[PopAny[self]]]; }; PushMark: PUBLIC PROC [self: Root] ~ { PushAny[self, [val: [executable: FALSE, variant: mark[]], ref: NIL]]; }; PopMark: PUBLIC PROC [self: Root] ~ { x: Any ~ PopAny[self]; WITH v: x.val SELECT FROM mark => NULL; ENDCASE => ERROR Error[typecheck]; }; END. ΦPSStackImpl.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Doug Wyatt, May 13, 1987 10:59:39 am PDT PostScript implementation: stack operations. Basic stack operations Top: PUBLIC PROC [self: Root] RETURNS [Any] ~ { stack: Stack ~ self.stack; IF NOT stack.count>0 THEN ERROR Error[stackunderflow]; RETURN [stack.array[stack.count-1]]; }; FOR i: ArrayIndex IN[0..stack.count) DO stack.array[i].ref _ NIL ENDLOOP; Convenience operations ΚF˜codešœ™KšœB™BK™(—K˜K™,K™šΟk ˜ Kšœ˜—K˜KšΟn œœ˜Kšœ˜ Kšœ˜ Kšœœœœ˜head™Kšœœœ ˜šœ œœœ˜ Kšœ˜Kšœ˜J˜K˜K˜—šžœœœ˜-K˜Kšœœœœ˜>Kšœ˜Kšœ˜K˜K˜—šžœœœœ ˜5K˜Kšœœœœ˜6Kšœ˜Kšœ˜"K˜K˜—šžœœœœ ™/K™Kšœœœœ™6Kšœ™$K™K™—šžœœœœ˜8K˜Kšœœœœ˜6Kšœ'˜-K˜K˜—K˜šžœœœœ˜*K˜Kšœœœ˜$Kšœœœ˜2Kšœœœ˜>šœœ*˜@Kšœ"˜"Kšœ˜—Kšœ˜K˜K˜—šžœœ*˜7šœœ˜%Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜K˜—šžœœœœ˜-K˜Kšœœœ˜$Kšœœœ˜2Kšœœœœ œœœ ˜=šœœ˜ K˜K˜K˜Kšœ˜Kšœ˜Kšœ˜K˜—K˜K˜—š žœœœœœ ˜9K˜Kšœœœ˜$Kšœœœœ˜6Kšœ ˜&K˜K˜—šžœœœ˜#K˜Kšœœœ œ™IKšœ˜Kšœ˜K˜—š žœœœœœ˜1K˜Kšœ˜Kšœ˜K˜—šž œœœœ˜2K˜Kšœ˜Kšœ˜K˜—šž œœœ˜)K˜šœ œœ˜3Kšœœœ˜AKšœ˜—Kšœ˜K˜K˜—š ž œœœœœ˜7K˜šœœ˜K˜!šœ œœ ˜,Kšœœœ ˜5Kšœ˜—K˜—Kšœ˜K˜K˜——™šžœœœœ˜/Kšœ!œ$œ˜PK˜K˜—šžœœœœ˜2Kšœ!œ#œ˜OK˜K˜—šžœœœœ˜2Kšœ!œ&œ˜RK˜K˜—šž œœœ˜5Kšœ#˜#K˜K˜—šž œœœ!˜8Kšœ%˜%K˜K˜—šžœœœ˜2Kšœ!˜!K˜K˜—šžœœœ˜2Kšœ!˜!K˜K˜—šžœœœ˜2Kšœ!˜!K˜K˜—K™š žœœœœœ˜2K˜šœ œ˜Kšœ œ ˜Kšœœ˜"—K˜K˜—š žœœœœœ˜4K˜šœ œ˜Kšœ œœ ˜ Kšœœ ˜Kšœœ˜#—K˜K˜—š žœœœœœ˜4K˜šœ œ˜Kšœ œ ˜Kšœœ˜#—K˜K˜—šžœœœœ ˜2K˜šœ œ˜Kšœ œ˜!Kšœœ˜ Kšœœ˜"—K˜K˜—šžœœœœ ˜6Kšœ˜#K˜K˜—šž œœœœ ˜8Kšœ˜$K˜K˜—šžœœœœ ˜4Kšœ˜"K˜K˜—šžœœœœ ˜4Kšœ˜"K˜K˜—K˜šžœœœ˜&Kšœ!œœ˜EK˜K˜—šžœœœ˜%K˜šœ œ˜Kšœœ˜ Kšœœ˜"—K˜K˜—K™—J˜Jšœ˜—…—Δΰ