-- File: LongStorageImpl.mesa Edited by
-- Karlton, Oct 8, 1980 1:37 PM
-- Forrest, July 25, 1980 7:06PM
-- Johnsson, 5-Dec-80 9:02:18
DIRECTORY
Environment USING [wordsPerPage],
Heap USING [Expand, FreeNode, MakeNode, Prune, systemZone],
LongStorage USING [],
Space USING [
Create, Delete, GetHandle, Handle, Map,
PageFromLongPointer, LongPointer, virtualMemory];
LongStorageImpl: PROGRAM IMPORTS Space, Heap EXPORTS LongStorage =
BEGIN
PageSize: CARDINAL = Environment.wordsPerPage;
InvalidNode: PUBLIC ERROR [p: LONG POINTER] = CODE;
ZoneTooSmall: PUBLIC ERROR [p: LONG POINTER] = CODE;
Pages: PUBLIC PROCEDURE [npages: CARDINAL] RETURNS [base: LONG POINTER] =
BEGIN OPEN Space;
space: Handle ← Create[npages, virtualMemory];
Map[space];
RETURN[LongPointer[space]];
END;
Words: PUBLIC PROCEDURE [nwords: CARDINAL] RETURNS [base: LONG POINTER] =
{RETURN[Pages[(nwords + PageSize - 1) / PageSize]]};
FreePages, FreeWords: PUBLIC PROCEDURE [base: LONG POINTER] =
BEGIN OPEN Space;
IF base # NIL THEN
Delete[GetHandle[PageFromLongPointer[base]]];
END;
-- management of the heap
Node: PUBLIC PROCEDURE [nwords: CARDINAL] RETURNS [p: LONG POINTER] =
{RETURN[Heap.MakeNode[n: nwords]]};
Free: PUBLIC PROCEDURE [p: LONG POINTER] = {IF p # NIL THEN Heap.FreeNode[p: p]};
String: PUBLIC PROCEDURE [nchars: CARDINAL] RETURNS [s: LONG STRING] =
BEGIN
s ← Node[(nchars+1)/2 + 2];
s↑ ← [length: 0, maxlength: nchars, text:];
RETURN
END;
CopyString: PUBLIC PROCEDURE [s: LONG STRING, longer: CARDINAL ← 0]
RETURNS [newS: LONG STRING] =
BEGIN
l: CARDINAL = (IF s = NIL THEN 0 ELSE s.length);
IF s = NIL AND longer = 0 THEN RETURN[NIL];
newS ← String[l + longer];
FOR i: CARDINAL IN [0..l) DO newS[i] ← s[i] ENDLOOP;
newS.length ← l;
END;
ExpandString: PUBLIC PROCEDURE [s: LONG POINTER TO LONG STRING, longer: CARDINAL ← 0] =
BEGIN
newS: LONG STRING ← CopyString[s↑, longer + (IF s↑ = NIL THEN 0 ELSE s.maxlength - s.length)];
FreeString[s↑];
s↑ ← newS;
END;
FreeString: PUBLIC PROCEDURE [s: LONG STRING] = LOOPHOLE[Free];
Prune: PUBLIC PROCEDURE RETURNS [BOOLEAN] = {
Heap.Prune[Heap.systemZone]; RETURN[TRUE]};
Expand: PUBLIC PROCEDURE [pages: CARDINAL] = {Heap.Expand[Heap.systemZone, pages]};
-- initialization code
END.