Search in sources :

Example 36 with Type

use of org.mvel2.asm.Type in project mvel by mikebrock.

the class TemplateCompiler method compileFrom.

public Node compileFrom(Node root, ExecutionStack stack) {
    line = 1;
    Node n = root;
    if (root == null) {
        n = root = new TextNode(0, 0);
    }
    IfNode last;
    Integer opcode;
    String name;
    int x;
    try {
        while (cursor < length) {
            switch(template[cursor]) {
                case '\n':
                    line++;
                    colStart = cursor + 1;
                    break;
                case '@':
                case '$':
                    if (isNext(template[cursor])) {
                        start = ++cursor;
                        (n = markTextNode(n)).setEnd(n.getEnd() + 1);
                        start = lastTextRangeEnding = ++cursor;
                        continue;
                    }
                    if ((x = captureOrbToken()) != -1) {
                        start = x;
                        switch((opcode = OPCODES.get(name = new String(capture()))) == null ? 0 : opcode) {
                            case Opcodes.IF:
                                /**
                                 * Capture any residual text node, and push the if statement on the nesting stack.
                                 */
                                stack.push(n = markTextNode(n).next = codeCache ? new CompiledIfNode(start, name, template, captureOrbInternal(), start, parserContext) : new IfNode(start, name, template, captureOrbInternal(), start));
                                n.setTerminus(new TerminalNode());
                                break;
                            case Opcodes.ELSE:
                                if (!stack.isEmpty() && stack.peek() instanceof IfNode) {
                                    markTextNode(n).next = (last = (IfNode) stack.pop()).getTerminus();
                                    last.demarcate(last.getTerminus(), template);
                                    last.next = n = codeCache ? new CompiledIfNode(start, name, template, captureOrbInternal(), start, parserContext) : new IfNode(start, name, template, captureOrbInternal(), start);
                                    n.setTerminus(last.getTerminus());
                                    stack.push(n);
                                }
                                break;
                            case Opcodes.FOREACH:
                                stack.push(n = markTextNode(n).next = codeCache ? new CompiledForEachNode(start, name, template, captureOrbInternal(), start, parserContext) : new ForEachNode(start, name, template, captureOrbInternal(), start));
                                n.setTerminus(new TerminalNode());
                                break;
                            case Opcodes.INCLUDE_FILE:
                                n = markTextNode(n).next = codeCache ? new CompiledIncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new IncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.INCLUDE_NAMED:
                                n = markTextNode(n).next = codeCache ? new CompiledNamedIncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new NamedIncludeNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.CODE:
                                n = markTextNode(n).next = codeCache ? new CompiledCodeNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new CodeNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.EVAL:
                                n = markTextNode(n).next = codeCache ? new CompiledEvalNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new EvalNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.COMMENT:
                                n = markTextNode(n).next = new CommentNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                break;
                            case Opcodes.DECLARE:
                                stack.push(n = markTextNode(n).next = codeCache ? new CompiledDeclareNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new DeclareNode(start, name, template, captureOrbInternal(), start = cursor + 1));
                                n.setTerminus(new TerminalNode());
                                break;
                            case Opcodes.END:
                                n = markTextNode(n);
                                Node end = (Node) stack.pop();
                                Node terminal = end.getTerminus();
                                terminal.setCStart(captureOrbInternal());
                                terminal.setEnd((lastTextRangeEnding = start) - 1);
                                terminal.calculateContents(template);
                                if (end.demarcate(terminal, template))
                                    n = n.next = terminal;
                                else
                                    n = terminal;
                                break;
                            default:
                                if (name.length() == 0) {
                                    n = markTextNode(n).next = codeCache ? new CompiledExpressionNode(start, name, template, captureOrbInternal(), start = cursor + 1, parserContext) : new ExpressionNode(start, name, template, captureOrbInternal(), start = cursor + 1);
                                } else if (customNodes != null && customNodes.containsKey(name)) {
                                    Class<? extends Node> customNode = customNodes.get(name);
                                    try {
                                        (n = markTextNode(n).next = (customNode.newInstance())).setBegin(start);
                                        n.setName(name);
                                        n.setCStart(captureOrbInternal());
                                        n.setCEnd(start = cursor + 1);
                                        n.setEnd(n.getCEnd());
                                        n.setContents(subset(template, n.getCStart(), n.getCEnd() - n.getCStart() - 1));
                                        if (n.isOpenNode()) {
                                            stack.push(n);
                                        }
                                    } catch (InstantiationException e) {
                                        throw new RuntimeException("unable to instantiate custom node class: " + customNode.getName());
                                    } catch (IllegalAccessException e) {
                                        throw new RuntimeException("unable to instantiate custom node class: " + customNode.getName());
                                    }
                                } else {
                                    throw new RuntimeException("unknown token type: " + name);
                                }
                        }
                    }
                    break;
            }
            cursor++;
        }
    } catch (RuntimeException e) {
        CompileException ce = new CompileException(e.getMessage(), template, cursor, e);
        ce.setExpr(template);
        if (e instanceof CompileException) {
            CompileException ce2 = (CompileException) e;
            if (ce2.getCursor() != -1) {
                ce.setCursor(ce2.getCursor());
                if (ce2.getColumn() == -1)
                    ce.setColumn(ce.getCursor() - colStart);
                else
                    ce.setColumn(ce2.getColumn());
            }
        }
        ce.setLineNumber(line);
        throw ce;
    }
    if (!stack.isEmpty()) {
        CompileException ce = new CompileException("unclosed @" + ((Node) stack.peek()).getName() + "{} block. expected @end{}", template, cursor);
        ce.setColumn(cursor - colStart);
        ce.setLineNumber(line);
        throw ce;
    }
    if (start < template.length) {
        n = n.next = new TextNode(start, template.length);
    }
    n.next = new EndNode();
    n = root;
    do {
        if (n.getLength() != 0) {
            break;
        }
    } while ((n = n.getNext()) != null);
    if (n != null && n.getLength() == template.length - 1) {
        if (n instanceof ExpressionNode) {
            return codeCache ? new CompiledTerminalExpressionNode(n, parserContext) : new TerminalExpressionNode(n);
        } else {
            return n;
        }
    }
    return root;
}
Also used : CompileException(org.mvel2.CompileException)

Example 37 with Type

use of org.mvel2.asm.Type in project mvel by mikebrock.

the class CollectionParser method parseCollection.

private Object parseCollection(boolean subcompile) {
    if (end - start == 0) {
        if (type == LIST)
            return new ArrayList();
        else
            return EMPTY_ARRAY;
    }
    Map<Object, Object> map = null;
    List<Object> list = null;
    int st = start;
    if (type != -1) {
        switch(type) {
            case ARRAY:
            case LIST:
                list = new ArrayList<Object>();
                break;
            case MAP:
                map = new HashMap<Object, Object>();
                break;
        }
    }
    Object curr = null;
    int newType = -1;
    for (; cursor < end; cursor++) {
        switch(property[cursor]) {
            case '{':
                if (newType == -1) {
                    newType = ARRAY;
                }
            case '[':
                if (cursor > start && isIdentifierPart(property[cursor - 1]))
                    continue;
                if (newType == -1) {
                    newType = LIST;
                }
                /**
                 * Sub-parse nested collections.
                 */
                Object o = new CollectionParser(newType).parseCollection(property, (st = cursor) + 1, (cursor = balancedCapture(property, st, end, property[st])) - st - 1, subcompile, colType, pCtx);
                if (type == MAP) {
                    map.put(curr, o);
                } else {
                    list.add(curr = o);
                }
                cursor = skipWhitespace(property, ++cursor);
                if ((st = cursor) < end && property[cursor] == ',') {
                    st = cursor + 1;
                } else if (cursor < end) {
                    if (ParseTools.opLookup(property[cursor]) == -1) {
                        throw new CompileException("unterminated collection element", property, cursor);
                    }
                }
                continue;
            case '(':
                cursor = balancedCapture(property, cursor, end, '(');
                break;
            case '\"':
            case '\'':
                cursor = balancedCapture(property, cursor, end, property[cursor]);
                break;
            case ',':
                if (type != MAP) {
                    list.add(new String(property, st, cursor - st).trim());
                } else {
                    map.put(curr, createStringTrimmed(property, st, cursor - st));
                }
                if (subcompile) {
                    subCompile(st, cursor - st);
                }
                st = cursor + 1;
                break;
            case ':':
                if (type != MAP) {
                    map = new HashMap<Object, Object>();
                    type = MAP;
                }
                curr = createStringTrimmed(property, st, cursor - st);
                if (subcompile) {
                    subCompile(st, cursor - st);
                }
                st = cursor + 1;
                break;
            case '.':
                cursor++;
                cursor = skipWhitespace(property, cursor);
                if (cursor != end && property[cursor] == '{') {
                    cursor = balancedCapture(property, cursor, '{');
                }
                break;
        }
    }
    if (st < end && isWhitespace(property[st])) {
        st = skipWhitespace(property, st);
    }
    if (st < end) {
        if (cursor < (end - 1))
            cursor++;
        if (type == MAP) {
            map.put(curr, createStringTrimmed(property, st, cursor - st));
        } else {
            if (cursor < end)
                cursor++;
            list.add(createStringTrimmed(property, st, cursor - st));
        }
        if (subcompile)
            subCompile(st, cursor - st);
    }
    switch(type) {
        case MAP:
            return map;
        case ARRAY:
            return list.toArray();
        default:
            return list;
    }
}
Also used : ArrayList(java.util.ArrayList) CompileException(org.mvel2.CompileException)

Example 38 with Type

use of org.mvel2.asm.Type in project mvel by mikebrock.

the class ProtoParser method parse.

public Proto parse() {
    Proto proto = new Proto(protoName);
    Mainloop: while (cursor < endOffset) {
        cursor = ParseTools.skipWhitespace(expr, cursor);
        int start = cursor;
        if (tk2 == null) {
            while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
            if (cursor > start) {
                tk1 = new String(expr, start, cursor - start);
                if ("def".equals(tk1) || "function".equals(tk1)) {
                    cursor++;
                    cursor = ParseTools.skipWhitespace(expr, cursor);
                    start = cursor;
                    while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
                    if (start == cursor) {
                        throw new CompileException("attempt to declare an anonymous function as a prototype member", expr, start);
                    }
                    FunctionParser parser = new FunctionParser(new String(expr, start, cursor - start), cursor, endOffset, expr, 0, pCtx, null);
                    proto.declareReceiver(parser.getName(), parser.parse());
                    cursor = parser.getCursor() + 1;
                    tk1 = null;
                    continue;
                }
            }
            cursor = ParseTools.skipWhitespace(expr, cursor);
        }
        if (cursor > endOffset) {
            throw new CompileException("unexpected end of statement in proto declaration: " + protoName, expr, start);
        }
        switch(expr[cursor]) {
            case ';':
                cursor++;
                calculateDecl();
                if (interpreted && type == DeferredTypeResolve.class) {
                    /**
                     * If this type could not be immediately resolved, it may be a look-ahead case, so
                     * we defer resolution of the type until later and place it in the wait queue.
                     */
                    enqueueReceiverForLateResolution(deferredName, proto.declareReceiver(name, Proto.ReceiverType.DEFERRED, null), null);
                } else {
                    proto.declareReceiver(name, type, null);
                }
                break;
            case '=':
                cursor++;
                cursor = ParseTools.skipWhitespace(expr, cursor);
                start = cursor;
                Loop: while (cursor < endOffset) {
                    switch(expr[cursor]) {
                        case '{':
                        case '[':
                        case '(':
                        case '\'':
                        case '"':
                            cursor = balancedCaptureWithLineAccounting(expr, cursor, endOffset, expr[cursor], pCtx);
                            break;
                        case ';':
                            break Loop;
                    }
                    cursor++;
                }
                calculateDecl();
                String initString = new String(expr, start, cursor++ - start);
                if (interpreted && type == DeferredTypeResolve.class) {
                    enqueueReceiverForLateResolution(deferredName, proto.declareReceiver(name, Proto.ReceiverType.DEFERRED, null), initString);
                } else {
                    proto.declareReceiver(name, type, (ExecutableStatement) subCompileExpression(initString, pCtx));
                }
                break;
            default:
                start = cursor;
                while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
                if (cursor > start) {
                    tk2 = new String(expr, start, cursor - start);
                }
        }
    }
    cursor++;
    /**
     * Check if the function is manually terminated.
     */
    if (splitAccumulator != null && ParseTools.isStatementNotManuallyTerminated(expr, cursor)) {
        /**
         * Add an EndOfStatement to the split accumulator in the parser.
         */
        splitAccumulator.add(new EndOfStatement());
    }
    return proto;
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) Proto(org.mvel2.ast.Proto) EndOfStatement(org.mvel2.ast.EndOfStatement) CompileException(org.mvel2.CompileException)

Example 39 with Type

use of org.mvel2.asm.Type in project mvel by mikebrock.

the class PropertyAccessor method getCollectionPropertyAO.

private Object getCollectionPropertyAO(Object ctx, String prop) throws Exception {
    if (prop.length() != 0) {
        ctx = getBeanProperty(ctx, prop);
    }
    if (ctx == null)
        return null;
    int _start = ++cursor;
    whiteSpaceSkip();
    if (cursor == end || scanTo(']'))
        throw new PropertyAccessException("unterminated '['", property, cursor);
    prop = new String(property, _start, cursor++ - _start);
    if (ctx instanceof Map) {
        if (hasPropertyHandler(Map.class))
            return getPropertyHandler(Map.class).getProperty(prop, ctx, variableFactory);
        else
            return ((Map) ctx).get(eval(prop, ctx, variableFactory));
    } else if (ctx instanceof List) {
        if (hasPropertyHandler(List.class))
            return getPropertyHandler(List.class).getProperty(prop, ctx, variableFactory);
        else
            return ((List) ctx).get((Integer) eval(prop, ctx, variableFactory));
    } else if (ctx instanceof Collection) {
        if (hasPropertyHandler(Collection.class))
            return getPropertyHandler(Collection.class).getProperty(prop, ctx, variableFactory);
        else {
            int count = (Integer) eval(prop, ctx, variableFactory);
            if (count > ((Collection) ctx).size())
                throw new PropertyAccessException("index [" + count + "] out of bounds on collections", property, cursor);
            Iterator iter = ((Collection) ctx).iterator();
            for (int i = 0; i < count; i++) iter.next();
            return iter.next();
        }
    } else if (ctx.getClass().isArray()) {
        if (hasPropertyHandler(Array.class))
            return getPropertyHandler(Array.class).getProperty(prop, ctx, variableFactory);
        return Array.get(ctx, (Integer) eval(prop, ctx, variableFactory));
    } else if (ctx instanceof CharSequence) {
        if (hasPropertyHandler(CharSequence.class))
            return getPropertyHandler(CharSequence.class).getProperty(prop, ctx, variableFactory);
        else
            return ((CharSequence) ctx).charAt((Integer) eval(prop, ctx, variableFactory));
    } else {
        try {
            return getClassReference(getCurrentThreadParserContext(), (Class) ctx, new TypeDescriptor(property, start, end - start, 0));
        } catch (Exception e) {
            throw new PropertyAccessException("illegal use of []: unknown type: " + (ctx == null ? null : ctx.getClass().getName()), property, st);
        }
    }
}
Also used : TypeDescriptor(org.mvel2.ast.TypeDescriptor)

Example 40 with Type

use of org.mvel2.asm.Type in project mvel by mikebrock.

the class MathProcessor method doOperationsSameType.

private static Object doOperationsSameType(int type1, Object val1, int operation, Object val2) {
    switch(type1) {
        case DataTypes.COLLECTION:
            switch(operation) {
                case ADD:
                    List list = new ArrayList((Collection) val1);
                    list.addAll((Collection) val2);
                    return list;
                case EQUAL:
                    return val1.equals(val2);
                case NEQUAL:
                    return !val1.equals(val2);
                default:
                    throw new UnsupportedOperationException("illegal operation on Collection type");
            }
        case DataTypes.INTEGER:
        case DataTypes.W_INTEGER:
            switch(operation) {
                case ADD:
                    return ((Integer) val1) + ((Integer) val2);
                case SUB:
                    return ((Integer) val1) - ((Integer) val2);
                case DIV:
                    return ((Integer) val1).doubleValue() / ((Integer) val2).doubleValue();
                case MULT:
                    return ((Integer) val1) * ((Integer) val2);
                case POWER:
                    double d = Math.pow((Integer) val1, (Integer) val2);
                    if (d > Integer.MAX_VALUE)
                        return d;
                    else
                        return (int) d;
                case MOD:
                    return ((Integer) val1) % ((Integer) val2);
                case GTHAN:
                    return ((Integer) val1) > ((Integer) val2) ? Boolean.TRUE : Boolean.FALSE;
                case GETHAN:
                    return ((Integer) val1) >= ((Integer) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LTHAN:
                    return ((Integer) val1) < ((Integer) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LETHAN:
                    return ((Integer) val1) <= ((Integer) val2) ? Boolean.TRUE : Boolean.FALSE;
                case EQUAL:
                    return ((Integer) val1).intValue() == ((Integer) val2).intValue() ? Boolean.TRUE : Boolean.FALSE;
                case NEQUAL:
                    return ((Integer) val1).intValue() != ((Integer) val2).intValue() ? Boolean.TRUE : Boolean.FALSE;
                case BW_AND:
                    return (Integer) val1 & (Integer) val2;
                case BW_OR:
                    return (Integer) val1 | (Integer) val2;
                case BW_SHIFT_LEFT:
                    return (Integer) val1 << (Integer) val2;
                case BW_SHIFT_RIGHT:
                    return (Integer) val1 >> (Integer) val2;
                case BW_USHIFT_RIGHT:
                    return (Integer) val1 >>> (Integer) val2;
                case BW_XOR:
                    return (Integer) val1 ^ (Integer) val2;
            }
        case DataTypes.SHORT:
        case DataTypes.W_SHORT:
            switch(operation) {
                case ADD:
                    return ((Short) val1) + ((Short) val2);
                case SUB:
                    return ((Short) val1) - ((Short) val2);
                case DIV:
                    return ((Short) val1).doubleValue() / ((Short) val2).doubleValue();
                case MULT:
                    return ((Short) val1) * ((Short) val2);
                case POWER:
                    double d = Math.pow((Short) val1, (Short) val2);
                    if (d > Short.MAX_VALUE)
                        return d;
                    else
                        return (short) d;
                case MOD:
                    return ((Short) val1) % ((Short) val2);
                case GTHAN:
                    return ((Short) val1) > ((Short) val2) ? Boolean.TRUE : Boolean.FALSE;
                case GETHAN:
                    return ((Short) val1) >= ((Short) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LTHAN:
                    return ((Short) val1) < ((Short) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LETHAN:
                    return ((Short) val1) <= ((Short) val2) ? Boolean.TRUE : Boolean.FALSE;
                case EQUAL:
                    return ((Short) val1).shortValue() == ((Short) val2).shortValue() ? Boolean.TRUE : Boolean.FALSE;
                case NEQUAL:
                    return ((Short) val1).shortValue() != ((Short) val2).shortValue() ? Boolean.TRUE : Boolean.FALSE;
                case BW_AND:
                    return (Short) val1 & (Short) val2;
                case BW_OR:
                    return (Short) val1 | (Short) val2;
                case BW_SHIFT_LEFT:
                    return (Short) val1 << (Short) val2;
                case BW_SHIFT_RIGHT:
                    return (Short) val1 >> (Short) val2;
                case BW_USHIFT_RIGHT:
                    return (Short) val1 >>> (Short) val2;
                case BW_XOR:
                    return (Short) val1 ^ (Short) val2;
            }
        case DataTypes.LONG:
        case DataTypes.W_LONG:
            switch(operation) {
                case ADD:
                    return ((Long) val1) + ((Long) val2);
                case SUB:
                    return ((Long) val1) - ((Long) val2);
                case DIV:
                    return ((Long) val1).doubleValue() / ((Long) val2).doubleValue();
                case MULT:
                    return ((Long) val1) * ((Long) val2);
                case POWER:
                    double d = Math.pow((Long) val1, (Long) val2);
                    if (d > Long.MAX_VALUE)
                        return d;
                    else
                        return (long) d;
                case MOD:
                    return ((Long) val1) % ((Long) val2);
                case GTHAN:
                    return ((Long) val1) > ((Long) val2) ? Boolean.TRUE : Boolean.FALSE;
                case GETHAN:
                    return ((Long) val1) >= ((Long) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LTHAN:
                    return ((Long) val1) < ((Long) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LETHAN:
                    return ((Long) val1) <= ((Long) val2) ? Boolean.TRUE : Boolean.FALSE;
                case EQUAL:
                    return ((Long) val1).longValue() == ((Long) val2).longValue() ? Boolean.TRUE : Boolean.FALSE;
                case NEQUAL:
                    return ((Long) val1).longValue() != ((Long) val2).longValue() ? Boolean.TRUE : Boolean.FALSE;
                case BW_AND:
                    return (Long) val1 & (Long) val2;
                case BW_OR:
                    return (Long) val1 | (Long) val2;
                case BW_SHIFT_LEFT:
                    return (Long) val1 << (Long) val2;
                case BW_USHIFT_LEFT:
                    throw new UnsupportedOperationException("unsigned left-shift not supported");
                case BW_SHIFT_RIGHT:
                    return (Long) val1 >> (Long) val2;
                case BW_USHIFT_RIGHT:
                    return (Long) val1 >>> (Long) val2;
                case BW_XOR:
                    return (Long) val1 ^ (Long) val2;
            }
        case DataTypes.UNIT:
            val2 = ((Unit) val1).convertFrom(val2);
            val1 = ((Unit) val1).getValue();
        case DataTypes.DOUBLE:
        case DataTypes.W_DOUBLE:
            switch(operation) {
                case ADD:
                    return ((Double) val1) + ((Double) val2);
                case SUB:
                    return ((Double) val1) - ((Double) val2);
                case DIV:
                    return ((Double) val1) / ((Double) val2);
                case MULT:
                    return ((Double) val1) * ((Double) val2);
                case POWER:
                    return Math.pow((Double) val1, (Double) val2);
                case MOD:
                    return ((Double) val1) % ((Double) val2);
                case GTHAN:
                    return ((Double) val1) > ((Double) val2) ? Boolean.TRUE : Boolean.FALSE;
                case GETHAN:
                    return ((Double) val1) >= ((Double) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LTHAN:
                    return ((Double) val1) < ((Double) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LETHAN:
                    return ((Double) val1) <= ((Double) val2) ? Boolean.TRUE : Boolean.FALSE;
                case EQUAL:
                    return ((Double) val1).doubleValue() == ((Double) val2).doubleValue() ? Boolean.TRUE : Boolean.FALSE;
                case NEQUAL:
                    return ((Double) val1).doubleValue() != ((Double) val2).doubleValue() ? Boolean.TRUE : Boolean.FALSE;
                case BW_AND:
                case BW_OR:
                case BW_SHIFT_LEFT:
                case BW_SHIFT_RIGHT:
                case BW_USHIFT_RIGHT:
                case BW_XOR:
                    throw new RuntimeException("bitwise operation on a non-fixed-point number.");
            }
        case DataTypes.FLOAT:
        case DataTypes.W_FLOAT:
            switch(operation) {
                case ADD:
                    return ((Float) val1) + ((Float) val2);
                case SUB:
                    return ((Float) val1) - ((Float) val2);
                case DIV:
                    return ((Float) val1).doubleValue() / ((Float) val2).doubleValue();
                case MULT:
                    return ((Float) val1) * ((Float) val2);
                case POWER:
                    return narrowType(new InternalNumber((Float) val1, MATH_CONTEXT).pow(new InternalNumber((Float) val2).intValue(), MATH_CONTEXT), -1);
                case MOD:
                    return ((Float) val1) % ((Float) val2);
                case GTHAN:
                    return ((Float) val1) > ((Float) val2) ? Boolean.TRUE : Boolean.FALSE;
                case GETHAN:
                    return ((Float) val1) >= ((Float) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LTHAN:
                    return ((Float) val1) < ((Float) val2) ? Boolean.TRUE : Boolean.FALSE;
                case LETHAN:
                    return ((Float) val1) <= ((Float) val2) ? Boolean.TRUE : Boolean.FALSE;
                case EQUAL:
                    return ((Float) val1).floatValue() == ((Float) val2).floatValue() ? Boolean.TRUE : Boolean.FALSE;
                case NEQUAL:
                    return ((Float) val1).floatValue() != ((Float) val2).floatValue() ? Boolean.TRUE : Boolean.FALSE;
                case BW_AND:
                case BW_OR:
                case BW_SHIFT_LEFT:
                case BW_SHIFT_RIGHT:
                case BW_USHIFT_RIGHT:
                case BW_XOR:
                    throw new RuntimeException("bitwise operation on a non-fixed-point number.");
            }
        case DataTypes.BIG_INTEGER:
            switch(operation) {
                case ADD:
                    return ((BigInteger) val1).add(((BigInteger) val2));
                case SUB:
                    return ((BigInteger) val1).subtract(((BigInteger) val2));
                case DIV:
                    return ((BigInteger) val1).divide(((BigInteger) val2));
                case MULT:
                    return ((BigInteger) val1).multiply(((BigInteger) val2));
                case POWER:
                    return ((BigInteger) val1).pow(((BigInteger) val2).intValue());
                case MOD:
                    return ((BigInteger) val1).remainder(((BigInteger) val2));
                case GTHAN:
                    return ((BigInteger) val1).compareTo(((BigInteger) val2)) == 1 ? Boolean.TRUE : Boolean.FALSE;
                case GETHAN:
                    return ((BigInteger) val1).compareTo(((BigInteger) val2)) >= 0 ? Boolean.TRUE : Boolean.FALSE;
                case LTHAN:
                    return ((BigInteger) val1).compareTo(((BigInteger) val2)) == -1 ? Boolean.TRUE : Boolean.FALSE;
                case LETHAN:
                    return ((BigInteger) val1).compareTo(((BigInteger) val2)) <= 0 ? Boolean.TRUE : Boolean.FALSE;
                case EQUAL:
                    return ((BigInteger) val1).compareTo(((BigInteger) val2)) == 0 ? Boolean.TRUE : Boolean.FALSE;
                case NEQUAL:
                    return ((BigInteger) val1).compareTo(((BigInteger) val2)) != 0 ? Boolean.TRUE : Boolean.FALSE;
                case BW_AND:
                case BW_OR:
                case BW_SHIFT_LEFT:
                case BW_SHIFT_RIGHT:
                case BW_USHIFT_RIGHT:
                case BW_XOR:
                    throw new RuntimeException("bitwise operation on a number greater than 32-bits not possible");
            }
        default:
            switch(operation) {
                case EQUAL:
                    return safeEquals(val2, val1);
                case NEQUAL:
                    return safeNotEquals(val2, val1);
                case ADD:
                    return valueOf(val1) + valueOf(val2);
            }
    }
    return null;
}
Also used : BigInteger(java.math.BigInteger) InternalNumber(org.mvel2.util.InternalNumber) ArrayList(java.util.ArrayList) BigInteger(java.math.BigInteger) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

MethodVisitor (org.mvel2.asm.MethodVisitor)19 Map (java.util.Map)15 Label (org.mvel2.asm.Label)13 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)12 List (java.util.List)11 Type (org.mvel2.asm.Type)10 IOException (java.io.IOException)7 ArrayList (java.util.ArrayList)7 CompileException (org.mvel2.CompileException)7 ParserContext (org.mvel2.ParserContext)7 HashMap (java.util.HashMap)6 TypeDescriptor (org.mvel2.ast.TypeDescriptor)6 WeakHashMap (java.util.WeakHashMap)4 WorkingMemory (org.drools.core.WorkingMemory)4 InternalFactHandle (org.drools.core.common.InternalFactHandle)4 Tuple (org.drools.core.spi.Tuple)4 FieldVisitor (org.mvel2.asm.FieldVisitor)4 ExpressionCompiler (org.mvel2.compiler.ExpressionCompiler)4 LeftTuple (org.drools.core.reteoo.LeftTuple)3 DeclarationMatcher (org.drools.core.rule.builder.dialect.asm.GeneratorHelper.DeclarationMatcher)3