DIRECTORY IO, Rope, RoseEvents, RoseTypes, RoseConditions, Trees; RoseConditionsImpl: CEDAR PROGRAM IMPORTS IO, Rope, RoseEvents, RoseTypes, Trees EXPORTS RoseConditions = BEGIN OPEN RoseConditions; ROPE: TYPE = Rope.ROPE; Cell: TYPE = RoseTypes.Cell; IncrementalCondition: TYPE = REF IncrementalConditionRep; IncrementalConditionRep: PUBLIC TYPE = RECORD [ eval: IncrementalEvalProc _ NIL, data: REF ANY _ NIL, parent: IncrementalCondition _ NIL, sibling: IncrementalCondition _ NIL, value, sensitiveTo: BOOLEAN _ FALSE]; IncrementalEvalProc: TYPE = PROC [ic: IncrementalCondition]; test: PUBLIC Trees.NodeType; UnPostIncrementally: PUBLIC PROC [ic: IncrementalCondition] = BEGIN SELECT ic.eval FROM IETop => UnPostIncrementally[NARROW[ic.data, TopData].child]; IEAnd, IEOr, IENot => FOR child: IncrementalCondition _ NARROW[ic.data], child.sibling WHILE child # NIL DO UnPostIncrementally[child]; ENDLOOP; IETest => BEGIN nt: NodeTest _ NARROW[ic.data]; RoseEvents.RemoveWatcher[$ChangeLate, [NotifyIncremental, ic], nt.node]; END; ENDCASE => ERROR; END; PostIncrementally: PUBLIC PROC [cond: Condition] RETURNS [ic: IncrementalCondition] = BEGIN ic _ NEW [IncrementalConditionRep _ [eval: IETop, sensitiveTo: TRUE]]; ic.data _ NEW [TopDataRep _ [ cond: cond, child: PostIE[parent: ic, cond: cond] ]]; END; TopData: TYPE = REF TopDataRep; TopDataRep: TYPE = RECORD [ cond: Condition, child: IncrementalCondition]; IETop: IncrementalEvalProc = BEGIN td: TopData _ NARROW[ic.data]; IF td.child.value THEN SIGNAL RoseTypes.Stop["Incremental Breakpoint hit", td.cond]; END; PostIE: PROC [parent: IncrementalCondition, cond: Condition] RETURNS [ic: IncrementalCondition] = BEGIN recurse: BOOLEAN _ TRUE; last: IncrementalCondition _ NIL; ic _ NEW [IncrementalConditionRep _ [parent: parent]]; SELECT cond.info FROM test => BEGIN nt: NodeTest _ NARROW[cond.leftChild]; ic.eval _ IETest; ic.data _ cond.leftChild; recurse _ FALSE; RoseEvents.AddWatcher[$ChangeLate, [NotifyIncremental, ic], nt.node]; END; Trees.and => ic.eval _ IEAnd; Trees.or => ic.eval _ IEOr; Trees.not => ic.eval _ IENot; ENDCASE => ERROR; IF recurse THEN BEGIN FOR c: Condition _ NARROW[cond.leftChild], c.rightSibling WHILE c # NIL DO next: IncrementalCondition _ PostIE[parent: ic, cond: c]; next.sibling _ last; last _ next; ENDLOOP; ic.data _ last; END; ic.eval[ic]; END; NotifyIncremental: RoseEvents.NotifyProc = BEGIN IncrementalEval[NARROW[watcherData]]; END; IncrementalEval: PROC [ic: IncrementalCondition] = BEGIN old: BOOLEAN _ ic.value; ic.eval[ic]; IF ic.value # old AND ic.value = ic.parent.sensitiveTo AND ic.parent # NIL THEN IncrementalEval[ic.parent]; END; IETest: IncrementalEvalProc = BEGIN nt: NodeTest _ NARROW[ic.data]; ic.sensitiveTo _ NOT (ic.value _ nt.testProc[testData: nt.testData, nodeType: nt.node.type, where: nt.node.visible.SocketToWP[]]); END; IEAnd: IncrementalEvalProc = BEGIN FOR child: IncrementalCondition _ NARROW[ic.data], child.sibling WHILE child # NIL DO IF NOT child.value THEN BEGIN ic.sensitiveTo _ NOT (ic.value _ FALSE); EXIT; END; ENDLOOP; ic.sensitiveTo _ NOT (ic.value _ TRUE); END; IEOr: IncrementalEvalProc = BEGIN FOR child: IncrementalCondition _ NARROW[ic.data], child.sibling WHILE child # NIL DO IF child.value THEN BEGIN ic.sensitiveTo _ NOT (ic.value _ TRUE); EXIT; END; ENDLOOP; ic.sensitiveTo _ NOT (ic.value _ FALSE); END; IENot: IncrementalEvalProc = BEGIN ic.value _ ic.sensitiveTo _ NOT NARROW[ic.data, IncrementalCondition].value; END; PostOnCell: PUBLIC PROC [cell: Cell, condition: Condition] = BEGIN RoseEvents.AddWatcher[$EndOfClockCycle, [CheckCondition, condition], cell]; END; UnPostOnCell: PUBLIC PROC [cell: Cell, condition: Condition] = BEGIN RoseEvents.RemoveWatcher[$EndOfClockCycle, [CheckCondition, condition], cell]; END; CheckCondition: RoseEvents.NotifyProc = BEGIN cond: Condition _ NARROW[watcherData]; ans: BOOLEAN _ EvalCondition[cond]; IF ans THEN SIGNAL RoseTypes.Stop["Strobed Breakpoint hit", cond]; END; EvalCondition: PROC [cond: Condition] RETURNS [ans: BOOLEAN] = BEGIN SELECT cond.info FROM test => BEGIN nt: NodeTest _ NARROW[cond.leftChild]; ans _ nt.testProc[testData: nt.testData, nodeType: nt.node.type, where: nt.node.visible.SocketToWP[]]; END; Trees.and => BEGIN FOR c: Condition _ NARROW[cond.leftChild], c.rightSibling WHILE c # NIL DO IF NOT EvalCondition[c] THEN RETURN [FALSE]; ENDLOOP; RETURN [TRUE]; END; Trees.or => BEGIN FOR c: Condition _ NARROW[cond.leftChild], c.rightSibling WHILE c # NIL DO IF EvalCondition[c] THEN RETURN [TRUE]; ENDLOOP; RETURN [FALSE]; END; Trees.not => ans _ NOT EvalCondition[NARROW[cond.leftChild]]; ENDCASE => ERROR; END; LongNodeName: PROC [nodeName: ROPE, cell: Cell] RETURNS [l: ROPE] = BEGIN l _ NIL; WHILE cell.parent # NIL DO l _ IF l = NIL THEN cell.name ELSE cell.name.Cat[".", l]; cell _ cell.parent; ENDLOOP; l _ IF l = NIL THEN nodeName ELSE l.Cat[".", nodeName]; END; WriteTest: Trees.WriteProc = BEGIN nt: NodeTest _ NARROW[leftChild]; to.PutF["%g=%g", IO.rope[LongNodeName[nt.nodeName, nt.cell]], IO.rope[nt.nodeFormat.FormatTest[ nt.node.type, nt.nodeFormat, nt.testProc, nt.testData]]]; END; Setup: PROC = BEGIN OPEN Trees.stuff; test _ Trees.NewNodeType[LIST[ DA[$arity, $Leafary], DP[$write, WriteTest] ]]; END; Setup[]; END. ZRoseConditionsImpl.Mesa Last Edited by: Spreitzer, September 3, 1984 2:29:39 pm PDT Κ˜J™J™;J˜codešΟk ˜ Kšœ5˜7—K˜šΠbxœœ˜!Kšœœ$˜.Kšœ˜—K˜Kšœœ˜K˜Kšœœœ˜Kšœœ˜K˜Kšœœœ˜9šœœœœ˜/Kšœœ˜ Kšœœœœ˜Kšœœ˜#Kšœ œ˜$Kšœœœ˜%—K˜KšΟnœœœ˜Kš˜K˜NKšœ˜—K˜šŸœ˜'Kš˜Kšœœ˜&Kšœœ˜#Kšœœœ0˜BKšœ˜—K˜šŸ œœœœ˜>Kš˜šœ ˜šœ˜ Kšœœ˜&Kšœf˜fKšœ˜—šœ ˜š œœ!œœ˜JKš œœœœœ˜,Kšœ˜—Kšœœ˜Kšœ˜—šœ ˜š œœ!œœ˜JKšœœœœ˜'Kšœ˜—Kšœœ˜Kšœ˜—Kšœœœ˜=Kšœœ˜—Kšœ˜—K˜š Ÿ œœ œœœ˜CKš˜Kšœœ˜šœœ˜Kš œœœœ œ˜9K˜Kšœ˜—Kš œœœœ œ˜7Kšœ˜—K˜šŸ œ˜Kš˜Kšœœ ˜!šœ˜Kšœ*˜,šœ˜!Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜——Kšœ˜—K˜šŸœœ˜ Kšœœ ˜K˜Kšœœœœ˜NK˜Kšœ˜—K˜K˜K˜Kšœ˜—…—¨!