-- file PGSInterface.Mesa
-- last modified by Satterthwaite, January 10, 1983 4:21 pm
DIRECTORY
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],
OSMiscOps: TYPE USING [FindFile],
PGSConDefs: TYPE USING [],
PGSOps: TYPE USING [PGSPhase, Generate, LockedSource, NoSource, BadSemantics],
Runtime USING [GetBcdTime],
Stream: TYPE USING [Delete, Handle, PutChar],
Strings: TYPE USING [String, AppendString],
Time: TYPE USING [Append, Unpack],
TTY: TYPE USING [Handle, PutChar],
UserTerminal: TYPE USING [CursorArray, GetCursorPattern, SetCursorPattern];
PGSInterface: PROGRAM
IMPORTS
CommandUtil, Exec, FileStream, Heap, OSMiscOps,
PGSOps, Runtime, Stream, Strings, Time, TTY, UserTerminal
EXPORTS PGSConDefs = {
-- command interface
tty: TTY.Handle;
log: Stream.Handle ← NIL;
commandStream: Stream.Handle ← NIL;
CR: CHAR = '\n;
LogChar: PROC [c: CHAR] = {
IF log # NIL THEN log.PutChar[c];
tty.PutChar[c]};
LogString: PROC [s: Strings.String] = {
FOR i: CARDINAL IN [0..s.length) DO LogChar[s[i]] ENDLOOP};
-- scratch region and scratch zone management
zone: PUBLIC UNCOUNTED ZONE ← NIL;
-- 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: BOOL ← 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: BOOL;
herald: STRING ← [50];
savedCursor: UserTerminal.CursorArray;
commandObject: CommandUtil.CommandObject;
commandLine: PACKED ARRAY [0.. 100) OF CHAR;
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];
LogString["\nCommand: "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];
LogString["\n "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[command.data[i]] ENDLOOP};
Exec.AddCommand["PGS.~"L, Main];
}.