// goes well with the stage {} macro (see tok_stages) srecord Stages2(L stages) is Steppable, Runnable { int iStage; Stage stage; // set this to record timing for each stage settable transient FunctionTimings timings; { stages = new L; } record noeq Stage(S name, Runnable body) { run { if (timings != null) timings.do(name, body); else callF(body); } toString { ret or2(name, "Unnamed stage"); } } public bool step() { if (iStage >= l(stages)) false; var stage = stages.get(iStage++); stage.run(); true; } Stage stage(Stage stage) { stages.add(stage); ret stage; } Stage stage(S name, Runnable body) { ret stage(new Stage(name, body)); } run { stepAll(this); } int indexOfStage(Stage stage) { ret stages.indexOf(stage); } void stepUntilStage(Stage stage) { int index = indexOfStage(stage); while (iStage <= index && step()) {} } L completedStages() { ret cloneTakeFirst(stages, iStage); } L remainingStages() { ret cloneDropFirst(stages, iStage); } }