--File SimParser.Mesa
--January 1980 by MN
--Updated: August 19, 1981 10:01 AM
--Program to parse output from MIT’s circuit extractor
DIRECTORY
IODefs: FROM "IODefs" USING[CR, LF, TAB, SP, WriteChar, WriteLine,
WriteString, WriteDecimal, GetOutputStream, SetOutputStream],
SimMOSDefs: FROM "SimMOSDefs" USING [ETrans, DTrans, Transistor,
EnumerateETrans, EnumerateDTrans, NodeNames],
SimParserDefs: FROM "SimParserDefs",
StreamDefs: FROM "StreamDefs" USING [StreamHandle],
StringDefs: FROM "StringDefs" USING [AppendChar, AppendString, AppendLongDecimal,
EqualString, StringBoundsFault],
SystemDefs: FROM "SystemDefs" USING [AllocateHeapString, FreeHeapString];
SimParser: PROGRAM
IMPORTS IODefs, SimMOSDefs, StringDefs, SystemDefs
EXPORTS SimParserDefs =
BEGIN OPEN IODefs, SimMOSDefs, SimParserDefs, StreamDefs, StringDefs, SystemDefs;
Line: STRING ← [256];
LineCount: CARDINAL;
ErrorCount: CARDINAL;
Index: CARDINAL;
TokenArray: ARRAY [0..maxTokens) OF STRING;
maxTokens: CARDINAL = 10;
nTokens: CARDINAL;
FileName: STRING ← [80];
InStream: StreamHandle;
SimRead: PUBLIC PROCEDURE[s: StreamHandle]
RETURNS[errorCount: CARDINAL] =
--Scan Sim document on stream s
BEGIN
gotone: BOOLEAN;
nETrans: LONG CARDINAL ← 0;
nDTrans: LONG CARDINAL ← 0;
InStream ← s;
InitScanner[];
UNTIL InStream.endof[InStream] DO
ReadLine[];
nTokens ← 0;
THROUGH [0..maxTokens) DO
gotone ← ReadToken[nTokens];
IF ~gotone THEN EXIT;
nTokens ← nTokens + 1;
ENDLOOP;
IF nTokens=0 THEN LOOP;
SELECT TRUE FROM
EqualString[TokenArray[0],"e"] =>
BEGIN
IF nTokens<4 THEN
BEGIN
Error["At least 3 parameters expected"];
LOOP;
END;
[] ← ETrans[TokenArray[1],TokenArray[2],TokenArray[3]];
nETrans ← nETrans + 1;
END;
EqualString[TokenArray[0],"d"] =>
BEGIN
IF nTokens<4 THEN
BEGIN
Error["At least 3 parameters expected"];
LOOP;
END;
[] ← DTrans[TokenArray[1],TokenArray[2],TokenArray[3]];
nDTrans ← nDTrans + 1;
END;
EqualString[TokenArray[0],"N"],
EqualString[TokenArray[0],"="],
EqualString[TokenArray[0],"|"],
EqualString[TokenArray[0],"C"],
EqualString[TokenArray[0],"i"] => NULL;
ENDCASE => Error["Unknown keyword"];
IF (nETrans+nDTrans) MOD 1000 = 0 THEN
BEGIN
WriteLongDecimal[nETrans+nDTrans];
IF (nETrans+nDTrans) MOD 5000 = 0 THEN WriteChar[CR];
END
ELSE IF (nETrans+nDTrans) MOD 100 = 0 THEN WriteChar[’.];
ENDLOOP;
WriteChar[CR];
WriteLongDecimal[nETrans]; WriteLine[" enhancement mode transistors"];
WriteLongDecimal[nDTrans]; WriteLine[" depletion mode transistors"];
RETURN[ErrorCount];
END;
SimWrite: PUBLIC PROCEDURE[s: StreamHandle] =
--Write Sim document onto stream s for subsequent SimRead
BEGIN
transtype: CHARACTER;
savestream: StreamHandle ← GetOutputStream[];
WriteTransistor: PROCEDURE[t: Transistor] RETURNS[BOOLEAN] =
BEGIN
g: STRING ← [50];
s: STRING ← [50];
d: STRING ← [50];
NodeNames[t,g,s,d];
WriteChar[transtype]; WriteChar[SP];
WriteString[g]; WriteChar[SP];
WriteString[s]; WriteChar[SP];
WriteLine[d];
RETURN[FALSE];
END;
SetOutputStream[s];
transtype ← ’e; [] ← EnumerateETrans[WriteTransistor];
transtype ← ’d; [] ← EnumerateDTrans[WriteTransistor];
SetOutputStream[savestream];
END;
InitScanner: PROCEDURE =
BEGIN
LineCount ← 0;
Line.length ← 0;
ErrorCount ← 0;
END;
ReadLine: PROCEDURE =
BEGIN
--Read line up to CR
ch: CHARACTER;
Line.length ← Index ← 0;
UNTIL InStream.endof[InStream] DO
ch ← InStream.get[InStream];
SELECT ch FROM
CR =>BEGIN
LineCount ← LineCount + 1;
EXIT;
END;
LF =>LOOP;
ENDCASE =>
BEGIN
IF Line.length<Line.maxlength
THENAppendChar[Line,ch]
ELSEBEGIN
Error["Line too long"]; --boo
UNTIL InStream.endof[InStream] DO
IF ch=CR
THENBEGIN
LineCount ← LineCount + 1;
EXIT;
END;
ENDLOOP;
END;
END;
ENDLOOP;
END;
Error: PROCEDURE[s: STRING] =
BEGIN
WriteString["*** Error in line "]; WriteDecimal[LineCount];
WriteString[" - "]; WriteLine[s];
WriteLine[Line];
ErrorCount ← ErrorCount + 1;
END;
ReadToken: PROCEDURE[i: CARDINAL] RETURNS[GotOne: BOOLEAN] =
BEGIN
left: CARDINAL;
TokenArray[i].length ← 0;
IF Index>=Line.length THEN RETURN[FALSE];
UNTIL ~Delim[Line[Index]] DO
Index ← Index + 1;
IF Index>=Line.length THEN RETURN[FALSE];
ENDLOOP;
left ← Index;
AppendChar[TokenArray[i],Line[Index]];
DO
Index ← Index + 1;
IF Index>=Line.length OR Delim[Line[Index]]
THEN RETURN[TRUE];
AppendChar[TokenArray[i],Line[Index] ! StringBoundsFault =>
BEGIN
ns ← AllocateHeapString[s.length*2];
AppendString[ns,s];
FreeHeapString[s];
TokenArray[i] ← ns;
RESUME[ns];
END];
ENDLOOP;
END;
Delim: PROCEDURE[ch: CHARACTER] RETURNS[BOOLEAN] =
BEGIN
RETURN[ch=SP OR ch=TAB];
END;
WriteLongDecimal: PROCEDURE[n: LONG INTEGER] =
BEGIN
s: STRING ← [20];
AppendLongDecimal[s,n];
WriteString[s];
END;
--START code
i: CARDINAL;
FOR i IN [0..maxTokens) DO TokenArray[i] ← AllocateHeapString[20]; ENDLOOP;
END.