Search code examples
rascal

Rascal - Rewrite AST using a visitor


I am trying to rewrite all the different Types in the AST to a single type (like char() for example). So far I am able to find the types, but I cannot seem to find a way to rewrite them.

So the idea is to do something like this (this example doesn't work ofcourse):

visit (ast) {
    case \Type(_) => \Type(char())
}

Can someone please help me, and tell me how to do this?


Solution

  • One thing to remember is that you can't change values in Rascal using side effects: when you change a value, what you get instead is a new instance of that datatype with the changes, but the old instance still remains (if anything refers to it). When you do a visit, you get back a new instance of the datatype with any changes you've made, but you need to assign this somewhere or it will be lost. Here is an example illustrating this:

    rascal>data A = a() | b();
    ok
    
    rascal>data A = c(A a);
    ok
    
    rascal>myA = c(a());
    A: c(a())
    
    rascal>visit(myA) { case a() => b() }
    A: c(b())
    
    rascal>myA;
    A: c(a())
    
    rascal>myA = visit(myA) { case a() => b() }
    A: c(b())
    
    rascal>myA;
    A: c(b())
    

    As you can see, with the first visit the a() inside c(a()) is changed to a b(), but myA is still what it was before. Once you assign the value of the visit into myA, the change is preserved.