DIRECTORY Atom, CD, CDDirectory, CDExpr, CDIO, PW, PWPLABasics, BoolOps, Rope, IO, FS, SymTab, TerminalIO; PWPLABasicsImpl: CEDAR PROGRAM IMPORTS Atom, BoolOps, CDDirectory, CDExpr, CDIO, FS, IO, PW, Rope, TerminalIO EXPORTS PWPLABasics SHARES CDDirectory = BEGIN OPEN PWPLABasics; Error: PUBLIC ERROR[ec: ErrorCode, msg: ROPE] ~ CODE; GetTile: PROC[from: CD.Design, name1, name2, name3: ROPE _ NIL, required: BOOL] RETURNS [obj: CD.Object] = BEGIN obj _ SELECT TRUE FROM IsPresent[from, name1] => PW.Get[from, name1], IsPresent[from, name2] => PW.Get[from, name2], IsPresent[from, name3] => PW.Get[from, name3], ENDCASE => NIL; IF obj = NIL AND required THEN BEGIN TerminalIO.PutF["PWPLA could not find tile '%g'", IO.rope[name1]]; IF name2 # NIL THEN TerminalIO.PutF[" nor '%g'", IO.rope[name2]]; IF name3 # NIL THEN TerminalIO.PutF[" nor '%g'", IO.rope[name3]]; TerminalIO.PutF[".\n'"]; ERROR Error[MissingTile, NIL]; END; END; IsPresent: PROC [whereTilesAre: CD.Design, name: ROPE] RETURNS [BOOL] = {RETURN [CDDirectory.Fetch[whereTilesAre, name]#NIL]}; AllPresent: PUBLIC PROC [list: LIST OF CD.Object] RETURNS [b: BOOL _ TRUE] = {WHILE list#NIL DO b _ b AND list.first#NIL; list _ list.rest; ENDLOOP}; RequiredTile: PUBLIC PROC [from: CD.Design, name1, name2, name3: ROPE _ NIL] RETURNS [CD.Object] = {RETURN[GetTile[from, name1, name2, name3, TRUE]]}; OptionalTile: PUBLIC PROC [from: CD.Design, name1, name2, name3: ROPE _ NIL] RETURNS [CD.Object] = {RETURN[GetTile[from, name1, name2, name3, FALSE]]}; ListRefAnyToListRope: PUBLIC PROC [list: LIST OF REF] RETURNS [LIST OF ROPE] = BEGIN RETURN[IF list=NIL THEN NIL ELSE CONS[NARROW[list.first], ListRefAnyToListRope[list.rest]]]; END; ListRefAnyToListOfListRope: PUBLIC PROC [list: LIST OF REF] RETURNS [llr: LIST OF LIST OF ROPE] = BEGIN IF list=NIL THEN RETURN[NIL]; llr _ CONS[ ListRefAnyToListRope[NARROW[list.first, LIST OF REF]], ListRefAnyToListOfListRope[list.rest]]; END; Length: PUBLIC PROC [list: LIST OF ROPE] RETURNS [length: INT _ 0] = BEGIN WHILE list # NIL DO length _ length+1; list _ list.rest; ENDLOOP; END; EnsureSize: PUBLIC PROC [list: LIST OF ROPE, quantity: INT] = {IF Length[list] # quantity THEN ERROR}; GetEQN: PUBLIC PROC[par: SymTab.Ref, inNames, outNames: LIST OF ROPE] RETURNS[BoolOps.TruthTable] = BEGIN tt: BoolOps.TruthTable; inAtoms, reverseAtoms: LIST OF ATOM _ NIL; eqnTrees, reversedEqnTrees: LIST OF BoolOps.Tree _ NIL; message: ROPE; allErrorMessages: ROPE _ NIL; IF inNames = NIL OR outNames = NIL THEN ERROR Error[ParameterErrors, "Both 'Inputs' and 'Outputs' must be specified."]; FOR outs: LIST OF ROPE _ outNames, outs.rest WHILE outs # NIL DO eqn: ROPE _ NIL; t: BoolOps.Tree _ NIL; eqn _ CDExpr.FetchRope[par, outs.first].val; IF eqn = NIL THEN { allErrorMessages _ Rope.Cat[allErrorMessages, "Equation for output '", outs.first, "' is missing.\n"]; }; FOR i: INT DECREASING IN [0 .. Rope.Length[eqn]) DO -- remove trailing semicolon ch: CHAR _ Rope.Fetch[eqn, i]; IF ch # ' AND ch # '\t AND ch # '\n THEN { IF ch = '; AND i > 0 THEN eqn _ Rope.Substr[eqn, 0, i]; EXIT; }; ENDLOOP; message _ NIL; t _ BoolOps.RopeToTree[eqn ! BoolOps.Error => {message _ msg; CONTINUE}]; IF message # NIL THEN allErrorMessages _ Rope.Cat[allErrorMessages, "Could not translate equation for output '", outs.first, Rope.Cat["', error was: ", message, "\n"]] ELSE { message _ NIL; t _ BoolOps.TreeToSOP[t ! BoolOps.Error => {message _ msg; CONTINUE}]; IF message # NIL THEN allErrorMessages _ Rope.Cat[allErrorMessages, "Could not translate output '", outs.first, Rope.Cat["' to sum-of-products form, error was: ", message, "\n"]] ELSE { reversedEqnTrees _ CONS[t, reversedEqnTrees]; }; }; ENDLOOP; IF ~Rope.Equal[allErrorMessages, NIL] THEN ERROR Error[ParameterErrors, allErrorMessages]; FOR trees: LIST OF BoolOps.Tree _ reversedEqnTrees, trees.rest WHILE trees # NIL DO eqnTrees _ CONS[trees.first, eqnTrees]; ENDLOOP; FOR ins: LIST OF ROPE _ inNames, ins.rest WHILE ins # NIL DO reverseAtoms _ CONS[Atom.MakeAtom[ins.first], reverseAtoms]; ENDLOOP; FOR ins: LIST OF ATOM _ reverseAtoms, ins.rest WHILE ins # NIL DO inAtoms _ CONS[ins.first, inAtoms]; ENDLOOP; message _ NIL; tt _ BoolOps.SOPToTT[inAtoms, eqnTrees ! BoolOps.Error => {message _ msg; CONTINUE}]; IF message # NIL THEN ERROR Error[ParameterErrors, Rope.Cat["Could not translate equations to truth table form, error was: ", message, "\n"]]; RETURN[tt]; END; FetchTT: PUBLIC PROC [par: SymTab.Ref] RETURNS [truthTable: BoolOps.TruthTable] = BEGIN GetTTFile: PROC[ttFile: ROPE] RETURNS[tt: BoolOps.TruthTable] = BEGIN ttStream: IO.STREAM; explanation: ROPE; IF ttFile = NIL THEN RETURN[NIL]; ttStream _ FS.StreamOpen[fileName: ttFile, wDir: CDIO.GetWorkingDirectory[] ! FS.Error => IF error.group = user THEN {ttStream _ NIL; CONTINUE}]; IF ttStream = NIL THEN ERROR Error[ParameterErrors, Rope.Cat["Could not open truth table file '", ttFile, "'.\n"]]; tt _ BoolOps.StreamToTT[ttStream ! BoolOps.Error => {explanation _ msg; CONTINUE}]; IF explanation # NIL THEN ERROR Error[ParameterErrors, Rope.Cat["Error in reading truth table: ", explanation, "\n"]]; END; GetTT: PROC[par: SymTab.Ref] RETURNS[BoolOps.TruthTable] = BEGIN ref: REF ANY; ref _ CDExpr.FetchRef[par, "TruthTable"].val; IF ref = NIL THEN RETURN[NIL]; IF ~ISTYPE[ref, BoolOps.TruthTable] THEN ERROR Error[ParameterErrors, Rope.Cat["TruthTable option is not of type BoolOps.TruthTable!"]]; RETURN[NARROW[ref]]; END; SELECT TRUE FROM CDExpr.FetchRope[par, "TruthTableFile"].found => truthTable _ GetTTFile[CDExpr.FetchRope[par, "TruthTableFile"].val]; -- Read TruthTable from a file CDExpr.FetchRef[par, "TruthTable"].found => truthTable _ GetTT[par]; -- Read TruthTable directly ENDCASE => -- should be GetEQN[inputNames, outputNames] truthTable _ NIL; END; DumpTruthTable: PUBLIC PROC [tt: BoolOps.TruthTable, ttFile: ROPE] = BEGIN ttStream: IO.STREAM; message: ROPE _ NIL; ttStream _ FS.StreamOpen[fileName: ttFile, wDir: CDIO.GetWorkingDirectory[], accessOptions: $create ! FS.Error => IF error.group = user THEN {ttStream _ NIL; CONTINUE}]; IF ttStream = NIL THEN ERROR Error[NoDump, Rope.Cat["Could not create truth table dump file '", ttFile, "'.\n"]]; BoolOps.TTToStream[tt, ttStream ! BoolOps.Error => {message _ msg; CONTINUE}]; IF message # NIL THEN ERROR Error[NoDump, Rope.Cat["Could not dump truth table to file '", ttFile, "', error was: ", message, "\n"]]; END; END. ΦFile: PWPLABasicsImpl.mesa Copyright Σ 1985, 1987 by Xerox Corporation. All rights reserved. Created by: Monier, March 14, 1985 9:54:02 pm PST Bertrand Serlet April 14, 1987 4:13:22 am PDT -- Looks for name1, name2, then name3; if absent, return NIL and screams if required -- Check if all names are non-NIL -- Read equations one at a time, converting to sum-of-products as we go -- read equations one at a time, converting to sum-of-products as we go -- reverse our list of equations since it is backwards -- create a list of atoms from the input names -- make a truth table -- get the truth table from a file -- read the truth table directly from parameters file -- get a truth table -- dump truth table to file Κ Ά˜– "Cedar" stylešΟnœ™JšœB™BJšœ.Οk™1Icodešœ-™-J˜—šž ˜ Jšœžœžœ˜%Jšžœ˜Jšœ ˜ šœžœžœ˜*J˜——šœžœžœ˜"Jš žœ%žœžœžœžœ˜NJšžœ ˜Jšžœžœ˜Jšžœ ˜J˜Jš Πbnœžœžœžœžœ˜5J˜JšΟcT™Tšœžœžœžœžœ žœžœžœ ˜kJšž˜šœžœžœž˜Jšœžœ˜.Jšœžœ˜.Jšœžœ˜.Jšžœžœ˜—šžœžœžœ ž˜Jšž˜Jšžœ#žœ˜BJš žœ žœžœžœžœ˜AJš žœ žœžœžœžœ˜AJšžœ ˜Jšžœžœ˜Jšžœ˜—Jšžœ˜J˜—š  œžœžœžœžœžœ˜GJšœžœ)žœ˜6—J™Jš !™!š œžœžœžœžœžœ žœžœžœ˜LJš œžœžœžœžœ žœžœ˜H—J˜š œžœžœžœžœžœžœžœ ˜cJšœžœ$žœ˜3—J˜š œžœžœžœžœžœžœžœ ˜cJšœžœ$žœ˜4—J™šœžœžœžœžœžœžœžœžœžœ˜NJšž˜Jšžœžœžœžœžœžœžœžœ0˜\Jšžœ˜—J˜šœžœžœžœžœžœžœžœžœžœžœžœ˜aJšž˜Jš žœžœžœžœžœ˜šœžœ˜ Jš œžœ žœžœžœ˜7Jšœ'˜'—Jšžœ˜—J˜šœžœžœžœžœžœžœ žœ˜DJšž˜Jšžœžœžœ&žœ˜AJšžœ˜J˜—š œžœžœžœžœžœ žœ˜=Jšœžœžœžœ˜(—J˜Jš G™Gšœžœžœ%žœžœžœžœ˜dJšž˜J˜Jš œžœžœžœžœ˜*Jšœžœžœžœ˜7Jšœ žœ˜Jšœžœžœ˜š žœ žœžœ žœžœ˜(JšžœJ˜O—Jš G™Gš žœžœžœžœžœžœž˜@Jšœžœžœ˜Jšœžœ˜Jšœ,˜,šžœžœžœ˜Jšœf˜fJ˜—š žœžœž œžœžœ ˜QJšœžœ˜šžœžœ žœ žœ˜*Jšžœ žœžœ˜7Jšžœ˜J˜—Jšžœ˜—Jšœ žœ˜Jšœ>žœ˜Išžœ žœž˜Jšœ‘˜‘—šžœ˜Jšœ žœ˜Jšœ;žœ˜Fšžœ žœž˜Jšœœ˜œ—šžœ˜Jšœžœ˜-J˜—J˜—Jšžœ˜ —Jšžœžœžœžœ*˜ZJš 6™6š žœžœžœ-žœ žœž˜SJšœ žœ˜'Jšžœ˜—Jš .™.š žœžœžœžœžœžœž˜