ModuleMaker.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Satterthwaite, November 2, 1982 11:52 am
Maxwell, August 10, 1983 3:29 pm
Doug Wyatt, April 2, 1984 2:24:40 pm PST
Russ Atkinson (RRA) March 19, 1985 10:06:19 am PST
DIRECTORY
Basics USING [bytesPerWord],
CommandUtil USING [GetRootName],
FS USING [StreamOpen],
IO USING [Close, EndOfStream, GetBlock, GetLength, PutBlock, SetIndex, STREAM, UnsafeGetBlock],
PGSConDefs USING [objectVersion, sourceVersion, FixupBcdHeader, WriteBcdHeader],
Rope USING [Equal, Find, Length, ROPE],
TableCommand USING [CreateTime, GenerateVersion];
ModuleMaker: PROGRAM
IMPORTS CommandUtil, FS, IO, PGSConDefs, Rope, TableCommand
EXPORTS TableCommand = {
bytesPerWord: NAT = Basics.bytesPerWord;
interface to PGSBcd
CreateBCDStream: PUBLIC PROC [
in: IO.STREAM,
modId, interfaceId: Rope.ROPE,
altoCode: BOOLFALSE]
RETURNS [output: IO.STREAM] = {
modRoot, interfaceRoot: Rope.ROPE;
PGSConDefs.sourceVersion ← [0, 0, LOOPHOLE[TableCommand.CreateTime[in]]];
PGSConDefs.objectVersion ← TableCommand.GenerateVersion[];
modRoot ← CommandUtil.GetRootName[modId];
output ← FS.StreamOpen[modId, $create];
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];
};
GetWord: PROC[stream: IO.STREAM] RETURNS[word: CARDINAL ← 0] = {
base: LONG POINTER ~ @word;
IF stream.UnsafeGetBlock[[base: base, count: bytesPerWord]]=2 THEN RETURN
ELSE ERROR IO.EndOfStream[stream];
};
SetWordIndex: PROC[stream: IO.STREAM, wordIndex: INT] = {
stream.SetIndex[wordIndex*bytesPerWord];
};
CreateSegmentStream: PROC [segmentId: Rope.ROPE]
RETURNS [in: IO.STREAM, byteCount: INT] = {
in ← FS.StreamOpen[segmentId];
IF CheckForBr[segmentId] THEN {
words: CARDINAL;
SetWordIndex[in, 7]; words ← GetWord[in];
SetWordIndex[in, words]; words ← GetWord[in];
byteCount ← words*bytesPerWord;
}
ELSE byteCount ← in.GetLength[];
};
overall control
WriteSegment: PROC [in, out: IO.STREAM, count: INT] = {
bufferBytes: NAT ~ 512;
buffer: REF TEXT ~ NEW[TEXT[bufferBytes]];
bytesRemaining: INT ← count*bytesPerWord;
WHILE bytesRemaining>0 DO
bytesRequested: NAT ~ MIN[bytesRemaining, bufferBytes];
bytesRead: NAT ~ in.GetBlock[block: buffer, count: bytesRequested];
out.PutBlock[block: buffer, count: bytesRead];
bytesRemaining ← bytesRemaining-bytesRead;
IF bytesRead<bytesRequested THEN ERROR IO.EndOfStream[in];
ENDLOOP;
};
MakeModule: PUBLIC PROC [
inputFile, moduleId, interfaceId: Rope.ROPE, altocode: BOOL] = {
in, out: IO.STREAM;
count: INT;
[in, count] ← CreateSegmentStream[inputFile];
out ← CreateBCDStream[in, moduleId, interfaceId, altocode];
WriteSegment[in, out, count];
FinishBcdStream[];
in.Close[]; out.Close[];
};
}.