DIRECTORY Parquet, ParquetInternal, TilerMenu USING [Register], StretchLines, Commander USING [CommandProc, Register], TerminalIO USING [WriteRope, WriteInt, RequestRope, UserAbort, UserSaysYes], ExprRead, CDIO USING [WriteDesign, ReadDesign, GetWorkingDirectory, SetWorkingDirectory], CDSequencer USING [Command, ImplementCommand], CD, CDOps USING [AddAnObject, CreateDesign], CDImports USING [Import, GetImport, DoImport], Rope USING [ROPE, Equal, Cat, IsEmpty], FileNames USING [CurrentWorkingDirectory], FS USING [FileInfo, ExpandName, Error], Process USING [SetPriority, priorityBackground], SymTab USING [Ref, Create, Fetch, Pairs, Store, EachPairAction]; ParquetImplB: CEDAR PROGRAM IMPORTS CD, TilerMenu, ExprRead, Commander, TerminalIO, CDIO, CDOps, CDImports, Rope, CDSequencer, SymTab, FileNames, FS, Process, Parquet, ParquetInternal EXPORTS Parquet = BEGIN OPEN Parquet, ParquetInternal; generatorTable: SymTab.Ref; GeneratorRec: TYPE = RECORD [ proc: ModuleGeneratorProc, needsTiles: BOOL _ TRUE ]; markScale: INT = 2; markWidth: INT = 16; markHeight: INT = 6; arrowSize: INT = 4; RegisterGenerator: PUBLIC PROC[generatorName: Rope.ROPE, proc: ModuleGeneratorProc, needsTiles: BOOL] RETURNS [BOOL] = BEGIN ptr: REF GeneratorRec ~ NEW[GeneratorRec _ [proc: proc, needsTiles: needsTiles]]; RETURN[SymTab.Store[generatorTable, generatorName, ptr]]; END; ProduceModule: PROC[context: Context, intoPos: CD.Position, fromFile: BOOL] RETURNS [BOOL]= BEGIN ENABLE { TerminalIO.UserAbort => GOTO abort; CD.Error => BEGIN TerminalIO.WriteRope["\nChipNDale raised an error flag: '"]; TerminalIO.WriteRope[explanation]; TerminalIO.WriteRope["'\n"]; END; ExprRead.Error => { TerminalIO.WriteRope[msg]; TerminalIO.WriteRope["'\n"]; GOTO abort; }; }; PrintGenerator: SymTab.EachPairAction = BEGIN TerminalIO.WriteRope[" "]; TerminalIO.WriteRope[key]; TerminalIO.WriteRope["\n"]; RETURN[FALSE]; END; generatorName: Rope.ROPE; needsTiles: BOOL; found: BOOL; generatorProc: ModuleGeneratorProc; module: Module; mod: Mod; tilesName: Rope.ROPE _ NIL; cellName: Rope.ROPE; errs: INT; IF context = NIL OR context.eventualOwner = NIL THEN ERROR; IF fromFile THEN { ok: BOOL _ FALSE; badFile: BOOL _ FALSE; errorMsg: Rope.ROPE _ NIL; inFile: Rope.ROPE; inFile _ TerminalIO.RequestRope[Rope.Cat["\nEnter name of a file describing the module (", context.workingDirectoryToUse, ") : "]]; inFile _ FS.ExpandName[inFile, context.workingDirectoryToUse].fullFName; [] _ FS.FileInfo[inFile !FS.Error => IF error.group = user THEN { badFile _ TRUE; CONTINUE }]; IF badFile THEN BEGIN TerminalIO.WriteRope[Rope.Cat["Could not open file '", inFile, "'.\n"]]; GOTO abort; END; errorMsg _ NIL; context.parameters _ ExprRead.ReadFile[inFile ! ExprRead.Error => {errorMsg _ msg; CONTINUE}]; IF errorMsg # NIL THEN { TerminalIO.WriteRope["Error while reading file: '"]; TerminalIO.WriteRope[errorMsg]; TerminalIO.WriteRope["'.\n"]; GOTO abort; }; generatorName _ ExprRead.FetchRope[context.parameters, "ModuleGenerator", TRUE ! ExprRead.Error => {errorMsg _ msg; CONTINUE}].val; IF errorMsg # NIL THEN { TerminalIO.WriteRope["Error while reading file: '"]; TerminalIO.WriteRope[errorMsg]; TerminalIO.WriteRope["'.\n"]; GOTO abort; }; IF generatorName = NIL THEN { TerminalIO.WriteRope["File does not include a 'ModuleGenerator _ xxx' line.\n"]; GOTO abort; }; } ELSE { generatorName _ TerminalIO.RequestRope["\nEnter name of a module generator: (hit return for options) "]; IF Rope.Equal[generatorName, ""] THEN BEGIN TerminalIO.WriteRope["These generators are currently running:\n"]; [] _ SymTab.Pairs[generatorTable, PrintGenerator]; TerminalIO.WriteRope[" --------\n"]; RETURN[FALSE]; END; }; { ptr: REF ANY; genRef: REF GeneratorRec; [found, ptr] _ SymTab.Fetch[generatorTable, generatorName]; IF ~found THEN BEGIN TerminalIO.WriteRope["Module generator '"]; TerminalIO.WriteRope[generatorName]; TerminalIO.WriteRope["' is not currently running.\n"]; GOTO abort; END; genRef _ NARROW[ptr]; generatorProc _ genRef.proc; needsTiles _ genRef.needsTiles; }; IF needsTiles THEN { IF fromFile THEN { errorMsg: Rope.ROPE _ NIL; IF context.tiles = NIL THEN { tilesName _ ExprRead.FetchRope[context.parameters, "TileSet", TRUE ! ExprRead.Error => {errorMsg _ msg; CONTINUE}].val; IF errorMsg # NIL THEN { TerminalIO.WriteRope["Could not read TileSet parameter: '"]; TerminalIO.WriteRope[errorMsg]; TerminalIO.WriteRope["'.\n"]; GOTO abort; }; }; IF tilesName = NIL THEN { TerminalIO.WriteRope["File does not include a 'TileSet _ xxx' line.\n"]; GOTO abort; }; } ELSE { IF context.tiles = NIL THEN { tilesName _ TerminalIO.RequestRope["\nEnter name of the imported design containing the tiles: \n(hit return for the top-level design, or type the name of an imported design) "]; }; }; IF context.tiles = NIL THEN { IF Rope.IsEmpty[tilesName] THEN context.tiles _ context.eventualOwner ELSE { import: REF CDImports.Import _ CDImports.GetImport[context.eventualOwner, tilesName, $false]; IF import = NIL THEN { TerminalIO.WriteRope[Rope.Cat["Could not find imported design called '", tilesName, "'.\n"]]; GOTO abort; }; context.tiles _ import.importee; }; }; }; cellName _ TerminalIO.RequestRope["What do you want to call the resulting cell? "]; Process.SetPriority[Process.priorityBackground]; module _ generatorProc[context]; IF module = NIL THEN BEGIN TerminalIO.WriteRope["A NIL module was produced by the generator.\n"]; GOTO abort; END; { err: BOOL _ FALSE; mod _ CheckValid[module ! Parquet.Error => {err _ TRUE; CONTINUE}]; IF err THEN BEGIN TerminalIO.WriteRope["An invalid module was produced by the generator!\nMaybe it returned something that was converted to a tile?\n"]; GOTO abort; END; }; IF mod.topCell = NIL THEN BEGIN TerminalIO.WriteRope["A garbaged module was returned by the generator!\n"]; GOTO abort; END; TerminalIO.WriteRope["Checking module . . . "]; errs _ CheckModule[module]; IF errs > 0 THEN BEGIN TerminalIO.WriteInt[errs]; TerminalIO.WriteRope[" ERRORS were found in the generated module, suspect areas are indicated by highlighting.\n"] END ELSE TerminalIO.WriteRope["looks OK to me.\n"]; TerminalIO.WriteRope["Creating ChipNDale cell '"]; TerminalIO.WriteRope[cellName]; TerminalIO.WriteRope["' ..."]; { ob: CD.ObPtr; ob _ ModuleIntoCell[module: module, name: cellName, applicationsPerScreenDot: 100]; IF ob = NIL THEN ERROR; CDOps.AddAnObject[context.eventualOwner, ob, intoPos]; }; RETURN[TRUE]; EXITS abort => { TerminalIO.WriteRope["Parquet exiting, no module was generated.\n"]; RETURN[FALSE]; }; END; GetWorkingDirectory: PROC [design: CD.Design] RETURNS [Rope.ROPE] = BEGIN wDir: Rope.ROPE _ CDIO.GetWorkingDirectory[design]; IF Rope.IsEmpty[wDir] THEN wDir _ FileNames.CurrentWorkingDirectory[]; RETURN[wDir]; END; RunTilerDirectly: Commander.CommandProc = BEGIN fromFile: BOOL; tilesName, designName: Rope.ROPE _ NIL; context: Context _ NEW[ContextRec]; context.workingDirectoryToUse _ FileNames.CurrentWorkingDirectory[]; tilesName _ TerminalIO.RequestRope[Rope.Cat["Enter name of file containg the tiles (", context.workingDirectoryToUse, ") : "]]; tilesName _ FS.ExpandName[tilesName, context.workingDirectoryToUse].fullFName; context.tiles _ CDIO.ReadDesign[tilesName]; CDIO.SetWorkingDirectory[context.tiles, context.workingDirectoryToUse]; IF context.tiles = NIL THEN { TerminalIO.WriteRope["Could not load the tiles.\n"]; RETURN[]; } ELSE TerminalIO.WriteRope["Tiles loaded.\n"]; designName _ TerminalIO.RequestRope[Rope.Cat["Enter name for output file (", context.workingDirectoryToUse, ") : "]]; context.eventualOwner _ CDOps.CreateDesign[context.tiles.technology]; CDIO.SetWorkingDirectory[context.eventualOwner, context.workingDirectoryToUse]; IF ~CDImports.DoImport[context.eventualOwner, context.tiles, $true] THEN { TerminalIO.WriteRope["Could not import the tile set!\n"]; RETURN[]; }; fromFile _ TerminalIO.UserSaysYes["From file?", "Do you want to run the module generator from a file (alternate way is to run interactively)?\n", TRUE]; IF ProduceModule[context, [0, 0], fromFile] THEN { TerminalIO.WriteRope["\nWritting ChipNDale file ...."]; IF ~CDIO.WriteDesign[context.eventualOwner, designName] THEN TerminalIO.WriteRope["\nOOPS!!! Could not write the ChipNDale file, at least I tried.\n"] ELSE TerminalIO.WriteRope["\nDone.\n"]; }; END; RunTiler: PROC [comm: CDSequencer.Command] = BEGIN fromFile: BOOL _ TerminalIO.UserSaysYes["From file?", "Do you want to run a module generator from a file (alternative is to run interactively)?\n", TRUE]; context: Context _ NEW[ContextRec]; context.workingDirectoryToUse _ GetWorkingDirectory[comm.design]; context.eventualOwner _ comm.design; [] _ ProduceModule[context, comm.pos, fromFile]; END; RunTilerFromFile: PROC [comm: CDSequencer.Command] = BEGIN context: Context _ NEW[ContextRec]; context.workingDirectoryToUse _ GetWorkingDirectory[comm.design]; context.eventualOwner _ comm.design; [] _ ProduceModule[context, comm.pos, TRUE]; END; RunTilerWithoutFile: PROC [comm: CDSequencer.Command] = BEGIN context: Context _ NEW[ContextRec]; context.workingDirectoryToUse _ GetWorkingDirectory[comm.design]; context.eventualOwner _ comm.design; [] _ ProduceModule[context, comm.pos, FALSE]; END; NoOp: Commander.CommandProc = BEGIN END; Init: PROC[] = BEGIN generatorTable _ SymTab.Create[case: FALSE]; CDSequencer.ImplementCommand[$RunTiler, RunTiler]; CDSequencer.ImplementCommand[$RunTilerFromFile, RunTilerFromFile]; CDSequencer.ImplementCommand[$RunTilerWithoutFile, RunTilerWithoutFile]; TilerMenu.Register["Run module generator interactively", $RunTilerWithoutFile]; TilerMenu.Register["Run module generator from file", $RunTilerFromFile]; END; Init[]; Commander.Register[key: "GenerateModule", proc: RunTilerDirectly, doc: "Run a module generator"]; Commander.Register[key: "Parquet", proc: NoOp, doc: "Does nothing"]; END. jFile: ParquetImplB.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Created by: Mayo, July 16, 1984 4:44:25 pm PDT Last Edited by: Mayo, November 5, 1984 7:10:22 pm PST -- ChipNDale user interface routines -- Top-level command routines -- register a module generator with the tiler -- let the system slide into the debugger -- PROC [key: Key, val: Val] RETURNS [quit: BOOL] -- Find the name of the module generator -- get file name -- read file -- get ModuleGenerator name -- Find the module generator given its name -- Get the tiles, if needed -- get TileSet import name -- Find the tile set given the name -- -- -- did we get a module back? -- load in the tiles -- create design for output -- import the tiles -- go for it -- Main body -- register a command. -- register a command so that we won't get ".load file failed to register command" Κ v˜– "Cedar" stylešœ™Jšœ Οmœ1™žœ&žœ˜wšžœ žœžœ˜Jšœ<˜Jšœžœ ˜#JšœA˜AJšœ$˜$Jšœ&žœ˜,Jšžœ˜—J˜š’œžœžœ˜AJšœžœ ˜#JšœA˜AJšœ$˜$Jšœ&žœ˜-Jšžœ˜—J˜šŸœžœ˜'Jšžœ˜J˜—š’œžœž˜Jšœ%žœ˜,Jšœ2˜2JšœB˜BJšœH˜HJšœO˜OJšœH˜HJšžœ˜—J˜—™ J™Jšœ˜Jšœ™Jšœa˜aJšœR™RJšœD˜D—Jšžœ˜—…—&œ5|