Reputation: 503
As a lot of people around the programming community, I am also trying to build my own programming language for a school project in Java. I am using antlr4 with intellij, as it helps a lot generating the tree at the same time I am writing test code. I created a visitor class to add functionality to my code and so far I was able to make an if/else statement and a while statement. So I would also like to create a switch statement and implement it to the visitor class. My grammar for the switch statement is the following:
switch_rule: SWITCH LPAREN any_var RPAREN LBRACKET case_rule* RBRACKET;
case_rule: CASE any_var PRES statement;
statement:
expression
| rule_ifset
| rule_for
| method_call
| rule_whiledo
| rule_dowhile
| switch_rule
| assign
|var_declaration;
any_var :INT # NumericConst
| DOUBLE # NumericConst
| IDENTIFIER # NumericVariable
|boolean_var # BooleanConst;
So I assume that I start the method like this:
@Override
public InputValue visitSwitch_rule(AdamantParser.Switch_ruleContext ctx) {
InputValue value = this.visit(ctx.any_var().getChild(0));
if(!value.isInteger()){throw new RuntimeException("switch value is not an integer");}
else{
//code to write here
}
return InputValue.VOIDval;
}
I want to write the case statement inside the switch method but I do not know how to go from here, and I didn't find any simple example... Can anyone point to the right direction, or provide with some simple code? Thanks in advance.
EDIT: A simple example of the syntax that I want is the following:
switch(aNumber){
case 1: print("return 1");
case 2: print("return 2");
}
Upvotes: 0
Views: 981
Reputation: 370465
From your comment it sounds like you're writing an interpreter that executes the code directly in the visitor without going through any IR or anything like that (please correct me if I misunderstood).
So your problem is that you can't just write a switch
statement inside your code if you don't even know how many case
statements there are going to be - you can't put a case
inside a loop after all. And even if that weren't a problem, the other problem would be that case
statements need compile-time constants, but you'd need to use them with values you extracted from your parse tree.
If you were generating code, none of that would be a problem because you could just generate the proper amount of cases with the given values and everything would be fine. But you're not, so everything is dynamic and you can't use switch
.
But that's not a problem because no one says that you have to implement switch
using switch
. As you probably know, a switch is just a more convenient (and often more performant) way of writing a series of if
statements. In your example (assuming your language has implicit break
s), that'd be:
if (aNumber == 1) {
print("return 1");
} else if (aNumber == 2) {
print("return 2");
}
What this means for your interpreter is that you can evaluate the expression you're switching on, then loop over all the cases and for each case compare the evaluated number to the value of the case
with an if
. As soon as one of the condition matches, you execute the associated code and break out of the loop.
If you don't have implicit break
s, you should instead only break out of the loop when you encounter a break
and otherwise use a flag to remember if you've already encountered a true condition and then execute every subsequent code block until you encounter a break
or reach the end of the switch
.
Upvotes: 0