DIRECTORY Basics, BasicTime, CedarProcess, FS, IO, MakeDo, MakeDoPrivate, RedBlackTree, Rope; MakeDoDownNodes: CEDAR MONITOR IMPORTS CedarProcess, IO, MakeDo, MakeDoPrivate, Rope EXPORTS MakeDo, MakeDoPrivate = BEGIN OPEN MakeDo, MakeDoPrivate; NodeRep: PUBLIC TYPE = MakeDoPrivate.NodeRep; CommandRep: PUBLIC TYPE = MakeDoPrivate.CommandRep; Enter: ENTRY PROC [n: Node] = { ENABLE UNWIND => {}; WHILE n.down.locked DO WAIT n.down.change ENDLOOP; n.down.locked _ TRUE; }; MayEnterDownNode: PUBLIC ENTRY PROC [n: Node] RETURNS [in: BOOL] = { ENABLE UNWIND => {}; in _ NOT n.down.locked; IF in THEN n.down.locked _ TRUE; }; ExitDownNode: PUBLIC ENTRY PROC [n: Node] = { ENABLE UNWIND => {}; n.down.locked _ FALSE; BROADCAST n.down.change; }; DoIn: PROC [n: Node, p: --INTERNAL-- PROC [Node]] = { Enter[n]; {ENABLE UNWIND => ExitDownNode[n]; p[n]; }; ExitDownNode[n]; }; SuspectProducer: PUBLIC --ENTRY-- PROC [n: Node, stack: Table] = { Inner: --INTERNAL-- PROC [n: Node] = { prod: Command = IF n.producer # NIL AND n.producer.c # leaf THEN n.producer.c ELSE NIL; IF prod # NIL THEN { CmdMayNeedRemaking[prod, cmd, stack]; CmdMayNeedRemaking[prod, data, stack]; } ELSE NodeMayNeedRemaking[n, stack]; }; DoIn[n, Inner]; }; PublicPartsOfNode: PUBLIC PROC [n: Node] RETURNS [name: ROPE, class: NodeClass] = { name _ n.name; class _ n.class; }; GetProducer: PUBLIC --ENTRY-- PROC [n: Node] RETURNS [producer: Command] = { Inner: INTERNAL PROC [n: Node] = { producer _ IF n.producer # NIL AND n.producer.c # leaf THEN n.producer.c ELSE NIL; }; DoIn[n, Inner]; }; GetLeaf: PUBLIC PROC [name: ROPE, class: NodeClass] RETURNS [node: Node] = { node _ GetNode[name, class]; VolunteerLeaf[node]; }; VolunteerLeaf: --ENTRY-- PROC [n: Node] = { DoIn[n, InnerVolunteerLeaf]; }; InnerVolunteerLeaf: --INTERNAL-- PROC [n: Node] = { IF n.producer = NIL THEN n.producer _ NEW [EdgeRep _ [ c: leaf, n: n, cNext: NIL, cPrev: NIL, nNext: NIL, nPrev: NIL, optional: FALSE ]] ELSE IF n.producer.c = NIL THEN ERROR; }; EnsureNodeProduced: --INTERNAL-- PROC [n: Node] = BEGIN n2: Node; IF n.producer # NIL THEN RETURN; n2 _ TryToProduce[n.name, n.class]; IF n # n2 THEN Warning[IO.PutFR["Disagreement on cannonical name for %g or %g", IO.rope[n.name], IO.rope[n2.name]]]; InnerVolunteerLeaf[n]; END; FindNode: PUBLIC PROC [someName: ROPE, class: NodeClass] RETURNS [node: Node] = { node _ TryToProduce[someName, class]; VolunteerLeaf[node]; }; RetryToProduce: PUBLIC --ENTRY-- PROC [n: Node] = { Inner: --INTERNAL-- PROC [n: Node] = { n2: Node; IF n.producer # NIL AND n.producer.c # leaf THEN RETURN; IF n.producer # NIL AND n.producer.c = leaf THEN { e: Edge = n.producer; IF e.cNext # NIL OR e.cPrev # NIL THEN ERROR; IF e.nNext # NIL OR e.nPrev # NIL THEN ERROR; n.producer.c _ NIL; n.producer _ NIL; }; n2 _ TryToProduce[n.name, n.class]; IF n # n2 THEN Warning[IO.PutFR["Disagreement on cannonical name for %g or %g", IO.rope[n.name], IO.rope[n2.name]]]; InnerVolunteerLeaf[n]; }; DoIn[n, Inner]; }; Found: ERROR = CODE; TryToProduce: PROC [resultName: ROPE, class: NodeClass] RETURNS [sought: Node] = BEGIN PerFinder: PROC [f: Finder] = { found: BOOLEAN; makes: NodeList; from, cmdFrom: From; cmd: ROPE; class: CommandClass; foundData: REF ANY; CedarProcess.CheckAbort[]; [found, sought, makes, from, cmdFrom, cmd, class, foundData] _ f.finderProc[resultName: resultName, finderData: f.finderData]; IF found THEN { c: Command; first: BOOLEAN _ TRUE; soughtIn: BOOL _ FALSE; already: Command _ NIL; FOR ml: NodeList _ makes, ml.rest WHILE ml # NIL DO this: Command _ IF ml.first.producer = NIL THEN NIL ELSE ml.first.producer.c; soughtIn _ soughtIn OR (sought = ml.first); IF first THEN {already _ this; first _ FALSE} ELSE {IF this # already THEN Warning[IO.PutFR[ "Command %g doesn't precisely cover command %g (e.g., at %g)", IO.refAny[cmd], IO.refAny[IF already # NIL THEN already.cmd ELSE NIL], IO.rope[ml.first.name]]]}; ENDLOOP; IF soughtIn THEN { IF already # NIL THEN ERROR Found; c _ NEW [CommandRep _ [cmd: cmd, class: class, foundData: foundData, down: NewMonitorLock[]]]; FOR nl: NodeList _ makes, nl.rest WHILE nl # NIL DO n: Node _ nl.first; peh: EdgeRingHead _ emptyHead; IF n.producer # NIL THEN ERROR; [c.makes, peh] _ Link[c, c.makes, n, peh, FALSE, TRUE]; n.producer _ peh.first; ENDLOOP; AddConsumption[c, cmdFrom.mustHave, cmd, FALSE]; AddConsumption[c, cmdFrom.optional, cmd, TRUE]; AddConsumption[c, from.mustHave, data, FALSE]; AddConsumption[c, from.optional, data, TRUE]; ERROR Found } ELSE { Warning[Rope.Cat["Finder (", f.name, ") blew it"]]; sought _ NIL; }; } ELSE sought _ NIL; }; sought _ NIL; EnumerateFinders[PerFinder !Found => CONTINUE]; IF sought=NIL THEN sought _ GetNode[resultName, class]; END; NodeWork: PUBLIC --INTERNAL-- PROC [nWork: NWork] RETURNS [Subgoal] = { OPEN nWork; sg: Subgoal; isLeaf: BOOL; IF debugging THEN Log[depth, "EWn -> %g", IO.rope[goal.name]]; IF job.boundaryKnown AND NOT NodeInTable[goal, job.modifiable] THEN isLeaf _ TRUE ELSE { EnsureNodeProduced[goal]; isLeaf _ goal.producer = NIL OR goal.producer.c = leaf; }; IF isLeaf THEN {PostAmble[nWork, "leaf out"]; RETURN[NIL]}; IF NOT ShouldRemakeNode[goal, job.do] THEN {PostAmble[nWork, "not suspect"]; RETURN[NIL]}; { c: Command = goal.producer.c; cWork: CWork _ NEW [WorkRec[cmd] _ [ job: job, depth: depth, subject: cmd[c, goal] ]]; sg _ NEW [SubgoalRep _ [ job: job, toDo: NewWorkTable[], parent: nWork, AllDone: FinishNodeWork ]]; InsertWork[sg.toDo, cWork]; RETURN[sg]; }; }; FinishNodeWork: PROC [parent: WorkRef] RETURNS [Subgoal] = { nWork: NWork = NARROW[parent]; {OPEN nWork; PostAmble[nWork, "end"]; RETURN [NIL]; }; }; PostAmble: PROC [nWork: NWork, msg: ROPE] = { OPEN nWork; IF debugging THEN Log[depth, "EWn <- %g %g", IO.rope[goal.name], IO.rope[msg]]; }; END. žMakeDoDownNodes.Mesa Last Edited by: Spreitzer, September 4, 1985 11:03:35 pm PDT Carl Hauser, April 11, 1985 3:43:34 pm PST LOCKS n.down USING n: Node Κό– "cedar" style˜code™J™˜>Kšœ ˜Kš œœ œœ œœ˜6Kšœ˜———Kšœ˜—šœ ˜ šœ˜Kšœ œœœ˜"KšœœW˜^šœœœ˜3K˜Kšœ˜Kšœœœœ˜Kšœ*œœ˜7Kšœ˜Kšœ˜—Kšœ)œ˜0Kšœ)œ˜/Kšœ'œ˜.Kšœ'œ˜-Kšœ˜ K˜—šœ˜Kšœ3˜3Kšœ œ˜ Kšœ˜——Kšœ˜—Kšœ œ˜K˜—Kšœ œ˜ Kšœ%œ˜/Kšœœœ%˜7Kšœ˜—K˜š Ÿœœ  œœœ˜GKšœ˜ K˜ Kšœœ˜ Kšœ œœ˜>Kš œœœ#œ ˜Qšœ˜K˜Kšœœœ˜7K˜—Kšœœ œœ˜;Kš œœ œ#œœ˜ZK˜K˜šœœ˜$K˜ Kšœ ˜ Kšœ˜K˜—šœœ˜K˜ K˜K˜K˜K˜—Kšœ˜Kšœ˜ K˜K˜—K˜šŸœœœ˜