| /* |
| * 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; |
| } |
| } |
| |