IPVectorImpl.mesa
Last edited by:
Doug Wyatt, July 7, 1983 11:46 am
DIRECTORY
IPBasic USING [Any, Integer, maxInteger, nullAny, State, Vec, VecRep, Vector, VectorShape],
IPConvert USING [AnyToInteger],
IPErrors USING [MasterError],
IPOps USING [EqN],
IPStack USING [PopAny, PushAny],
IPVector USING [];
IPVectorImpl: CEDAR PROGRAM
IMPORTS IPConvert, IPErrors, IPOps, IPStack
EXPORTS IPVector
= BEGIN OPEN IPBasic;
VecToVector: PROC[v: Vec] RETURNS[Vector] = INLINE { RETURN[v] };
VectorToVec: PUBLIC PROC[v: Vector] RETURNS[Vec] = {
WITH v SELECT FROM
vec: Vec => RETURN[vec];
ENDCASE => {
shape: VectorShape = Shape[v];
vec: Vec = NewVec[shape];
FOR i: NAT IN[0..vec.size) DO
vec[i] ← Get[v, shape.l+i];
ENDLOOP;
RETURN[vec];
};
};
NewVec: PUBLIC PROC[shape: VectorShape] RETURNS[Vec] = {
IF shape.n>0 AND (shape.n-1)>(maxInteger-shape.l) THEN
ERROR IPErrors.MasterError[InvalidArgs]
ELSE IF shape.n>maxVecSize THEN ERROR IPErrors.MasterError[LimitExceeded]
ELSE RETURN[NEW[VecRep[shape.n] ← [shape: shape, array: ]]];
};
CopyVec: PUBLIC PROC[v: Vec] RETURNS[Vec] = {
new: Vec = NEW[VecRep[v.size] ← [shape: v.shape, array: ]];
FOR i: NAT IN[0..new.size) DO new[i] ← v[i] ENDLOOP;
RETURN[new];
};
Get: PUBLIC PROC[v: Vector, n: Integer] RETURNS[Any] = {
WITH v SELECT FROM
v: Vec => {
IF n IN[v.shape.l..v.shape.l+v.shape.n) THEN RETURN[v[n-v.shape.l]]
ELSE ERROR IPErrors.MasterError[BoundsFault];
};
ENDCASE => ERROR IPErrors.MasterError[Unimplemented];
};
Shape: PUBLIC PROC[v: Vector] RETURNS[VectorShape] = {
WITH v SELECT FROM
v: Vec => RETURN[v.shape];
ENDCASE => ERROR IPErrors.MasterError[Unimplemented];
};
maxVecSize: NAT = (LAST[NAT]-SIZE[VecRep[0]])/SIZE[Any];
Make: PUBLIC PROC[self: State, shape: VectorShape] RETURNS[Vec] = {
v: Vec = NewVec[shape];
FOR i: NAT DECREASING IN[0..v.size) DO v[i] ← IPStack.PopAny[self] ENDLOOP;
RETURN[v];
};
MakeVec: PUBLIC PROC[self: State, n: Integer] RETURNS[Vector] = {
shape: VectorShape = [l: 0, n: n];
RETURN[VecToVector[Make[self, shape]]];
};
MakeVecLU: PUBLIC PROC[self: State, l, u: Integer] RETURNS[Vector] = {
IF l>0 AND (l-1)>u THEN ERROR IPErrors.MasterError[InvalidArgs]
ELSE IF u>=l AND (u-l)>=maxInteger THEN ERROR IPErrors.MasterError[LimitExceeded]
ELSE { shape: VectorShape = IF u<l THEN [l: l, n: 0] ELSE [l: l, n: u-l+1];
RETURN[VecToVector[Make[self, shape]]] };
};
OpenVec: PUBLIC PROC[self: State, v: Vector] = {
shape: VectorShape = Shape[v];
FOR i: Integer IN[shape.l..shape.l+shape.n) DO
IPStack.PushAny[self, Get[v, i]];
ENDLOOP;
};
GetProp: PUBLIC PROC[v: Vector, propName: Any] RETURNS[x: Any, b: BOOL] = {
shape: VectorShape = Shape[v];
IF (shape.n MOD 2)#0 THEN ERROR IPErrors.MasterError[InvalidArgs];
FOR i: Integer ← shape.l, i+2 WHILE i<(shape.l+shape.n) DO
IF IPOps.EqN[Get[v, i], propName] THEN RETURN[Get[v, i+1], TRUE];
ENDLOOP;
RETURN[nullAny, FALSE];
};
GetP: PUBLIC PROC[v: Vector, propName: Any] RETURNS[Any] = {
x: Any; found: BOOL;
[x, found] ← GetProp[v, propName];
IF found THEN RETURN[x]
ELSE ERROR IPErrors.MasterError[UndefinedProperty];
};
MergeProp: PUBLIC PROC[v1, v2: Vector] RETURNS[Vector] = {
ERROR IPErrors.MasterError[Unimplemented];
};
RunSize: PUBLIC PROC[r: Vector] RETURNS[Integer] = {
shape: VectorShape = Shape[r];
s: Integer ← 0; -- sum of the run lengths
IF shape.l#0 OR (shape.n MOD 2)#0 THEN ERROR IPErrors.MasterError[InvalidArgs];
FOR j: Integer ← shape.l, j+2 WHILE j<(shape.l+shape.n) DO
c: Integer = IPConvert.AnyToInteger[Get[r, j]];
IF c<=(maxInteger-s) THEN s ← s + c
ELSE ERROR IPErrors.MasterError[LimitExceeded];
ENDLOOP;
RETURN[s];
};
RunGet: PUBLIC PROC[r: Vector, i: Integer] RETURNS[Any] = {
shape: VectorShape = Shape[r];
s: Integer ← 0; -- sum of the run lengths
IF shape.l#0 OR (shape.n MOD 2)#0 THEN ERROR IPErrors.MasterError[InvalidArgs];
IF i<1 THEN ERROR IPErrors.MasterError[BoundsFault];
FOR j: Integer ← shape.l, j+2 WHILE j<(shape.l+shape.n) DO
c: Integer = IPConvert.AnyToInteger[Get[r, j]];
IF (i-s)<=c THEN RETURN[Get[r, j+1]];
IF c<=(maxInteger-s) THEN s ← s + c
ELSE ERROR IPErrors.MasterError[LimitExceeded];
ENDLOOP;
ERROR IPErrors.MasterError[BoundsFault];
};
END.