<> <> <> <<>> DIRECTORY IO, IPInterpreter, Rope; IPVectorImpl: CEDAR PROGRAM IMPORTS IO, IPInterpreter, Rope EXPORTS IPInterpreter ~ BEGIN OPEN IPInterpreter; Shape: PUBLIC PROC[v: Vector] RETURNS[VectorShape] ~ { RETURN[v.class.shape[v]] }; Get: PUBLIC PROC[v: Vector, j: Integer] RETURNS[Any] ~ { RETURN[v.class.get[v, j]] }; GetInteger: PUBLIC PROC[v: Vector, j: Integer] RETURNS[Integer] ~ { RETURN[IntegerFromAny[Get[v, j]]]; }; GetReal: PUBLIC PROC[v: Vector, j: Integer] RETURNS[REAL] ~ { RETURN[RealFromAny[Get[v, j]]]; }; GetProp: PUBLIC PROC[v: Vector, propName: Any] RETURNS[found: BOOL, value: Any] ~ { IF v.class.getProp#NIL THEN [found, value] _ v.class.getProp[v, propName] ELSE { shape: VectorShape ~ Shape[v]; IF NOT Even[shape.n] THEN { MasterError[$invalidArgs, "Property vector has illegal shape."]; ERROR Error; }; FOR i: Integer _ shape.l, i+2 WHILE i<(shape.l+shape.n) DO IF EqName[Get[v, i], propName] THEN RETURN[TRUE, Get[v, i+1]]; ENDLOOP; RETURN[found: FALSE, value: NIL]; }; }; GetP: PUBLIC PROC[v: Vector, propName: Any] RETURNS[Any] ~ { found: BOOL; value: Any; [found, value] _ GetProp[v, propName]; IF found THEN RETURN[value] ELSE { MasterError[$undefinedProperty, "Undefined property."]; ERROR Error; }; }; RunSize: PUBLIC PROC[r: Vector] RETURNS[Integer] ~ { shape: VectorShape ~ Shape[r]; s: Integer _ 0; -- sum of the run lengths IF NOT(shape.l=0 AND Even[shape.n]) THEN { MasterError[$invalidArgs, "Run encoded vector has illegal shape."]; ERROR Error; }; FOR j: Integer _ 0, j+2 WHILE j> arrayClass: VectorClass ~ NEW[VectorClassRep _ [type: $Array, shape: ArrayShape, get: ArrayGet]]; ArrayShape: PROC[v: Vector] RETURNS[VectorShape] ~ { array: Array ~ NARROW[v.data]; RETURN[[l: array.l, n: array.n]]; }; ArrayGet: PROC[v: Vector, j: Integer] RETURNS[Any] ~ { array: Array ~ NARROW[v.data]; RETURN[array[j-array.l]]; }; MakeVec: PUBLIC PROC[shape: VectorShape, pop: PROC RETURNS[Any]] RETURNS[Vector] ~ { array: Array ~ NEW[ArrayRep[shape.n] _ [l: shape.l, array: ]]; FOR i: NAT DECREASING IN[0..array.n) DO array[i] _ pop[] ENDLOOP; RETURN[NEW[VectorRep _ [class: arrayClass, data: array]]]; }; CopyArray: PROC[old: Array] RETURNS[new: Array] ~ { new _ NEW[ArrayRep[old.n] _ [l: old.l, array: ]]; FOR i: NAT IN[0..new.n) DO new[i] _ old[i] ENDLOOP; }; VectorFromArray: PUBLIC PROC[array: Array] RETURNS[Vector] ~ { RETURN[NEW[VectorRep _ [class: arrayClass, data: CopyArray[array]]]]; }; ArrayFromVector: PUBLIC PROC[v: Vector] RETURNS[Array] ~ { IF v.class.type=$Array THEN { array: Array ~ NARROW[v.data]; RETURN[CopyArray[array]]; } ELSE { shape: VectorShape ~ Shape[v]; array: Array ~ NEW[ArrayRep[shape.n] _ [l: shape.l, array: ]]; FOR i: NAT IN[0..array.n) DO array[i] _ Get[v, array.l+i] ENDLOOP; RETURN[array]; }; }; MergedData: TYPE ~ REF MergedDataRep; MergedDataRep: TYPE ~ RECORD[v1, v2: Vector]; mergedClass: VectorClass ~ NEW[VectorClassRep _ [type: $Merged, shape: MergedShape, get: MergedGet, getProp: MergedGetProp]]; MergedShape: PROC[v: Vector] RETURNS[VectorShape] ~ { data: MergedData ~ NARROW[v.data]; MasterError[$undefinedOperation, "SHAPE is undefined for the result of MERGEPROP."]; ERROR Error; }; MergedGet: PROC[v: Vector, j: Integer] RETURNS[Any] ~ { data: MergedData ~ NARROW[v.data]; MasterError[$undefinedOperation, "GET is undefined for the result of MERGEPROP."]; ERROR Error; }; MergedGetProp: PROC[v: Vector, propName: Any] RETURNS[found: BOOL, value: Any] ~ { data: MergedData ~ NARROW[v.data]; [found, value] _ GetProp[data.v2, propName]; IF NOT found THEN [found, value] _ GetProp[data.v1, propName]; }; MergeProp: PUBLIC PROC[v1, v2: Vector] RETURNS[Vector] ~ { data: MergedData ~ NEW[MergedDataRep _ [v1: v1, v2: v2]]; RETURN[NEW[VectorRep _ [class: mergedClass, data: data]]]; }; CharAction: TYPE ~ PROC[c: CARDINAL] RETURNS[quit: BOOL _ FALSE]; BYTE: TYPE ~ [0..255]; StringMap: PROC[rope: ROPE, action: CharAction] RETURNS[BOOL] ~ { offset: BYTE _ 0; state: {run, escape, escape2, extended, extended2} _ run; FOR i: INT IN[0..Rope.Length[rope]) DO b: BYTE ~ ORD[CHAR[Rope.Fetch[rope, i]]]; SELECT state FROM run => IF b=255 THEN state _ escape ELSE IF action[offset*256+b] THEN RETURN[TRUE]; escape => IF b=255 THEN state _ escape2 ELSE { offset _ b; state _ run }; escape2 => IF b=0 THEN state _ extended ELSE ERROR; extended => IF b=255 THEN state _ escape ELSE { offset _ b; state _ extended2 }; extended2 => { IF action[offset*256+b] THEN RETURN[TRUE]; state _ extended }; ENDCASE; ENDLOOP; IF NOT(state=run OR state=extended) THEN MasterWarning[$illegalString, "Encoded string ended in wrong state."]; RETURN[FALSE]; }; stringClass: VectorClass ~ NEW[VectorClassRep _ [type: $String, shape: StringShape, get: StringGet]]; StringShape: PROC[v: Vector] RETURNS[VectorShape] ~ { string: ROPE ~ NARROW[v.data]; n: Integer _ 0; action: CharAction ~ { n _ n+1 }; [] _ StringMap[string, action]; RETURN[[l: 0, n: n]]; }; StringGet: PROC[v: Vector, j: Integer] RETURNS[Any] ~ { string: ROPE ~ NARROW[v.data]; n: Integer _ 0; result: Integer; action: CharAction ~ { IF n=j THEN { result _ c; RETURN[TRUE] } ELSE n _ n+1 }; IF StringMap[string, action] THEN RETURN[NumberFromInteger[result]] ELSE { MasterError[$boundsFault, "Invalid index for string."]; ERROR Error; }; }; VectorFromString: PUBLIC PROC[string: ROPE] RETURNS[Vector] ~ { RETURN[NEW[VectorRep _ [class: stringClass, data: string]]]; }; StringFromVector: PUBLIC PROC[v: Vector] RETURNS[ROPE] ~ { IF v.class.type=$String THEN { string: ROPE ~ NARROW[v.data]; RETURN[string]; } ELSE { shape: VectorShape ~ Shape[v]; stream: STREAM ~ IO.ROS[]; offset: BYTE _ 0; FOR i: Integer IN[shape.l .. shape.l+shape.n) DO char: CARDINAL ~ GetInteger[v, i]; IF (char/256)#offset THEN { stream.PutChar[VAL[255]]; stream.PutChar[VAL[offset _ char/256]]; }; stream.PutChar[VAL[char MOD 256]]; ENDLOOP; RETURN[IO.RopeFromROS[stream]]; }; }; RopeFromVector: PUBLIC PROC[v: Vector] RETURNS[ROPE] ~ { IF v.class.type=$String THEN { string: ROPE ~ NARROW[v.data]; stream: STREAM ~ IO.ROS[]; action: CharAction ~ { stream.PutChar[VAL[c]] }; [] _ StringMap[string, action]; RETURN[IO.RopeFromROS[stream]]; } ELSE { shape: VectorShape ~ Shape[v]; i: Integer _ 0; p: PROC RETURNS[CHAR] ~ { b: BYTE ~ GetInteger[v, shape.l+i]; i _ i+1; RETURN[VAL[b]] }; RETURN[Rope.FromProc[len: shape.n, p: p]]; }; }; <<>> <> <> <> <> <> <<];>> <<>> <> <> <> <> <> <> <> <<];>> <> <> <> <> <<};>> <> <> <= data.length THEN ERROR IO.EndOfStream[self]>> <> <> <> <> <<};>> <<};>> <> <> <= data.length];>> <<};>> <> <> <> <<};>> <> <> <> <> <<};>> <> <> <> <<};>> END.