Add continue and do-while, close #331
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m15s
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m15s
This commit is contained in:
parent
974582f7e5
commit
295bf079b9
@ -9,4 +9,13 @@ public class While {
|
|||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public m2() {
|
||||||
|
int i = 0;
|
||||||
|
do {
|
||||||
|
++i;
|
||||||
|
} while(i < 10);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
@ -978,6 +978,27 @@ public class Codegen {
|
|||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TargetDo _do: {
|
||||||
|
Label start = new Label();
|
||||||
|
Label end = new Label();
|
||||||
|
Label check = new Label();
|
||||||
|
|
||||||
|
var env = new BreakEnv();
|
||||||
|
env.startLabel = check;
|
||||||
|
env.endLabel = end;
|
||||||
|
|
||||||
|
mv.visitLabel(start);
|
||||||
|
state.breakStack.push(env);
|
||||||
|
generate(state, _do.body());
|
||||||
|
state.breakStack.pop();
|
||||||
|
|
||||||
|
mv.visitLabel(check);
|
||||||
|
generate(state, _do.cond());
|
||||||
|
mv.visitJumpInsn(IFEQ, end);
|
||||||
|
mv.visitJumpInsn(GOTO, start);
|
||||||
|
mv.visitLabel(end);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TargetIf _if: {
|
case TargetIf _if: {
|
||||||
generate(state, _if.cond());
|
generate(state, _if.cond());
|
||||||
Label _else = new Label();
|
Label _else = new Label();
|
||||||
|
@ -597,8 +597,12 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java17Parser.ContinuestmtContext stmt) {
|
private Statement convert(Java17Parser.ContinuestmtContext stmt) {
|
||||||
// TODO
|
Token offset = stmt.getStart();
|
||||||
throw new NotImplementedException();
|
if (!Objects.isNull(stmt.identifier())) {
|
||||||
|
return new Continue(localVars.get(stmt.identifier().getText()), offset);
|
||||||
|
} else {
|
||||||
|
return new Continue(TypePlaceholder.fresh(offset), offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java17Parser.SemistmtContext stmt) {
|
private Statement convert(Java17Parser.SemistmtContext stmt) {
|
||||||
|
@ -236,6 +236,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
|||||||
aBreak.accept(this);
|
aBreak.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Continue aContinue) {
|
||||||
|
aContinue.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
|
|
||||||
|
@ -53,6 +53,8 @@ public interface StatementVisitor {
|
|||||||
|
|
||||||
void visit(Break aBreak);
|
void visit(Break aBreak);
|
||||||
|
|
||||||
|
void visit(Continue aContinue);
|
||||||
|
|
||||||
void visit(Yield aYield);
|
void visit(Yield aYield);
|
||||||
|
|
||||||
void visit(StaticClassName staticClassName);
|
void visit(StaticClassName staticClassName);
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package de.dhbwstuttgart.syntaxtree.statement;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
|
public class Continue extends Statement {
|
||||||
|
|
||||||
|
public Continue(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
||||||
|
super(type, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(StatementVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -333,6 +333,11 @@ public class OutputGenerator implements ASTVisitor {
|
|||||||
out.append("break");
|
out.append("break");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Continue aContinue) {
|
||||||
|
out.append("continue");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
|
|
||||||
|
@ -261,6 +261,11 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
result = new TargetBreak();
|
result = new TargetBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Continue aContinue) {
|
||||||
|
result = new TargetContinue();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
result = new TargetClassName(converter.convert(staticClassName.getType()));
|
result = new TargetClassName(converter.convert(staticClassName.getType()));
|
||||||
@ -283,7 +288,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoStmt whileStmt) {
|
public void visit(DoStmt whileStmt) {
|
||||||
throw new NotImplementedException();
|
result = new TargetDo(converter.convert(whileStmt.expr), converter.convert(whileStmt.loopBlock));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO These two might not be necessary
|
// TODO These two might not be necessary
|
||||||
|
@ -124,6 +124,11 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Continue aContinue) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
|
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
package de.dhbwstuttgart.target.tree.expression;
|
||||||
|
|
||||||
|
public record TargetDo(TargetExpression cond, TargetExpression body) implements TargetExpression {
|
||||||
|
}
|
@ -3,7 +3,7 @@ package de.dhbwstuttgart.target.tree.expression;
|
|||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
|
|
||||||
public sealed interface TargetExpression
|
public sealed interface TargetExpression
|
||||||
permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
|
permits TargetBinaryOp, TargetBlock, TargetBreak, TargetCast, TargetClassName, TargetContinue, TargetDo, TargetFieldVar, TargetFor, TargetForEach, TargetIf, TargetInstanceOf, TargetLambdaExpression, TargetLiteral, TargetLocalVar, TargetPattern, TargetReturn, TargetStatementExpression, TargetSuper, TargetSwitch, TargetTernary, TargetThis, TargetThrow, TargetUnaryOp, TargetVarDecl, TargetWhile, TargetYield {
|
||||||
|
|
||||||
default TargetType type() {
|
default TargetType type() {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
package de.dhbwstuttgart.target.tree.expression;
|
package de.dhbwstuttgart.target.tree.expression;
|
||||||
|
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
|
||||||
|
|
||||||
public record TargetWhile(TargetExpression cond, TargetExpression body) implements TargetExpression {
|
public record TargetWhile(TargetExpression cond, TargetExpression body) implements TargetExpression {
|
||||||
}
|
}
|
||||||
|
@ -514,6 +514,11 @@ public class TYPEStmt implements StatementVisitor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(Continue aContinue) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
// Hier entstehen keine Constraints
|
// Hier entstehen keine Constraints
|
||||||
@ -569,7 +574,10 @@ public class TYPEStmt implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoStmt whileStmt) {
|
public void visit(DoStmt whileStmt) {
|
||||||
throw new NotImplementedException();
|
RefType booleanType = new RefType(ASTFactory.createClass(java.lang.Boolean.class).getClassName(), new NullToken());
|
||||||
|
whileStmt.expr.accept(this);
|
||||||
|
constraintsSet.addUndConstraint(new Pair(whileStmt.expr.getType(), booleanType, PairOperator.EQUALSDOT, loc(whileStmt.expr.getOffset())));
|
||||||
|
whileStmt.loopBlock.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -925,6 +925,15 @@ public class TestComplete {
|
|||||||
assertEquals(clazz.getDeclaredMethod("main", Integer.class).invoke(instance, 5), "small");
|
assertEquals(clazz.getDeclaredMethod("main", Integer.class).invoke(instance, 5), "small");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWhile() throws Exception {
|
||||||
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "While.jav");
|
||||||
|
var clazz = classFiles.get("While");
|
||||||
|
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
|
assertEquals(clazz.getDeclaredMethod("m", Integer.class).invoke(instance, 5), 5);
|
||||||
|
assertEquals(clazz.getDeclaredMethod("m2").invoke(instance), 10);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBug122() throws Exception {
|
public void testBug122() throws Exception {
|
||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav");
|
||||||
|
Loading…
Reference in New Issue
Block a user