how do I generate the code corresponding to a bytecode instruction IF THEN - ELSE with the optioanal ELSE branch?
For example, the program If-else.pas is considered correct, while the program If.pas isn't considered correct, because it doesn't contains the ELSE branch.
If-else.pas
var a, b : integer;
begin
a := 3;
b := 5;
if a > b then
print(a)
else
print(b)
end
If.pas
var a, b : integer;
begin
a := 3;
b := 5;
if a > b then
print(a)
end
So Jasmin give me this error:
Output.j:62: JAS Error: Label: L11 has not been added to the code.
Output.j: Found 1 errors
My grammar .g has this rule:
stmt -> ID := expr
| print( expr )
| if( expr ) then ( stmt ) [ else stmt ]?
| while( expr ) do stmt
| begin stmt [ ; stmt ]* end
For the if-else statement I wrote this:
'if'
{
int lfalse = code.newLabel(); //Generates a new number for the LABEL
int lnext = lfalse;
}
( expr )
{
if($expr.type != Type.BOOLEAN) //Checking the condition is boolean
throw new IllegalArgumentException("Type error in '( expr )': expr is not a boolean.");
code.emit(Opcode.IFEQ, lfalse); //I create the instruction IFEQ L(lfalse)
}
'then' s1 = stmt
{
lnext = code.newLabel(); //Generates a new number for the LABEL
code.emit(Opcode.GOTO, lnext); //I create the instruction GOTO L(lnext)
code.emit(Opcode.LABEL, lfalse); //I create the instruction L(lfalse):
}
( 'else' s2 = stmt
{
code.emit(Opcode.LABEL, lnext); //I create the instruction L(lnext):
})?
But in this way the second branch is not optional, but must always be present.
How do I make it optional? I thought it was necessary the question mark (( 'else' s2 = stmt )?
), but no.
I am using ANTLR.
Thanks.
I do not know if the bytecode files (. J) generated by Jasmin will be useful, but I write it.
If-else.j
ldc 3
istore 1
ldc 5
istore 0
iload 1
iload 0
if_icmpgt L7
ldc 0
goto L8
L7:
ldc 1
L8:
ifeq L4
iload 1
invokestatic Output/printInt(I)V
goto L11
L4:
iload 0
invokestatic Output/printInt(I)V
L11:
return
If.j
ldc 3
istore 1
ldc 5
istore 0
iload 1
iload 0
if_icmpgt L7
ldc 0
goto L8
L7:
ldc 1
L8:
ifeq L4
iload 1
invokestatic Output/printInt(I)V
goto L11
L4:
return