Bytecode for if/elseif/else
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run

This commit is contained in:
i22007 2024-06-27 19:56:31 -04:00
parent f12e553ffc
commit 612c967023
5 changed files with 46 additions and 34 deletions

View File

@ -1,11 +1,10 @@
package ast.statements;
import ast.ASTNode;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
public class ElseNode implements IStatementNode {
BlockNode block;
public BlockNode block;
public ElseNode(BlockNode block) {
this.block = block;

View File

@ -1,6 +1,5 @@
package ast.statements;
import ast.ASTNode;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
@ -8,9 +7,9 @@ import java.util.ArrayList;
import java.util.List;
public class IfElseNode implements IStatementNode {
IfNode ifStatement;
List<IfNode> elseIfStatements = new ArrayList<>();
ElseNode elseStatement;
public IfNode ifStatement;
public List<IfNode> elseIfStatements = new ArrayList<>();
public ElseNode elseStatement;
public IfElseNode(IfNode ifStatement, ElseNode elseNode) {
this.ifStatement = ifStatement;

View File

@ -1,13 +1,12 @@
package ast.statements;
import ast.ASTNode;
import ast.expressions.IExpressionNode;
import semantic.SemanticVisitor;
import typechecker.TypeCheckResult;
public class IfNode implements IStatementNode {
IExpressionNode expression;
BlockNode block;
public IExpressionNode expression;
public BlockNode block;
public IfNode(IExpressionNode expression, BlockNode block) {
this.expression = expression;

View File

@ -9,7 +9,6 @@ import ast.members.MainMethodNode;
import ast.members.MethodNode;
import ast.parameters.ParameterNode;
import ast.statementexpressions.AssignNode;
import ast.statementexpressions.AssignableNode;
import ast.statementexpressions.NewDeclarationNode;
import ast.statementexpressions.crementexpressions.DecrementNode;
import ast.statementexpressions.crementexpressions.IncrementNode;
@ -282,29 +281,47 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
// Statements
@Override
public void visit(ElseNode elseNode) {
}
@Override
public void visit(IfElseNode ifElseNode) {
}
@Override
public void visit(IfNode ifNode) {
// Process condition
Label elseLabel = new Label();
ifNode.expression.accept(this);
methodVisitor.visitJumpInsn(IFLE, elseLabel);
// Process block
for (IStatementNode statementNode : ifNode.block.statements) {
statementNode.accept(this);
Label[] elseIfLabels = new Label[ifElseNode.elseIfStatements.size()];
for(int i = 0; i < ifElseNode.elseIfStatements.size(); i++) {
elseIfLabels[i] = new Label();
}
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
@ -403,14 +420,14 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
public void visit(DecrementNode decrementNode) {
switch (decrementNode.crementType) {
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);
} else { // Field or var from other object
}
break;
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);
} else { // Field or var from other object
@ -423,7 +440,7 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
public void visit(IncrementNode incrementNode) {
switch (incrementNode.crementType) {
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.visitVarInsn(ISTORE, localVaribales.indexOf(incrementNode.assignableExpression.identifier));
@ -432,7 +449,7 @@ public class MethodCodeGen implements bytecode.visitor.MethodVisitor {
}
break;
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.visitIincInsn(localVaribales.indexOf(incrementNode.assignableExpression.identifier), 1);
} else { // Field or var from other object

View File

@ -37,9 +37,7 @@ public interface MethodVisitor {
void visit(UnaryNode unaryExpressionNode);
// statements
void visit(ElseNode elseNode);
void visit(IfElseNode ifElseNode);
void visit(IfNode ifNode);
void visit(LocalVariableDeclarationNode localVariableDeclarationNode);
void visit(ReturnNode returnNode);