File: Mirror.mesa   
Copyright © 1984 by Xerox Corporation. All rights reserved.
Created by: Bob Mayo, June 8, 1984 12:35:52 pm PDT
Last Edited by: Mayo, August 8, 1984 7:50:05 pm PDT
-- This is a sample of a module generator built using Parquet. It creates an array of tiles in which alternate rows and columns are flipped.
DIRECTORY
Parquet,
TerminalIO,
CDOrient USING [rotate90, mirrorX, rotate270, ComposeOrient],
Rope USING [ROPE];
Mirror: CEDAR PROGRAM    
IMPORTS Parquet, TerminalIO, CDOrient = BEGIN
MirrorProc: Parquet.ModuleGeneratorProc = BEGIN
-- user parameters
tileSetName, tileName: Rope.ROPE;
tile: Parquet.Tile;
technology: Parquet.Technology;
flipRows, flipCols: BOOL;
numRows, numCols: NAT;
-- state information
tiles: Parquet.Design;
module: Parquet.Module;
prevTile: Parquet.PlacedTile;   -- the previous tile placed
prevRow: Parquet.PlacedTile;  -- the first tile in the previous row
orient: Parquet.Orientation ← Parquet.IdentityOrient;
-- constants
mirrorY: Parquet.Orientation ← CDOrient.ComposeOrient[CDOrient.ComposeOrient[CDOrient.rotate90, CDOrient.mirrorX], CDOrient.rotate270];
-- query user for parameters
tileSetName ← TerminalIO.RequestRope["What file contains the tiles? "];
[tiles, technology, ] ← Parquet.ReadDesign[tileSetName];
IF tiles = NIL THEN GOTO BadFile;
tileName ← TerminalIO.RequestRope["What cell do you want to array? "];
tile ← Parquet.InstantiateTile[tiles, tileName];
IF tile = NIL THEN GOTO BadTile;
numRows ← TerminalIO.RequestInt["How many rows? "];
numCols ← TerminalIO.RequestInt["How many columns? "];
flipRows ← TerminalIO.UserSaysYes["Flip alternate rows? "];
flipCols ← TerminalIO.UserSaysYes["Flip alternate columns? "];
-- initialize data structures
[module, prevTile] ← Parquet.NewModule[technology];
prevRow ← prevTile;
-- main body of module generator
FOR y: NAT IN [0..numRows) DO
lastOrient: Parquet.Orientation;
lastOrient ← orient;
FOR x: NAT IN [0..numCols) DO
IF x = 0 THEN
prevRow ← prevTile ← Parquet.AdjacentTile[prevRow, tile, below, orient]
ELSE
prevTile ← Parquet.AdjacentTile[prevTile, tile, rightOf, orient];
IF flipCols THEN orient ← CDOrient.ComposeOrient[orient, CDOrient.mirrorX];
ENDLOOP;
orient ← lastOrient;
IF flipRows THEN orient ← CDOrient.ComposeOrient[orient, mirrorY];
ENDLOOP;
-- pass result back to Parquet
TerminalIO.WriteRope["Mirror done.\n"];
RETURN[module];
-- error exits
EXITS
BadFile => BEGIN
TerminalIO.WriteRope["Could not load tiles -- goodbye!\n"];
RETURN[NIL];
END;
BadTile => BEGIN
TerminalIO.WriteRope["Could not find that tile -- goodbye!\n"];
RETURN[NIL];
END;
END;
-- register this generator with Parquet
[] ← Parquet.RegisterGenerator["Mirror", MirrorProc];
END.