=========================== DATA patternAB = [Sequence, [[ZeroOrMore, "a"], [Text, "b"]]]. ========================== HANDLERS Matcher = type variant (Sequence, ZeroOrMore, Text) matchSequence = function(text::string, sequence::undef):: int{ textLength = length(text):: int. loop fold(sequence-> matcher:: undef, 0->pos){ n = match(mid(text, pos, textLength), matcher). if (n == pos_FAIL:: break){ pos } else { pos+n } } } matchZeroOrMore= function(text::string, matcher::string):: int{ textLength = length(text):: int. loop fold inf(0->pos, n==pos_FAIL){ //<--- infinite loop? n = match(matcherChild, mid(text, pos, textLength)). if (n == pos_FAIL:: break){ pos } else { pos+n } } } matchText = function(text::string, matcher::string):: int { textLength = length(text):: int. if (length(matcher) <= textLength, mid(text, 0, length(matcher)) == matcher) { textLength; } else { pos_FAIL; } } match = function(text::string, pattern::undef)::string{ n = switch (pattern[0]) :: int case (Sequence) {matchSequence(text, pattern[1])} case (ZeroOrMore) {matchZeroOrMore(text, pattern[1])} case (Text) {matchText(text, pattern[1])} case default {pos_FAIL} if (n != pos_FAIL) {mid(text, 0, n)} else {text_FAIL} } ================================= CLIENT test = function(){ match(patternAB, "aaaaab"). match(patternAB, "baaaaa"). }