-- File ParserTypes.mesa
--March 5, 1980 5:04 PM
-- Converte to Mesa 6 October 20, 1980 4:20 PM
--October 20, 1980 4:20 PM by MN
DIRECTORY
SystemDefs: FROM "SystemDefs" USING [AllocateHeapNode, FreeHeapNode],
ParserTypeDefs: FROM "ParserTypeDefs";
ParserTypes: PROGRAM IMPORTS SystemDefs EXPORTS ParserTypeDefs =
BEGIN OPEN ParserTypeDefs;
free: POINTER TO LinkedPoint;
tFree: POINTER TO LinkedTEntry;
-- for debugging space leaks:
PathNodes: INTEGER ← 0;
PointNodes: INTEGER ← 0;
UserNodes: INTEGER ← 0;
TListNodes: INTEGER ← 0;
TNodes: INTEGER ← 0;
InitTypes: PUBLIC PROCEDURE RETURNS [BOOLEAN] =
BEGIN
free ← NIL;
tFree ← NIL;
PathNodes ← PointNodes ← UserNodes ← TListNodes ← TNodes ← 0;
RETURN[TRUE];
END;
FinishTypes: PUBLIC PROCEDURE RETURNS [BOOLEAN] =
BEGIN
RETURN[TRUE];
END;
PathLength: PUBLIC PROCEDURE [a: Path] RETURNS [CARDINAL] =
BEGIN
RETURN[a.length];
END;
AllocatePath: PUBLIC PROCEDURE RETURNS [Path] =
BEGIN
A: Path;
A ← SystemDefs.AllocateHeapNode[SIZE[PathRecord]];
A↑ ← PathRecord[first: NIL,last: NIL, length: 0];
PathNodes ← PathNodes + 1;
RETURN[A];
END;
FreePath: PUBLIC PROCEDURE [a: Path] =
BEGIN
node: POINTER TO LinkedPoint ← a.first;
saved: POINTER TO LinkedPoint;
UNTIL node = NIL DO
saved ← node.next;
FreeNode[node];
node ← saved;
ENDLOOP;
PathNodes ← PathNodes - 1;
SystemDefs.FreeHeapNode[a];
END;
AppendPoint: PUBLIC PROCEDURE [a: Path, p: Point] =
BEGIN
temp: POINTER TO LinkedPoint ← a.last;
a.last ← GetNode[];
IF temp # NIL THEN temp.next ← a.last;
a.last.value ← p;
a.last.next ← NIL;
IF a.first = NIL THEN a.first ← a.last;
a.length ← a.length + 1;
END;
CopyPath: PUBLIC PROCEDURE [from,to: Path] =
BEGIN
temp: POINTER TO LinkedPoint;
IF from = to THEN RETURN;
FOR temp ← from.first, temp.next UNTIL temp = NIL DO
AppendPoint[to,temp.value];
ENDLOOP;
END;
RemovePoint: PUBLIC PROCEDURE [a: Path] RETURNS [BOOLEAN, Point] =
BEGIN
ans: Point;
IF a.first = NIL THEN RETURN [FALSE, ans] ELSE
BEGIN
Temp: POINTER TO LinkedPoint ← a.first.next;
ans ← a.first.value;
FreeNode[a.first];
a.first ← Temp;
IF a.first = NIL THEN a.last ← NIL;
a.length ← a.length - 1;
RETURN [TRUE, ans];
END;
END;
AllocateUserNode: PUBLIC PROCEDURE[nwords: CARDINAL] RETURNS [POINTER] =
BEGIN
UserNodes ← UserNodes + 1;
RETURN[SystemDefs.AllocateHeapNode[nwords]];
END;
FreeUserNode: PUBLIC PROCEDURE [address: POINTER] =
BEGIN
UserNodes ← UserNodes - 1;
SystemDefs.FreeHeapNode[address];
END;
--Private Procedures
FreeNode: PROCEDURE [node: POINTER TO LinkedPoint] = INLINE
BEGIN
node.next ← free;
free ← node;
END;
GetNode: PROCEDURE RETURNS [POINTER TO LinkedPoint] = INLINE
BEGIN
ans: POINTER TO LinkedPoint;
IF free = NIL THEN
BEGIN
PointNodes ← PointNodes + 1;
RETURN[SystemDefs.AllocateHeapNode[SIZE[LinkedPoint]]];
END;
ans ← free;
free ← free.next;
RETURN[ans];
END;
AllocateTList: PUBLIC PROCEDURE RETURNS [TList] =
BEGIN
A: TList;
A ← SystemDefs.AllocateHeapNode[SIZE[TRecord]];
A↑ ← TRecord[first: NIL,last: NIL, length: 0];
TListNodes ← TListNodes + 1;
RETURN[A];
END;
FreeTList: PUBLIC PROCEDURE [a: TList] =
BEGIN
node: POINTER TO LinkedTEntry ← a.first;
saved: POINTER TO LinkedTEntry;
UNTIL node = NIL DO
saved ← node.next;
FreeTNode[node];
node ← saved;
ENDLOOP;
TListNodes ← TListNodes - 1;
SystemDefs.FreeHeapNode[a];
END;
AppendTList: PUBLIC PROCEDURE [a: TList, p: TEntry] =
BEGIN
temp: POINTER TO LinkedTEntry ← a.last;
a.last ← GetTNode[];
IF temp # NIL THEN temp.next ← a.last;
a.last.value ← p;
a.last.next ← NIL;
IF a.first = NIL THEN a.first ← a.last;
a.length ← a.length + 1;
END;
RemoveTList: PUBLIC PROCEDURE [a: TList] RETURNS [BOOLEAN, TEntry] =
BEGIN
ans: TEntry;
IF a.first = NIL THEN RETURN [FALSE, ans] ELSE
BEGIN
temp: POINTER TO LinkedTEntry ← a.first.next;
ans ← a.first.value;
FreeTNode[a.first];
a.first ← temp;
IF a.first = NIL THEN a.last ← NIL;
a.length ← a.length - 1;
RETURN [TRUE, ans];
END;
END;
TListLength: PUBLIC PROCEDURE [a: TList] RETURNS [CARDINAL] =
BEGIN
RETURN[a.length];
END;
-- More Private Procedures
FreeTNode: PROCEDURE [node: POINTER TO LinkedTEntry] = INLINE
BEGIN
node.next ← tFree;
tFree ← node;
END;
GetTNode: PROCEDURE RETURNS [POINTER TO LinkedTEntry] = INLINE
BEGIN
ans: POINTER TO LinkedTEntry;
IF tFree = NIL THEN
BEGIN
TNodes ← TNodes + 1;
RETURN[SystemDefs.AllocateHeapNode[SIZE[LinkedTEntry]]];
END;
ans ← tFree;
tFree ← tFree.next;
RETURN[ans];
END;
END.