/** * Copyright (C) 2010 dennis zhuang (killme2008@gmail.com) * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * **/ package com.googlecode.aviator.lexer.token; import com.googlecode.aviator.exception.ExpressionRuntimeException; import com.googlecode.aviator.runtime.type.AviatorBoolean; import com.googlecode.aviator.runtime.type.AviatorJavaType; import com.googlecode.aviator.runtime.type.AviatorObject; /** * Operator type * * @author dennis * */ public enum OperatorType { BIT_OR("|", 2), BIT_AND("&", 2), BIT_XOR("^", 2), BIT_NOT("~", 1), SHIFT_LEFT("<<", 2), SHIFT_RIGHT(">>", 2), U_SHIFT_RIGHT(">>>", 2), NOT("!", 1), MULT("*", 2), DIV("/", 2), MOD("%", 2), ADD("+", 2), SUB("-sub", 2), LT("<", 2), LE("<=", 2), GT(">", 2), GE(">=", 2), EQ("==", 2), NEQ("!=", 2), AND("&&", 2), MATCH("=~", 2), OR("||", 2), INDEX("[]", 2), FUNC("()", Integer.MAX_VALUE), NEG("-neg", 1), TERNARY("?:", 3); private String token; private int operandCount; OperatorType(String token, int operandCount) { this.token = token; this.operandCount = operandCount; } public AviatorObject eval(AviatorObject[] args) { if (args.length < this.operandCount) { throw new ExpressionRuntimeException("There are not enough operands for " + this); } switch (this) { case ADD: return args[0].add(args[1], null); case SUB: return args[0].sub(args[1], null); case MOD: return args[0].mod(args[1], null); case DIV: return args[0].div(args[1], null); case MULT: return args[0].mult(args[1], null); case EQ: int result = args[0].compare(args[1], null); return AviatorBoolean.valueOf(result == 0); case NEQ: result = args[0].compare(args[1], null); return AviatorBoolean.valueOf(result != 0); case LT: result = args[0].compare(args[1], null); return AviatorBoolean.valueOf(result < 0); case LE: result = args[0].compare(args[1], null); return AviatorBoolean.valueOf(result <= 0); case GT: result = args[0].compare(args[1], null); return AviatorBoolean.valueOf(result > 0); case GE: result = args[0].compare(args[1], null); return AviatorBoolean.valueOf(result >= 0); case NOT: return args[0].not(null); case NEG: return args[0].neg(null); case MATCH: // swap arguments return args[1].match(args[0], null); case AND: return args[0].booleanValue(null) && args[1].booleanValue(null) ? AviatorBoolean.TRUE : AviatorBoolean.FALSE; case OR: return args[0].booleanValue(null) || args[1].booleanValue(null) ? AviatorBoolean.TRUE : AviatorBoolean.FALSE; case FUNC: // TODO break; case INDEX: return ((AviatorJavaType) args[0]).getElement(null, args[1]); case TERNARY: return args[0].booleanValue(null) ? args[1] : args[2]; case BIT_OR: return args[0].bitOr(args[1], null); case BIT_AND: return args[0].bitAnd(args[1], null); case BIT_XOR: return args[0].bitXor(args[1], null); case SHIFT_LEFT: return args[0].shiftLeft(args[1], null); case SHIFT_RIGHT: return args[0].shiftRight(args[1], null); case U_SHIFT_RIGHT: return args[0].unsignedShiftRight(args[1], null); case BIT_NOT: return args[0].bitNot(null); } return null; } public String getToken() { return this.token; } public int getOperandCount() { return this.operandCount; } }