<> <<>> <> <> 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; <> 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; }; <> 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.