DIRECTORY IO USING [PutF, real, rope, STREAM], Real USING [FixC], RefText USING [Append, New], Rope USING [Cat, Equal, ROPE], RopeFrom USING [String], spGlobals USING [Aborted, argList, argNames, assignExpr, BranchRec, Canned, CircuitRec, CktInstance, conLink, conLinkPtr, ConRec, elements, error, ErrorSignal, ErrorStrings, eval, expression, expressionPtr, findFunction, findModel, function, FuncTableBlk, FunctionRec, Handle, keys, ModelRec, ModelTableBlk, nameBlk, namePtr, namePtrSeq, next, NodeRec, ParmRec, RefBranchRec, RefCircuitRec, RefCktInstRec, RefConRec, RefFunctionRec, RefModelRec, RefNodeRec, RefParmRec, searchKey, ValueSeq]; spInput: CEDAR PROGRAM IMPORTS IO, Real, RefText, Rope, RopeFrom, spGlobals EXPORTS spGlobals= BEGIN OPEN spGlobals; enterName: PROC[handle: Handle] RETURNS[newCktNames: namePtr_ NIL]= { OPEN handle.vars; IF searchName[newString, oneLevel, currentCkt]=NIL THEN { curCktDetails: RefCircuitRec_ NARROW[currentCkt.details]; newCktNames_ NEW[nameBlk_ [srchLink: curCktDetails.names, name: RopeFrom.String[newString]]]; curCktDetails.names_ newCktNames; } ELSE error[handle, 250]; }; -- enterName searchName: PROC[nameString: REF TEXT, -- usually newString level: {oneLevel, allLevels}_ oneLevel, oldCktNames: namePtr] -- usually currentCkt RETURNS[newCktNames: namePtr_ NIL]= { lastNamePtr: namePtr; oldDetails: RefCircuitRec; nameRope: Rope.ROPE_ RopeFrom.String[nameString]; UNTIL oldCktNames=NIL DO oldDetails_ NARROW[oldCktNames.details]; newCktNames_ oldDetails.names; lastNamePtr_ NIL; UNTIL newCktNames=NIL DO IF Rope.Equal[nameRope, newCktNames.name] THEN GOTO found; lastNamePtr_ newCktNames; newCktNames_ newCktNames.srchLink; ENDLOOP; IF level=oneLevel THEN EXIT; oldCktNames_ oldDetails.father; REPEAT found => IF lastNamePtr # NIL THEN { lastNamePtr.srchLink_ newCktNames.srchLink; newCktNames.srchLink_ oldDetails.names; oldDetails.names_ newCktNames; }; ENDLOOP; }; -- searchName getNames: PROC[handle: Handle] RETURNS[names: namePtr_ NIL, nameCount: NAT_ 0]= { nPtr: namePtr; UNTIL handle.vars.item # name DO nPtr_ enterName[handle]; IF nPtr # NIL THEN { -- usually not nil nPtr.nextName_ names; names_ nPtr; }; nameCount_ nameCount + 1; next[handle]; IF handle.vars.item # comma THEN EXIT ELSE next[handle]; IF handle.vars.item # name THEN error[handle, 208] ENDLOOP }; -- getNames getName: PROC[handle: Handle] RETURNS[nPtr: namePtr_ NIL]= { OPEN handle.vars; IF item # name THEN error[handle, 208] ELSE nPtr_ searchName[newString, allLevels, currentCkt]; IF nPtr=NIL THEN error[handle, 251]; next[handle]; }; -- getName variable: PUBLIC PROC[handle: Handle, string: REF TEXT, -- often newString context: namePtr] RETURNS[nPtr: namePtr_ NIL]= { nPtr_ IF context # NIL THEN searchName[string, oneLevel, context] ELSE searchName[string, allLevels, handle.vars.currentCkt]; IF nPtr=NIL THEN error[handle, 252] ELSE -- check if nPtr has an acceptable type WITH nPtr.details SELECT FROM x: RefParmRec => NULL; x: RefNodeRec => NULL; x: RefConRec => NULL; ENDCASE => error[handle, 221]; next[handle]; }; -- variable findNode: PROC[handle: Handle] RETURNS[n: namePtr]= { nPtr: namePtr_ getName[handle]; IF nPtr=NIL THEN RETURN[handle.vars.undefNode] ELSE WITH nPtr.details SELECT FROM x: RefNodeRec => n_ nPtr; x: RefConRec => n_ nPtr; ENDCASE => error[handle, 222]; }; -- findNode getFunction: PROC[handle: Handle, na, np: NAT] RETURNS[args: argNames_ NIL, actual: expressionPtr_ NIL]= { iArg, iParm: NAT_ 0; aname: namePtr; newExpr: expressionPtr; IF handle.vars.item=leftB THEN { next[handle]; IF na > 0 THEN { args_ NEW[namePtrSeq[na]]; args.visited _ FALSE; UNTIL iArg=na DO aname _ getName[handle]; args[iArg]_ aname; IF aname # NIL THEN WITH aname.details SELECT FROM x: RefNodeRec => NULL; x: RefConRec => NULL; ENDCASE => error[handle, 222]; IF handle.vars.item=quote THEN {next[handle]; error[handle, 299]}; iArg_ iArg + 1; IF handle.vars.item=comma THEN next[handle] ELSE EXIT; ENDLOOP; }; IF na=0 OR handle.vars.item=vertical THEN { IF handle.vars.item=vertical THEN next[handle]; UNTIL iParm=np DO newExpr_ expression[handle]; newExpr.next_ actual; actual_ newExpr; iParm_ iParm + 1; IF handle.vars.item=comma THEN next[handle] ELSE EXIT; ENDLOOP; }; IF handle.vars.item=rightB THEN next[handle] ELSE error[handle, 202, , TRUE]; }; IF iArg # na THEN error[handle, 231]; IF iParm # np THEN error[handle, 232]; }; -- getFunction controlFunc: PROC[handle: Handle, thisBranch: namePtr]= { nPtr, f: namePtr; na, np: NAT; bDetails: RefBranchRec_ NARROW[thisBranch.details]; next[handle]; IF handle.vars.item=name THEN { nPtr_ searchName[handle.vars.newString, allLevels, handle.vars.currentCkt]; IF nPtr=NIL THEN { fTableEntry: REF FuncTableBlk = findFunction[RopeFrom.String[handle.vars.newString]]; fDetails: RefFunctionRec_ NEW[FunctionRec_ [branch: thisBranch] ]; f_ NEW[nameBlk_ [details: fDetails]]; fDetails.functionProc _ fTableEntry.proc; fDetails.data _ fTableEntry.data; na _ fTableEntry.numArgs; np _ fTableEntry.numParms; IF fDetails.functionProc=NIL THEN error[handle, 502, FALSE]; next[handle]; bDetails.controller_ f; [fDetails.funcArgs, fDetails.funcParms]_ getFunction[handle, na, np]; fDetails.funcArgVec_ InitArgList[na]; } ELSE WITH nPtr.details SELECT FROM n: RefModelRec => { bDetails.controller_ nPtr; next[handle]; IF handle.vars.item=leftB THEN next[handle] ELSE error[handle, 201,, TRUE]; IF handle.vars.item=number THEN { bDetails.modelIndex_ Real.FixC[handle.vars.value]; IF n.modelResults=NIL THEN {-- unlikely, though IF handle.vars.value > 0 THEN error[handle, 233]} ELSE IF handle.vars.value >= n.modelResults.size THEN error[handle, 233]; next[handle]; } ELSE error[handle, 209]; IF handle.vars.item=rightB THEN next[handle] ELSE error[handle, 202,, TRUE]; }; ENDCASE => error[handle, 223]; } ELSE error[handle, 208]; }; -- controlFunc InitArgList: PROC[size: NAT] RETURNS [a: argList] = { a _ NEW[spGlobals.ValueSeq[size]]; a.visited _ FALSE; a.handle _ NIL; a.modFunc _ NIL; FOR i: NAT IN [0..size) DO a.value[i] _ 0.0; ENDLOOP; }; -- InitArgList enterBranches: PROC[handle: Handle, bName: namePtr, branchKey: keys]= { pNode, nNode: namePtr; bDetails: RefBranchRec; kind: elements; IF handle.vars.item=leftB THEN next[handle] ELSE error[handle, 201,, TRUE]; pNode_ findNode[handle]; IF handle.vars.item=comma THEN next[handle] ELSE error[handle, 200,, TRUE]; nNode_ findNode[handle]; IF handle.vars.item=rightB THEN next[handle] ELSE error[handle, 202,, TRUE]; kind_ SELECT branchKey FROM resKey => resistor, capKey => capacitor, indKey => inductor, vsKey => vSource, isKey => iSource, ENDCASE => nullElement; IF kind=nullElement THEN error[handle, 224, TRUE]; IF pNode=nNode THEN error[handle, 241]; IF bName # NIL THEN -- else error! ... bName.details_ bDetails_ NEW[BranchRec_ [branchType: kind, posNode: pNode, negNode: nNode ] ]; IF handle.vars.item=equal THEN { next[handle]; bDetails.valExpr_ expression[handle]; } ELSE IF handle.vars.item=leftArrow THEN controlFunc[handle, bName] ELSE error[handle, 205]; }; -- enterBranches enterModel: PROC[handle: Handle, mName: namePtr]= { na, np, nr: NAT; IF handle.vars.item=leftArrow THEN next[handle] ELSE error[handle, 210]; IF handle.vars.item=name THEN { mTableEntry: REF ModelTableBlk = findModel[RopeFrom.String[handle.vars.newString]]; mDetails: RefModelRec_ NEW[ModelRec_ []]; mDetails.modelProc _ mTableEntry.proc; mDetails.data _ mTableEntry.data; na _ mTableEntry.numArgs; np _ mTableEntry.numParms; nr _ mTableEntry.numResults; IF mDetails.modelProc=NIL THEN error[handle, 501, FALSE]; next[handle]; [mDetails.modelArgs, mDetails.modelParms]_ getFunction[handle, na, np]; mDetails.modelResults_ InitArgList[nr]; mDetails.modelArgVec _ InitArgList[na]; mDetails.modelOldArgVec _ InitArgList[na]; mName.details_ mDetails; } ELSE error[handle, 208]; }; -- enterModel GetCircuitTree: PROC[ckt: namePtr] RETURNS[r: Rope.ROPE]= { GetTree: PROC[c: namePtr]= { cktDetail: RefCircuitRec_ NARROW[c.details]; IF c # NIL AND cktDetail # NIL AND cktDetail.father # NIL THEN { GetTree[cktDetail.father]; r_ Rope.Cat[r, c.name, "."]; }; }; -- GetTree GetTree[ckt]; }; -- GetCircuitTree getNewParameters: PROC[handle: Handle] RETURNS[plist: namePtr_ NIL]= { n: namePtr; nparms: NAT_ 0; IF handle.vars.item=vertical THEN next[handle]; UNTIL handle.vars.item # name DO n_ enterName[handle]; next[handle]; nparms_ nparms + 1; n.details_ NEW[ParmRec_ [nextParm: plist]]; IF handle.vars.item=leftArrow THEN { ENABLE ErrorSignal => { ErrorStrings[handle, error, GetCircuitTree[handle.vars.currentCkt], s]; CONTINUE; -- GOTO badEnd }; nDetails: RefParmRec _ NARROW[n.details]; next[handle]; nDetails.default _ TRUE; nDetails.dfltValue _ eval[handle, expression[handle]]; }; plist_ n; IF handle.vars.item=comma THEN next[handle] ELSE EXIT; IF handle.vars.item # name THEN error[handle, 208] ENDLOOP; }; -- getNewParameters defineCircuit: PUBLIC PROC[handle: Handle, ckt: namePtr, root: BOOL]= { OPEN handle.vars; exp: expressionPtr; curCktDetails: RefCircuitRec_ NEW[CircuitRec_ [father: currentCkt]]; IF Canned[handle] THEN SIGNAL Aborted; ckt.details_ curCktDetails; currentCkt_ ckt; IF root AND cktRoot=NIL THEN { cktRoot_ currentCkt; undefNode_ NEW[nameBlk_ [name: "Undefined", details: NEW[NodeRec] ] ]; gndNodeName_ NEW[nameBlk_ [name: "Gnd", details: NEW[NodeRec] ] ]; curCktDetails.names_ gndNodeName; next[handle]; }; IF item=leftB THEN { next[handle]; IF ~root AND item # vertical THEN { fakes: namePtr; [fakes, curCktDetails.conCount]_ getNames[handle]; curCktDetails.fakeNodes_ fakes; FOR fn: namePtr_ fakes, fn.nextName UNTIL fn=NIL DO fn.details_ NEW[ConRec]; ENDLOOP; }; IF root OR item=vertical THEN curCktDetails.parms_ getNewParameters[handle]; IF item=rightB THEN next[handle] ELSE error[handle, 202,, TRUE]; }; IF item=name AND searchKey[handle]=assertsKey THEN { next[handle]; IF item=leftB THEN { next[handle]; DO exp_ expression[handle]; exp.next_ curCktDetails.assertions; curCktDetails.assertions_ exp; IF item=comma THEN next[handle] ELSE EXIT; ENDLOOP; IF item=rightB THEN next[handle] ELSE error[handle, 202,, TRUE]; } ELSE error[handle, 201]; }; IF item=equal THEN next[handle] ELSE error[handle, 205, TRUE, TRUE]; IF item=leftC THEN next[handle] ELSE error[handle, 203, TRUE, FALSE]; DO IF item=name THEN enterDefinition[handle]; IF item=rightC OR item= eof THEN EXIT; IF item=semi THEN next[handle] ELSE error[handle, 206, TRUE, FALSE]; ENDLOOP; curCktDetails_ NARROW[currentCkt.details]; currentCkt_ curCktDetails.father; next[handle]; }; -- defineCircuit getActualParameters: PROC[handle: Handle, ckt: namePtr] RETURNS[apList: expressionPtr_ NIL]= { e: expressionPtr; IF handle.vars.item=vertical THEN next[handle]; IF handle.vars.item=rightB THEN RETURN; DO IF handle.vars.item # name THEN GOTO nameErr; e_ assignExpr[handle, ckt]; e.next_ apList; apList_ e; IF handle.vars.item=comma THEN next[handle] ELSE EXIT; REPEAT nameErr => error[handle, 208]; ENDLOOP; }; -- getActualParameters defCktInstance: PROC[handle: Handle, cn: REF TEXT, iName: namePtr]= { cktName: namePtr; n: namePtr; cons: conLinkPtr_ NIL; cCnt: NAT_ 0; noConnections: BOOL; actuals: expressionPtr_ NIL; cktName_ searchName[cn, allLevels, handle.vars.currentCkt]; IF cktName # NIL THEN WITH cktName.details SELECT FROM c: RefCircuitRec => { IF handle.vars.item=leftB THEN { next[handle]; noConnections_ (c.conCount=0); IF ~noConnections THEN WHILE handle.vars.item=name DO n_ findNode[handle]; cons_ NEW[conLink_ [nextLink: cons, namedNode: n]]; cCnt_ cCnt + 1; IF handle.vars.item=comma THEN next[handle] ELSE EXIT; ENDLOOP; IF noConnections OR handle.vars.item=vertical THEN actuals_ getActualParameters[handle, cktName]; IF handle.vars.item=rightB THEN next[handle] ELSE error[handle, 202,, TRUE]; }; IF cCnt # c.conCount THEN error[handle, 260]; iName.details_ NEW[CktInstance_ [of: cktName, connections: cons, actualParms: actuals] ]; }; ENDCASE => error[handle, 225, TRUE] ELSE error[handle, 251, TRUE]; }; -- defCktInstance enterDefinition: PROC[handle: Handle]= { key: keys; nameCount: NAT; nPtr: namePtr; s: REF TEXT_ RefText.New[256]; explodeExpr: expressionPtr_ NIL; [nPtr, nameCount]_ getNames[handle]; IF nPtr=NIL THEN error[handle, 208]; IF handle.vars.item # colon THEN error[handle, 207,, TRUE] ELSE next[handle]; IF handle.vars.item=leftP THEN { explodeExpr_ expression[handle]; IF nPtr # NIL THEN nPtr.expExpr_ explodeExpr; IF handle.vars.item=implies THEN next[handle] ELSE error[handle, 215,, TRUE]; }; IF handle.vars.item=name THEN { key_ searchKey[handle]; s.length_ 0; s_ RefText.Append[s, handle.vars.newString]; next[handle]; IF key # nodeKey AND nameCount # 1 THEN error[handle, 261]; SELECT key FROM nodeKey => { IF nPtr.expExpr # NIL THEN error[handle, 253]; UNTIL nPtr=NIL DO nPtr.details_ NEW[NodeRec]; nPtr_ nPtr.nextName; ENDLOOP; }; resKey, capKey, indKey, vsKey, isKey => enterBranches[handle, nPtr, key]; circuitKey => { IF nPtr.expExpr # NIL THEN error[handle, 253]; defineCircuit[handle: handle, ckt: nPtr, root: FALSE]; }; modelKey => { IF nPtr.expExpr # NIL THEN error[handle, 253]; enterModel[handle, nPtr]; }; ENDCASE => defCktInstance[handle, s, nPtr]; } ELSE error[handle, 208, TRUE] }; -- enterDefinition levelSpace: PROC[stream: IO.STREAM, level: NAT]= { UNTIL level=0 DO stream.PutF[" "]; level_ level - 1 ENDLOOP }; -- levelSpace output: PUBLIC PROC[handle: Handle, ckt: namePtr, level: NAT]= { cLink: conLinkPtr; np: namePtr; cktDetails: RefCircuitRec_ NARROW[ckt.details]; np_ cktDetails.names; UNTIL np=NIL DO levelSpace[handle.msgStream, level]; handle.msgStream.PutF["%g", IO.rope[np.name]]; WITH np.details SELECT FROM n: RefNodeRec => NULL; n: RefBranchRec => handle.msgStream.PutF[": branch[%s, %s]", IO.rope[n.posNode.name], IO.rope[n.negNode.name]]; n: RefCircuitRec => { handle.msgStream.PutF[": circuit.\n"]; output[handle, np, level + 1]; }; n: RefConRec => NULL; n: RefParmRec => { handle.msgStream.PutF[": parameter"]; IF n.default THEN handle.msgStream.PutF["_ %13.5f", IO.real[n.dfltValue]]; }; n: RefCktInstRec => { handle.msgStream.PutF[": %g[", IO.rope[n.of.name]]; cLink_ n.connections; UNTIL cLink=NIL DO handle.msgStream.PutF["%g", IO.rope[cLink.namedNode.name]]; cLink_ cLink.nextLink; IF cLink # NIL THEN handle.msgStream.PutF[", "] ENDLOOP; handle.msgStream.PutF["]"] }; ENDCASE; np_ np.srchLink; handle.msgStream.PutF[".\n"]; ENDLOOP; }; -- output END. File: [Cherry]Cedar5.2>System>spInput.mesa Last Edited by: SChen, May 17, 1985 4:50:11 pm PDT enter a (one level unique) name string to the search link of currentCkt enter (unique) name strings on the current circuits search link search RefNodeRec or RefConRec with name newString on all levels of currentCkt get na arguments and np parameters(expressions) arguments parameters get values for other fields in f.details, and assign f as the controller for this branch: enter (uniquie) connection names on currentCkt CHANGE LOG Wilhelm April 6, 1982 9:59 AM Barth, 7-May-82 12:20:02 PDT Chen, February 12, 1984 7:57 PM, to support oldArgVector. Chen, June 10, 1984 8:54:05 pm PDT, cedarized. 82 "cedar" styleJ"mycedar" style11J"mycedar" style22J"mycedar" style"mycedar" stylek J"mycedar" style$J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style  J"mycedar" style J"mycedar" styleJ"mycedar" style - bJ"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" style EJ"mycedar" styleGGJ"mycedar" style "mycedar" style-9J"mycedar" style9"mycedar" style  J"mycedar" styleCCJ"mycedar" style!!J"mycedar" styleJ"mycedar" styleJ"mycedar" stylec J"mycedar" style"mycedar" style  ;J"mycedar" style''J"mycedar" style+J"mycedar" style%J"mycedar" styleJ"mycedar" styleJ"mycedar" style1"mycedar" style J"mycedar" style (J"mycedar" styleJ"mycedar" style "mycedar" style J"mycedar" style(:J"mycedar" styleJ"mycedar" style""J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style"mycedar" style"mycedar" style"mycedar" styleJ"mycedar" style++J"mycedar" style''J"mycedar" styleJ"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" style  QJ"mycedar" style??J"mycedar" style"mycedar" style J"mycedar" style"mycedar" style'J"mycedar" styleJ"mycedar" style J"mycedar" styleJ"mycedar" styleJ"mycedar" style J"mycedar" style8J"mycedar" style2J"mycedar" styleJ"mycedar" style J"mycedar" style"mycedar" style