interface(extern-c){ xml2 = library:: pkgconfig("libxml-2.0"). include { xml2 = ["string.h"] }. } Matcher = type variant (Sequence, ZeroOrMore, Text). matchText = function(text::string, matcher::string, posStart::i64):: i64 { textLength = strlen(text):: i64. matcherLength = strlen(matcher):: i64. if(textLength >= posStart + matcherLength):: i64{ if(strncmp(text + posStart, matcher, matcherLength) == 0):: i64 { matcherLength } else {-1:: i64} } else {-2:: i64} } matchSequence = function(text::string, pattern::undef; interpretation(force), posStart::i64):: i64; interpretation(suppress){ textLength = length(text):: i64. loop fold(pattern-> matcher:: undef, posStart->pos):: i64{ recognizedSymbols = match(text, matcher, pos):: i64. if (recognizedSymbols > 0):: i64{ pos+recognizedSymbols } else { pos:: i64; break } } } matchZeroOrMore= function(text::string, matcher::undef; interpretation(force), posStart::i64):: i64; interpretation(suppress){ textLength = length(text):: i64. loop fold inf(posStart->pos):: i64{ recognizedSymbols = match(text, matcher, pos):: i64. if (recognizedSymbols > 0):: i64{ pos+recognizedSymbols } else { pos:: i64; break } } } match = function(text::string, pattern::undef; interpretation(force), posStart::i64)::i64; interpretation(suppress){ switch (pattern[0]) :: int case (Sequence) {matchSequence(text, pattern[1], posStart)} case (ZeroOrMore) {matchZeroOrMore(text, pattern[1], posStart)} case (Text) {matchText(text, pattern[1], posStart)} case default {-1} } main = function:: i64; entry { patternAB = [Sequence, [[ZeroOrMore, [Text, "a"]], [Text, "b"]]] :: undef; interpretation(force). // matchers = ["The ", "only ", "way "] :: [string]; interpretation(force). match("aaab", patternAB, 0):: i64 }