2015-05-28 23:00:52 +03:00
|
|
|
package com.annimon.ownlang.parser.ast;
|
|
|
|
|
|
|
|
import com.annimon.ownlang.lib.NumberValue;
|
|
|
|
import com.annimon.ownlang.lib.StringValue;
|
|
|
|
import com.annimon.ownlang.lib.Value;
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @author aNNiMON
|
|
|
|
*/
|
|
|
|
public final class ConditionalExpression implements Expression {
|
|
|
|
|
2015-06-04 18:44:32 +03:00
|
|
|
public static enum Operator {
|
|
|
|
EQUALS("=="),
|
|
|
|
NOT_EQUALS("!="),
|
|
|
|
|
|
|
|
LT("<"),
|
|
|
|
LTEQ("<="),
|
|
|
|
GT(">"),
|
|
|
|
GTEQ(">="),
|
|
|
|
|
|
|
|
AND("&&"),
|
|
|
|
OR("||");
|
|
|
|
|
|
|
|
private final String name;
|
|
|
|
|
|
|
|
private Operator(String name) {
|
|
|
|
this.name = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getName() {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-29 20:50:59 +03:00
|
|
|
public final Expression expr1, expr2;
|
|
|
|
public final Operator operation;
|
2015-05-28 23:00:52 +03:00
|
|
|
|
2015-06-04 18:44:32 +03:00
|
|
|
public ConditionalExpression(Operator operation, Expression expr1, Expression expr2) {
|
2015-05-28 23:00:52 +03:00
|
|
|
this.operation = operation;
|
|
|
|
this.expr1 = expr1;
|
|
|
|
this.expr2 = expr2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Value eval() {
|
|
|
|
final Value value1 = expr1.eval();
|
|
|
|
final Value value2 = expr2.eval();
|
2015-06-04 18:44:32 +03:00
|
|
|
|
|
|
|
double number1, number2;
|
2015-05-28 23:00:52 +03:00
|
|
|
if (value1 instanceof StringValue) {
|
2015-06-04 18:44:32 +03:00
|
|
|
number1 = value1.asString().compareTo(value2.asString());
|
|
|
|
number2 = 0;
|
|
|
|
} else {
|
|
|
|
number1 = value1.asNumber();
|
|
|
|
number2 = value2.asNumber();
|
2015-05-28 23:00:52 +03:00
|
|
|
}
|
|
|
|
|
2015-06-04 18:44:32 +03:00
|
|
|
boolean result;
|
2015-05-28 23:00:52 +03:00
|
|
|
switch (operation) {
|
2015-06-30 13:19:50 +03:00
|
|
|
case EQUALS: result = number1 == number2; break;
|
|
|
|
case NOT_EQUALS: result = number1 != number2; break;
|
|
|
|
|
2015-06-04 18:44:32 +03:00
|
|
|
case LT: result = number1 < number2; break;
|
|
|
|
case LTEQ: result = number1 <= number2; break;
|
|
|
|
case GT: result = number1 > number2; break;
|
|
|
|
case GTEQ: result = number1 >= number2; break;
|
|
|
|
|
|
|
|
case AND: result = (number1 != 0) && (number2 != 0); break;
|
|
|
|
case OR: result = (number1 != 0) || (number2 != 0); break;
|
|
|
|
|
2015-05-28 23:00:52 +03:00
|
|
|
default:
|
2015-06-30 13:19:50 +03:00
|
|
|
throw new RuntimeException("Operation " + operation + " is not supported");
|
2015-05-28 23:00:52 +03:00
|
|
|
}
|
2015-06-04 18:44:32 +03:00
|
|
|
return new NumberValue(result);
|
2015-05-28 23:00:52 +03:00
|
|
|
}
|
2015-06-29 20:50:59 +03:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void accept(Visitor visitor) {
|
|
|
|
visitor.visit(this);
|
|
|
|
}
|
2015-05-28 23:00:52 +03:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
2015-06-04 18:44:32 +03:00
|
|
|
return String.format("[%s %s %s]", expr1, operation.getName(), expr2);
|
2015-05-28 23:00:52 +03:00
|
|
|
}
|
|
|
|
}
|