<> <> <> DIRECTORY Basics, BasicTime, CedarProcess, Commander, CommandTool, Containers, FS, Icons, IO, IOClasses, List, MakeDo, MakeDoBasics, MakeDoPrivate, MessageWindow, MoreIOClasses, Process, ProcessProps, RedBlackTree, Rope, TypeScript, UserProfile, ViewerClasses, ViewerEvents, ViewerIO, ViewerOps; MakeDoBasic2Impl: CEDAR PROGRAM IMPORTS CedarProcess, IO, MakeDo, MakeDoBasics, MakeDoPrivate, RedBlackTree EXPORTS MakeDo = BEGIN OPEN MakeDo, MakeDoPrivate, MakeDoBasics; NodeRep: PUBLIC TYPE = MakeDoPrivate.NodeRep; ActionRep: PUBLIC TYPE = MakeDoPrivate.ActionRep; NodeClassRep: PUBLIC TYPE = MakeDoPrivate.NodeClassRep; Abandon: ERROR = CODE; GetActions: PUBLIC PROC [goals: RefTable, modifiabilitySpec: ModifiabilitySpec, report: ReportSpec] RETURNS [actions: ActionList] = { nodesSeen: RefTable = MakeRefTable[]; stackedActions: RefTable = MakeRefTable[]; actionsSeen: RefTable = MakeRefTable[]; WorkOnGoal: PROC [data: REF ANY] RETURNS [stop: BOOL _ FALSE] --RedBlackTree.EachNode-- = { goal: Node = NARROW[data]; WOG: --INTERNAL-- PROC = { InnerSetModifiability[goal, goals, modifiabilitySpec]; [] _ WorkOn[goal]; }; DoIn[WOG]; }; WorkOn: --INTERNAL-- PROC [subj: Node] RETURNS [do: BOOL _ FALSE] = { a: Action _ NIL; subDo: BOOL _ FALSE; sourceMissing, sourceNonCurrent, sourceBroken: BOOL _ FALSE; missedList: NodeList _ NIL; Finish: --INTERNAL-- PROC [current: ExpensiveBool] = { SetCurrency[subj, current]; nodesSeen.Insert[subj, subj]; do _ do OR subDo; IF a # NIL THEN { [] _ stackedActions.Delete[a]; IF (SELECT report FROM none => FALSE, all => TRUE, toBeDone => do, ENDCASE => ERROR) AND actionsSeen.Lookup[a] = NIL THEN { actionsSeen.Insert[a, a]; actions _ CONS[a, actions]; }; }; }; CheckSource: --INTERNAL-- PROC [n: Node, which: ActionDep, optional: BOOL] = { CedarProcess.CheckAbort[]; InnerSetModifiability[n, goals, modifiabilitySpec]; subDo _ WorkOn[n] OR subDo; IF (NOT optional) AND n.created = notExistTime THEN { sourceMissing _ TRUE; IF subj.modifiability=yes THEN missedList _ CONS[n, missedList]; }; SELECT n.current FROM true => {IF n.broken THEN SetBroken[subj, sourceBroken _ TRUE]}; false => sourceNonCurrent _ TRUE; notComputed => ERROR; ENDCASE => ERROR; }; detTrue, detFalse: BOOL _ FALSE; IF subj.producer = NIL THEN InnerGetProduced[subj]; IF InnerLeaf[subj] THEN { IF NOT nodesSeen.Lookup[subj] = subj THEN Finish[true]; RETURN}; a _ subj.producer.a; IF nodesSeen.Lookup[subj] = subj THEN { IF subj.current = notComputed THEN ERROR; do _ actionsSeen.Lookup[a] = a; RETURN; }; SELECT stackedActions.Lookup[a] FROM NIL => stackedActions.Insert[a, a]; a => { Warning[IO.PutFR["Found cycle containing %g --- you lose", [rope[a.cmd]]]]; Abandon[]}; ENDCASE => ERROR; SetBroken[subj, subj.modifiability=yes AND subj.created=notExistTime]; InnerEnumerateSources[a, cmd, CheckSource]; IF sourceNonCurrent THEN detFalse _ TRUE ELSE IF sourceBroken THEN detTrue _ TRUE; SELECT a.derivedFromCurrentDeterminers FROM TRUE => NULL; FALSE => { InnerRederive[a]; a.derivedFromCurrentDeterminers _ TRUE; }; ENDCASE => ERROR; sourceNonCurrent _ sourceBroken _ sourceMissing _ FALSE; missedList _ NIL; InnerEnumerateSources[a, data, CheckSource]; IF detFalse THEN {Finish[false]; RETURN}; IF detTrue THEN {Finish[true]; RETURN}; IF sourceNonCurrent THEN {Finish[false]; RETURN}; IF sourceBroken THEN {Finish[true]; RETURN}; IF sourceMissing THEN { IF subj.modifiability=yes THEN { SetBroken[subj, TRUE]; Warning[IO.PutFR[ "Can't %g because %g don't exist", [rope[a.cmd]], [rope[EnglishList[missedList].el]] ]]; }; Finish[true]; RETURN; }; IF a.fails = true THEN {Finish[true]; RETURN}; IF NOT subj.consistencyAsked THEN { [subj.consistent, subj.consistencyReason] _ a.class.CheckConsistency[a, subj]; subj.consistencyAsked _ TRUE; }; IF subj.consistent THEN {Finish[true]; RETURN}; do _ TRUE; Finish[false]; }; actions _ NIL; StatelessEnumerateRefTable[goals, WorkOnGoal !Abandon => CONTINUE]; nodesSeen.DestroyTable[]; actionsSeen.DestroyTable[]; stackedActions.DestroyTable[]; }; Start: PROC = { }; Start[]; END.