-- file PGSInterface.Mesa
-- last modified by Satterthwaite, August 13, 1982 12:36 pm
DIRECTORY
CharIO: TYPE USING [CR, PutChar, PutString],
CommandUtil: TYPE USING [
PairList, Echo, Failed, FreePairList, FreeString, Parse, CommandPtr,
CommandObject],
Exec: TYPE USING [AddCommand, commandLine, w],
FileStream: TYPE USING [Create, SetLength],
Heap: TYPE USING [Create, Delete],
PGSConDefs: TYPE USING [],
PGSOps: TYPE USING [PGSPhase, Generate, LockedSource, NoSource, BadSemantics],
PGSParseData: TYPE,
OSMiscOps: TYPE USING [FindFile],
Runtime USING [GetBcdTime, GetTableBase],
Stream: TYPE USING [Delete, Handle],
Strings: TYPE USING [String, AppendString],
Time: TYPE USING [Append, Unpack],
TTY: TYPE USING [Handle, PutChar],
UserTerminal: TYPE USING [CursorArray, GetCursorPattern, SetCursorPattern];
PGSInterface: PROGRAM
IMPORTS
CharIO, CommandUtil, Exec, FileStream, Heap, OSMiscOps,
PGSOps, PGSParseData, Runtime, Stream, Strings, Time, TTY, UserTerminal
EXPORTS PGSConDefs = {
-- command interface
tty: TTY.Handle;
log: Stream.Handle ← NIL;
commandStream: Stream.Handle ← NIL;
CR: CHARACTER = CharIO.CR;
LogChar: PROC [c: CHARACTER] = {
IF log # NIL THEN CharIO.PutChar[log, c];
TTY.PutChar[tty, c]};
LogString: PROC [s: Strings.String] = {
IF log # NIL THEN CharIO.PutString[log, s];
FOR i: CARDINAL IN [0..s.length) DO TTY.PutChar[tty, s[i]] ENDLOOP};
-- scratch region and scratch zone management
zone: UNCOUNTED ZONE ← NIL;
AcquireZone: PUBLIC PROC RETURNS [UNCOUNTED ZONE] = {
RETURN [zone]};
-- parse table management
tableSeg: LONG POINTER = Runtime.GetTableBase[LOOPHOLE[PGSParseData]];
AcquireTable: PUBLIC PROC RETURNS [LONG POINTER] = {
RETURN [tableSeg]};
ReleaseTable: PUBLIC PROC = {};
-- cursor management
PreCursor: UserTerminal.CursorArray = [
0, 0, 0, 0, 76b, 146b, 300b, 4300b, 76336b, 4304b, 314b, 164b, 0, 0, 0, 0];
PGSCursor: UserTerminal.CursorArray = [
37000b, 63000b, 140000b, 140010b, 157174b, 142010b, 146000b, 72000b,
0b, 177777b, 111111b, 177777b, 111111b, 177777b, 111111b, 177777b];
StartPhase: PROC [phase: PGSOps.PGSPhase] RETURNS [goOn: BOOLEAN ← TRUE] = {
SELECT phase FROM
format => UserTerminal.SetCursorPattern[PreCursor];
lalr => UserTerminal.SetCursorPattern[PGSCursor];
ENDCASE};
-- * * * * * * HERE IT BEGINS * * * * * *
Main: PROC = {
source: Strings.String;
args, results: CommandUtil.PairList;
switches: Strings.String;
ok, warnings: BOOLEAN;
herald: STRING ← [50];
savedCursor: UserTerminal.CursorArray;
commandObject: CommandUtil.CommandObject;
commandLine: PACKED ARRAY [ 0.. 100) OF CHARACTER;
zone ← Heap.Create[initial: 16, increment: 8];
Strings.AppendString[to:herald, from:"Cedar 3.3 PGS of "L];
Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]];
herald.length ← herald.length - 3;
tty ← Exec.w;
log ← FileStream.Create[OSMiscOps.FindFile["pgs.log"L, write]];
FileStream.SetLength[log, 0];
LogString[herald]; LogChar[CR];
savedCursor ← UserTerminal.GetCursorPattern[];
-- set up command stream
BEGIN
commandObject.data ← @commandLine;
BuildCommand[@commandObject];
LogChar[CR]; LogString["Command: "L];
EchoCommand[@commandObject];
[source, args, results, switches] ← CommandUtil.Parse[
s: @commandObject,
opX: 0, resultX: 2+("mesa"L).length
! CommandUtil.Failed => GO TO badSyntax];
CommandUtil.Echo[log, source, args, results, switches];
IF source = NIL THEN GO TO noOp;
[ok, warnings] ← PGSOps.Generate[source, args, results, switches, StartPhase, TRUE
! PGSOps.NoSource => GO TO noSource;
PGSOps.LockedSource => GO TO lockedSource;
PGSOps.BadSemantics => GO TO badSemantics];
LogChar[CR]; LogString[" "L];
LogString[SELECT TRUE FROM
~ok => "Errors logged, bad output"L,
warnings => "Warnings logged"L,
ENDCASE => "Completed successfully"L];
EXITS
noOp => NULL;
noSource => LogString[" -- Cannot be opened"L];
lockedSource => LogString[" -- Cannot be modified"L];
badSyntax => LogString["Unparsable command"L];
badSemantics => LogString[" -- Illegal command"L];
END;
source ← CommandUtil.FreeString[source];
args ← CommandUtil.FreePairList[args];
results ← CommandUtil.FreePairList[results];
switches ← CommandUtil.FreeString[switches];
Heap.Delete[zone]; zone ← NIL;
LogChar[CR]; LogChar[CR]; Stream.Delete[log]; log ← NIL;
UserTerminal.SetCursorPattern[savedCursor]};
BuildCommand: PROC [command: CommandUtil.CommandPtr] = {
command.pos ← command.len ← 0;
FOR i: CARDINAL IN [Exec.commandLine.i .. Exec.commandLine.s.length) DO
IF command.len >= 100 THEN EXIT;
command.data[command.len] ← Exec.commandLine.s[i];
command.len ← command.len + 1;
ENDLOOP};
EchoCommand: PROC [command: CommandUtil.CommandPtr] = {
first: CARDINAL ← command.pos;
last: CARDINAL ← command.len;
WHILE first < command.len AND command.data[first] = ' DO first ← first+1 ENDLOOP;
WHILE last > command.pos AND command.data[last-1] = CR DO last ← last-1 ENDLOOP;
FOR i: CARDINAL IN [first .. last) DO TTY.PutChar[tty, command.data[i]] ENDLOOP};
Exec.AddCommand["PGS.~"L, Main];
}.