class WordList inherits System { word: String; next: WordList; init(value: String, tail: Object) : WordList {{ assert(not (isvoid value), "init", "value argument cannot be void!"); assert(word = "", "init", "List has already been initialised!"); word <- value; if isvoid tail then void else case tail of wl: WordList => next <- wl; o: Object => assert(false, "init", "tail argument can be either a ConsumerList or void!"); esac fi; self; }}; push(value: String) : WordList {{ assert(not (isvoid value), "push", "value argument cannot be void!"); if word = "" then word <- value else if isvoid next then next <- (new WordList).init(value, void) else next.push(value) fi fi; self; }}; any_starts(s: String, start: Int) : Int { if or(word = "", s.length() <= start) then 0 else if and(s.length() < start + word.length(), not isvoid next) then next.any_starts(s, start) else if s.substr(start, word.length()) = word then word.length() else if isvoid next then 0 else next.any_starts(s, start) fi fi fi fi }; empty() : Bool { if not (word = "") then false else if isvoid next then true else next.empty() fi fi }; }; class IWordsConsumer inherits IStringConsumer { matched_words: WordList <- new WordList; consume(s: String) : Int { let word_length: Int <- 0 in { assert(not matched_words.empty(), "consume", "object of class hasn't been initialised!"); consumed_length <- 0; while 0 < (word_length <- matched_words.any_starts(s, consumed_length)) loop consumed_length <- consumed_length + word_length pool; consumed_length; }}; };