-- file TableControl.Mesa
-- last edited by Satterthwaite on August 13, 1982 12:45 pm
DIRECTORY
BcdDefs: TYPE USING [VersionStamp],
CharIO: TYPE USING [PutChar, PutDecimal, PutString],
Exec: TYPE USING [CommandLine, AddCommand, commandLine, w],
FileStream: TYPE USING [Create, GetLeaderProperties],
Heap: TYPE USING [systemZone],
OSMiscOps: TYPE USING [FileError, FindFile, GenerateUniqueId],
PGSConDefs: TYPE USING [],
Runtime: TYPE USING [GetBcdTime],
Stream: TYPE USING [Handle, Delete],
Strings: TYPE USING [
String, SubStringDescriptor, AppendChar, AppendString, EquivalentSubStrings],
TableCommand: TYPE USING [CompileStrings, MakeModule],
Time: TYPE USING [Append, Current, Unpack],
TTY: TYPE USING [Handle, PutChar, PutDecimal],
UserTerminal: TYPE USING [CursorArray, GetCursorPattern, SetCursorPattern];
TableControl: PROGRAM
IMPORTS
CharIO, Exec, FileStream, Heap, OSMiscOps, Runtime, Stream, Strings,
TableCommand, Time, TTY, UserTerminal
EXPORTS TableCommand, PGSConDefs = {
CR: CHAR = '\n;
-- cursor control
savedCursor: UserTerminal.CursorArray;
TableCursor: UserTerminal.CursorArray = [
177777b, 177777b, 177777b, 160007b,
160007b, 160007b, 160007b, 160007b, 160007b, 160007b, 160007b, 160007b,
160007b, 177777b, 177777b, 177777b];
-- OS interface
AcquireZone: PUBLIC PROC RETURNS [UNCOUNTED ZONE] = {
RETURN [Heap.systemZone]};
-- command gathering and logging
log: Stream.Handle ← NIL;
tty: TTY.Handle;
LogChar: PROC [c: CHAR] = {
IF log # NIL THEN CharIO.PutChar[log, c];
tty.PutChar[c]};
LogString: PROC [s: Strings.String] = {
IF log # NIL THEN CharIO.PutString[log, s];
FOR i: CARDINAL IN [0..s.length) DO tty.PutChar[s[i]] ENDLOOP};
LogDecimal: PROC [n: INTEGER] = {
IF log # NIL THEN CharIO.PutDecimal[log, n];
tty.PutDecimal[n]};
command: Exec.CommandLine;
Rubout: ERROR = CODE;
CommandEnded: PROC RETURNS [BOOL] = {
RETURN [command.i >= command.s.length]};
CommandChar: PROC RETURNS [char: CHAR] = {
IF command.i < command.s.length THEN {
char ← command.s[command.i]; command.i ← command.i+1}
ELSE char ← 0c;
RETURN};
ReadCommand: PROC [name, switches: Strings.String] RETURNS [BOOL] = {
input: STRING ← [80];
i: CARDINAL;
c: CHAR;
activeString: Strings.String ← name;
DO
IF CommandEnded[] THEN EXIT;
c ← CommandChar[];
SELECT c FROM
' => IF input.length # 0 THEN EXIT;
CR => EXIT;
ENDCASE => Strings.AppendChar[input, c];
ENDLOOP;
i ← name.length ← switches.length ← 0;
WHILE i < input.length AND input[i] = ' DO i ← i+1 ENDLOOP;
--parse command--
FOR i IN [i..input.length) DO
SELECT (c←input[i]) FROM
'/ => activeString ← switches;
' , CR => EXIT;
ENDCASE => Strings.AppendChar[activeString,c];
ENDLOOP;
FOR i IN [0..switches.length) DO -- convert all to lower case
IF (c←switches[i]) IN ['A..'Z] THEN switches[i] ← c + ('a-'A);
ENDLOOP;
RETURN [name.length # 0 OR switches.length # 0]};
DefaultFileName: PROC [name, defaultExtension: Strings.String] = {
FOR i: CARDINAL IN [0..name.length) DO IF name[i] = '. THEN RETURN ENDLOOP;
Strings.AppendString[name, defaultExtension]};
ExtensionIs: PROC [name, ext: Strings.String] RETURNS [BOOL] = {
dn, dx: Strings.SubStringDescriptor;
IF name.length <= ext.length THEN RETURN [FALSE];
dn ← [name, name.length-ext.length, ext.length];
dx ← [ext, 0, ext.length];
RETURN [Strings.EquivalentSubStrings[@dn, @dx]]};
CreateTime: PUBLIC PROC [s: Stream.Handle] RETURNS [time: LONG INTEGER] = {
RETURN [FileStream.GetLeaderProperties[s].create]};
GenerateVersion: PUBLIC PROC RETURNS [version: BcdDefs.VersionStamp] = {
RETURN [OSMiscOps.GenerateUniqueId[]]};
WriteHerald: PROC = {
t: STRING ← [20];
LogString["Cedar 3.3 Table Compiler of "L];
Time.Append[t, Time.Unpack[Runtime.GetBcdTime[]]];
t.length ← t.length - 3;
LogString[t]; LogChar[CR];
t.length ← 0;
Time.Append[t, Time.Unpack[Time.Current[]]];
t.length ← t.length - 3;
LogString["TableCompiler.log"L]; LogString[" -- "L];
LogString[t]; LogChar[CR]};
-- PGSConDefs error logging interface
warningsLogged: PUBLIC BOOL;
seterrstream, resetoutstream: PUBLIC PROC = {NULL};
outeol: PUBLIC PROC [n: CARDINAL] = {
THROUGH [1..n] DO LogChar['\n] ENDLOOP};
outstring: PUBLIC PROC [string: Strings.String] = LogString;
-- version identification
sourceName: PUBLIC Strings.String ← NIL;
pgsVersion: PUBLIC BcdDefs.VersionStamp ← [0, 0, Runtime.GetBcdTime[]];
sourceVersion: PUBLIC BcdDefs.VersionStamp ← [0, 0, 0];
objectVersion: PUBLIC BcdDefs.VersionStamp ← [0, 0, 0];
Main: PROC = {
input: {strings, binary}; -- compiling strings
compact: BOOL;
dStar: BOOL;
rootName: STRING ← [100];
interfaceName: STRING ← [100];
formatName: STRING ← [100];
bcdName: STRING ← [100];
GetCommand: PROC = {
file: STRING ← [100];
sw: STRING ← [10];
i: CARDINAL;
c: CHAR;
done: BOOL ← FALSE;
sense: BOOL;
GetSwitch: PROC RETURNS [c: CHAR] = {
sense ← TRUE;
WHILE i < sw.length DO
c ← sw[i]; i ← i + 1;
IF c = '- OR c = '~ THEN sense ← ~sense ELSE EXIT;
ENDLOOP;
RETURN};
sourceName ← NIL;
bcdName.length ← interfaceName.length ← formatName.length ← 0;
dStar ← TRUE;
file.length ← 0;
IF ~ReadCommand[file, sw] OR file.length = 0 THEN RETURN;
DefaultFileName[file, ".mesa"L];
IF ExtensionIs[file, ".mesa"L] THEN {input ← strings; compact ← TRUE}
ELSE input ← binary;
i ← 0;
WHILE i < sw.length DO
SELECT (c←GetSwitch[]) FROM
'a => dStar ← ~sense;
'c => compact ← sense;
'm => input ← binary;
's => {input ← strings; compact ← FALSE};
't => {input ← strings; compact ← TRUE};
'g => done ← TRUE;
ENDCASE => GO TO barf;
REPEAT
barf => ERROR Rubout;
ENDLOOP;
sourceName ← (Heap.systemZone).NEW[StringBody[file.length]];
Strings.AppendString[sourceName, file];
WHILE ~done AND ReadCommand[file, sw] DO
i ← 0;
WHILE i < sw.length DO
SELECT (c←GetSwitch[]) FROM
'f => {
DefaultFileName[file, ".format"L];
formatName.length ← 0; Strings.AppendString[formatName, file]};
'i => {
DefaultFileName[file, ".bcd"L];
interfaceName.length ← 0; Strings.AppendString[interfaceName, file]};
'o => {
DefaultFileName[file, ".bcd"L];
bcdName.length ← 0; Strings.AppendString[bcdName, file]};
'g => done ← TRUE;
ENDCASE => ERROR Rubout;
ENDLOOP;
ENDLOOP};
LogCommand: PROC = {
SELECT input FROM
strings => {
LogString["\nCompiling "L]; LogString[sourceName];
LogString[", exporting "L]; LogString[rootName];
LogString[" to "L]; LogString[interfaceName];
IF bcdName.length # 0 THEN {LogString[", BCD to "L]; LogString[bcdName]};
LogString["\nRecord format on "L]; LogString[formatName]};
binary => {
LogString["\nProcessing "L]; LogString[sourceName];
LogString[", exporting "L]; LogString[rootName];
LogString[" to "L]; LogString[interfaceName];
IF bcdName.length # 0 THEN {LogString[", BCD to "L]; LogString[bcdName]}};
ENDCASE;
LogChar[CR]};
-- initialization
command ← Exec.commandLine;
tty ← Exec.w;
log ← FileStream.Create[OSMiscOps.FindFile["TableCompiler.log"L, write]];
WriteHerald[];
-- main loop
DO
BEGIN
ENABLE
OSMiscOps.FileError => {
LogString["Can't open "L]; LogString[name]; LogChar[CR];
GO TO FileFault};
GetCommand[ ! Rubout => GOTO Abort];
IF sourceName = NIL THEN EXIT;
rootName.length ← 0;
FOR i: CARDINAL IN [0..sourceName.length) DO
IF sourceName[i] = '. THEN EXIT;
Strings.AppendChar[rootName, sourceName[i]];
ENDLOOP;
IF interfaceName.length = 0 THEN Strings.AppendString[interfaceName, "SELF"L];
IF formatName.length = 0 THEN {
Strings.AppendString[formatName, rootName];
Strings.AppendString[formatName, "Format."L]};
LogCommand[];
IF bcdName.length = 0 THEN {
Strings.AppendString[bcdName, rootName];
Strings.AppendString[bcdName, ".bcd"L]};
savedCursor ← UserTerminal.GetCursorPattern[];
UserTerminal.SetCursorPattern[TableCursor];
SELECT input FROM
strings => {
nChars, nStrings: CARDINAL;
[nStrings, nChars] ← TableCommand.CompileStrings[
inputFile: sourceName,
interfaceId: interfaceName,
formatId: formatName,
moduleId: bcdName,
compact: compact,
altoCode: ~dStar];
LogString["Strings: "L]; LogDecimal[nStrings];
LogString[", characters: "L]; LogDecimal[nChars];
LogChar[CR]};
binary =>
TableCommand.MakeModule[
inputFile: sourceName,
interfaceId: interfaceName,
moduleId: bcdName,
altocode: ~dStar];
ENDCASE;
LogChar[CR];
UserTerminal.SetCursorPattern[savedCursor];
EXITS
FileFault => NULL;
Abort => LogChar['?];
END;
IF sourceName # NIL THEN (Heap.systemZone).FREE[@sourceName];
ENDLOOP;
IF log # NIL THEN Stream.Delete[log]};
Exec.AddCommand["TableCompiler.~"L, Main];
}.