SchemeEdit.Mesa
Last Edited by: Spreitzer, February 23, 1984 10:42 pm
DIRECTORY Basics, IO, OrderedSymbolTableRef, Rope, SchemeRep, SchemeEditing, ViewerClasses, ViewerOps, ViewerTools, ViewRec;
SchemePictures:
CEDAR
PROGRAM
IMPORTS IO, OrderedSymbolTableRef, Rope, SchemeEditing, ViewerOps, ViewerTools, ViewRec
EXPORTS SchemeEditing =
BEGIN OPEN SchemeRep, SchemeEditing;
CompareNames:
PUBLIC OrderedSymbolTableRef.CompareProc
--PROC [r1, r2: Item] RETURNS [Comparison]-- =
BEGIN
ToRope:
PROC [any:
REF
ANY]
RETURNS [k:
ROPE] =
{k ←
WITH any
SELECT
FROM
r: ROPE => r,
ct: CellType => ct.name,
p: Port => p.name,
n: Net => n.name,
c: Component => c.name,
cp: ComponentPort => cp.port.name,
pic: PictureDef => pic.name,
c: Coord => c.name,
pt: Point => pt.name,
l: Line => l.name,
t: Text => t.name,
pi: PictureInstance => pi.name,
ENDCASE => ERROR};
k1: ROPE ← ToRope[r1];
k2: ROPE ← ToRope[r2];
RETURN [k1.Compare[k2]];
END;
CompareCoords: OrderedSymbolTableRef.CompareProc
--PROC [r1, r2: Item] RETURNS [Comparison]-- =
BEGIN
k1:
REAL ←
WITH r1
SELECT
FROM
c: Coord => c.z,
l: LORA => NARROW[l.first, Coord].z,
r: REF REAL => r^,
ENDCASE => ERROR;
k2:
REAL ←
WITH r2
SELECT
FROM
c: Coord => c.z,
l: LORA => NARROW[l.first, Coord].z,
r: REF REAL => r^,
ENDCASE => ERROR;
RETURN [IF k1 < k2 THEN less ELSE IF k1 > k2 THEN greater ELSE equal];
END;
NotifyLabels:
PUBLIC
PROC [labels:
LORA, editor: Editor] =
BEGIN
ViewerOps.PaintViewer[viewer: editor.v, hint: client, clearClient: FALSE, whatChanged: CONS[$Labels, labels]];
END;
NewPicture:
PUBLIC
PROC [session: Session, name:
ROPE]
RETURNS [pic: PictureDef] =
BEGIN
pic ←
NEW [PictureDefRep ← [
name: name,
coordsByValue: [
OrderedSymbolTableRef.CreateTable[CompareCoords],
OrderedSymbolTableRef.CreateTable[CompareCoords]],
coordsByName: OrderedSymbolTableRef.CreateTable[CompareNames],
points: OrderedSymbolTableRef.CreateTable[CompareNames],
objects: OrderedSymbolTableRef.CreateTable[CompareNames]
]];
session.picsTable.Insert[pic];
END;
Export:
PROC [session: Session, export:
BOOLEAN] =
BEGIN
editor: Editor ← session.mostRecentEditor;
session.ctlRV.DisplayMessage[ViewRec.clearMessagePlace];
IF editor.primary.point = NIL THEN {Complain[editor, "No point selected"]; RETURN};
IF
NOT export
THEN {
uses: LIST OF ROPE ← FindExportedPointUses[editor.primary.point];
IF uses # NIL THEN {Complain[editor, IO.PutFR["Can't unexport; it's used by %g", IO.refAny[uses]]]; RETURN};
editor.primary.point.exported ← export;
RecomputeExported[editor.primary.point.c[X]];
RecomputeExported[editor.primary.point.c[Y]]}
ELSE {
editor.primary.point.exported ← export;
editor.primary.point.c[X].exported ← TRUE;
editor.primary.point.c[Y].exported ← TRUE};
END;
RecomputeExported:
PROC [c: Coord] =
{e: BOOL ← FALSE;
FOR l:
LORA ← c.dependents, l.rest
WHILE l #
NIL
DO
WITH l.first
SELECT
FROM
c2: Coord => NULL;
p: Point => IF p.exported THEN e ← TRUE;
ENDCASE => ERROR;
ENDLOOP;
c.exported ← e};
FindExportedPointUses:
PROC [point: Point]
RETURNS [uses:
LIST
OF
ROPE] =
BEGIN
uses ← NIL;
FOR l:
LORA ← point.pic.instances, l.rest
WHILE l #
NIL
DO
pi: PictureInstance ← NARROW[l.first];
pip: Point ← NARROW[pi.points.Lookup[PIPointName[pi.name, point.name]]];
IF pip.dependents # NIL THEN uses ← CONS[IO.PutFR["%g.%g", IO.rope[pi.in.name], IO.rope[pi.name]], uses];
ENDLOOP;
END;
PIPointName:
PUBLIC
PROC [piName, pointName:
ROPE]
RETURNS [piPointName:
ROPE] =
{piPointName ← piName.Cat[".", pointName]};
MakePoint:
PUBLIC
PROC [pic: PictureDef, vertex: Vertex, name:
ROPE ←
NIL]
RETURNS [point: Point] =
BEGIN
Try:
PROC [x: Coord]
RETURNS [found:
BOOLEAN ←
FALSE] =
BEGIN
FOR l:
LORA ← x.dependents, l.rest
WHILE l #
NIL
DO
WITH l.first
SELECT
FROM
c: Coord => NULL;
p: Point => IF p.c[Y] = vertex[Y] THEN {point ← p; RETURN [TRUE]};
ENDCASE => ERROR;
ENDLOOP;
END;
atX: REF ANY ← pic.coordsByValue[X].Lookup[vertex[X]];
WITH atX
SELECT
FROM
c: Coord => IF Try[c] THEN RETURN;
la:
LORA =>
FOR l:
LORA ← la, l.rest
WHILE l #
NIL
DO
IF Try[NARROW[l.first]] THEN RETURN;
ENDLOOP;
ENDCASE => ERROR;
IF name = NIL THEN name ← NewName[pic.points];
point ← NewPoint[pic, name, vertex];
END;
NewPoint:
PUBLIC
PROC [pic: PictureDef, name:
ROPE, vertex: Vertex]
RETURNS [point: Point] =
BEGIN
point ← NEW [PointRep ← [c: vertex, name: name, pic: pic, dependents: NIL]];
pic.points.Insert[point];
vertex[X].dependents ← CONS[point, vertex[X].dependents];
vertex[Y].dependents ← CONS[point, vertex[Y].dependents];
END;
nameCount: INT ← 0;
NewName:
PUBLIC
PROC [for: Table]
RETURNS [name:
ROPE] =
{found: REF ANY ← $Found;
WHILE found #
NIL
DO
found ← for.Lookup[name ← IO.PutFR["^%g|", IO.int[nameCount ← nameCount + 1]]];
ENDLOOP};
NewCoord:
PUBLIC
PROC [axis: Axis, at:
REAL, pic: PictureDef, parent:
REF
ANY ←
NIL, name:
ROPE ←
NIL]
RETURNS [new: Coord] =
BEGIN
org:
REAL ←
IF parent #
NIL
THEN
WITH parent
SELECT
FROM
coord: Coord => coord.z,
pi: PictureInstance => pi.org.c[axis].z,
ENDCASE => ERROR
ELSE 0;
IF name = NIL THEN name ← NewName[pic.coordsByName];
new ← EnsureCoord[pic, name];
new^ ← [name: new.name, pic: pic, axis: axis, z: at, sz: at, dependents: NIL, parent: parent, dz: at - org];
EntableCoord[pic.coordsByValue[axis], new];
IF parent #
NIL
THEN
WITH parent
SELECT
FROM
coord: Coord => coord.dependents ← CONS[new, coord.dependents];
pi: PictureInstance => pi.coords.Insert[new];
ENDCASE => ERROR;
END;
NewLine:
PUBLIC
PROC [pic: PictureDef, a, b: Point]
RETURNS [line: Line] =
BEGIN
editor: Editor ← NARROW[pic.editor];
IF a = NIL OR b = NIL THEN RETURN [NIL];
IF a.deleted OR b.deleted THEN ERROR;
line ← NEW [LineRep ← [name: NewName[pic.objects], a: a, b: b, sa: [0, 0], sb: [0, 0]]];
pic.objects.Insert[line];
a.dependents ← CONS[line, a.dependents];
b.dependents ← CONS[line, b.dependents];
IF editor # NIL THEN ViewerOps.PaintViewer[viewer: editor.v, hint: client, clearClient: FALSE, whatChanged: line];
END;
DeleteLine:
PUBLIC
PROC [pic: PictureDef, a, b: Point, line: Line ←
NIL] =
BEGIN
editor: Editor ← NARROW[pic.editor];
IF line = NIL THEN line ← FindLine[a, b];
IF line = NIL THEN RETURN;
IF editor # NIL THEN ViewerOps.PaintViewer[viewer: editor.v, hint: client, clearClient: FALSE, whatChanged: line];
line.a.dependents ← Filter[line.a.dependents, line];
line.b.dependents ← Filter[line.b.dependents, line];
[] ← pic.objects.Delete[line];
END;
FindLine:
PUBLIC
PROC [a, b: Point]
RETURNS [line: Line] =
{IF a = NIL OR b = NIL THEN RETURN [NIL];
FOR l:
LORA ← a.dependents, l.rest
WHILE l #
NIL
DO
WITH l.first
SELECT
FROM
t: Text => NULL;
l2: Line => IF (l2.a = a AND l2.b = b) OR (l2.a = b AND l2.b = a) THEN RETURN [l2];
pi: PictureInstance => NULL;
ENDCASE => ERROR;
ENDLOOP;
line ← NIL};
NewText:
PUBLIC
PROC [pic: PictureDef, p: Point, rope:
ROPE] =
BEGIN
editor: Editor ← NARROW[pic.editor];
text: Text;
text ← NEW [TextRep ← [name: NewName[pic.objects], org: p, sxy: [0, 0], rope: rope]];
pic.objects.Insert[text];
p.dependents ← CONS[text, p.dependents];
IF editor # NIL THEN ViewerOps.PaintViewer[viewer: editor.v, hint: client, clearClient: FALSE, whatChanged: text];
END;
DeleteText:
PUBLIC
PROC [pic: PictureDef, at: Point, text: Text ←
NIL] =
BEGIN
editor: Editor ← NARROW[pic.editor];
IF text = NIL THEN text ← FindText[at];
IF text = NIL THEN RETURN;
IF editor # NIL THEN ViewerOps.PaintViewer[viewer: editor.v, hint: client, clearClient: FALSE, whatChanged: text];
text.org.dependents ← Filter[text.org.dependents, text];
[] ← pic.objects.Delete[text];
END;
FindText:
PROC [at: Point]
RETURNS [text: Text] =
{
FOR l:
LORA ← at.dependents, l.rest
WHILE l #
NIL
DO
WITH l.first
SELECT
FROM
t: Text => IF t.org = at THEN RETURN [t];
l2: Line => NULL;
pi: PictureInstance => NULL;
ENDCASE => ERROR;
ENDLOOP;
text ← NIL};
NewInstance:
PUBLIC
PROC [pic: PictureDef, p: Point, className, iconName:
ROPE] =
BEGIN
editor: Editor ← NARROW[pic.editor];
ct: CellType ← NARROW[editor.session.typesTable.Lookup[className]];
def: PictureDef;
IF ct = NIL THEN {Complain[editor, "No such cellType"]; RETURN};
def ← NARROW[IF ct.icons.Size[] = 1 THEN ct.icons.LookupSmallest[] ELSE ct.icons.Lookup[iconName]];
IF def = NIL THEN {Complain[editor, "No such icon"]; RETURN};
[] ← CreateInstance[in: pic, of: def, org: p];
END;
FindPI:
PUBLIC
PROC [at: Point]
RETURNS [pi: PictureInstance] =
{
FOR l:
LORA ← at.dependents, l.rest
WHILE l #
NIL
DO
WITH l.first
SELECT
FROM
t: Text => NULL;
l2: Line => NULL;
pi: PictureInstance => IF pi.org = at THEN RETURN [pi];
ENDCASE => ERROR;
ENDLOOP;
pi ← NIL};
DeleteInstance:
PUBLIC
PROC [pic: PictureDef, at: Point, pi: PictureInstance ←
NIL] =
BEGIN
check, ok: BOOLEAN ← TRUE;
Per:
PROC [any:
REF
ANY]
RETURNS [stop:
BOOLEAN] =
{stop ← FALSE;
WITH any
SELECT
FROM
c: Coord =>
IF check
THEN
{bad: BOOLEAN ← FALSE;
FOR l:
LORA ← c.dependents, l.rest
WHILE l #
NIL
DO
WITH l.first
SELECT
FROM
c2: Coord => bad ← TRUE;
p: Point => bad ← bad OR (p.fromPI # pi);
ENDCASE => ERROR;
ENDLOOP;
IF bad THEN {ok ← FALSE; Complain[editor, IO.PutFR[" exported coord %g has dependents", IO.rope[c.name]]]}}
ELSE DeleteCoord[c];
p: Point =>
IF check
THEN
{IF p.dependents # NIL THEN {ok ← FALSE; Complain[editor, IO.PutFR[" exported point %g has dependents", IO.rope[p.name]]]}}
ELSE DeletePoint[pic, p];
ENDCASE => ERROR};
editor: Editor ← NARROW[pic.editor];
IF pi = NIL THEN pi ← FindPI[at];
IF pi = NIL THEN RETURN;
pi.coords.EnumerateIncreasing[Per];
IF NOT ok THEN RETURN;
pi.points.EnumerateIncreasing[Per];
IF NOT ok THEN RETURN;
check ← FALSE;
IF editor # NIL THEN ViewerOps.PaintViewer[viewer: editor.v, hint: client, clearClient: FALSE, whatChanged: pi];
pi.points.EnumerateIncreasing[Per];
pi.coords.EnumerateIncreasing[Per];
pi.org.dependents ← Filter[pi.org.dependents, pi];
[] ← pic.objects.Delete[pi];
pi.of.instances ← Filter[pi.of.instances, pi];
END;
CreateInstance:
PUBLIC
PROC [in, of: PictureDef, org: Point]
RETURNS [pi: PictureInstance] =
BEGIN
AddCoord:
PROC [any:
REF
ANY]
RETURNS [stop:
BOOLEAN] =
BEGIN
inDef: Coord ← NARROW[any];
stop ← FALSE;
IF NOT inDef.exported THEN RETURN;
IF (inDef.exportedTo # NIL) AND (inDef.exportedTo.parent = pi) THEN RETURN;
inDef.exportedTo ← NewCoord[inDef.axis, inDef.z + pi.org.c[inDef.axis].z, in, pi];
END;
AddPoint:
PROC [any:
REF
ANY]
RETURNS [stop:
BOOLEAN] =
BEGIN
inDef: Point ← NARROW[any];
inCaller: Point;
stop ← FALSE;
IF NOT inDef.exported THEN RETURN;
inCaller ← MakePoint[in, [inDef.c[X].exportedTo, inDef.c[Y].exportedTo], PIPointName[pi.name, inDef.name]];
inCaller.fromPort ← inDef.name;
inCaller.fromPI ← pi;
pi.points.Insert[inCaller];
END;
editor: Editor ← NARROW[in.editor];
pi ← EnsurePictureInstance[in, NewName[in.objects]];
pi^ ← [name: pi.name, in: in, of: of, org: org, s: [0, 0],
coords: OrderedSymbolTableRef.CreateTable[CompareNames],
points: OrderedSymbolTableRef.CreateTable[CompareNames]];
pi.of.instances ← CONS[pi, pi.of.instances];
org.dependents ← CONS[pi, org.dependents];
of.coordsByName.EnumerateIncreasing[AddCoord];
of.points.EnumerateIncreasing[AddPoint];
IF editor # NIL THEN ViewerOps.PaintViewer[viewer: editor.v, hint: client, clearClient: FALSE, whatChanged: pi];
END;
CheckInstances:
PROC [pic: PictureDef] =
BEGIN
Check:
PROC [any:
REF
ANY]
RETURNS [stop:
BOOL] =
{stop ← FALSE;
WITH any
SELECT
FROM
l: Line => NULL;
t: Text => NULL;
pi: PictureInstance => IF pi.in # pic THEN ERROR;
ENDCASE => ERROR};
pic.objects.EnumerateIncreasing[Check];
END;
Complain:
PUBLIC
PROC [editor: Editor, complaint:
ROPE] =
{editor.session.ctlRV.DisplayMessage[complaint]};
CreateSession:
PROC [name:
ROPE]
RETURNS [session: Session] =
BEGIN
ctl: CtlPanel ←
NEW [CtlPanelRep ← [
Clear: Clear,
ReadFile: ReadFile,
WriteFile: WriteFile,
CreateCellType: CreateCellType,
CreateIcon: CreateIcon,
EditType: EditType,
Export: Export,
cellType: "foo",
icon: "bar",
name: "baz"]];
session ←
NEW [SessionRep ← [
name: name,
typesMenu: ViewerTools.MakeNewTextViewer[info: [name: name.Cat[" Types"], iconic: FALSE], paint: FALSE],
ctlRV: NIL,
ctlPanel: ctl,
editors: NIL,
typesTable: OrderedSymbolTableRef.CreateTable[CompareNames],
picsTable: OrderedSymbolTableRef.CreateTable[CompareNames]]];
ViewerOps.SetOpenHeight[session.typesMenu, 100];
session.ctlRV ← ViewRec.ViewRef[
agg: ctl,
specs: ViewRec.BindAllOfATypeFromRefs[rec: ctl, handle: NEW [Session ← session]],
viewerInit: [name: name.Cat[" Ctl"], iconic: FALSE]];
END;
END.