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;
|
||||
}
|
||||
|
||||
public m2() {
|
||||
int i = 0;
|
||||
do {
|
||||
++i;
|
||||
} while(i < 10);
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
@ -978,6 +978,27 @@ public class Codegen {
|
||||
mv.visitLabel(end);
|
||||
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: {
|
||||
generate(state, _if.cond());
|
||||
Label _else = new Label();
|
||||
|
@ -597,8 +597,12 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Statement convert(Java17Parser.ContinuestmtContext stmt) {
|
||||
// TODO
|
||||
throw new NotImplementedException();
|
||||
Token offset = stmt.getStart();
|
||||
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) {
|
||||
|
@ -236,6 +236,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
||||
aBreak.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Continue aContinue) {
|
||||
aContinue.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(StaticClassName staticClassName) {
|
||||
|
||||
|
@ -53,6 +53,8 @@ public interface StatementVisitor {
|
||||
|
||||
void visit(Break aBreak);
|
||||
|
||||
void visit(Continue aContinue);
|
||||
|
||||
void visit(Yield aYield);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Continue aContinue) {
|
||||
out.append("continue");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(StaticClassName staticClassName) {
|
||||
|
||||
|
@ -261,6 +261,11 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
result = new TargetBreak();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Continue aContinue) {
|
||||
result = new TargetContinue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(StaticClassName staticClassName) {
|
||||
result = new TargetClassName(converter.convert(staticClassName.getType()));
|
||||
@ -283,7 +288,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@ -124,6 +124,11 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Continue aContinue) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
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.*;
|
||||
|
||||
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() {
|
||||
return null;
|
||||
|
@ -1,6 +1,4 @@
|
||||
package de.dhbwstuttgart.target.tree.expression;
|
||||
|
||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||
|
||||
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
|
||||
public void visit(StaticClassName staticClassName) {
|
||||
// Hier entstehen keine Constraints
|
||||
@ -569,7 +574,10 @@ public class TYPEStmt implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
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
|
||||
|
@ -925,6 +925,15 @@ public class TestComplete {
|
||||
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
|
||||
public void testBug122() throws Exception {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav");
|
||||
|
Loading…
Reference in New Issue
Block a user