001: /*
002: * $Id: ChainedComparisonNode.java,v 1.5 2002/09/16 08:05:04 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.script.expression;
011:
012: import anvil.core.Any;
013: import anvil.core.Any.Op;
014: import anvil.codec.Code;
015: import anvil.codec.Source;
016: import anvil.script.compiler.ByteCompiler;
017: import anvil.script.Context;
018: import anvil.script.parser.ParserBaseConstants;
019: import java.io.IOException;
020:
021: /**
022: * class ChainedComparisonNode
023: *
024: * @author: Jani Lehtimäki
025: */
026: public class ChainedComparisonNode extends MultiParent implements
027: ParserBaseConstants {
028:
029: private int[] _op;
030:
031: public ChainedComparisonNode(Node[] child, int[] op) {
032: super (child);
033: _op = op;
034: }
035:
036: public int typeOf() {
037: return Node.EXPR_COMPARISON_CHAIN;
038: }
039:
040: public String getOp(int op) {
041: switch (op) {
042: case LESS:
043: return "<";
044: case LESS_OR_EQUAL:
045: return "<=";
046: case GREATER_OR_EQUAL:
047: return ">=";
048: case GREATER:
049: return ">";
050: default:
051: return "";
052: }
053: }
054:
055: public Any eval() {
056: Any a = getChild(0).eval();
057: Any b;
058: int n = childs();
059: for (int i = 1; i < n; i++) {
060: b = getChild(i).eval();
061: switch (_op[i - 1]) {
062: case LESS:
063: if (Op.test(a, b) >= 0) {
064: return Any.FALSE;
065: }
066: break;
067: case LESS_OR_EQUAL:
068: if (Op.test(a, b) > 0) {
069: return Any.FALSE;
070: }
071: break;
072: case GREATER_OR_EQUAL:
073: if (Op.test(a, b) < 0) {
074: return Any.FALSE;
075: }
076: break;
077: case GREATER:
078: if (Op.test(a, b) <= 0) {
079: return Any.FALSE;
080: }
081: break;
082: }
083: a = b;
084: }
085: return Any.TRUE;
086: }
087:
088: public void compile(ByteCompiler context, int operation) {
089: Code code = context.getCode();
090: int n = childs();
091: int testmethod = code.getPool().addMethodRef(
092: context.TYPE_ANY_OP, "test",
093: "(Lanvil/core/Any;Lanvil/core/Any;)I");
094: Source isfalse = code.getSource();
095: for (int i = 0; i < n; i++) {
096: if (i == 0) {
097: getChild(i++).compile(context, GET);
098: }
099: getChild(i).compile(context, GET);
100: code.dup_x1();
101: code.invokestatic(testmethod);
102: switch (_op[i - 1]) {
103: case LESS:
104: code.if_ge(isfalse);
105: break;
106: case LESS_OR_EQUAL:
107: code.if_gt(isfalse);
108: break;
109: case GREATER_OR_EQUAL:
110: code.if_lt(isfalse);
111: break;
112: case GREATER:
113: code.if_le(isfalse);
114: break;
115: default:
116: code.go_to(isfalse);
117: }
118: }
119: code.pop();
120: code.iconst(true);
121: Source toend = code.go_to();
122: isfalse.bind();
123: code.pop();
124: code.iconst(false);
125: toend.bind();
126: if (operation != GET_BOOLEAN) {
127: context.boolean2any();
128: }
129: }
130:
131: }
|