3

Suppose I want to print all locations with a hard coded value, in a context were d is an M3 Declaration:

top-down visit(d) {
    case \number(str numberValue) :
        println("hardcode value <numberValue> encountered at <d@\src>");
}

The problem is that the location <d@\src> is too generic, it yields the entire declaration (like the whole procedure). The expression <numberValue@\src> seems more appropriate, but it is not allowed, probably because we are too low in the parse tree.

So, the question is how to get a parent E (the closest parent, like the expression itself) of <numberValue> such that <E@\src> is defined?

One option is to add an extra level in the top-down traversal:

top-down visit(d) {
    case \expressionStatement(Expression stmt): {
        case \number(str numberValue) :
            println("hardcode value <numberValue> encountered at <stmt@\src>");
    }
}

This works, but has some drawbacks:

  • It is ugly, in order to cover all cases we have to add many more variants;
  • It is very inefficient.

So, what is the proper way to get the location of a numberValue (and similar low-level constructs like stringValue's, etc)?

1 Answers1

1

You should be able to do the following:

top-down visit(d) { case n:\number(str numberValue) : println("hardcode value <numberValue> encountered at <n@\src>"); }

Saying n:\number(str numberValue) will bind the name n to the \number node that the case matched. You can then use this in your message to get the location for n. Just make sure that n isn't already in scope. You should be able to create similar patterns for the other scenarios you mentioned as well.

Mark Hills
  • 1,028
  • 5
  • 4