file ModuleMaker.mesa
last edited by Satterthwaite, November 2, 1982 11:52 am
Last Edited by: Maxwell, August 10, 1983 3:29 pm
DIRECTORY
CommandUtil: TYPE USING [GetRootName],
FileIO: TYPE USING [Open, StreamFromOpenFile],
FS: TYPE USING [Open, OpenFile],
IO: TYPE USING [Close, GetLength, SetIndex, STREAM, UnsafeGetBlock, UnsafePutBlock],
PGSConDefs: TYPE USING [
objectVersion, sourceVersion, FixupBcdHeader, WriteBcdHeader],
PrincOps: TYPE USING [bytesPerWord],
Rope: TYPE USING [Equal, Find, Length, ROPE],
TableCommand: TYPE USING [CreateTime, GenerateVersion],
VM: TYPE USING [Allocate, Free, Interval, PageNumberToAddress, WordsToPages];
ModuleMaker: PROGRAM
IMPORTS
CommandUtil, FileIO, FS, IO, PGSConDefs, Rope, TableCommand, VM
EXPORTS TableCommand = {
StreamIndex: TYPE = INT; -- FileStream.FileByteIndex
bytesPerWord: NAT = PrincOps.bytesPerWord;
interface to PGSBcd
CreateBCDStream: PUBLIC PROC [
in: IO.STREAM,
modId, interfaceId: Rope.ROPE,
altoCode: BOOLFALSE]
RETURNS [output: IO.STREAM] = {
modRoot: Rope.ROPE;
interfaceRoot: Rope.ROPE;
SetSourceVersion[in];
PGSConDefs.objectVersion ← TableCommand.GenerateVersion[];
modRoot ← CommandUtil.GetRootName[modId];
output ← FileIO.Open[modId, write];
fill in interface info
interfaceRoot ← CommandUtil.GetRootName[interfaceId];
PGSConDefs.WriteBcdHeader[
outStream: output,
tableId: modRoot, binaryId: modId,
interfaceId: IF Rope.Equal[interfaceRoot, "SELF", FALSE] THEN NIL ELSE interfaceRoot,
fileId: NIL, -- for now
altoCode: altoCode];
RETURN};
FinishBcdStream: PUBLIC PROC = {
PGSConDefs.FixupBcdHeader[]};
input management
CheckForBr: PROC [name: Rope.ROPE] RETURNS [BOOL] = {
index: INT ← Rope.Find[s1: name, s2: ".BR", case: FALSE];
IF index < 0 THEN RETURN[FALSE];
RETURN[name.Length[] = index + 3]};
FindSegmentSize: PROC [br: BOOL, file: FS.OpenFile]
RETURNS [count: CARDINAL, in: IO.STREAM] = {
GetWord: PROC[stream: IO.STREAM] RETURNS[word: WORD ← 0] = INLINE {
[] ← stream.UnsafeGetBlock[[@word, 0, 1]]};
in ← FileIO.StreamFromOpenFile[file];
IF br THEN {
IO.SetIndex[in, 7*PrincOps.bytesPerWord];
count ← GetWord[in];
IO.SetIndex[in, count*PrincOps.bytesPerWord];
count ← GetWord[in]}
ELSE {
eof: StreamIndex = IO.GetLength[in];
count ← eof/PrincOps.bytesPerWord;
IO.SetIndex[in, 0]};
RETURN};
CreateSegmentStream: PROC [segmentId: Rope.ROPE]
RETURNS [in: IO.STREAM, count: CARDINAL] = {
brFile: BOOL = CheckForBr[segmentId];
file: FS.OpenFile;
file ← FS.Open[segmentId, read];
[count, in] ← FindSegmentSize[brFile, file];
RETURN};
SetSourceVersion: PROC [sh: IO.STREAM] = {
PGSConDefs.sourceVersion ← [0, 0, TableCommand.CreateTime[sh]]};
overall control
WriteSegment: PROC [in, out: IO.STREAM, count: CARDINAL] = {
interval: VM.Interval ← VM.Allocate[VM.WordsToPages[count]];
p: LONG POINTERVM.PageNumberToAddress[interval.page];
[] ← in.UnsafeGetBlock[[p, 0, count*PrincOps.bytesPerWord]];
out.UnsafePutBlock[[p, 0, count*PrincOps.bytesPerWord]];
VM.Free[interval]};
MakeModule: PUBLIC PROC [
inputFile, moduleId, interfaceId: Rope.ROPE, altocode: BOOL] = {
in, output: IO.STREAM;
count: CARDINAL;
[in, count] ← CreateSegmentStream[inputFile];
output ← CreateBCDStream[in, moduleId, interfaceId, altocode];
WriteSegment[in, output, count];
FinishBcdStream[];
IO.Close[in];
IO.Close[output]};
}.