Search code examples
rascal

use pattern to bind to parameters of a constructor while visiting nodes in Rascal


I am trying to do a top-down visit of an Algebraic Data Type. When I find a node of a certain type, I would also like to bind to the nodes of that particular node, for e.g.

data Script=script(list[Stmt] body | ...
data Stmt  =exprstmt(Expr expr)| ...
data Expr  =assign(Expr left, Expr right) | var(str name)| scalar(Type aType)|... ;


Script myScript=someScript(srcFile);
top-down visit(myScript)
{
    case (Expr e:assign(left,right), left:=var(_), right :=scalar(_) )
    {
        str varName=left.name;
        Type myType=right.aType;
    }
}

So what I'm trying to do in the case statement is to search for a specific kind of node: i.e. of type assign(var(),scalar()) by doing a couple of pattern matches. My intention is to bind the variables left and right to var() and scalar() respectively at the same time that I find the particular kind of node. I hoped to NOT do a nested 'case' statement in order to retrieve information about the sub-nodes. Maybe that is possible, but I'm not sure.


Solution

  • You can just nest the patterns, like so:

    top-down visit(myScript) {
        case e:assign(l:var(varName),r:scalar(aType)) :
          // do something useful
          println("<varName> : <aType>");
    }
    

    I believe left and right might be reserved keywords so this is why I used l and r instead.

    Or simpler (because you don't need names for the nested patterns:

    top-down visit(myScript) {
        case assign(var(varName),scalar(aType)) :
          // do something useful
          println("<varName> : <aType>");
    }