DIRECTORY Core, CoreCreate, CoreOps, CoreProperties, CoreRecord, CoreSequence, IO, Rope; CoreCreateImpl: CEDAR PROGRAM IMPORTS CoreOps, CoreProperties, CoreRecord, CoreSequence, IO, Rope EXPORTS CoreCreate = BEGIN OPEN Core, CoreCreate; CreateError: PUBLIC SIGNAL [type: CreateErrorType, message: ROPE] = CODE; CreateRecordCell: PUBLIC PROC [design: Design, name: ROPE, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] RETURNS [cell: CellType] = { recCell: CoreRecord.RecordCellType _ NEW[CoreRecord.RecordCellTypeRec _ [ internalWire: NEW[WireRec _ [ structure: record, elements: NEW[WireSequenceRec[0]]]]]]; cell _ NEW[CellTypeRec _ [ name: name, class: CoreRecord.recordCellClass, publicWire: NEW[WireRec _ [ structure: record, elements: NEW[WireSequenceRec[0]]]], data: recCell, properties: InsertAttributes[attribute: attribute, attributes: attributes]]]; IF name=NIL THEN SIGNAL CreateError[type: MissingParameter, message: "no name given for CreateRecordCell call"]; IF CoreOps.FetchCellType[design: design, name: name]#NIL THEN SIGNAL CreateError[type: DuplicateName, message: name]; CoreOps.InsertCellType[design: design, cellType: cell]; }; CreateSequenceCell: PUBLIC PROC [design: Design, name: ROPE, baseCell: CellType, count: NAT, sequencePorts: RopeList _ NIL, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] RETURNS [cell: CellType] = { sequenceCount: NAT _ 0; seqCell: CoreSequence.SequenceCellType; FOR rList: RopeList _ sequencePorts, rList.rest UNTIL rList=NIL DO sequenceCount _ sequenceCount + 1; ENDLOOP; seqCell _ NEW[CoreSequence.SequenceCellTypeRec[sequenceCount]]; seqCell.base _ baseCell; seqCell.count _ count; sequenceCount _ 0; FOR rList: RopeList _ sequencePorts, rList.rest UNTIL rList=NIL DO FOR base: NAT IN [0..baseCell.publicWire.elements.size) DO IF Rope.Equal[baseCell.publicWire.elements[base].name, rList.first] THEN { seqCell.sequence[sequenceCount] _ base; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; sequenceCount _ sequenceCount + 1; ENDLOOP; cell _ CoreSequence.Create[design: design, name: name, args: seqCell]; cell.properties _ InsertAttributes[attribute: attribute, attributes: attributes]; IF name=NIL THEN SIGNAL CreateError[type: MissingParameter, message: "no name given for CreateSequenceCell call"]; IF CoreOps.FetchCellType[design: design, name: name]#NIL THEN SIGNAL CreateError[type: DuplicateName, message: name]; CoreOps.InsertCellType[design: design, cellType: cell]; }; CreateIdentityCell: PUBLIC PROC [design: Design, name: ROPE, baseCell: CellType, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] RETURNS [cell: CellType] = { IF name=NIL THEN SIGNAL CreateError[type: MissingParameter, message: "no name given for CreateIdentityCell call"]; IF CoreOps.FetchCellType[design: design, name: name]#NIL THEN SIGNAL CreateError[type: DuplicateName, message: name]; cell _ CoreOps.Identity[cellType: baseCell, name: name]; cell.properties _ InsertAttributes[attribute: attribute, attributes: attributes]; CoreOps.InsertCellType[design: design, cellType: cell]; }; FetchCell: PUBLIC PROC [design: Design, name: ROPE] RETURNS [cell: CellType] = { IF name=NIL OR design=NIL THEN SIGNAL CreateError[type: MissingParameter, message: "no name or design given for FetchCellType call"]; cell _ CoreOps.FetchCellType[design: design, name: name]; }; CreateCellInstance: PUBLIC PROC [design: Design, in: CellType, type: CellType, bind: ROPE _ NIL, bindings: RopeList _ NIL, name: ROPE _ NIL, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] RETURNS [instance: CellInstance] = { PeekTokenType: PROC RETURNS [tokenKind: IO.TokenKind] = { pos: INT _ IO.GetIndex[s]; tokenKind _ IO.GetCedarTokenRope[s].tokenKind; IO.SetIndex[s, pos]; }; Complain: PROC [prefix: ROPE] RETURNS [complaint: ROPE] = { complaint _ IO.PutFR["%g in cell type %g while binding instance of %g", IO.rope[prefix], IO.rope[in.name], IO.rope[type.name]] }; IDError: PROC = { SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["field parse failed during parse of %g", IO.rope[bind]]]]; }; GetBreakChar: PROC RETURNS [b: CHAR] ={ tokenKind: IO.TokenKind; token: ROPE; [tokenKind: tokenKind, token: token] _ IO.GetCedarTokenRope[s]; IF tokenKind # tokenSINGLE THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["parsed %g when expecting break character", IO.rope[token]]]]; b _ Rope.Fetch[base: token, index: 0]; }; ParseSelector: PROC RETURNS [actualWire: Wire, finalChar: CHAR] = { actualWire _ into.internalWire; SELECT PeekTokenType[] FROM tokenID => { actualWire _ ParseField[actualWire ! IO.Error => GOTO idError]; DO SELECT (finalChar _ GetBreakChar[! IO.EndOfStream => EXIT]) FROM '[ => { CheckIndex: PROC [index: INT] = { IF index>= actualWire.elements.size OR index<0 THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["index larger than element count or less than zero during parse of %g", IO.rope[formal]]]]; }; index: INT _ IO.GetInt[s]; IF actualWire.structure # sequence OR actualWire.elements = NIL THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["cannot index during parse of %g", IO.rope[formal]]]]; CheckIndex[index]; SELECT PeekTokenType[] FROM tokenDOUBLE => { open: INT; construct: Wire; IF NOT Rope.Equal["..", IO.GetCedarTokenRope[s].token] THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["expected .. during parse of %g", IO.rope[formal]]]]; open _ IO.GetInt[s]; IF GetBreakChar[] # ') THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["expected ) during parse of %g", IO.rope[formal]]]]; CheckIndex[open-1]; construct _ NEW[WireRec _ [ structure: sequence, elements: NEW[WireSequenceRec[open-index]]]]; FOR i: INT IN [index..open) DO construct.elements[i-index] _ actualWire.elements[i]; ENDLOOP; actualWire _ construct; }; tokenSINGLE => { IF GetBreakChar[] # '] THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["expected ] during parse of %g", IO.rope[formal]]]]; actualWire _ actualWire.elements[index]; }; ENDCASE => SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["illegal token in selector during parse of %g", IO.rope[formal]]]]; }; '. => actualWire _ ParseField[actualWire ! IO.Error => GOTO idError]; ', => EXIT; '] => EXIT; ENDCASE => SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["illegal character in selector during parse of %g", IO.rope[formal]]]]; ENDLOOP; EXITS idError => IDError[]; }; tokenSINGLE => { construct: Wire; IF GetBreakChar[] # '[ THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["expected [ during parse of %g", IO.rope[formal]]]]; construct _ NEW[WireRec _ [ structure: record, elements: NEW[WireSequenceRec[0]]]]; DO fc: CHAR; newElements: WireSequence _ NEW[WireSequenceRec[construct.elements.size+1]]; FOR i: NAT IN [0..construct.elements.size) DO newElements[i] _ construct.elements[i] ENDLOOP; construct.elements _ newElements; [construct.elements[construct.elements.size-1], fc] _ ParseSelector[]; IF fc='] THEN EXIT; ENDLOOP; IF GetBreakChar[! IO.EndOfStream => CONTINUE]#', THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR[", must follow constructor during parse of %g", IO.rope[formal]]]]; actualWire _ construct; }; ENDCASE => SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["illegal token in selector during parse of %g", IO.rope[formal]]]]; }; ParseField: PROC [context: Wire] RETURNS [actualWire: Wire] = { actual: ROPE _ IO.GetID[s]; IF context.structure # record OR context.elements = NIL THEN SIGNAL CreateError[type: BadBinding, message: "cannot field select"]; FOR i: NAT IN [0..context.elements.size) DO IF Rope.Equal[context.elements[i].name, actual] THEN { actualWire _ context.elements[i]; EXIT; }; REPEAT FINISHED => SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["cannot find field %g", IO.rope[actual]]]]; ENDLOOP; }; into: CoreRecord.RecordCellType; formal: ROPE; s: IO.STREAM; IF design=NIL OR in=NIL OR type=NIL THEN SIGNAL CreateError[MissingParameter, NIL]; IF in.data=NIL THEN SIGNAL CreateError[NotRecordCell, NIL]; IF NOT ISTYPE[in.data, CoreRecord.RecordCellType] THEN SIGNAL CreateError[NotRecordCell, NIL]; into _ NARROW[in.data]; IF bindings=NIL THEN bindings _ LIST[bind]; FOR bindList: RopeList _ bindings, bindList.rest UNTIL bindList=NIL DO bind _ bindList.first; s _ IO.RIS[bind]; instance _ NEW[CoreRecord.CellInstanceRec _ [ name: name, actualWire: NEW[WireRec _ [ structure: record, elements: NEW[WireSequenceRec[type.publicWire.elements.size]]]], type: type, properties: InsertAttributes[attribute: attribute, attributes: attributes]]]; into.instances _ CONS[instance, into.instances]; DO actualWire: Wire; fc: CHAR; formal _ IO.GetID[s ! IO.EndOfStream => EXIT; IO.Error => GOTO idError]; IF GetBreakChar[] # ': THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR[": must follow formal %g", IO.rope[formal]]]]; [actualWire, fc] _ ParseSelector[! IO.EndOfStream => GOTO unexpectedEnd]; FOR i:NAT IN [0..type.publicWire.elements.size) DO IF Rope.Equal[type.publicWire.elements[i].name, formal] THEN { instance.actualWire.elements[i] _ actualWire; EXIT; }; REPEAT FINISHED => SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["cannot find formal %g", IO.rope[formal]]]]; ENDLOOP; REPEAT idError => IDError[]; unexpectedEnd => SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["unexpected end of binding rope during parse of %g", IO.rope[formal]]]]; ENDLOOP; FOR act:NAT IN [0..instance.actualWire.elements.size) DO IF instance.actualWire.elements[act]=NIL THEN { FOR int:NAT IN [0..into.internalWire.elements.size) DO IF Rope.Equal[type.publicWire.elements[act].name, into.internalWire.elements[int].name] THEN { instance.actualWire.elements[act] _ into.internalWire.elements[int]; EXIT; }; REPEAT FINISHED => SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["cannot bind formal %g", IO.rope[type.publicWire.elements[act].name]]]]; ENDLOOP; }; IF NOT CoreRecord.Conform[instance.actualWire.elements[act], type.publicWire.elements[act]] THEN SIGNAL CreateError[type: BadBinding, message: Complain[IO.PutFR["actual does not match formal %g", IO.rope[type.publicWire.elements[act].name]]]]; ENDLOOP; ENDLOOP; }; CreateWireSequenceType: PUBLIC PROC [design: Design, name: ROPE _ NIL, count: NAT, base: Wire _ NIL, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] RETURNS [wire: Wire] = { wire _ NEW[WireRec _ [ name: name, structure: sequence, elements: NEW[WireSequenceRec[count]], properties: InsertAttributes[attributes: attributes]]]; IF base=NIL THEN base _ CoreOps.CreateAtomWire[]; FOR i: NAT IN [0..count) DO wire.elements[i] _ base; ENDLOOP; }; CreateWireRecordType: PUBLIC PROC [design: Design, name: ROPE _ NIL, components: LIST OF Wire, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] RETURNS [wire: Wire] = { wire _ CoreOps.CreateRecordWire[name: name, components: components]; wire.properties _ InsertAttributes[attributes: attributes]; }; CreateWireType: PUBLIC PROC [design: Design, name: ROPE _ NIL, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] RETURNS [wire: Wire] = { wire _ CoreOps.CreateAtomWire[name: name]; wire.properties _ InsertAttributes[attributes: attributes]; }; CreateWire: PUBLIC PROC [design: Design, in: CellType, name: ROPE _ NIL, names: RopeList _ NIL, type: Wire _ NIL, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] RETURNS [wire: Wire] = { IF names=NIL THEN names _ LIST[name]; FOR nameList: RopeList _ names, nameList.rest UNTIL nameList=NIL DO wire _ ReallyCreateWire[design: design, in: in, name: nameList.first, type: type, attributes: attributes]; ENDLOOP; }; ReallyCreateWire: PROC [design: Design, in: CellType, name: ROPE _ NIL, type: Wire _ NIL, attributes: Attributes _ NIL] RETURNS [newWire: Wire] = { recCell: CoreRecord.RecordCellType _ NARROW[in.data]; intWire: Wire _ recCell.internalWire; newWireSeq: WireSequence _ NEW[WireSequenceRec[intWire.elements.size+1]]; FOR i: NAT IN [0..intWire.elements.size) DO newWireSeq[i] _ intWire.elements[i]; ENDLOOP; newWire _ IF type= NIL THEN CoreOps.CreateAtomWire[name: name] ELSE CoreOps.CopyWire[wire: type]; newWire.name _ name; newWire.properties _ InsertAttributes[attributes: attributes]; IF type#NIL THEN newWire.properties _ CoreProperties.AppendProps[winner: newWire.properties, loser: type.properties]; newWireSeq[intWire.elements.size] _ newWire; intWire.elements _ newWireSeq; }; CreatePublicWire: PUBLIC PROC [design: Design, on: CellType, name: ROPE _ NIL, names: RopeList _ NIL, type: Wire _ NIL, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] RETURNS [wire: Wire] = { IF names=NIL THEN names _ LIST[name]; FOR nameList: RopeList _ names, nameList.rest UNTIL nameList=NIL DO pubWire: Wire _ on.publicWire; newWireSeq: WireSequence _ NEW[WireSequenceRec[pubWire.elements.size+1]]; wire _ ReallyCreateWire[design: design, in: on, name: nameList.first, type: type, attributes: attributes]; FOR i: NAT IN [0..pubWire.elements.size) DO newWireSeq[i] _ pubWire.elements[i]; ENDLOOP; newWireSeq[pubWire.elements.size] _ wire; pubWire.elements _ newWireSeq; ENDLOOP; }; PutAttributeOnCell: PUBLIC PROC [design: Design, on: CellType, attribute: Attribute _ [NIL, NIL], attributes: Attributes _ NIL] = { on.properties _ InsertAttributes[attribute: attribute, attributes: attributes, properties: on.properties]; }; InsertAttributes: PROC [attribute: Attribute _ [NIL, NIL], attributes: Attributes, properties: Properties _ NIL] RETURNS [newProperties: Properties] = { newProperties _ properties; newProperties _ CoreProperties.PutProp[on: newProperties, prop: attribute.key, value: attribute.val]; FOR att: Attributes _ attributes, att.rest UNTIL att=NIL DO newProperties _ CoreProperties.PutProp[on: newProperties, prop: att.first.key, value: att.first.val]; ENDLOOP; }; END. ˜CoreCreateImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Barth, September 26, 1985 2:19:39 pm PDT Cells Wires Attributes สญ– "cedar" style˜codešœ™Kšœ ฯmœ1™Kšœ-˜-Kšžœ˜K˜—šž˜Kšžœžœ1žœ žœ˜x—Kšžœ˜—šž˜Kšœ˜Kšœžœ1žœ<žœ˜™—Kšžœ˜—šžœžœžœ(ž˜8šžœ#žœžœ˜/šžœžœžœ&ž˜6šžœVžœ˜^KšœD˜DKšžœ˜K˜—šž˜Kšžœžœ1žœ žœ-˜”—Kšžœ˜—K˜—Kš žœžœVžœžœ1žœ*žœ-˜๓Kšžœ˜—Kšžœ˜—Kšœ˜K˜——™š œžœžœžœžœ žœžœžœžœžœžœ˜พšœžœ ˜K˜ Kšœ˜Kšœ žœ˜&Kšœ7˜7—Kšžœžœžœ!˜1šžœžœžœ ž˜Kšœ˜Kšžœ˜—Kšœ˜K˜—š œžœžœžœžœžœžœžœžœžœžœ˜ธKšœD˜DKšœ;˜;Jšœ˜J˜—š œžœžœžœžœžœžœžœžœ˜˜Kšœ*˜*Kšœ;˜;Jšœ˜J˜—š  œžœžœ&žœžœžœžœžœžœžœžœ˜หKšžœžœžœ žœ˜%šžœ+žœ žœž˜CKšœj˜jKšžœ˜—Kšœ˜K˜—š œžœ&žœžœžœžœžœ˜“Kšœ%žœ ˜5Kšœ%˜%Kšœžœ+˜Išžœžœžœž˜+Kšœ$˜$Kšžœ˜—Kš œ žœžœžœ$žœ˜aKšœ˜Kšœ>˜>Kšžœžœžœe˜uKšœ,˜,Kšœ˜Kšœ˜K˜—š œžœžœ&žœžœžœžœžœžœžœžœ˜ัKšžœžœžœ žœ˜%šžœ+žœ žœž˜CKšœ˜Kšœžœ+˜IKšœj˜jšžœžœžœž˜+Kšœ$˜$Kšžœ˜—Kšœ)˜)Kšœ˜Kšžœ˜—Kšœ˜K˜——™ š  œžœžœ8žœžœžœ˜ƒKšœj˜jKšœ˜K˜—š  œžœžœžœ4žœžœ ˜˜Kšœ˜Kšœe˜ešžœ(žœžœž˜;Kšœe˜eKšžœ˜—Kšœ˜K˜——Kšžœ˜K˜—…—6‚Eว