Add Ternary, fix #324
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 2m48s
All checks were successful
Build and Test with Maven / Build-and-test-with-Maven (push) Successful in 2m48s
This commit is contained in:
parent
9358130468
commit
b774281cbb
9
resources/bytecode/javFiles/Ternary.jav
Normal file
9
resources/bytecode/javFiles/Ternary.jav
Normal file
@ -0,0 +1,9 @@
|
||||
import java.lang.Boolean;
|
||||
import java.lang.String;
|
||||
import java.lang.Integer;
|
||||
|
||||
public class Ternary {
|
||||
public main(x) {
|
||||
return x > 10 ? "big" : "small";
|
||||
}
|
||||
}
|
@ -1108,6 +1108,20 @@ public class Codegen {
|
||||
mv.visitInsn(ATHROW);
|
||||
break;
|
||||
}
|
||||
case TargetTernary ternary: {
|
||||
generate(state, ternary.cond());
|
||||
var iffalse = new Label();
|
||||
var end = new Label();
|
||||
mv.visitJumpInsn(IFEQ, iffalse);
|
||||
generate(state, ternary.iftrue());
|
||||
convertTo(state, ternary.iftrue().type(), ternary.type());
|
||||
mv.visitJumpInsn(GOTO, end);
|
||||
mv.visitLabel(iffalse);
|
||||
generate(state, ternary.iffalse());
|
||||
convertTo(state, ternary.iffalse().type(), ternary.type());
|
||||
mv.visitLabel(end);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new CodeGenException("Unexpected value: " + expr);
|
||||
}
|
||||
|
@ -832,7 +832,13 @@ public class StatementGenerator {
|
||||
}
|
||||
|
||||
private Expression convert(Java17Parser.ConditionalassignexpressionContext expression) {
|
||||
throw new NotImplementedException();
|
||||
return new Ternary(TypePlaceholder.fresh(
|
||||
expression.getStart()),
|
||||
convert(expression.expression(0)),
|
||||
convert(expression.expression(1)),
|
||||
convert(expression.expression(2)),
|
||||
expression.getStart()
|
||||
);
|
||||
}
|
||||
|
||||
private Expression convert(Java17Parser.OrexpressionContext expression) {
|
||||
|
@ -332,4 +332,11 @@ public abstract class AbstractASTWalker implements ASTVisitor {
|
||||
public void visit(GuardedPattern aGuardedPattern) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Ternary ternary) {
|
||||
ternary.cond.accept(this);
|
||||
ternary.iftrue.accept(this);
|
||||
ternary.iffalse.accept(this);
|
||||
}
|
||||
}
|
||||
|
@ -80,4 +80,6 @@ public interface StatementVisitor {
|
||||
void visit(Literal literal);
|
||||
|
||||
void visit(Throw aThrow);
|
||||
|
||||
void visit(Ternary ternary);
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package de.dhbwstuttgart.syntaxtree.statement;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
public class Ternary extends Expression {
|
||||
|
||||
public final Expression cond;
|
||||
public final Expression iftrue;
|
||||
public final Expression iffalse;
|
||||
|
||||
public Ternary(RefTypeOrTPHOrWildcardOrGeneric type, Expression cond, Expression iftrue, Expression iffalse, Token offset) {
|
||||
super(type, offset);
|
||||
this.cond = cond;
|
||||
this.iftrue = iftrue;
|
||||
this.iffalse = iffalse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(StatementVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
@ -427,6 +427,18 @@ public class OutputGenerator implements ASTVisitor {
|
||||
// TODO implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Ternary ternary) {
|
||||
out.append("(");
|
||||
ternary.cond.accept(this);
|
||||
out.append(" ? ");
|
||||
ternary.iftrue.accept(this);
|
||||
out.append(" : ");
|
||||
ternary.iffalse.accept(this);
|
||||
out.append(")::");
|
||||
ternary.getType().accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Switch switchStmt) {
|
||||
out.append("switch(");
|
||||
|
@ -359,6 +359,11 @@ public class StatementToTargetExpression implements ASTVisitor {
|
||||
result = new TargetThrow(converter.convert(aThrow.expr));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Ternary ternary) {
|
||||
result = new TargetTernary(converter.convert(ternary.getType()), converter.convert(ternary.cond), converter.convert(ternary.iftrue), converter.convert(ternary.iffalse));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Switch switchStmt) {
|
||||
var cases = switchStmt.getBlocks().stream().filter(s -> !s.isDefault()).map(converter::convert).toList();
|
||||
|
@ -203,4 +203,11 @@ public abstract class TracingStatementVisitor implements StatementVisitor {
|
||||
public void visit(Yield aYield) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Ternary ternary) {
|
||||
ternary.cond.accept(this);
|
||||
ternary.iftrue.accept(this);
|
||||
ternary.iffalse.accept(this);
|
||||
}
|
||||
}
|
||||
|
@ -2,5 +2,5 @@ package de.dhbwstuttgart.target.tree.expression;
|
||||
|
||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||
|
||||
public record TargetTernary(TargetType type, TargetExpression cond, TargetExpression ifTrue, TargetExpression ifFalse) implements TargetExpression {
|
||||
public record TargetTernary(TargetType type, TargetExpression cond, TargetExpression iftrue, TargetExpression iffalse) implements TargetExpression {
|
||||
}
|
||||
|
@ -488,6 +488,16 @@ public class TYPEStmt implements StatementVisitor {
|
||||
aThrow.expr.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Ternary ternary) {
|
||||
ternary.cond.accept(this);
|
||||
ternary.iftrue.accept(this);
|
||||
ternary.iffalse.accept(this);
|
||||
constraintsSet.addUndConstraint(new Pair(ternary.cond.getType(), bool, PairOperator.EQUALSDOT));
|
||||
constraintsSet.addUndConstraint(new Pair(ternary.iftrue.getType(), ternary.getType(), PairOperator.SMALLERDOT));
|
||||
constraintsSet.addUndConstraint(new Pair(ternary.iffalse.getType(), ternary.getType(), PairOperator.SMALLERDOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Return returnExpr) {
|
||||
returnExpr.retexpr.accept(this);
|
||||
|
@ -916,6 +916,14 @@ public class TestComplete {
|
||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTernary() throws Exception {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Ternary.jav");
|
||||
var clazz = classFiles.get("Ternary");
|
||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||
assertEquals(clazz.getDeclaredMethod("main", Integer.class).invoke(instance, 5), "small");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBug122() throws Exception {
|
||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Bug122.jav");
|
||||
|
Loading…
Reference in New Issue
Block a user