file PGSSymbols.mesa
last modified by Satterthwaite, January 10, 1983 4:15 pm
Last Edited by: Maxwell, August 10, 1983 10:38 am
DIRECTORY
Alloc: TYPE USING [
Handle, Notifier, TableInfo,
AddNotify, Bounds, Create, Destroy, DropNotify, Words],
ConvertUnsafe: TYPE USING [SubString],
IO: TYPE USING [STREAM, UnsafePutBlock],
PGSConDefs: TYPE USING [objectVersion, pgsVersion, sourceVersion, zone],
PrincOps: TYPE USING [bytesPerWord, ControlLink],
Rope: TYPE USING [Flatten, Length, ROPE],
SymbolOps: TYPE USING [
Initialize, Finalize,
EnterString, HashBlock, MakeCtxSe, NewCtx, MakeNonCtxSe],
SymbolPack: TYPE,
Symbols: TYPE USING [
Base, HashVector, 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],
Table: TYPE USING [Selector];
PGSSymbols: PROGRAM
IMPORTS Alloc, PGSConDefs, IO, Rope, SymbolOps, SymbolPack
EXPORTS PGSConDefs = {
OPEN SymbolOps, Symbols;
table: Alloc.Handle ← NIL;
seb: Symbols.Base; -- semantic entry base (local copy)
ctxb: Symbols.Base; -- context table base (local copy)
bb: Symbols.Base; -- body table base (local copy)
Notify: Alloc.Notifier = {
OPEN SymbolSegment;
seb ← base[seType]; ctxb ← base[ctxType]; bb ← base[bodyType]};
dirCtx: CTXIndex;
EnterModule: PROC [moduleId: Rope.ROPE, bodyCtx: CTXIndex] = {
tSei: CSEIndex;
sei: ISEIndex;
bti: CBTIndex;
generate a program type
tSei ← MakeNonCtxSe[SERecord.cons.transfer.SIZE];
seb[tSei] ← SERecord[
mark3: TRUE, mark4: TRUE,
body: cons[transfer[
mode: program, safe: FALSE,
typeIn: RecordSENull, typeOut: RecordSENull]]];
generate an id
sei ← MakeConstant[moduleId, dirCtx, tSei];
seb[sei].public ← TRUE;
seb[sei].idValue ← PrincOps.ControlLink[
procedure[gfi: 1, ep: 0, tag: TRUE]];
bti ← table.Words[SymbolSegment.bodyType, BodyRecord.Callable.Outer.SIZE];
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, noXfers: 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};
MakeConstant: PROC [name: Rope.ROPE, ctx: CTXIndex, type: SEIndex]
RETURNS [sei: ISEIndex] = {
makes an se entry for a built-in constant
ss: ConvertUnsafe.SubString;
ss.offset ← 0;
ss.length ← name.Length[];
ss.base ← LOOPHOLE[Rope.Flatten[name]];
sei ← MakeCtxSe[EnterString[ss], ctx];
seb[sei].idType ← type;
seb[sei].immutable ← seb[sei].constant ← TRUE;
seb[sei].extended ← seb[sei].public ← seb[sei].linkSpace ← FALSE;
seb[sei].mark3 ← seb[sei].mark4 ← TRUE;
RETURN};
CreateSymbols: PROC [moduleId: Rope.ROPE] = {
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: ConvertUnsafe.SubString ← [base:" "L, offset:1, length:0];
[] ← EnterString[desc]};
WriteSymbols: PUBLIC PROC [s: IO.STREAM, moduleId: Rope.ROPE] = {
weights: ARRAY SymbolSegment.Tables OF Alloc.TableInfo ← ALL[[1]];
table ← Alloc.Create[weights: DESCRIPTOR[weights]];
table.AddNotify[Notify];
SymbolOps.Initialize[table, PGSConDefs.zone];
CreateSymbols[moduleId];
EnterHashMark[];
table.DropNotify[Notify];
TableOut[s];
SymbolOps.Finalize[];
Alloc.Destroy[table]; table ← NIL};
BytesPerWord: CARDINAL = PrincOps.bytesPerWord;
TableOut: PROC [s: IO.STREAM] = {
OPEN SymbolSegment;
header: STHeader;
d: WordOffset;
WriteSubTable: PROC [selector: Table.Selector] = {
base: Symbols.Base;
size: CARDINAL;
[base, size] ← table.Bounds[selector];
s.UnsafePutBlock[[base, 0, size*BytesPerWord]]};
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 ← STHeader.SIZE;
hvBlock.offset ← d; d ← d + (hvBlock.size ← Symbols.HashVector.SIZE);
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;
s.UnsafePutBlock[[@header, 0, STHeader.SIZE*BytesPerWord]];
s.UnsafePutBlock[[SymbolOps.HashBlock[], 0, header.hvBlock.size*BytesPerWord]];
WriteSubTable[htType];
WriteSubTable[ssType];
WriteSubTable[seType];
WriteSubTable[ctxType];
WriteSubTable[mdType];
WriteSubTable[bodyType]};
started: BOOLFALSE;
IF ~started THEN {START SymbolPack; started ← TRUE};
}.