Bytecode for if/elseif/else
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
This commit is contained in:
parent
f12e553ffc
commit
612c967023
@ -1,11 +1,10 @@
|
|||||||
package ast.statements;
|
package ast.statements;
|
||||||
|
|
||||||
import ast.ASTNode;
|
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import typechecker.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class ElseNode implements IStatementNode {
|
public class ElseNode implements IStatementNode {
|
||||||
BlockNode block;
|
public BlockNode block;
|
||||||
|
|
||||||
public ElseNode(BlockNode block) {
|
public ElseNode(BlockNode block) {
|
||||||
this.block = block;
|
this.block = block;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package ast.statements;
|
package ast.statements;
|
||||||
|
|
||||||
import ast.ASTNode;
|
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import typechecker.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
@ -8,9 +7,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class IfElseNode implements IStatementNode {
|
public class IfElseNode implements IStatementNode {
|
||||||
IfNode ifStatement;
|
public IfNode ifStatement;
|
||||||
List<IfNode> elseIfStatements = new ArrayList<>();
|
public List<IfNode> elseIfStatements = new ArrayList<>();
|
||||||
ElseNode elseStatement;
|
public ElseNode elseStatement;
|
||||||
|
|
||||||
public IfElseNode(IfNode ifStatement, ElseNode elseNode) {
|
public IfElseNode(IfNode ifStatement, ElseNode elseNode) {
|
||||||
this.ifStatement = ifStatement;
|
this.ifStatement = ifStatement;
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package ast.statements;
|
package ast.statements;
|
||||||
|
|
||||||
import ast.ASTNode;
|
|
||||||
import ast.expressions.IExpressionNode;
|
import ast.expressions.IExpressionNode;
|
||||||
import semantic.SemanticVisitor;
|
import semantic.SemanticVisitor;
|
||||||
import typechecker.TypeCheckResult;
|
import typechecker.TypeCheckResult;
|
||||||
|
|
||||||
public class IfNode implements IStatementNode {
|
public class IfNode implements IStatementNode {
|
||||||
IExpressionNode expression;
|
public IExpressionNode expression;
|
||||||
BlockNode block;
|
public BlockNode block;
|
||||||
|
|
||||||
public IfNode(IExpressionNode expression, BlockNode block) {
|
public IfNode(IExpressionNode expression, BlockNode block) {
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
|
@ -9,7 +9,6 @@ import ast.members.MainMethodNode;
|
|||||||
import ast.members.MethodNode;
|
import ast.members.MethodNode;
|
||||||
import ast.parameters.ParameterNode;
|
import ast.parameters.ParameterNode;
|
||||||
import ast.statementexpressions.AssignNode;
|
import ast.statementexpressions.AssignNode;
|
||||||
import ast.statementexpressions.AssignableNode;
|
|
||||||
import ast.statementexpressions.NewDeclarationNode;
|
import ast.statementexpressions.NewDeclarationNode;
|
||||||
import ast.statementexpressions.crementexpressions.DecrementNode;
|
import ast.statementexpressions.crementexpressions.DecrementNode;
|
||||||
import ast.statementexpressions.crementexpressions.IncrementNode;
|
import ast.statementexpressions.crementexpressions.IncrementNode;
|
||||||
@ -282,29 +281,47 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
|||||||
|
|
||||||
// Statements
|
// Statements
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(ElseNode elseNode) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(IfElseNode ifElseNode) {
|
public void visit(IfElseNode ifElseNode) {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(IfNode ifNode) {
|
|
||||||
// Process condition
|
|
||||||
Label elseLabel = new Label();
|
Label elseLabel = new Label();
|
||||||
|
|
||||||
ifNode.expression.accept(this);
|
Label[] elseIfLabels = new Label[ifElseNode.elseIfStatements.size()];
|
||||||
|
for(int i = 0; i < ifElseNode.elseIfStatements.size(); i++) {
|
||||||
methodVisitor.visitJumpInsn(IFLE, elseLabel);
|
elseIfLabels[i] = new Label();
|
||||||
|
|
||||||
// Process block
|
|
||||||
for (IStatementNode statementNode : ifNode.block.statements) {
|
|
||||||
statementNode.accept(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ifElseNode.ifStatement.expression.accept(this);
|
||||||
|
if (ifElseNode.elseIfStatements.isEmpty()) {
|
||||||
|
// No else if
|
||||||
|
methodVisitor.visitJumpInsn(IFEQ, elseLabel);
|
||||||
|
} else {
|
||||||
|
// else if statements
|
||||||
|
methodVisitor.visitJumpInsn(IFEQ, elseIfLabels[0]);
|
||||||
|
}
|
||||||
|
ifElseNode.ifStatement.block.accept(this); // accept if block
|
||||||
|
|
||||||
|
Label endLabel = new Label();
|
||||||
|
methodVisitor.visitJumpInsn(GOTO, endLabel);
|
||||||
|
|
||||||
|
for(int i = 0; i < ifElseNode.elseIfStatements.size(); i++) {
|
||||||
|
methodVisitor.visitLabel(elseIfLabels[i]);
|
||||||
|
ifElseNode.elseIfStatements.get(i).expression.accept(this);
|
||||||
|
if(i + 1 < elseIfLabels.length) {
|
||||||
|
// at least one more else if
|
||||||
|
methodVisitor.visitJumpInsn(IFEQ, elseIfLabels[i+1]);
|
||||||
|
} else {
|
||||||
|
methodVisitor.visitJumpInsn(IFEQ, elseLabel);
|
||||||
|
}
|
||||||
|
ifElseNode.elseIfStatements.get(i).block.accept(this);
|
||||||
|
methodVisitor.visitJumpInsn(GOTO, endLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ifElseNode.elseStatement != null) {
|
||||||
|
methodVisitor.visitLabel(elseLabel);
|
||||||
|
ifElseNode.elseStatement.block.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
methodVisitor.visitLabel(endLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -403,14 +420,14 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
|||||||
public void visit(DecrementNode decrementNode) {
|
public void visit(DecrementNode decrementNode) {
|
||||||
switch (decrementNode.crementType) {
|
switch (decrementNode.crementType) {
|
||||||
case PREFIX: // --i
|
case PREFIX: // --i
|
||||||
if(decrementNode.assignableExpression.memberAccess == null) { // local Var
|
if (decrementNode.assignableExpression.memberAccess == null) { // local Var
|
||||||
methodVisitor.visitIincInsn(localVaribales.indexOf(decrementNode.assignableExpression.identifier), -1);
|
methodVisitor.visitIincInsn(localVaribales.indexOf(decrementNode.assignableExpression.identifier), -1);
|
||||||
} else { // Field or var from other object
|
} else { // Field or var from other object
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SUFFIX: // i--
|
case SUFFIX: // i--
|
||||||
if(decrementNode.assignableExpression.memberAccess == null) { // local Var
|
if (decrementNode.assignableExpression.memberAccess == null) { // local Var
|
||||||
methodVisitor.visitIincInsn(localVaribales.indexOf(decrementNode.assignableExpression.identifier), -1);
|
methodVisitor.visitIincInsn(localVaribales.indexOf(decrementNode.assignableExpression.identifier), -1);
|
||||||
} else { // Field or var from other object
|
} else { // Field or var from other object
|
||||||
|
|
||||||
@ -423,7 +440,7 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
|||||||
public void visit(IncrementNode incrementNode) {
|
public void visit(IncrementNode incrementNode) {
|
||||||
switch (incrementNode.crementType) {
|
switch (incrementNode.crementType) {
|
||||||
case PREFIX: // ++i
|
case PREFIX: // ++i
|
||||||
if(incrementNode.assignableExpression.memberAccess == null) { // local Var
|
if (incrementNode.assignableExpression.memberAccess == null) { // local Var
|
||||||
methodVisitor.visitIincInsn(localVaribales.indexOf(incrementNode.assignableExpression.identifier), 1);
|
methodVisitor.visitIincInsn(localVaribales.indexOf(incrementNode.assignableExpression.identifier), 1);
|
||||||
methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(incrementNode.assignableExpression.identifier));
|
methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(incrementNode.assignableExpression.identifier));
|
||||||
|
|
||||||
@ -432,7 +449,7 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SUFFIX: // i++
|
case SUFFIX: // i++
|
||||||
if(incrementNode.assignableExpression.memberAccess == null) { // local Var
|
if (incrementNode.assignableExpression.memberAccess == null) { // local Var
|
||||||
methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(incrementNode.assignableExpression.identifier));
|
methodVisitor.visitVarInsn(ISTORE, localVaribales.indexOf(incrementNode.assignableExpression.identifier));
|
||||||
methodVisitor.visitIincInsn(localVaribales.indexOf(incrementNode.assignableExpression.identifier), 1);
|
methodVisitor.visitIincInsn(localVaribales.indexOf(incrementNode.assignableExpression.identifier), 1);
|
||||||
} else { // Field or var from other object
|
} else { // Field or var from other object
|
||||||
|
@ -37,9 +37,7 @@ public interface MethodVisitor {
|
|||||||
void visit(UnaryNode unaryExpressionNode);
|
void visit(UnaryNode unaryExpressionNode);
|
||||||
|
|
||||||
// statements
|
// statements
|
||||||
void visit(ElseNode elseNode);
|
|
||||||
void visit(IfElseNode ifElseNode);
|
void visit(IfElseNode ifElseNode);
|
||||||
void visit(IfNode ifNode);
|
|
||||||
|
|
||||||
void visit(LocalVariableDeclarationNode localVariableDeclarationNode);
|
void visit(LocalVariableDeclarationNode localVariableDeclarationNode);
|
||||||
void visit(ReturnNode returnNode);
|
void visit(ReturnNode returnNode);
|
||||||
|
Loading…
Reference in New Issue
Block a user