DIRECTORY BiScrollers, IO, OrderedSymbolTableRef, Rope, SchemeRep, SchemeEditing, ViewerClasses, ViewerTools, ViewRec; SchemeCells: CEDAR PROGRAM IMPORTS BiScrollers, IO, OrderedSymbolTableRef, Rope, SchemeEditing, ViewerTools, ViewRec EXPORTS SchemeEditing = BEGIN OPEN SchemeRep, SchemeEditing; CreateCellType: PUBLIC PROC [session: Session, name: ROPE] = BEGIN session.ctlRV.DisplayMessage[ViewRec.clearMessagePlace]; IF session.typesTable.Lookup[name] # NIL THEN {session.ctlRV.DisplayMessage["Already exists"]; RETURN}; [] _ NewCellType[session, name, FALSE]; END; CreateIcon: PUBLIC PROC [session: Session, cellTypeName, iconName: ROPE] = BEGIN cellType: CellType _ NARROW[session.typesTable.Lookup[cellTypeName]]; picName: ROPE _ cellTypeName.Cat["[", iconName, "]"]; pic: PictureDef; session.ctlRV.DisplayMessage[ViewRec.clearMessagePlace]; IF cellType = NIL THEN {session.ctlRV.DisplayMessage["No such CellType"]; RETURN}; pic _ NARROW[cellType.icons.Lookup[iconName]]; IF pic # NIL THEN {session.ctlRV.DisplayMessage["Icon name taken"]; RETURN}; pic _ NewPicture[session, picName]; cellType.icons.Insert[pic]; END; EditType: PUBLIC PROC [session: Session, cellTypeName, iconName: ROPE, part: SubjectClass] = BEGIN picName: ROPE _ cellTypeName.Cat["[", iconName, "]"]; cellType: CellType; editor: Editor; session.ctlRV.DisplayMessage[ViewRec.clearMessagePlace]; cellType _ NARROW[session.typesTable.Lookup[cellTypeName]]; IF cellType = NIL THEN {session.ctlRV.DisplayMessage["No such type"]; RETURN}; editor _ NEW [EditorRep _ [ session: session, bs: NIL, v: NIL, subjectPic: SELECT part FROM icon => NARROW[IF cellType.icons.Size[] = 1 THEN cellType.icons.LookupSmallest[] ELSE cellType.icons.Lookup[picName]], expansion => cellType.expansion, ENDCASE => ERROR, subjectCell: cellType, subjectClass: part, primary: NIL, secondary: NIL]]; IF editor.subjectPic = NIL THEN {session.ctlRV.DisplayMessage["No such icon"]; RETURN}; IF editor.subjectPic.editor # NIL THEN {session.ctlRV.DisplayMessage["Already being edited"]; RETURN}; editor.subjectPic.editor _ editor; session.editors _ CONS[editor, session.editors]; editor.primary _ NEW [PointBackRep _ [primary: TRUE]]; editor.secondary _ NEW [PointBackRep _ [primary: FALSE]]; editor.bs _ BiScrollers.CreateBiScroller[class: editorClasses[part], info: [name: IO.PutFR["%g.%g", IO.rope[session.name], IO.rope[editor.subjectPic.name]], data: editor, iconic: FALSE]]; editor.v _ editor.bs.QuaViewer[]; END; DestroyEditor: PUBLIC ViewerClasses.DestroyProc --PROC [self: Viewer]-- = BEGIN editor: Editor _ NARROW[BiScrollers.QuaBiScroller[self].ClientDataOf[]]; last: LIST OF Editor _ NIL; IF editor.subjectPic.editor # editor THEN ERROR; editor.subjectPic.editor _ NIL; IF editor.session.mostRecentEditor = editor THEN editor.session.mostRecentEditor _ NIL; FOR l: LIST OF Editor _ editor.session.editors, l.rest WHILE l # NIL DO IF l.first = editor THEN { IF last = NIL THEN editor.session.editors _ l.rest ELSE last.rest _ l.rest; EXIT}; last _ l; ENDLOOP; editor.session _ NIL; END; NewCellType: PUBLIC PROC [session: Session, name: ROPE, skeletal: BOOLEAN] RETURNS [cellType: CellType] = BEGIN picName: ROPE _ name.Cat["[expansion]"]; cellType _ NEW [CellTypeRep _ [ name: name, icons: OrderedSymbolTableRef.CreateTable[CompareNames], expansion: NIL, ports: OrderedSymbolTableRef.CreateTable[CompareNames], nets: OrderedSymbolTableRef.CreateTable[CompareNames], components: OrderedSymbolTableRef.CreateTable[CompareNames]]]; IF NOT skeletal THEN cellType.expansion _ NewPicture[session, picName]; session.typesTable.Insert[cellType]; ViewerTools.SetContents[session.typesMenu, ViewerTools.GetContents[session.typesMenu].Cat[" ", name]]; END; NewComponent: PUBLIC PROC [editor: Editor] = BEGIN cellType: CellType _ NARROW[editor.session.typesTable.Lookup[editor.session.ctlPanel.cellType]]; icon: PictureDef; comp: Component; inst: PictureInstance; IF cellType = NIL THEN {Complain[editor, "No such cell type"]; RETURN}; icon _ NARROW[IF cellType.icons.Size[] = 1 THEN cellType.icons.LookupSmallest[] ELSE cellType.icons.Lookup[editor.session.ctlPanel.icon]]; IF icon = NIL THEN {Complain[editor, "No such icon"]; RETURN}; IF editor.subjectCell.components.Lookup[editor.session.ctlPanel.name] # NIL THEN {Complain[editor, "Instance name taken"]; RETURN}; inst _ CreateInstance[in: editor.subjectPic, of: icon, org: editor.primary.point]; comp _ CreateComponent[editor.subjectCell, cellType, editor.session.ctlPanel.name, inst]; END; DeleteComponent: PUBLIC PROC [editor: Editor] = BEGIN Check: PROC [any: REF ANY] RETURNS [stop: BOOLEAN] = {cp: ComponentPort _ NARROW[any]; stop _ FALSE; IF NOT DeleteableNet[cp.point.net, cp.point] THEN {ok _ FALSE; Complain[editor, IO.PutFR[" port %g used by net %g", IO.rope[cp.port.name], IO.rope[cp.point.net.name]]]}}; Delete: PROC [any: REF ANY] RETURNS [stop: BOOLEAN] = {cp: ComponentPort _ NARROW[any]; stop _ FALSE; DeleteNet[from, cp.point.net]; DeletePoint[from.expansion, cp.point]}; org: Point _ editor.primary.point; inst: PictureInstance _ FindPI[org]; comp: Component; from: CellType _ editor.subjectCell; ok: BOOLEAN _ TRUE; IF inst = NIL THEN RETURN; IF inst.asComponent = NIL THEN RETURN; comp _ inst.asComponent; comp.ports.EnumerateIncreasing[Check]; IF NOT ok THEN RETURN; comp.ports.EnumerateIncreasing[Delete]; IF comp.label # NIL THEN DeleteText[from.expansion, NIL, comp.label]; DeleteInstance[from.expansion, NIL, comp.inst]; IF org.dependents = NIL THEN DeletePoint[from.expansion, org]; [] _ from.components.Delete[comp]; END; DeleteableNet: PROC [net: Net, pt: Point] RETURNS [deleteable: BOOLEAN] = {deleteable _ TRUE; IF net = NIL THEN RETURN; FOR l: LORA _ net.stuff, l.rest WHILE l # NIL DO WITH l.first SELECT FROM p: Point => IF p # pt THEN deleteable _ FALSE; l2: Line => deleteable _ FALSE; t: Text => NULL; ENDCASE => ERROR; ENDLOOP}; DeleteNet: PROC [from: CellType, net: Net] = BEGIN IF net = NIL THEN RETURN; FOR l: LORA _ net.stuff, l.rest WHILE l # NIL DO WITH l.first SELECT FROM p: Point => p.net _ NIL; l2: Line => ERROR; t: Text => {t.labelOf _ NIL; DeleteText[from.expansion, NIL, t]}; ENDCASE => ERROR; ENDLOOP; net.stuff _ NIL; [] _ from.nets.Delete[net]; END; DeletePoint: PUBLIC PROC [from: PictureDef, point: Point] = BEGIN IF point.dependents # NIL THEN ERROR; [] _ from.points.Delete[point]; point.deleted _ TRUE; point.c[X].dependents _ Filter[point.c[X].dependents, point]; point.c[Y].dependents _ Filter[point.c[Y].dependents, point]; IF Scavengeable[point.c[X]] THEN DeleteCoord[point.c[X]]; IF Scavengeable[point.c[Y]] THEN DeleteCoord[point.c[Y]]; END; Scavengeable: PUBLIC PROC [coord: Coord] RETURNS [s: BOOLEAN] = {s _ coord.dependents = NIL AND (coord.parent = NIL OR ISTYPE[coord.parent, Coord])}; DeleteCoord: PUBLIC PROC [coord: Coord] = BEGIN IF coord.dependents # NIL THEN ERROR; IF coord.parent = NIL THEN NULL ELSE WITH coord.parent SELECT FROM c: Coord => c.dependents _ Filter[c.dependents, coord]; pi: PictureInstance => NULL--I hope--; ENDCASE => ERROR; END; NewPort: PUBLIC PROC [editor: Editor] = BEGIN port: Port _ NARROW[editor.subjectCell.ports.Lookup[editor.session.ctlPanel.name]]; IF port # NIL THEN {Complain[editor, "Name taken"]; RETURN}; [] _ CreatePort[editor.subjectCell, editor.session.ctlPanel.name, editor.primary.point]; END; DeletePort: PUBLIC PROC [editor: Editor] = BEGIN port: Port _ editor.primary.point.toPort; from: CellType _ editor.subjectCell; IF port = NIL THEN RETURN; IF port.label # NIL THEN DeleteText[from.expansion, NIL, port.label]; IF DeleteableNet[port.pt.net, port.pt] THEN DeleteNet[from, port.pt.net]; IF port.pt.dependents = NIL THEN DeletePoint[from.expansion, port.pt]; [] _ from.ports.Delete[port]; END; DeleteStrand: PUBLIC PROC [editor: Editor] = BEGIN strand: Line _ FindLine[editor.secondary.point, editor.primary.point]; newName: ROPE _ editor.session.ctlPanel.name; from: CellType _ editor.subjectCell; changes: LORA; IF strand = NIL THEN RETURN; IF from.nets.Lookup[newName] # NIL THEN {Complain[editor, "net name taken"]; RETURN}; strand.net.stuff _ Filter[strand.net.stuff, strand]; strand.net _ NIL; changes _ BreakNet[from, editor.secondary.point, newName]; DeleteLine[from.expansion, NIL, NIL, strand]; END; BreakNet: PROC [in: CellType, start: Point, name: ROPE] RETURNS [changes: LORA] = BEGIN Explore: PROC [from: Point] = BEGIN new.stuff _ CONS[from, new.stuff]; from.net _ new; old.stuff _ Filter[old.stuff, from]; FOR la: LORA _ from.dependents, la.rest WHILE la # NIL DO WITH la.first SELECT FROM t: Text => ERROR; l: Line => IF l.net = new THEN NULL ELSE IF l.net = old THEN { new.stuff _ CONS[l, new.stuff]; l.net _ new; old.stuff _ Filter[old.stuff, l]; IF l.a = from THEN Explore[l.b] ELSE IF l.b = from THEN Explore[l.a] ELSE ERROR} ELSE IF l.net # NIL THEN ERROR; pi: PictureInstance => NULL; ENDCASE => ERROR; ENDLOOP; END; old: Net _ start.net; new: Net _ NEW [NetRep _ [name: name]]; changes _ NIL; Explore[start]; in.nets.Insert[new]; END; NewStrand: PUBLIC PROC [editor: Editor, final: BOOLEAN] = BEGIN cellType: CellType _ editor.subjectCell; strand: Line; net: Net _ NIL; changed: LORA _ NIL; a, b: Point; IF final AND editor.strandGoal # NIL THEN {a _ editor.primary.point; b _ editor.strandGoal} ELSE {a _ editor.secondary.point; b _ editor.primary.point}; IF a.net = b.net AND a.net # NIL THEN {Complain[editor, "Already connected"]; RETURN}; strand _ NewLine[editor.subjectPic, a, b]; IF strand = NIL THEN RETURN; IF strand.a.net # NIL THEN net _ strand.a.net ELSE StartNet[cellType, strand.a]; IF strand.b.net # NIL THEN net _ strand.b.net ELSE StartNet[cellType, strand.b]; IF net = NIL THEN net _ strand.a.net; strand.net _ net; net.stuff _ CONS[strand, net.stuff]; IF strand.a.net # net THEN changed _ JoinNet[cellType, strand.a.net, net]; IF strand.b.net # net THEN changed _ JoinNet[cellType, strand.b.net, net]; IF changed # NIL THEN NotifyLabels[changed, editor]; IF final THEN editor.strandGoal _ NIL; END; StartNet: PROC [cellType: CellType, point: Point] = {point.net _ NEW [NetRep _ [name: NewName[cellType.nets], otherProps: NIL, stuff: LIST[point]]]; cellType.nets.Insert[point.net]}; JoinNet: PROC [in: CellType, from, to: Net] RETURNS [changed: LORA] = BEGIN FOR l: LORA _ from.stuff, l.rest WHILE l # NIL DO WITH l.first SELECT FROM point: Point => IF point.net # to THEN {to.stuff _ CONS[point, to.stuff]; point.net _ to}; line: Line => IF line.net # to THEN {to.stuff _ CONS[line, to.stuff]; line.net _ to}; label: Text => IF label.labelOf = from THEN {to.stuff _ CONS[label, to.stuff]; label.labelOf _ to; label.rope _ to.name; changed _ CONS[label, changed]}; ENDCASE => ERROR; ENDLOOP; from.stuff _ NIL; from.eatenBy _ to; [] _ in.nets.Delete[from]; END; BreakWire: PUBLIC PROC [editor: Editor, input: LORA] RETURNS [output: LORA] = BEGIN new: Line; strand: Line _ FindLine[editor.secondary.point, editor.primary.point]; cellType: CellType _ editor.subjectCell; pic: PictureDef _ cellType.expansion; mv: Vertex; mp: Point; output _ input.rest; IF strand = NIL THEN {Complain[editor, "No strand between primary & secondary"]; RETURN}; mv[X] _ NewCoord[axis: X, at: (strand.a.c[X].z + strand.b.c[X].z)/2, pic: pic]; mv[Y] _ NewCoord[axis: Y, at: (strand.a.c[Y].z + strand.b.c[Y].z)/2, pic: pic]; mp _ MakePoint[pic: pic, vertex: mv]; mp.net _ strand.net; mp.net.stuff _ CONS[mp, mp.net.stuff]; new _ NewLine[pic, strand.a, mp]; new.net _ strand.net; new.net.stuff _ CONS[new, new.net.stuff]; SetBackToPoint[editor, editor.primary, mp]; strand.a _ mp; NotifyCoord[mp.c[X], editor]; NotifyCoord[mp.c[Y], editor]; END; JoinWire: PUBLIC PROC [editor: Editor, input: LORA] RETURNS [output: LORA] = BEGIN l1, l2: Line _ NIL; tooMany: BOOLEAN; mp: Point _ editor.primary.point; l1p: Point; cellType: CellType _ editor.subjectCell; pic: PictureDef _ cellType.expansion; output _ input.rest; IF mp = NIL THEN {Complain[editor, "primary empty"]; RETURN}; IF mp.deleted THEN ERROR; FOR la: LORA _ mp.dependents, la.rest WHILE la # NIL DO WITH la.first SELECT FROM t: Text => NULL; l: Line => IF l1 = NIL THEN l1 _ l ELSE IF l2 = NIL THEN l2 _ l ELSE {tooMany _ TRUE; EXIT}; pi: PictureInstance => NULL; ENDCASE => ERROR; ENDLOOP; IF tooMany THEN {Complain[editor, "Too many lines attached"]; RETURN}; l1p _ IF l1.a = mp THEN l1.b ELSE l1.a; l1.net.stuff _ Filter[l1.net.stuff, l1]; l1.net _ NIL; mp.net.stuff _ Filter[mp.net.stuff, mp]; mp.net _ NIL; DeletePoint[from: pic, point: mp]; DeleteLine[pic: pic, a: NIL, b: NIL, line: l1]; IF l2.a = mp THEN l2.a _ l1p ELSE l2.b _ l1p; NotifyCoord[mp.c[X], editor]; NotifyCoord[mp.c[Y], editor]; END; CreatePort: PUBLIC PROC [cellType: CellType, name: ROPE, point: Point] RETURNS [port: Port] = BEGIN port _ NEW [PortRep _ [name: name, pt: point]]; cellType.ports.Insert[port]; END; CreateComponent: PUBLIC PROC [in, of: CellType, name: ROPE, inst: PictureInstance] RETURNS [comp: Component] = BEGIN CreateComponentPort: PROC [any: REF ANY] RETURNS [stop: BOOLEAN] = {port: Port _ NARROW[any]; cp: ComponentPort _ NEW [ComponentPortRep _ [component: comp, port: port]]; cp.point _ NARROW[in.expansion.points.Lookup[ PIPointName[comp.inst.name, port.name]]]; stop _ FALSE; comp.ports.Insert[cp]; cp.point.fromCP _ cp}; comp _ NEW [ComponentRep _ [name: name, type: of, inst: inst]]; comp.inst.asComponent _ comp; in.components.Insert[comp]; comp.type.ports.EnumerateIncreasing[CreateComponentPort]; END; END. TScheme>SchemeCells.Mesa Last Edited by: Spreitzer, February 23, 1984 10:49 pm ΚD˜Icode™Jšœ5™5K˜KšΟk œœ]˜vK˜šΠbx œœ˜KšœR˜YKšœ˜—K˜Kšœœ˜$K˜šΟnœœœœ˜˜>—Kšœœ œ3˜GKšœ$˜$Kšœf˜fKšœ˜—K˜šŸ œœœ˜,Kš˜KšœœE˜`K˜K˜K˜Kšœ œœ)œ˜GKš œœœœ!œ6˜ŠKšœœœ$œ˜>šœF˜KKšœ+œ˜7—KšœR˜RKšœY˜YKšœ˜—K˜šŸœœœ˜/Kš˜š Ÿœœœœœœ˜4Kšœœœ˜/Kšœœ'œœœ"œœ˜ͺ—š Ÿœœœœœœ˜5Kšœœœ˜/Kšœ˜Kšœ'˜'—K˜"K˜$K˜K˜$Kšœœœ˜Kšœœœœ˜Kšœœœœ˜&K˜K˜&Kšœœœœ˜K˜'Kšœœœœ˜EKšœœ ˜/Kšœœœ"˜>K˜"Kšœ˜—K˜šŸ œœœœ˜IKšœœ˜Kšœœœœ˜š œœœœ˜0šœ œ˜Kšœ œœœ˜.Kšœœ˜Kšœ œ˜Kšœœ˜—Kšœ˜ ——K˜šŸ œœ˜,Kš˜Kšœœœœ˜š œœœœ˜0šœ œ˜Kšœœ˜Kšœ œ˜Kšœœœ˜AKšœœ˜—Kš˜—Kšœ œ˜K˜Kšœ˜—K˜šŸ œœœ#˜;Kš˜Kšœœœœ˜%K˜Kšœœ˜Kšœœœ˜=Kšœœœ˜=Kšœœœœ˜9Kšœœœœ˜9Kšœ˜—K˜š Ÿ œœœœœ˜?Kš œœœœœœ˜U—K˜šŸ œœœ˜)Kš˜Kšœœœœ˜%Kšœœœ˜šœœœ˜"K˜7Kšœ  œ˜&Kšœœ˜—Kšœ˜—K˜šŸœœœ˜'Kš˜Kšœ œ@˜SKšœœœ"œ˜