!7 cprint { class State extends ProbabilisticMachine2.State { ImmutableListWalker inputWalker; Chain stack; public State makeDescendant() { State s = prepareDescendant(new State); s.inputWalker = inputWalker; s.stack = stack; ret s; } void doneWithSubroutine { if (stack == null) ret; State s = makeDescendant(); s.stack = dropFirst(s.stack); process(s, first(stack)); } void step { doneWithSubroutine(); } } record SequenceCons(a, b) > State { void step { State s = makeDescendant(); s.stack = chainPlus(s.stack, b); process(s, a); } } record grab(S what) > Executable { void step(State state) { if (state.inputWalker.atEnd()) ret; S token = state.inputWalker!; if (eq(token, what)) { State s = state.makeDescendant(); s.inputWalker = s.inputWalker.next(); } } } class EndOfInput > Executable { void step(State state) { print("end of input reached"); super.step(); } } // what: string or a GrammarClass Executable sequence(O... steps) { if (empty(steps)) ret new Executable; ret foldl_noSeed((a, b) -> new SequenceCons(a, b), steps); } start-thread { Sequence main = sequence( new grab("Hello"), new grab("world"), new EndOfInput); printIndentedStruct(main); S input = "Hello world"; new ProbabilisticMachine2 pm; pm.withState(new State { { inputWalker = new ImmutableListWalker(javaTokC(input)); } }, r { main.step(pm.currentState!); }); stepAllWithStats(pm); } }