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.