Skip to content

Commit

Permalink
Merge pull request #2 from LunarClient/add-conditionals
Browse files Browse the repository at this point in the history
Added Conditionals and related tests
  • Loading branch information
bernie-g authored Nov 2, 2023
2 parents 348a6fa + 16b5189 commit bcb0d5d
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 3 deletions.
9 changes: 6 additions & 3 deletions src/main/java/com/eliotlash/molang/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,12 @@ private Expr unary() {
Expr access = access();
if (match(QUESTION)) {
Expr left = expression();
consume(COLON, "Expected ':' after ternary");
Expr right = expression();
return new Expr.Ternary(access, left, right);
if (match(COLON)) {
Expr right = expression();
return new Expr.Ternary(access, left, right);
} else {
return new Expr.Conditional(access, left);
}
}
if (match(ARROW)) {
Expr right = expression();
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/eliotlash/molang/ast/ASTTransformation.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ public Expr visitNot(Expr.Not expr) {
return new Expr.Not(visit(expr.value()));
}

@Override
public Expr visitConditional(Expr.Conditional expr) {
return new Expr.Conditional(visit(expr.condition()), visit(expr.ifTrue()));
}

@Override
public Expr visitTernary(Expr.Ternary expr) {
return new Expr.Ternary(visit(expr.condition()), visit(expr.ifTrue()), visit(expr.ifFalse()));
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/eliotlash/molang/ast/Evaluator.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ public Double visitNot(Expr.Not expr) {
return evaluate(expr.value()) == 0 ? 1.0 : 0.0;
}

@Override
public Double visitConditional(Expr.Conditional expr) {
double result = evaluate(expr.condition());
if (result == 0) return 0.0;
return evaluate(expr.ifTrue());
}

@Override
public Double visitTernary(Expr.Ternary expr) {
Expr branch = evaluate(expr.condition()) == 0 ? expr.ifFalse() : expr.ifTrue();
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/eliotlash/molang/ast/Expr.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,16 @@ public <R> R accept(Visitor<R> visitor) {
}
}

/**
* condition ? ifTrue
*/
record Conditional(Expr condition, Expr ifTrue) implements Expr {
@Override
public <R> R accept(Visitor<R> visitor) {
return visitor.visitConditional(this);
}
}

/**
* condition ? ifTrue : ifFalse
*/
Expand Down Expand Up @@ -228,6 +238,8 @@ default R visit(Expr node) {

R visitNot(Not expr);

R visitConditional(Conditional expr);

R visitTernary(Ternary expr);

R visitSwitchContext(SwitchContext expr);
Expand Down
25 changes: 25 additions & 0 deletions src/test/java/com/eliotlash/molang/ParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,31 @@ void testOperators() {
}
}

@Test
void testConditionals() {
// Binary Conditional
assertEquals(new Expr.Conditional(c(0), c(20)), e("0 ? 20"));
assertEquals(
new Expr.Conditional(c(0), paren(new Expr.Conditional(c(20), c(30)))),
e("0 ? (20 ? 30)")
);
// Ternary Conditional
assertEquals(new Expr.Ternary(c(0), c(10), c(20)), e("0 ? 10 : 20"));
assertEquals(
new Expr.Ternary(c(0), paren(new Expr.Ternary(c(10), c(20), c(30))), c(20)),
e("0 ? (10 ? 20 : 30) : 20")
);
// Combinations
assertEquals(
new Expr.Conditional(c(0), new Expr.Ternary(c(10), c(20), c(30))),
e("0 ? 10 ? 20 : 30")
);
assertEquals(
new Expr.Ternary(c(0), c(10), new Expr.Conditional(c(20), c(30))),
e("0 ? 10 : 20 ? 30")
);
}

@Test
void testMath() {
Expr.Constant twenty = c(20);
Expand Down
6 changes: 6 additions & 0 deletions src/test/java/com/eliotlash/molang/ast/EvaluatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ void visitNot() {
assertEquals(1, eval.visitNot(new Expr.Not(c(0))));
}

@Test
void visitConditional() {
assertEquals(10, eval.visitConditional(new Expr.Conditional(c(1), c(10))));
assertEquals(0, eval.visitConditional(new Expr.Conditional(c(0), c(10))));
}

@Test
void visitTernary() {
assertEquals(10, eval.visitTernary(new Expr.Ternary(c(1), c(10), c(30))));
Expand Down

0 comments on commit bcb0d5d

Please sign in to comment.