Search code examples
breakrascal

What is an elegant way to break out of a visit statement in Rascal MPL?


I'm using visit in rascal to iterate through a string. I would like to break out once I match a specific case. In other words, I would like to achieve this exact behavior:

str toVisit = "abcdefgh";

while(true) {
    visit(toVisit) {
        case /^bc/: println("before");
        case /^de/: break;
        case /^fg/: println("after");
    }

    break;
}

but without the while loop. There is no mention of this in the manual page of visit. Hence my question: is there an elegant way to break out of a visit statement in Rascal MPL?


Solution

  • visit is general better at recursive traversals then iterating, but return is the typical way people do break out of visits:

    void myFunction() {
        visit (toVisit) {
            case /^bc/: println("before");
            case /^de/: return;
            case /^fg/: println("after");
        }
    }
    

    So that favors smaller functions :-)

    Otherwise, regular expressions themselves have excellent backtracking behavior for searching linear patterns like that:

    for (/<before:.*>bc<middle:.*>de<after:.*>fg/ := "abcdefgh") {
       println("match! <before> <middle> <after>");
       // fail brings you to the next match (also for visit, if, etc)
       fail;
       // break jumps out of the loop
       break;
       // continue brings you to the next match as well
       continue;
    }