ASTBinaryExpression.java
package edu.udel.cis.vsl.tass.front.minimp.ast.expression;
import java.util.HashMap;
import java.util.Map;
import edu.udel.cis.vsl.tass.front.minimp.ast.type.ASTBoolType;
import edu.udel.cis.vsl.tass.front.minimp.ast.type.ASTIntegerType;
import edu.udel.cis.vsl.tass.front.minimp.ast.type.ASTPointerType;
import edu.udel.cis.vsl.tass.front.minimp.ast.type.ASTRealType;
import edu.udel.cis.vsl.tass.front.minimp.ast.type.ASTTypeIF;
import edu.udel.cis.vsl.tass.model.IF.SyntaxException;
public class ASTBinaryExpression extends ASTExpression {
public static enum BinaryOperator {
PLUS, SUB, MUL, DIV, MOD, OR, AND, EQ, NEQ, LT, LTE, GT, GTE;
private static Map<String, BinaryOperator> STRING_TO_OPERATOR_MAP;
static {
STRING_TO_OPERATOR_MAP = new HashMap<String, BinaryOperator>();
STRING_TO_OPERATOR_MAP.put("add", BinaryOperator.PLUS);
STRING_TO_OPERATOR_MAP.put("and", BinaryOperator.AND);
STRING_TO_OPERATOR_MAP.put("divide", BinaryOperator.DIV);
STRING_TO_OPERATOR_MAP.put("equals", BinaryOperator.EQ);
STRING_TO_OPERATOR_MAP.put("leq", BinaryOperator.LTE);
STRING_TO_OPERATOR_MAP.put("less_than", BinaryOperator.LT);
STRING_TO_OPERATOR_MAP.put("modulo", BinaryOperator.MOD);
STRING_TO_OPERATOR_MAP.put("or", BinaryOperator.OR);
STRING_TO_OPERATOR_MAP.put("multiply", BinaryOperator.MUL);
STRING_TO_OPERATOR_MAP.put("subtract", BinaryOperator.SUB);
STRING_TO_OPERATOR_MAP.put("+=", BinaryOperator.PLUS);
STRING_TO_OPERATOR_MAP.put("-=", BinaryOperator.SUB);
STRING_TO_OPERATOR_MAP.put("*=", BinaryOperator.MUL);
STRING_TO_OPERATOR_MAP.put("/=", BinaryOperator.DIV);
STRING_TO_OPERATOR_MAP.put("%=", BinaryOperator.MOD);
STRING_TO_OPERATOR_MAP.put("&=", BinaryOperator.AND);
STRING_TO_OPERATOR_MAP.put("|=", BinaryOperator.OR);
}
public static BinaryOperator stringToOperator(String anOperator) {
return STRING_TO_OPERATOR_MAP.get(anOperator);
}
};
private BinaryOperator exprOperator;
private ASTExpressionIF left;
private ASTExpressionIF right;
private boolean isPointerOp = false;
public ASTBinaryExpression(BinaryOperator op, ASTExpressionIF lhs,
ASTExpressionIF rhs) throws SyntaxException {
super(null);
exprOperator = op;
left = lhs;
right = rhs;
switch (op) {
case PLUS:
exprType = checkAdditiveType(lhs, lhs.getType(), rhs.getType());
break;
case SUB:
case MUL:
case DIV:
case MOD:
exprType = mixType(lhs.getType(), rhs.getType());
break;
default:
exprType = new ASTBoolType();
}
}
private ASTTypeIF mixType(ASTTypeIF left, ASTTypeIF right) {
if (left instanceof ASTRealType || right instanceof ASTRealType) {
return new ASTRealType();
} else if (left != null) {
return left;
} else {
return right;
}
}
private ASTTypeIF checkAdditiveType(ASTExpressionIF lhs, ASTTypeIF left,
ASTTypeIF right) throws SyntaxException {
if (left instanceof ASTPointerType) {
if (right instanceof ASTIntegerType) {
this.isPointerOp = true;
return left;
} else {
throw new SyntaxException(lhs, "Type inconsistency: " + left
+ " and " + right);
}
} else if (right instanceof ASTPointerType) {
if (left instanceof ASTIntegerType) {
this.isPointerOp = true;
return left;
} else {
throw new SyntaxException(lhs, "Type inconsistency: " + left
+ " and " + right);
}
} else {
return this.mixType(left, right);
}
}
public BinaryOperator getOperator() {
return exprOperator;
}
public ASTExpressionIF getLeft() {
return left;
}
public ASTExpressionIF getRight() {
return right;
}
public boolean isPointerOp() {
return this.isPointerOp;
}
public String toString() {
String op = new String();
switch (this.exprOperator) {
case PLUS:
op = "+";
break;
case SUB:
op = "-";
break;
case MUL:
op = "*";
break;
case DIV:
op = "/";
break;
case MOD:
op = "%";
break;
case OR:
op = "||";
break;
case AND:
op = "&&";
break;
case EQ:
op = "==";
break;
case NEQ:
op = "!=";
break;
case LT:
op = "<";
break;
case LTE:
op = "<=";
break;
case GT:
op = ">";
break;
case GTE:
op = ">=";
break;
default:
op = "?????? UNKNOWN BINARY OPERATOR ??????";
}
return this.left.toString() + op + this.right.toString();
}
}