DIRECTORY Ascii USING [ControlZ, CR, SP, TAB, Upper], IO USING [Close, EndOf, Flush, GetChar, int, PutF, PutFR, rope, STREAM], FS USING [ComponentPositions, Error, ExpandName, maxFNameLength, StreamOpen], RefText USING [AppendChar, AppendRope, New, ObtainScratch, ReleaseScratch, TrustTextAsRope], Rope USING [Concat, Equal, Fetch, Find, IsEmpty, Length, ROPE, Substr], RopeFrom USING [String], spGlobals USING [error, Handle, itemType, keys, maxInclude, PutMsgLine], TypeScript USING [ChangeLooks], ViewerTools USING [GetContents, SetContents]; spGlobalsImpl: CEDAR PROGRAM IMPORTS Ascii, IO, FS, RefText, Rope, RopeFrom, spGlobals, TypeScript, ViewerTools EXPORTS spGlobals= BEGIN Handle: TYPE= spGlobals.Handle; Aborted: PUBLIC SIGNAL = CODE; keyList: ARRAY spGlobals.keys OF Rope.ROPE_ [ "node", "resistor", "capacitor", "inductor", "voltage", "current", "run", "print", "circuit", "model", "plot", "ic", "dump", "asserts", "checkpoint", "library", ""]; openInputFile: PUBLIC PROC[handle: Handle] = { OPEN handle.vars; RemoveFunnyChars: PROC[old: Rope.ROPE] RETURNS [new: Rope.ROPE _ NIL] = { name: REF TEXT _ RefText.New[FS.maxFNameLength]; c: CHAR; hasFunnyChar: BOOL _ FALSE; name.length _ 0; FOR i: INT IN [0..old.Length[]) DO c _ old.Fetch[i]; SELECT c FROM IN['0..'9], IN['a..'z], IN['A..'Z], '$, '-, '+, '' , '[, '], '<, '>, '., '!, '#, '/ => name _ RefText.AppendChar[name, c]; ENDCASE => hasFunnyChar _ TRUE; IF name.length >= FS.maxFNameLength THEN EXIT; ENDLOOP; IF hasFunnyChar THEN { new _ RopeFrom.String[name]; ViewerTools.SetContents[handle.input, new]; } ELSE new _ old; }; -- RemoveCtrlChars inputName, fullInputName: Rope.ROPE; inputName _ RemoveFunnyChars[ViewerTools.GetContents[handle.input]]; inputName _ EnsureExtension[inputName, "thy"]; [fullInputName, ]_ FS.ExpandName[inputName, WorkingDirectory[handle]]; inStream_ FS.StreamOpen[fullInputName]; }; -- openInputFile EnsureExtension: PROC[old, ext: Rope.ROPE] RETURNS[Rope.ROPE]= { -- does nothing if old name has '! in it. IF Rope.Find[old, "!"] >= 0 THEN RETURN[old] ELSE { realExt: Rope.ROPE _ Rope.Concat[".", ext]; dotPos, extStart: INT _ old.Find["."]; UNTIL dotPos <= 0 OR dotPos+1 >= old.Length[] DO dotPos _ old.Find[".", dotPos+1]; IF dotPos >= 0 THEN extStart _ dotPos; ENDLOOP; IF extStart >= 0 THEN extStart_ old.Find[realExt, extStart, FALSE]; IF extStart >= 0 AND extStart + realExt.Length[] = old.Length[] THEN RETURN[old] ELSE RETURN[IO.PutFR["%g.%g", IO.rope[old], IO.rope[ext]]]; }; }; -- EnsureExtension OutputFileRoot: PUBLIC PROC[handle: Handle] RETURNS[Rope.ROPE]= { fullName: Rope.ROPE; inputName: Rope.ROPE _ EnsureExtension[ViewerTools.GetContents[handle.input], "thy"]; c: FS.ComponentPositions; workDir: Rope.ROPE _ WorkingDirectory[handle]; [fullName, c]_ FS.ExpandName[inputName, workDir]; RETURN[Rope.Concat[workDir, Rope.Substr[fullName, c.base.start, c.base.length]]]; }; -- OutputFileRoot WorkingDirectory: PUBLIC PROC[handle: Handle] RETURNS [dir: Rope.ROPE] = { dir _ ViewerTools.GetContents[handle.wDir]; IF dir.IsEmpty[] THEN { dir _ "///Thyme/"; ViewerTools.SetContents[handle.wDir, dir]; }; }; -- WorkingDirectory includeFile: PROC[handle: Handle]= {OPEN handle.vars; fname: REF TEXT_ RefText.ObtainScratch[128]; fname.length_ 0; nextChar[handle, TRUE]; UNTIL fname.length=128 OR char=Ascii.TAB OR char=Ascii.CR OR char=Ascii.SP DO fname_ RefText.AppendChar[fname, char]; nextChar[handle, FALSE]; ENDLOOP; IF fileStackTop < spGlobals.maxInclude THEN { fileName: Rope.ROPE_ EnsureExtension[RopeFrom.String[fname], "thy"]; fullName: Rope.ROPE; [fullName, ]_ FS.ExpandName[fileName, WorkingDirectory[handle] ! FS.Error => { spGlobals.error[handle, 103, FALSE]; handle.msgStream.PutF[" %g\n", IO.rope[error.explanation]]; GOTO fileError; } ]; fileStack[fileStackTop]_ inStream; fileStackTop_ fileStackTop + 1; inStream_ FS.StreamOpen[fullName ! FS.Error => { spGlobals.error[handle, 103, FALSE]; fileStackTop _ fileStackTop - 1; inStream_ fileStack[fileStackTop]; GOTO fileError; } ]; EXITS fileError => NULL; } ELSE spGlobals.error[handle, 104, FALSE]; RefText.ReleaseScratch[fname]; next[handle]; }; -- includeFile FlushCloseNil: PUBLIC PROC[stream: IO.STREAM] RETURNS [IO.STREAM _ NIL] = { IF stream # NIL THEN { stream.Flush[ ]; stream.Close[ ]; }; }; -- FlushCloseNil CloseNil: PUBLIC PROC[stream: IO.STREAM] RETURNS [IO.STREAM _ NIL] = { IF stream # NIL THEN stream.Close[ ]; }; -- CloseNil MsgTextsWithLook: PUBLIC PROC[handle: Handle, text: Rope.ROPE, look: CHAR['a..'z]]= { TypeScript.ChangeLooks[handle.message, look]; handle.msgStream.PutF[text]; TypeScript.ChangeLooks[handle.message, Ascii.Upper[look]]; }; -- MsgTextsWithLook popIncludeFile: PROC[handle: Handle]= {OPEN handle.vars; IF fileStackTop > 0 THEN { fileStack[fileStackTop] _ CloseNil[inStream]; fileStackTop_ fileStackTop - 1; inStream_ fileStack[fileStackTop]; nextChar[handle, FALSE]; next[handle]; } ELSE item_ eof; }; -- popIncludeFile newLine: PROC[handle: Handle]= {OPEN handle.vars; cptr_ 0; line.length_ 0; DO char_ IF inStream.EndOf[ ] THEN Ascii.ControlZ ELSE inStream.GetChar[ ]; IF char=Ascii.ControlZ OR char=Ascii.CR THEN EXIT; line_ RefText.AppendChar[line, char]; ENDLOOP; -- MsgTextsWithLook[handle, RopeFrom.String[line], 'p]; -- handle.msgStream.PutF["\n"]; spGlobals.PutMsgLine[handle, RopeFrom.String[line]]; line_ RefText.AppendChar[line, char]; IF char=Ascii.ControlZ THEN line_ RefText.AppendChar[line, Ascii.CR]; }; -- newLine nextChar: PROC[handle: Handle, skip: BOOLEAN]= { DO OPEN handle.vars; IF cptr >= line.length THEN newLine[handle]; char_ line[cptr]; cptr_ cptr + 1; IF char # Ascii.SP THEN EXIT; IF ~skip THEN EXIT; ENDLOOP }; -- nextChar scaleFactor: PROC[handle: Handle] RETURNS[s: INT]= { s_ SELECT handle.vars.char FROM 'M => 6, 'k => 3, 'K => 3, 'c => -2, 'm => -3, 'u => -6, 'n => -9, 'p => -12, ENDCASE => 0; IF s # 0 THEN nextChar[handle, FALSE]; SELECT handle.vars.char FROM 'F, 'H, 'V, 'A, 's => nextChar[handle, TRUE]; ENDCASE }; -- scaleFactor next: PUBLIC PROC[handle: Handle]= {OPEN handle.vars; minusExp, validReal: BOOLEAN_ FALSE; exp: INTEGER_ 0; f1, f10: REAL; MoveOnWithNewItem: PROC[c: CHAR]= { -- "MoveOn" means: get next char in input file, skipping blanks. item_ SELECT c FROM '{ => leftC, '} => rightC, '[ => leftB, '] => rightB, '( => leftP, ') => rightP, ': => colon, '; => semi, ', => comma, '' => quote, '_ => leftArrow, '^ => upArrow, '/ => slash, '| => vertical, '\\ => backSlash, '+ => plus, '~ => squiggle, '@ => atSign, '* => star, '& => amperesand, '# => pound, ENDCASE => nullItem; IF item=nullItem THEN spGlobals.error[handle, 100, FALSE]; nextChar[handle, TRUE]; }; -- MoveOnWithNewItem SELECT char FROM Ascii.ControlZ => popIncludeFile[handle]; '! => includeFile[handle]; Ascii.TAB, Ascii.SP, Ascii.CR => {nextChar[handle, TRUE]; next[handle]}; '{, '}, '[, '], '(, '), ':, ';, ',, '', '_, '^, '/, '|, '\\, '+, '~, '@, '*, '&, '# => MoveOnWithNewItem[char]; '= => {nextChar[handle, FALSE]; IF char='> THEN {item_ implies; nextChar[handle, TRUE]} ELSE item_ equal; }; '- => {item_ minus; nextChar[handle, FALSE]; IF char='- THEN { UNTIL char=Ascii.CR OR char=Ascii.ControlZ DO nextChar[handle, TRUE]; IF char='- THEN { nextChar[handle, FALSE]; IF char='- THEN {nextChar[handle, TRUE]; EXIT}; }; ENDLOOP; next[handle]; }; }; '> => {nextChar[handle, FALSE]; IF char='= THEN {item_ greatEqual; nextChar[handle, TRUE]} ELSE item_ greater; }; '< => {nextChar[handle, FALSE]; IF char='= THEN {item_ lessEqual; nextChar[handle, TRUE]} ELSE item_ less; }; '" => {item_ string; newString.length_ 0; DO nextChar[handle, FALSE]; IF char=Ascii.ControlZ THEN {spGlobals.error[handle, 213, FALSE]; EXIT}; IF char='" THEN { nextChar[handle, FALSE]; IF char # '" THEN EXIT }; newString_ RefText.AppendChar[newString, char]; ENDLOOP; }; '? => {newString.length_ 0; newString_ RefText.AppendRope[newString, IO.PutFR["?%g", IO.int[genSymCtr]] ]; genSymCtr_ genSymCtr + 1; item_ name; nextChar[handle, TRUE]; }; '$ => {nextChar[handle, FALSE]; newString.length_ 0; UNTIL char='$ DO IF char=Ascii.ControlZ THEN {spGlobals.error[handle, 214, FALSE]; EXIT}; newString_ RefText.AppendChar[newString, char]; nextChar[handle, FALSE] ENDLOOP; nextChar[handle, TRUE]; item_ name; }; IN ['A..'Z], IN ['a..'z] => { newString.length_ 0; UNTIL ~(char IN ['A..'Z] OR char IN ['a..'z] OR char IN ['0..'9]) DO newString_ RefText.AppendChar[newString, char]; nextChar[handle, FALSE]; ENDLOOP; IF Rope.Equal[RefText.TrustTextAsRope[newString], "MAX", FALSE] THEN {item_ maximum; GOTO done} ELSE IF Rope.Equal[RefText.TrustTextAsRope[newString], "MIN", FALSE] THEN {item_ minimum; GOTO done} ELSE item_ name; EXITS done => IF char=Ascii.SP OR char=Ascii.CR OR char=Ascii.TAB THEN nextChar[handle, TRUE]; }; '., IN ['0..'9] => { item_ number; value_ 0.0; WHILE char IN ['0..'9] DO validReal_ TRUE; value_ value*10.0 + (char - '0); nextChar[handle, FALSE] ENDLOOP; IF char='. THEN { nextChar[handle, FALSE]; f10_ 0.1; WHILE char IN ['0..'9] DO validReal_ TRUE; value_ value + f10*(char - '0); f10_ 0.1*f10; nextChar[handle, FALSE] ENDLOOP }; IF char='e OR char='E THEN { nextChar[handle, FALSE]; minusExp_ (char='-); IF minusExp OR (char='+) THEN nextChar[handle, FALSE]; IF char IN ['0..'9] THEN { WHILE char IN ['0..'9] DO exp_ exp*10 + (char - '0); nextChar[handle, FALSE]; ENDLOOP; } ELSE validReal_ FALSE; IF minusExp THEN exp_ -exp; }; exp_ exp + scaleFactor[handle]; validReal_ validReal AND (exp < 37) AND (exp > -37); IF validReal THEN { f1_ 1.0E+1; f10_ 1.0E+10; IF exp < 0 THEN {f1_ 1.0/f1; f10_ 1.0/f10; exp_ -exp }; UNTIL exp < 10 DO value_ value*f10; exp_ exp - 10 ENDLOOP; UNTIL exp=0 DO value_ value*f1; exp_ exp - 1 ENDLOOP } ELSE spGlobals.error[handle, 102, FALSE]; }; ENDCASE => { nextChar[handle, TRUE]; spGlobals.error[handle, 101, FALSE]; }; }; -- next getSignedNumber: PUBLIC PROC[handle: Handle] RETURNS[n: REAL_ 1.0]= { negative: BOOLEAN_ (handle.vars.item=minus); IF negative THEN next[handle]; IF handle.vars.item=number THEN { n_ IF negative THEN -handle.vars.value ELSE handle.vars.value; next[handle] } ELSE spGlobals.error[handle, 105, FALSE]; }; -- getSignedNumber searchKey: PUBLIC PROC[handle: Handle] RETURNS[index: spGlobals.keys]= { FOR i: spGlobals.keys IN spGlobals.keys DO index_ i; IF Rope.Equal[ RefText.TrustTextAsRope[handle.vars.newString], keyList[i], FALSE] THEN EXIT; ENDLOOP; }; -- searchKey GetLineAndCptr: PUBLIC PROC[handle: Handle] RETURNS[Rope.ROPE, NAT]= { RETURN[RopeFrom.String[handle.vars.line], handle.vars.cptr]}; END. ΄File: [Cherry]Cedar5.2>System>spGlobalsimpl.mesa Last Edited by: SChen, September 18, 1984 12:38:04 pm PDT Current Cedar doesn't seem to support PutF with looks CHANGE LOG Wilhelm, April 27, 1982 4:05 PM Barth, 7-May-82 11:00:25 PDT Chen, April 19, 1983 1:45 PM, modified "next" to support min and max operations. Chen, February 12, 1984 7:56 PM, to support oldArgVector. Chen, June 11, 1984 7:34:25 pm PDT, cedarized. ΚŸ–"mycedar" style˜J–"mycedar" stylešœ7™7J–"mycedar" stylešœ9™9–"mycedar" stylešςœΟk œ œ œœœ œœ8œœœPœWœ/œœœGœœ/œœœœœ@œ œ œœœœ œœœΐœœœΟnœœ œœ œœœœœœœœœœœœœœ œ œ œsœœœœœœœœœdœΟcœ"œœ?œ!ŸœžœœœœœŸ)œœœœœœ0œœ œœ/œ œœœœ'œœœ,œœ œœœœ œŸœžœœœœœœœGœ%œ.œ#œQŸœžœœœœ œ6œœUŸœœœœœDœœœ œœ œœ œœBœœœ%œœEœœ7œ1œ*œ#œrœœ1œ_œœœ œœ9Ÿœž œœœ œœœœœœœ œœ9Ÿœžœœœ œœœœœœœ œœŸ žœœœœœ ˜΄&Jšœ5™5J–"mycedar" style˜-J–"mycedar" stylešœ˜J–"mycedar" stylešœ:˜:J–"mycedar" stylešœŸœ˜—J–"mycedar" stylešϋœœœœœ•œœŸœ œœ-œ œœœœœ œœœ.œΏœœ&œŸ œ œœœœœœ@œœœœœœœœŸ œœœœ œœŒœ œœœœœ,œœŸœœœœ%œœ œœžœœœŸAœ œœώœœœœœ ŸœœœZœœœœ­œœ œ"œœQœœ œœ œœœ!œœ œ%œœ œœœ$œYœœ œ%œœ;œœ œ$œœ`œœœœ.œœœ œ#œœ œœ[œsœœlœ.œ.œ œœœœœ^œ œœ-œ œ:œœ œœ œœ œ\œœ œ7œœœœœ7œœœœœœ œœ œœ#œœœœJœœ œœNœ œ œ œ!œ'œœ œœnœœœ œ œ!œ2œ œ œœœœ œœœ œOœœ œ œœ œgœ œœ œ7œ œ6œ œ!œœœœœœœœ$œŸœœœœœœœ œœœ œ œœ-œœŸœ œœœœœœœUœœœœŸ œžœœœœœœœ9œ˜˜;J–"mycedar" style˜J–"mycedar" stylešœ ™ J–"mycedar" stylešœ ™ J–"mycedar" stylešœ™J–"mycedar" stylešœQ™QJ–"mycedar" stylešœ:™:J–"mycedar" stylešœ.™.J–"mycedar" style˜—…—1n;Α