blob: ddadb788fbfca542e5d782af4064041ad5f3a124 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.axis2.corba.idl.parser;
import antlr.collections.AST;
import org.apache.axis2.corba.exceptions.InvalidIDLException;
import org.apache.axis2.corba.idl.types.ConstType;
import org.apache.axis2.corba.idl.types.DataType;
import org.apache.axis2.corba.idl.types.Typedef;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
import java.math.BigDecimal;
public class ExpressionUtil {
public static Object eval(AST expressionNode, DataType returnType, IDLVisitor visitor) throws InvalidIDLException {
Object value;
AST node1;
AST node2;
int expressionType = expressionNode.getType();
TypeCode typeCode = returnType.getTypeCode();
switch (expressionType) {
case IDLTokenTypes.PLUS:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = node2 == null? eval(node1, returnType, visitor)
: add(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.MINUS:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = node2 == null? minus(eval(node1, returnType, visitor), typeCode)
: subtract(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.STAR:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = multiply(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.DIV:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = div(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.MOD:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = mod(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.OR:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = or(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.AND:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = and(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.RSHIFT:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = rshift(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.LSHIFT:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = lshift(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.XOR:
node1 = expressionNode.getFirstChild();
node2 = node1.getNextSibling();
value = xor(eval(node1, returnType, visitor), eval(node2, returnType, visitor), typeCode);
break;
case IDLTokenTypes.TILDE:
node1 = expressionNode.getFirstChild();
Object boolObj = eval(node1, returnType, visitor);
if (!(boolObj instanceof Boolean)) {
throw new InvalidIDLException("A boolean value is expected after (~) operator");
}
value = Boolean.valueOf(!((Boolean) boolObj).booleanValue());
break;
case IDLTokenTypes.INT:
case IDLTokenTypes.FLOAT:
case IDLTokenTypes.STRING_LITERAL:
case IDLTokenTypes.WIDE_STRING_LITERAL:
case IDLTokenTypes.CHAR_LITERAL:
case IDLTokenTypes.WIDE_CHAR_LITERAL:
case IDLTokenTypes.FIXED:
value = getValueObject(expressionNode.getText(), returnType);
break;
case IDLTokenTypes.LITERAL_TRUE:
value = Boolean.valueOf(true);
break;
case IDLTokenTypes.LITERAL_FALSE:
value = Boolean.valueOf(true);
break;
case IDLTokenTypes.IDENT:
value = getConstant(expressionNode.getText(), visitor);
break;
case IDLTokenTypes.LPAREN:
value = eval(expressionNode.getFirstChild(), returnType, visitor);
break;
default:
throw new InvalidIDLException("Unsupported IDL token " + expressionNode);
}
return value;
}
private static Object add(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() + ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() + ((Long) o2).longValue());
break;
case TCKind._tk_float:
valueObj = new Float(((Float) o1).floatValue() + ((Float) o2).floatValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() + ((Short) o2).shortValue()));
break;
case TCKind._tk_double:
valueObj = new Double(((Double) o1).doubleValue() + ((Double) o2).doubleValue());
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() + ((Byte) o2).byteValue()));
break;
case TCKind._tk_fixed:
valueObj = ((BigDecimal) o1).add((BigDecimal) o2);
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object minus(Object o, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(-((Integer) o).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(-((Long) o).longValue());
break;
case TCKind._tk_float:
valueObj = new Float(-((Float) o).floatValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (-((Short) o).shortValue()));
break;
case TCKind._tk_double:
valueObj = new Double(- ((Double) o).doubleValue());
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (- ((Byte) o).byteValue()));
break;
case TCKind._tk_fixed:
valueObj = ((BigDecimal) o).multiply(new BigDecimal(-1));
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object subtract(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() - ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() - ((Long) o2).longValue());
break;
case TCKind._tk_float:
valueObj = new Float(((Float) o1).floatValue() - ((Float) o2).floatValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() - ((Short) o2).shortValue()));
break;
case TCKind._tk_double:
valueObj = new Double(((Double) o1).doubleValue() - ((Double) o2).doubleValue());
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() - ((Byte) o2).byteValue()));
break;
case TCKind._tk_fixed:
valueObj = ((BigDecimal) o1).subtract((BigDecimal) o2);
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object multiply(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() * ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() * ((Long) o2).longValue());
break;
case TCKind._tk_float:
valueObj = new Float(((Float) o1).floatValue() * ((Float) o2).floatValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() * ((Short) o2).shortValue()));
break;
case TCKind._tk_double:
valueObj = new Double(((Double) o1).doubleValue() * ((Double) o2).doubleValue());
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() * ((Byte) o2).byteValue()));
break;
case TCKind._tk_fixed:
valueObj = ((BigDecimal) o1).multiply((BigDecimal) o2);
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object div(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() / ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() / ((Long) o2).longValue());
break;
case TCKind._tk_float:
valueObj = new Float(((Float) o1).floatValue() / ((Float) o2).floatValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() / ((Short) o2).shortValue()));
break;
case TCKind._tk_double:
valueObj = new Double(((Double) o1).doubleValue() / ((Double) o2).doubleValue());
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() / ((Byte) o2).byteValue()));
break;
case TCKind._tk_fixed:
valueObj = ((BigDecimal) o1).divide((BigDecimal) o2);
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object rshift(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() >> ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() >> ((Long) o2).longValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() >> ((Short) o2).shortValue()));
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() >> ((Byte) o2).byteValue()));
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object lshift(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() << ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() << ((Long) o2).longValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() << ((Short) o2).shortValue()));
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() << ((Byte) o2).byteValue()));
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object xor(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() ^ ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() ^ ((Long) o2).longValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() ^ ((Short) o2).shortValue()));
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() ^ ((Byte) o2).byteValue()));
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object mod(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() % ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() % ((Long) o2).longValue());
break;
case TCKind._tk_float:
valueObj = new Float(((Float) o1).floatValue() % ((Float) o2).floatValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() % ((Short) o2).shortValue()));
break;
case TCKind._tk_double:
valueObj = new Double(((Double) o1).doubleValue() % ((Double) o2).doubleValue());
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() % ((Byte) o2).byteValue()));
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object or(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() | ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() | ((Long) o2).longValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() | ((Short) o2).shortValue()));
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() | ((Byte) o2).byteValue()));
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object and(Object o1, Object o2, TypeCode returnType) throws InvalidIDLException {
TCKind kind = returnType.kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(((Integer) o1).intValue() & ((Integer) o2).intValue());
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(((Long) o1).longValue() & ((Long) o2).longValue());
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short((short) (((Short) o1).shortValue() & ((Short) o2).shortValue()));
break;
case TCKind._tk_octet:
valueObj = new Byte((byte) (((Byte) o1).byteValue() & ((Byte) o2).byteValue()));
break;
default:
throw new InvalidIDLException("Unsupported IDL token");
}
return valueObj;
}
private static Object getValueObject(String value, DataType type) throws InvalidIDLException {
TCKind kind = type.getTypeCode().kind();
Object valueObj;
switch (kind.value()) {
case TCKind._tk_long:
case TCKind._tk_ulong:
valueObj = new Integer(value);
break;
case TCKind._tk_longlong:
case TCKind._tk_ulonglong:
valueObj = new Long(value);
break;
case TCKind._tk_float:
valueObj = new Float(value);
break;
case TCKind._tk_short:
case TCKind._tk_ushort:
valueObj = new Short(value);
break;
case TCKind._tk_char:
case TCKind._tk_wchar:
valueObj = new Character(value.charAt(0));
break;
case TCKind._tk_double:
valueObj = new Double(value);
break;
case TCKind._tk_octet:
valueObj = new Byte(value);
break;
case TCKind._tk_string:
case TCKind._tk_wstring:
valueObj = value;
break;
case TCKind._tk_alias:
Typedef typedef = (Typedef) type;
valueObj = getValueObject(value, typedef.getDataType());
break;
case TCKind._tk_fixed:
valueObj = new BigDecimal(value);
break;
default:
throw new InvalidIDLException("Unsupported IDL token ");
}
return valueObj;
}
private static Object getConstant(String expressionName, IDLVisitor visitor) throws InvalidIDLException {
Object value;
DataType dataType = visitor.getDataType(expressionName);
if (dataType != null && dataType instanceof ConstType) {
ConstType constType = (ConstType) dataType;
value = constType.getValue();
} else {
throw new InvalidIDLException("Constant " + expressionName + " not found.");
}
return value;
}
}