<Cedar5.2>System>spMain.mesa>> <> <> <<>> DIRECTORY CommandTool USING [Run], IO USING [PutF, rope, STREAM], Process USING [Abort], RefText USING [New], Rope USING [ROPE, Equal, Find, FromRefText, IsEmpty, Substr], spGlobals USING [Aborted, bomb, CircuitRec, CloseNil, defineCircuit, error, fileStackSeq, FuncTableBlk, FuncTablePtr, function, Handle, keys, maxInclude, model, ModelTableBlk, ModelTablePtr, nameBlk, namePtr, next, output, RefUnReal, searchKey, ThymeToolRec, Variables], ThymeParser; spMain: CEDAR MONITOR IMPORTS CommandTool, IO, Process, RefText, Rope, spGlobals EXPORTS spGlobals, ThymeParser = { OPEN spGlobals, ThymeParser; refUnReal: PUBLIC RefUnReal; modelTable: PUBLIC ModelTablePtr _ NIL; functionTable: PUBLIC FuncTablePtr _ NIL; Canned: PUBLIC ENTRY PROC[handle: Handle] RETURNS[BOOL]= { ENABLE UNWIND => NULL; IF handle.vars.stopValue # NIL THEN IF handle.vars.stopValue^ THEN RETURN [TRUE]; RETURN[handle.vars.canned]}; 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 findModel: PUBLIC ENTRY PROC[name: Rope.ROPE] RETURNS[model, NAT, NAT, NAT]= { ENABLE UNWIND => NULL; m: ModelTablePtr; <> 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 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 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 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]; <<>> simulation_ NIL; }; -- CleanUp 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_ Rope.FromRefText[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 Rope.IsEmpty[errMsg] THEN IO.PutF[handle.msgStream, "%s\n", IO.rope[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 ReadFile: PUBLIC PROC[inStream, errorStream:IO.STREAM, table: TypeList _ NIL, resProc: ResistorProc _ NIL, capProc: CapacitorProc _ NIL, fetProc: TransistorProc _ NIL, attProc: AttributeProc _ NIL, nodeProc: NodeProc _ NIL, clientData: REF ANY _ NIL, stopValue: REF BOOL _ NIL] RETURNS [nodes, fets, caps, res: INT] = { handle: Handle _ NEW[ThymeToolRec _ []]; { ENABLE { Aborted => GOTO stop; ABORTED => {handle.vars.canned _ TRUE; GOTO stop}; }; InitVars[handle]; handle.msgStream _ errorStream; handle.vars.inStream _ inStream; handle.vars.fetTable _ table; handle.vars.resProc _ resProc; handle.vars.capProc _ capProc; handle.vars.fetProc _ fetProc; handle.vars.attProc _ attProc; handle.vars.nodeProc _ nodeProc; handle.vars.clientData _ clientData; handle.vars.stopValue _ stopValue; next[handle]; <> WHILE handle.vars.item=name DO IF Canned[handle] THEN GOTO stop; IF searchKey[handle]=libraryKey THEN AddLibrary[handle] ELSE EXIT; ENDLOOP; <> 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]; }; <> IF handle.vars.item#semi THEN error[handle, 800,, FALSE] ELSE IF handle.vars.errCount <= 0 THEN { bomb[handle]; -- may signal Aborted }; <<>> GOTO stop; EXITS stop=> RETURN[handle.vars.nodeCount, handle.vars.fetCount, handle.vars.capCount, handle.vars.resCount]; }}; -- Simulate SkipToSemi: PROC[handle: Handle] = { WHILE handle.vars.item # semi DO next[handle]; ENDLOOP; next[handle]; }; <<>> InitVars: PROC[handle: Handle]= { handle.vars_ NEW[Variables_ [ ]]; {OPEN handle.vars; line_ RefText.New[256]; newString_ RefText.New[256]; line.length_ 0; newString.length_ 0; fileStack_ NEW[fileStackSeq[maxInclude]]; }; }; -- InitVars }. <<>> <> <> <> <> <> <>