-- file PGSSymbols.Mesa
-- last modified by Satterthwaite, August 26, 1980 1:50 PM
DIRECTORY
ControlDefs: TYPE USING [ControlLink],
PGScondefs: TYPE USING [objectVersion, pgsVersion, sourceVersion],
StreamDefs: TYPE USING [StreamHandle, WriteBlock],
StringDefs: TYPE USING [SubStringDescriptor],
Symbols: TYPE USING [
SERecord, BodyRecord, StandardContext,
SEIndex, ISEIndex, CSEIndex, RecordSEIndex, CTXIndex, CBTIndex,
ISENull, CSENull, RecordSENull, CTXNull, BTNull, lG, lZ],
SymbolSegment: TYPE USING [
Tables, htType, ssType, ctxType, seType, mdType, bodyType,
VersionID, STHeader, WordOffset],
SymbolOps: TYPE USING [
Initialize, Finalize,
EnterString, HashBlock, MakeCtxSe, NewCtx, MakeNonCtxSe],
SymbolPack: TYPE ,
SystemDefs: TYPE USING [AllocateSegment, FreeSegment],
Table: TYPE USING [
Base, Notifier, Region, Selector,
AddNotify, Allocate, Bounds, Create, Destroy, DropNotify];
PGSSymbols: PROGRAM
IMPORTS PGScondefs, StreamDefs, SymbolOps, SymbolPack, SystemDefs, Table
EXPORTS PGScondefs =
BEGIN
OPEN SymbolOps, Symbols;
seb: Table.Base; -- semantic entry base (local copy)
ctxb: Table.Base; -- context table base (local copy)
bb: Table.Base; -- body table base (local copy)
Notify: Table.Notifier = {
OPEN SymbolSegment;
seb ← base[seType]; ctxb ← base[ctxType]; bb ← base[bodyType]};
dirCtx: CTXIndex;
EnterModule: PROC [moduleId: STRING, bodyCtx: CTXIndex] = {
tSei: CSEIndex;
sei: ISEIndex;
bti: CBTIndex;
-- generate a program type
tSei ← MakeNonCtxSe[SIZE[transfer cons SERecord]];
seb[tSei] ← SERecord[
mark3: TRUE, mark4: TRUE,
body: cons[transfer[
mode: program, inRecord: RecordSENull, outRecord: RecordSENull]]];
-- generate an id
sei ← MakeConstant[moduleId, dirCtx, tSei];
seb[sei].public ← TRUE;
seb[sei].idValue ← ControlDefs.ControlLink[
procedure[gfi: 1, ep: 0, tag: procedure]];
bti ← Table.Allocate[SymbolSegment.bodyType, SIZE[Outer Callable BodyRecord]];
bb[bti] ← BodyRecord[
link: [parent, BTNull], firstSon: BTNull,
localCtx: CTXNull, type: RecordSENull, level: lG,
sourceIndex: 0,
info: [External[0, 0, 0]],
extension: Callable[
inline: FALSE, id: ISENull, ioType: CSENull,
monitored: FALSE, stopping: FALSE, resident: FALSE,
entry: FALSE, internal: FALSE, entryIndex: 0,
hints: [FALSE, FALSE, FALSE, FALSE],
closure: Outer[]]];
bb[bti].id ← sei; bb[bti].ioType ← tSei; bb[bti].localCtx ← bodyCtx;
seb[sei].idInfo ← bti};
SubStringDescriptor: TYPE = StringDefs.SubStringDescriptor;
MakeConstant: PROC [name: STRING, ctx: CTXIndex, type: SEIndex]
RETURNS [sei: ISEIndex] = {
-- makes an se entry for a built-in constant
desc: SubStringDescriptor ← [base:name, offset:0, length:name.length];
sei ← MakeCtxSe[EnterString[@desc], ctx];
BEGIN OPEN seb[sei];
idType ← type;
immutable ← constant ← TRUE;
extended ← public ← linkSpace ← FALSE;
mark3 ← mark4 ← TRUE;
END;
RETURN};
CreateSymbols: PROC [moduleId: STRING] = {
ctx: CTXIndex;
WHILE (ctx ← NewCtx[lZ]) IN StandardContext DO NULL ENDLOOP;
dirCtx ← ctx;
EnterModule[moduleId, NewCtx[lG]]};
EnterHashMark: PROC = {
-- marks end of symbols from source file in hash table
desc: SubStringDescriptor ← [base:" "L, offset:1, length:0];
[] ← EnterString[@desc]};
WriteSymbols: PUBLIC PROC [s: StreamDefs.StreamHandle, moduleId: STRING] = {
weights: ARRAY SymbolSegment.Tables OF CARDINAL ← ALL[1];
tableRegion: Table.Region = [
origin: LOOPHOLE[SystemDefs.AllocateSegment[256]],
size: 256];
Table.Create[tableRegion, DESCRIPTOR[weights]]; Table.AddNotify[Notify];
SymbolOps.Initialize[];
CreateSymbols[moduleId];
EnterHashMark[];
Table.DropNotify[Notify];
TableOut[s];
SymbolOps.Finalize[]; Table.Destroy[];
SystemDefs.FreeSegment[LOOPHOLE[tableRegion.origin]]};
TableOut: PROC [s: StreamDefs.StreamHandle] = {
OPEN Table, SymbolSegment;
header: STHeader;
d: WordOffset;
WriteSubTable: PROC [table: Table.Selector] = {
OPEN Table;
base: Table.Base;
size: CARDINAL;
[base, size] ← Table.Bounds[table];
[] ← StreamDefs.WriteBlock[s, LOOPHOLE[base], size]};
BEGIN
OPEN header;
versionIdent ← SymbolSegment.VersionID;
version ← LOOPHOLE[PGScondefs.objectVersion]; -- for bootstrap
sourceVersion ← LOOPHOLE[PGScondefs.sourceVersion];
creator ← LOOPHOLE[PGScondefs.pgsVersion];
definitionsFile ← FALSE;
directoryCtx ← dirCtx;
importCtx ← outerCtx ← CTXNull;
d ← SIZE[STHeader];
hvBlock.offset ← d;
d ← d + (hvBlock.size ← SymbolOps.HashBlock[].length);
htBlock.offset ← d; d ← d + (htBlock.size ← Table.Bounds[htType].size);
ssBlock.offset ← d; d ← d + (ssBlock.size ← Table.Bounds[ssType].size);
seBlock.offset ← d; d ← d + (seBlock.size ← Table.Bounds[seType].size);
ctxBlock.offset ← d;
d ← d + (ctxBlock.size ← Table.Bounds[ctxType].size);
mdBlock.offset ← d; d ← d + (mdBlock.size ← Table.Bounds[mdType].size);
bodyBlock.offset ← d;
d ← d + (bodyBlock.size ←Table.Bounds[bodyType].size);
treeBlock ← litBlock ← sLitBlock ← extBlock ← [d, 0];
constBlock ← [0, 0];
fgRelPgBase ← fgPgCount ← 0;
END;
[] ← StreamDefs.WriteBlock[s, @header, SIZE[STHeader]];
[] ← StreamDefs.WriteBlock[s, SymbolOps.HashBlock[].base, header.hvBlock.size];
WriteSubTable[htType];
WriteSubTable[ssType];
WriteSubTable[seType];
WriteSubTable[ctxType];
WriteSubTable[mdType];
WriteSubTable[bodyType]};
started: BOOLEAN ← FALSE;
IF ~started THEN {START SymbolPack; started ← TRUE};
END.