package jp.ac.aiit.jointry.services.lang.ast;
import java.util.List;
import jp.ac.aiit.jointry.services.lang.parser.Environment;
import jp.ac.aiit.jointry.util.JoinTryException;
public class BinaryExpr extends ASTList {
public BinaryExpr(List<ASTree> c) {
super(c);
}
public ASTree left() {
return child(0);
}
public String operator() {
return ((ASTLeaf) child(1)).token().getText();
}
public ASTree right() {
return child(2);
}
public Object eval(Environment env) {
String op = operator();
if ("=".equals(op)) {
Object right = ((ASTree) right()).eval(env);
return computeAssign(env, right);
}
Object left = ((ASTree) left()).eval(env);
Object right = ((ASTree) right()).eval(env);
return computeOp(left, op, right);
}
protected Object computeAssign(Environment env, Object rvalue) {
ASTree l = left();
if (l instanceof Name) {
env.put(((Name) l).name(), rvalue);
return rvalue;
} else {
throw new JoinTryException("bad assignment", this);
}
}
protected Object computeOp(Object left, String op, Object right) {
if (left instanceof Integer && right instanceof Integer) {
return computeNumber((Integer) left, op, (Integer) right);
}
if (op.equals("+")) {
return String.valueOf(left) + String.valueOf(right);
}
if (op.equals("==")) {
if (left == null) {
return right == null ? TRUE : FALSE;
} else {
return left.equals(right) ? TRUE : FALSE;
}
}
if (op.equals("!=")) {
if (left == null) {
return right == null ? FALSE : TRUE;
} else {
return left.equals(right) ? FALSE : TRUE;
}
}
throw new JoinTryException("bad type", this);
}
protected Object computeNumber(Integer left, String op, Integer right) {
int a = left.intValue();
int b = right.intValue();
if (op.equals("+")) {
return a + b;
}
if (op.equals("-")) {
return a - b;
}
if (op.equals("*")) {
return a * b;
}
if (op.equals("/")) {
return a / b;
}
if (op.equals("%")) {
return a % b;
}
if (op.equals("==")) {
return a == b ? TRUE : FALSE;
}
if (op.equals(">")) {
return a > b ? TRUE : FALSE;
}
if (op.equals("<")) {
return a < b ? TRUE : FALSE;
}
if (op.equals(">=")) {
return a >= b ? TRUE : FALSE;
}
if (op.equals("<=")) {
return a <= b ? TRUE : FALSE;
}
if (op.equals("!=")) {
return a != b ? TRUE : FALSE;
}
throw new JoinTryException("bad operator", this);
}
}