File: [Thyme]<Thyme>Cedar5.2>System>spMain.mesa
Last Edited by: SChen, September 18, 1984 1:06:20 pm PDT
DIRECTORY
BasicTime USING [Now],
CommandTool USING [Run],
FS USING [Error],
IO USING [PutF, rope],
Labels USING [Set],
MessageWindow USING [Append, Blink],
Plot USING [IsPlotViewer, SavePlot],
PlotOps USING [Handle],
PrincOps USING [NoTimeout],
Process USING [Abort, Detach, GetPriority, Priority, priorityBackground, SetPriority, SetTimeout],
Real USING [FixC],
RefText USING [New],
Rope USING [Equal, Find, IsEmpty, ROPE, Substr],
RopeFrom USING [String],
spGlobals USING [Aborted, bomb, CircuitRec, CloseNil, defineCircuit, dumpAll, error, ErrWarnSummary, fileStackSeq, FlushCloseNil, function, functionTable, FuncTableBlk, FuncTablePtr, Handle, keys, makePlotList, makePrintList, maxInclude, maxLog, maxPlots, maxPrints, model, modelTable, ModelTableBlk, ModelTablePtr, nameBlk, namePtr, next, openInputFile, output, PlotSeq, printHole, PrintSeq, PutMsgLine, runIt, searchKey, SetCursor, setICs, topoAnalysis, Variables, WorstNodeLog],
ViewerClasses USING [Viewer];
spMain: CEDAR MONITOR
IMPORTS BasicTime, CommandTool, FS, IO, Labels, MessageWindow, Plot, Process, Real, RefText, Rope, RopeFrom, spGlobals
EXPORTS spGlobals=
{ OPEN spGlobals;
EnterModels: PUBLIC ENTRY PROC[name: Rope.ROPE, proc: model,
numArgs, numParms, numResults: NAT]= {
ENABLE UNWIND => NULL;
m: ModelTablePtr;
FOR m← modelTable, m.next UNTIL m=NIL DO
IF Rope.Equal[m.name, name] THEN {
m^← [
next: m.next,
name: name,
proc: proc,
numArgs: numArgs,
numParms: numParms,
numResults: numResults];
RETURN;
};
ENDLOOP;
m← NEW[ModelTableBlk←
[next: modelTable,
name: name,
proc: proc,
numArgs: numArgs,
numParms: numParms,
numResults: numResults]];
modelTable← m;
}; -- EnterModels
EnterFunctions: PUBLIC ENTRY PROC[name: Rope.ROPE, proc: function,
numArgs, numParms: NAT]= {
ENABLE UNWIND => NULL;
f: FuncTablePtr;
FOR f← functionTable, f.next UNTIL f=NIL DO
IF Rope.Equal[f.name, name] THEN {
f^← [f.next, name, proc, numArgs, numParms];
RETURN;
};
ENDLOOP;
f← NEW[FuncTableBlk← [functionTable, name, proc, numArgs, numParms]];
functionTable← f;
}; -- EnterFunctions
entry procs
findModel: PUBLIC ENTRY PROC[name: Rope.ROPE] RETURNS[model, NAT, NAT, NAT]= {
ENABLE UNWIND => NULL;
m: ModelTablePtr;
find the model named newString from ModelTable
FOR m← modelTable, m.next UNTIL m=NIL DO
IF Rope.Equal[m.name, name] THEN
RETURN[m.proc, m.numArgs, m.numParms, m.numResults];
ENDLOOP;
RETURN[NIL, 0, 0, 0];
}; -- findModel
findFunction: PUBLIC ENTRY PROC[name: Rope.ROPE]
RETURNS[function, NAT, NAT]= {
ENABLE UNWIND => NULL;
f: FuncTablePtr;
FOR f← functionTable, f.next UNTIL f=NIL DO
IF Rope.Equal[f.name, name] THEN
RETURN[f.proc, f.numArgs, f.numParms];
ENDLOOP;
RETURN[NIL, 0, 0];
}; -- findFunction
ResetCheckPoint: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
handle.vars.checkPoint← FALSE };
Canned: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.vars.canned]};
ForcedDump: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.vars.forcedDump]};
CheckPoint: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.vars.checkPoint]};
ShowDetails: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= {
ENABLE UNWIND => NULL;
RETURN[handle.showTimeStep]};
StopIt: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
IF handle # NIL THEN {
IF handle.vars # NIL THEN {
handle.vars.forcedDump← FALSE;
handle.vars.canned← TRUE;
};
AbortCheckPoint[handle];
};
}; -- StopIt
DumpIt: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
IF handle # NIL THEN {
IF handle.vars # NIL THEN {
handle.vars.forcedDump← TRUE;
handle.vars.canned← TRUE;
};
AbortCheckPoint[handle];
};
}; -- DumpIt
ToggleShowDetails: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
handle.showTimeStep← ~handle.showTimeStep;
}; -- ToggleShowDetails
SimulateIt: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
IF handle = NIL THEN RETURN;
IF handle.stage=idle AND handle.simulation=NIL THEN {
curPriority: Process.Priority = Process.GetPriority[];
handle.stage← input;
SetCursor[handle];
Process.SetPriority[Process.priorityBackground];
handle.simulation← FORK Simulate[handle];
Process.SetPriority[curPriority];
TRUSTED {Process.Detach[handle.simulation]};
}
ELSE MessageWindow.Append[message: "It's still running.", clearFirst: TRUE];
}; -- SimulateIt
NextStage: PUBLIC ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
SELECT handle.stage FROM
input, bomb, topo => {
handle.stage← SUCC[handle.stage];
SetCursor[handle];
};
run => {
handle.vars.runState ← (handle.vars.runState + 1) MOD 4;
SetCursor[handle];
};
ENDCASE => MessageWindow.Append[ -- should not get here
message: "* Weird situation detected in 'NextStage', please inform SChen.pa",
clearFirst: TRUE];
}; -- NextStage
PeriodicSetCheckPoint: ENTRY PROC[handle: Handle]= {
ENABLE UNWIND => NULL;
WHILE handle # NIL DO
ENABLE ABORTED => EXIT;
WAIT handle.checkPointCV;
IF handle # NIL THEN
IF handle.vars # NIL THEN handle.vars.checkPoint← TRUE
ELSE EXIT;
ENDLOOP;
IF handle # NIL THEN
TRUSTED {Process.SetTimeout[@handle.checkPointCV, PrincOps.NoTimeout]};
}; -- PeriodicSetCheckPoint
CleanUp: ENTRY PROC[handle: Handle]= {OPEN handle;
ENABLE UNWIND => NULL;
IF checkProcess # NIL THEN {
TRUSTED {Process.Abort[LOOPHOLE[checkProcess, UNSPECIFIED]]};
checkProcess← NIL;
};
IF vars.canned THEN msgStream.PutF["\n...... Aborted.\n"];
vars.thymeDotErrors ← CloseNil[vars.thymeDotErrors];
FOR i: NAT IN [0..vars.fileStackTop) DO
vars.fileStack[vars.fileStackTop] ← CloseNil[vars.fileStack[vars.fileStackTop]];
ENDLOOP;
vars.inStream ← CloseNil[vars.inStream];
FOR i: NAT IN [0..vars.numPrints) DO
vars.prints[i].printStream ← FlushCloseNil[vars.prints[i].printStream];
ENDLOOP;
FOR i: NAT IN [0..vars.numPlots) DO
v: ViewerClasses.Viewer ← vars.plots[i].plotViewer;
IF Plot.IsPlotViewer[v] THEN {
h: PlotOps.Handle ← NARROW[v.data];
IF h # NIL THEN {
msg: Rope.ROPE ← Plot.SavePlot[v, h.plotSpec.file];
IF msg # NIL THEN {
MessageWindow.Blink[];
MessageWindow.Append[message: msg, clearFirst: TRUE];
};
};
v.inhibitDestroy ← FALSE;
};
vars.plots[i].plotViewer ← NIL;
ENDLOOP;
FOR i: NAT IN [0..maxLog) DO
vars.worstNodeLog[i] ← [];
ENDLOOP;
handle.stage← idle;
SetCursor[handle];
Labels.Set[handle.time, ""];
Labels.Set[handle.step, ""];
simulation← NIL;
vars← NIL;
}; -- CleanUp
AbortCheckPoint: INTERNAL PROC[handle: Handle]= {
IF handle = NIL THEN RETURN;
IF handle.stage=run AND handle.checkProcess # NIL THEN {
TRUSTED {Process.Abort[LOOPHOLE[handle.checkProcess, UNSPECIFIED]]};
handle.checkProcess← NIL;
};
}; -- AbortCheckPoint
AddLibrary: PROC[handle: Handle]= {
next[handle];
IF handle.vars.item=leftB THEN next[handle] ELSE error[handle, 801, TRUE];
IF handle.vars.item=name THEN {
originalName, nameRoot, errMsg: Rope.ROPE;
dotPosition: INT;
originalName← RopeFrom.String[handle.vars.newString];
dotPosition← Rope.Find[originalName, "."];
nameRoot← IF dotPosition=-1 THEN originalName
ELSE Rope.Substr[originalName, 0, dotPosition-1];
IF NOT (Rope.Equal[nameRoot, "MosModels", FALSE] OR
Rope.Equal[nameRoot, "StdFunctions", FALSE] OR
Rope.Equal[nameRoot, "Level2Model", FALSE]) THEN {
[errMsg, ]← CommandTool.Run[originalName];
IF NOT errMsg.IsEmpty[] THEN PutMsgLine[handle, errMsg];
};
next[handle];
}
ELSE error[handle, 804, TRUE];
IF handle.vars.item=rightB THEN next[handle] ELSE error[handle, 802, FALSE];
IF handle.vars.item=semi THEN next[handle] ELSE error[handle, 800, FALSE];
}; -- AddLibrary
main proc
Simulate: PUBLIC PROC[handle: Handle]= {
ENABLE {
Aborted => GOTO stop;
ABORTED => {handle.vars.canned ← TRUE; GOTO stop};
FS.Error => {
handle.msgStream.PutF["%g\nProgram stopped.\n", IO.rope[error.explanation]];
GOTO stop;
};
};
InitVars[handle];
openInputFile[handle];
next[handle];
libraries
WHILE handle.vars.item=name DO
IF Canned[handle] THEN GOTO stop;
IF searchKey[handle]=libraryKey THEN AddLibrary[handle] ELSE EXIT;
ENDLOOP;
circuit definition
IF handle.vars.item=name AND searchKey[handle]=circuitKey THEN {
theRoot: namePtr← NEW[nameBlk←
[name: "Main Circuit", details: NEW[CircuitRec← []]] ];
defineCircuit[handle: handle, ckt: theRoot, root: TRUE]; -- may signal Aborted
}
ELSE error[handle, 820, TRUE];
IF handle.vars.item=slash AND handle.vars.errCount <= 0 THEN {
next[handle];
output[handle, handle.vars.cktRoot, 0];
};
explode
IF handle.vars.item#semi THEN error[handle, 800,, FALSE]
ELSE IF handle.vars.errCount <= 0 THEN {
NextStage[handle];
bomb[handle]; -- may signal Aborted
next[handle];
IF handle.vars.item=plus THEN {next[handle]; printHole[handle]};
};
analyze
IF handle.vars.errCount <= 0 THEN {
NextStage[handle];
topoAnalysis[handle];
IF Canned[handle] THEN GOTO stop;
};
run
IF handle.vars.errCount <= 0 THEN {
NextStage[handle];
WHILE handle.vars.item=name DO
OPEN handle.vars;
key: keys← searchKey[handle];
next[handle];
SELECT key FROM
runKey=> {
TRUSTED {
Process.SetTimeout[@handle.checkPointCV,
Real.FixC[60.0*checkPointInterval]];
Process.Detach[handle.checkProcess← FORK PeriodicSetCheckPoint[handle]]};
lastTime← runIt[handle];
IF NOT Canned[handle] THEN PutMsgLine[handle, "Done."];
};
printKey=> makePrintList[handle];
plotKey => makePlotList[handle];
icKey => setICs[handle];
dumpKey => IF ~ForcedDump[handle] THEN dumpAll[handle, lastTime];
checkPointKey=> {
IF item=leftB THEN next[handle] ELSE error[handle, 801];
IF item=number THEN {
checkPointInterval← value;
next[handle]
}
ELSE error[handle, 809, FALSE];
IF item=rightB THEN next[handle] ELSE error[handle, 802];
}
ENDCASE=> GOTO err1;
IF item=eof THEN EXIT;
IF item=semi THEN next[handle] ELSE error[handle, 800,, FALSE];
REPEAT
err1=> error[handle, 821, TRUE];
ENDLOOP;
}; -- run
IF ForcedDump[handle] THEN dumpAll[handle, handle.vars.lastTime];
ErrWarnSummary[handle];
killPlot[]
GOTO stop;
EXITS
stop=> {CleanUp[handle]; handle.msgStream.PutF["Thyme is idle now .....\n"];};
}; -- Simulate
InitVars: PROC[handle: Handle]= {
handle.vars← NEW[Variables← [ ]];
{OPEN handle.vars;
simTime ← BasicTime.Now[];
line← RefText.New[256];
newString← RefText.New[256];
line.length← 0;
newString.length← 0;
fileStack← NEW[fileStackSeq[maxInclude]];
prints← NEW[PrintSeq[maxPrints]];
plots← NEW[PlotSeq[maxPlots]];
worstNodeLog← NEW[WorstNodeLog[maxLog]];
};
}; -- InitVars
}.
CHANGE LOG
Wilhelm, April 27, 1982 4:07 PM
Barth, 7-May-82 14:41:52 PDT
Chen, April 19, 1983 6:45 PM, changed the version name for openSysWindow.
Barth, July 11, 1983 12:46 PM
Chen, June 12, 1984 11:37:19 am PDT, cedarized.