I’m building a tree walker for an homogeneus AST (all nodes have same class), what’s the correct way to evaluate an if statement?
My AST for if are like this:

I would something that when parses an IF block, evaluates sequentially his CONDBLOCK children and if one of them is true, the tree walker doesn’t evaluate the remaining.
More clearly, my tree walker is something like:
ifStat : ^(IF { jump=false; } condition* defcond?)
condition : { if (jump) return retval; } ^(CONDBLOCK exp block) { jump=$exp.value; }
defcond : ^(DEFAULT block)
My question is, if in the example $op=+ so the first CONDBLOCK must be executed, I don’t want evaluate anything else, I want execute the first CODEBLOCK and go up in my AST tree to evaluate the block after if.
Now I’ve implemented that with a flag and a check in condition rule that returns if the flag was true (that means another block is already been executed).
But return retval; completely stops the execution, I want just go up without evaluate remaining conditions. How can I do that?
Any kind of runtime evaluation from an AST that involves branching or jumps is probably going to get ugly. You may want to consider converting the AST into a series of more conventional operations and execute them in sequence. It’s an extra step, but it will get you out of jams like this one and I think it’s easier to verify and to debug than an AST evaluator.
With that out of the way, here is a way to skip evaluating subsequent
conditionanddefcondrules. I’m sticking with the structure that you have, which means that evaluations have two distinct phases: a matching phase (exp) and an execution phase (block). This is only worth noting because the phases are handled in different parts of a subgraph and there is no natural means of jumping around, so they need to be tracked across the wholeifstatement.Here’s a simple class to manage tracking a single
ifevaluation:When
matchedis true anddoneis false, the nextblockgets executed. After execution,doneis set to true. Whenmatchedanddoneare both true, no moreblocks get executed for the remainder of theifstatement.Here are the tree parser rules to handle this:
Here are the grammars and the code I used to test this:
TreeEvaluator.g (combined grammar to produce an AST)
AstTreeEvaluatorParser.g (tree parser)
TreeEvaluatorTest.java (test code)
The test code evaluates
if a == b {b} elif a == c {c} elif a == d {d} else {e}. The id between the{}s is printed if it is evaluated. So ifa == bis true, then"Executed b"will be printed.Variable values are assigned by calling
tparser.addVar(...). In this case,adoesn’t equal any other variable, so block{e}is evaluated.