JaMArrayImpl.mesa
Last edited by:
Doug Wyatt, November 21, 1983 1:22 pm
DIRECTORY
JaM USING [Any, Array, ArrayRep, Dict, Eq, Error, Execute, Pop, PopArray, PopDict, PopInt, Push, PushArray, PushBool, PushInt, Sequence, SequenceRep, State, TryToGet],
JaMPrimitives USING [];
JaMArrayImpl: CEDAR PROGRAM
IMPORTS JaM
EXPORTS JaM, JaMPrimitives
= BEGIN OPEN JaM;
Array Operations
maxArrayLength: NAT = (LAST[NAT]-SIZE[SequenceRep[0]])/SIZE[Any];
NewArray: PUBLIC PROC[length: INT] RETURNS[Array] = {
IF length IN[0..maxArrayLength) THEN {
seq: Sequence = NEW[SequenceRep[length]];
RETURN[NEW[ArrayRep ← [start: 0, length: length, seq: seq]]];
}
ELSE ERROR Error[BoundsFault];
};
MakeArray: PUBLIC PROC[self: State, length: INT] RETURNS[Array] = {
IF length IN[0..maxArrayLength) THEN {
len: NAT = length;
seq: Sequence = NEW[SequenceRep[len]];
FOR i: NAT DECREASING IN[0..len) DO seq[i] ← Pop[self] ENDLOOP;
RETURN[NEW[ArrayRep ← [start: 0, length: len, seq: seq]]];
}
ELSE ERROR Error[BoundsFault];
};
APut: PUBLIC PROC[array: Array, i: INT, x: Any] = {
IF i IN[0..array.length) THEN array.seq[array.start+i] ← x
ELSE ERROR Error[BoundsFault];
};
AGet: PUBLIC PROC[array: Array, i: INT] RETURNS[Any] = {
IF i IN[0..array.length) THEN RETURN[array.seq[array.start+i]]
ELSE ERROR Error[BoundsFault];
};
SubArray, ASub: PUBLIC PROC[array: Array, start, length: INT] RETURNS[Array] = {
IF start<=array.length AND length<=(array.length-start) THEN
RETURN[NEW[ArrayRep ← [start: array.start+start, length: length, seq: array.seq]]]
ELSE ERROR Error[BoundsFault];
};
AFind: PUBLIC PROC[array: Array, x: Any] RETURNS[found: BOOL, i: INT] = {
FOR i: INT IN[0..array.length) DO
elem: Any = AGet[array, i];
IF Eq[elem, x] THEN RETURN[TRUE, i];
ENDLOOP;
RETURN[FALSE, 0];
}; -- find object in array
ABind: PUBLIC PROC[array: Array, dict: Dict] = {
FOR i: INT IN[0..array.length) DO
x: Any = AGet[array, i];
WITH x SELECT FROM
x: ATOM => {
known: BOOL; value: Any;
[known, value] ← TryToGet[dict, x];
IF known THEN APut[array, i, value];
};
x: Array => ABind[x, dict];
ENDCASE;
ENDLOOP;
}; -- bind names in array to values in dict
ArrayForAll: PUBLIC PROC[self: State, array: Array, action: Any] = {
FOR i: INT IN[0..array.length) DO
Push[self, AGet[array, i]];
Execute[self, action];
ENDLOOP;
};
Array Intrinsics
ApplyArray: PUBLIC PROC[self: State] = {
n: INT = PopInt[self];
PushArray[self, NewArray[n]];
};
ApplyAPut: PUBLIC PROC[self: State] = {
x: Any = Pop[self];
i: INT = PopInt[self];
array: Array = PopArray[self];
APut[array, i, x];
};
ApplyAGet: PUBLIC PROC[self: State] = {
i: INT = PopInt[self];
array: Array = PopArray[self];
Push[self, AGet[array, i]];
};
ApplySubArray: PUBLIC PROC[self: State] = {
len: INT = PopInt[self];
start: INT = PopInt[self];
array: Array = PopArray[self];
PushArray[self, SubArray[array, start, len]];
};
ApplyAFind: PUBLIC PROC[self: State] = {
x: REF = Pop[self];
array: Array = PopArray[self];
known: BOOL; i: INT;
[known, i] ← AFind[array, x];
IF known THEN PushInt[self, i];
PushBool[self, known];
};
ApplyAStore: PUBLIC PROC[self: State] = {
array: Array = PopArray[self];
FOR i: INT DECREASING IN[0..array.length) DO APut[array, i, Pop[self]] ENDLOOP;
PushArray[self, array];
};
ApplyALoad: PUBLIC PROC[self: State] = {
array: Array = PopArray[self];
FOR i: INT IN[0..array.length) DO Push[self, AGet[array, i]] ENDLOOP;
PushArray[self, array];
};
ApplyABind: PUBLIC PROC[self: State] = {
dict: Dict = PopDict[self];
array: Array = PopArray[self];
ABind[array, dict];
};
ApplyArrayForAll: PUBLIC PROC[self: State] = {
action: REF = Pop[self];
array: Array = PopArray[self];
ArrayForAll[self, array, action];
};
END.