Search in sources :

Example 1 with NumberToken

use of com.googlecode.aviator.lexer.token.NumberToken in project aviatorscript by killme2008.

the class OptimizeCodeGenerator method getTokenFromOperand.

/**
 * Get token from executing result
 *
 * @param operand
 * @return
 */
private Token<?> getTokenFromOperand(final Token<?> operatorToken, final AviatorObject operand) {
    Token<?> token = null;
    switch(operand.getAviatorType()) {
        case JavaType:
            if (operand instanceof AviatorRuntimeJavaType) {
                Object val = operand.getValue(null);
                if (val == null) {
                    token = Variable.NIL;
                } else if (val instanceof Number) {
                    token = new NumberToken((Number) val, val.toString(), operatorToken.getLineNo(), operatorToken.getStartIndex());
                } else if (val instanceof String || val instanceof Character) {
                    String s = val.toString();
                    token = new StringToken(s, operatorToken.getLineNo(), operatorToken.getStartIndex()).withMeta(Constants.INTER_META, s.contains("#"));
                } else if (val instanceof Pattern) {
                    token = new PatternToken(((Pattern) val).pattern(), operatorToken.getLineNo(), operatorToken.getStartIndex());
                } else if (val instanceof Boolean) {
                    token = (boolean) val ? Variable.TRUE : Variable.FALSE;
                } else {
                    throw new CompileExpressionErrorException("Invalid operand:" + operand.desc(null));
                }
            } else {
                throw new CompileExpressionErrorException("Invalid operand:" + operand.desc(null));
            }
            break;
        case Boolean:
            token = operand.booleanValue(null) ? Variable.TRUE : Variable.FALSE;
            break;
        case Nil:
            token = Variable.NIL;
            break;
        case BigInt:
        case Decimal:
        case Double:
        case Long:
            final Number value = (Number) operand.getValue(null);
            token = new NumberToken(value, value.toString(), operatorToken.getLineNo(), operatorToken.getStartIndex());
            break;
        case String:
            final String str = (String) operand.getValue(null);
            token = new StringToken(str, operatorToken.getLineNo(), operatorToken.getStartIndex());
            break;
        case Pattern:
            token = new PatternToken(((AviatorPattern) operand).getPattern().pattern(), operatorToken.getLineNo(), operatorToken.getStartIndex());
            break;
    }
    return token;
}
Also used : AviatorPattern(com.googlecode.aviator.runtime.type.AviatorPattern) Pattern(java.util.regex.Pattern) PatternToken(com.googlecode.aviator.lexer.token.PatternToken) AviatorNumber(com.googlecode.aviator.runtime.type.AviatorNumber) CompileExpressionErrorException(com.googlecode.aviator.exception.CompileExpressionErrorException) AviatorRuntimeJavaType(com.googlecode.aviator.runtime.type.AviatorRuntimeJavaType) NumberToken(com.googlecode.aviator.lexer.token.NumberToken) AviatorObject(com.googlecode.aviator.runtime.type.AviatorObject) AviatorString(com.googlecode.aviator.runtime.type.AviatorString) AviatorBoolean(com.googlecode.aviator.runtime.type.AviatorBoolean) StringToken(com.googlecode.aviator.lexer.token.StringToken)

Example 2 with NumberToken

use of com.googlecode.aviator.lexer.token.NumberToken in project aviatorscript by killme2008.

the class OptimizeCodeGenerator method getAviatorObjectFromToken.

private AviatorObject getAviatorObjectFromToken(final Token<?> lookhead) {
    AviatorObject result = null;
    switch(lookhead.getType()) {
        case Number:
            // load numbers
            NumberToken numberToken = (NumberToken) lookhead;
            Number num = numberToken.getNumber();
            result = AviatorNumber.valueOf(num);
            break;
        case String:
            // load string
            result = new AviatorString((String) lookhead.getValue(null), true, true, lookhead.getLineNo());
            break;
        case Pattern:
            // load pattern
            result = new AviatorPattern((String) lookhead.getValue(null));
            break;
        case Variable:
            if (lookhead == Variable.TRUE) {
                result = AviatorBoolean.TRUE;
            } else if (lookhead == Variable.FALSE) {
                result = AviatorBoolean.FALSE;
            } else if (lookhead == Variable.NIL) {
                result = AviatorNil.NIL;
            }
            break;
        case Char:
            result = new AviatorString(String.valueOf(lookhead.getValue(null)), true, true, lookhead.getLineNo());
            break;
    }
    return result;
}
Also used : AviatorObject(com.googlecode.aviator.runtime.type.AviatorObject) AviatorPattern(com.googlecode.aviator.runtime.type.AviatorPattern) AviatorNumber(com.googlecode.aviator.runtime.type.AviatorNumber) AviatorString(com.googlecode.aviator.runtime.type.AviatorString) NumberToken(com.googlecode.aviator.lexer.token.NumberToken) AviatorString(com.googlecode.aviator.runtime.type.AviatorString)

Example 3 with NumberToken

use of com.googlecode.aviator.lexer.token.NumberToken in project aviatorscript by killme2008.

the class ExpressionLexer method scan.

public Token<?> scan(final boolean analyse) {
    // If buffer is not empty,return
    if (this.tokenBuffer != null && !this.tokenBuffer.isEmpty()) {
        return this.tokenBuffer.pop();
    }
    // Skip white space or line
    for (; ; nextChar()) {
        if (this.peek == CharacterIterator.DONE) {
            return null;
        }
        if (analyse) {
            if (this.peek == ' ' || this.peek == '\t' || this.peek == '\r' || this.peek == '\n') {
                if (this.peek == '\n') {
                    this.lineNo++;
                }
                continue;
            }
            break;
        } else {
            char ch = this.peek;
            int index = this.iterator.getIndex();
            nextChar();
            return new CharToken(ch, this.lineNo, index);
        }
    }
    // if it is a hex digit
    if (Character.isDigit(this.peek) && this.peek == '0') {
        nextChar();
        if (this.peek == 'x' || this.peek == 'X') {
            nextChar();
            StringBuilder sb = new StringBuilder();
            int startIndex = this.iterator.getIndex() - 2;
            long value = 0L;
            do {
                sb.append(this.peek);
                value = 16 * value + Character.digit(this.peek, 16);
                nextChar();
            } while (isValidHexChar(this.peek));
            return new NumberToken(value, sb.toString(), this.lineNo, startIndex);
        } else {
            prevChar();
        }
    }
    // If it is a digit
    if (Character.isDigit(this.peek) || this.peek == '.') {
        StringBuilder sb = new StringBuilder();
        int startIndex = this.iterator.getIndex();
        long lval = 0L;
        double dval = 0d;
        boolean hasDot = false;
        double d = 10.0;
        boolean isBigInt = false;
        boolean isBigDecimal = false;
        boolean scientificNotation = false;
        boolean negExp = false;
        boolean isOverflow = false;
        do {
            sb.append(this.peek);
            if (this.peek == '.') {
                if (scientificNotation) {
                    throw new CompileExpressionErrorException("Illegal number " + sb + " at " + this.iterator.getIndex());
                }
                if (hasDot) {
                    throw new CompileExpressionErrorException("Illegal Number " + sb + " at " + this.iterator.getIndex());
                } else {
                    hasDot = true;
                    nextChar();
                }
            } else if (this.peek == 'N') {
                // big integer
                if (hasDot) {
                    throw new CompileExpressionErrorException("Illegal number " + sb + " at " + this.iterator.getIndex());
                }
                isBigInt = true;
                nextChar();
                break;
            } else if (this.peek == 'M') {
                isBigDecimal = true;
                nextChar();
                break;
            } else if (this.peek == 'e' || this.peek == 'E') {
                if (scientificNotation) {
                    throw new CompileExpressionErrorException("Illegal number " + sb + " at " + this.iterator.getIndex());
                }
                scientificNotation = true;
                nextChar();
                if (this.peek == '-') {
                    negExp = true;
                    sb.append(this.peek);
                    nextChar();
                }
            } else {
                int digit = Character.digit(this.peek, 10);
                if (scientificNotation) {
                    int n = digit;
                    nextChar();
                    while (Character.isDigit(this.peek)) {
                        sb.append(this.peek);
                        n = 10 * n + Character.digit(this.peek, 10);
                        nextChar();
                    }
                    while (n-- > 0) {
                        if (negExp) {
                            dval = dval / 10;
                        } else {
                            dval = 10 * dval;
                        }
                    }
                    hasDot = true;
                } else if (hasDot) {
                    dval = dval + digit / d;
                    d = d * 10;
                    nextChar();
                } else {
                    if (!isOverflow && (lval > OVERFLOW_FLAG || (lval == OVERFLOW_FLAG && digit > OVERFLOW_SINGLE))) {
                        isOverflow = true;
                    }
                    lval = 10 * lval + digit;
                    dval = 10 * dval + digit;
                    nextChar();
                }
            }
        } while (Character.isDigit(this.peek) || this.peek == '.' || this.peek == 'E' || this.peek == 'e' || this.peek == 'M' || this.peek == 'N');
        Number value;
        if (isBigDecimal) {
            value = new BigDecimal(getBigNumberLexeme(sb), this.mathContext);
        } else if (isBigInt) {
            value = new BigInteger(getBigNumberLexeme(sb));
        } else if (hasDot) {
            if (this.parseFloatIntoDecimal && sb.length() > 1) {
                value = new BigDecimal(sb.toString(), this.mathContext);
            } else if (sb.length() == 1) {
                // only have a dot character.
                return new CharToken('.', this.lineNo, startIndex);
            } else {
                value = dval;
            }
        } else {
            if (this.parseIntegralNumberIntoDecimal) {
                // we make integral number as a BigDecimal.
                value = new BigDecimal(sb.toString(), this.mathContext);
            } else {
                // The long value is overflow, we should prompt it to be a BigInteger.
                if (isOverflow) {
                    value = new BigInteger(sb.toString());
                } else {
                    value = lval;
                }
            }
        }
        String lexeme = sb.toString();
        if (isBigDecimal || isBigInt) {
            lexeme = lexeme.substring(0, lexeme.length() - 1);
        }
        return new NumberToken(value, lexeme, this.lineNo, startIndex);
    }
    // It is a variable
    if (this.peek == '#') {
        int startIndex = this.iterator.getIndex();
        // skip '#'
        nextChar();
        boolean hasBackquote = false;
        if (this.peek == '#') {
            // ## comments
            while (this.peek != CharacterIterator.DONE && this.peek != '\n') {
                nextChar();
            }
            return this.scan(analyse);
        } else if (this.peek == '`') {
            hasBackquote = true;
            nextChar();
        }
        StringBuilder sb = new StringBuilder();
        if (hasBackquote) {
            while (this.peek != '`') {
                if (this.peek == CharacterIterator.DONE) {
                    throw new CompileExpressionErrorException("EOF while reading string at index: " + this.iterator.getIndex());
                }
                sb.append(this.peek);
                nextChar();
            }
            // skip '`'
            nextChar();
        } else {
            while (Character.isJavaIdentifierPart(this.peek) || this.peek == '.' || this.peek == '[' || this.peek == ']') {
                sb.append(this.peek);
                nextChar();
            }
        }
        String lexeme = sb.toString();
        if (lexeme.isEmpty()) {
            throw new ExpressionSyntaxErrorException("Blank variable name after '#'");
        }
        Variable variable = new Variable(lexeme, this.lineNo, startIndex);
        variable.setQuote(true);
        return this.symbolTable.reserve(variable);
    }
    if (Character.isJavaIdentifierStart(this.peek)) {
        int startIndex = this.iterator.getIndex();
        StringBuilder sb = new StringBuilder();
        do {
            sb.append(this.peek);
            nextChar();
        } while (Character.isJavaIdentifierPart(this.peek) || this.peek == '.');
        String lexeme = sb.toString();
        Variable variable = new Variable(lexeme, this.lineNo, startIndex);
        return this.symbolTable.reserve(variable);
    }
    if (isBinaryOP(this.peek)) {
        CharToken opToken = new CharToken(this.peek, this.lineNo, this.iterator.getIndex());
        nextChar();
        return opToken;
    }
    // String
    if (this.peek == '"' || this.peek == '\'') {
        char left = this.peek;
        int startIndex = this.iterator.getIndex();
        StringBuilder sb = new StringBuilder();
        boolean hasInterpolation = false;
        // char prev = this.peek;
        while ((this.peek = this.iterator.next()) != left) {
            // It's not accurate,but acceptable.
            if (this.peek == '#' && !hasInterpolation) {
                hasInterpolation = true;
            }
            if (this.peek == '\\') {
                // escape
                nextChar();
                if (this.peek == CharacterIterator.DONE) {
                    throw new CompileExpressionErrorException("EOF while reading string at index: " + this.iterator.getIndex());
                }
                if (this.peek == left) {
                    sb.append(this.peek);
                    continue;
                }
                switch(this.peek) {
                    case 't':
                        this.peek = '\t';
                        break;
                    case 'r':
                        this.peek = '\r';
                        break;
                    case 'n':
                        this.peek = '\n';
                        break;
                    case '\\':
                        break;
                    case 'b':
                        this.peek = '\b';
                        break;
                    case 'f':
                        this.peek = '\f';
                        break;
                    case '#':
                        hasInterpolation = hasInterpolation || true;
                        if (this.instance.isFeatureEnabled(Feature.StringInterpolation)) {
                            sb.append('\\');
                            this.peek = '#';
                            break;
                        }
                    default:
                        {
                            throw new CompileExpressionErrorException("Unsupported escape character: \\" + this.peek);
                        }
                }
            }
            if (this.peek == CharacterIterator.DONE) {
                throw new CompileExpressionErrorException("EOF while reading string at index: " + this.iterator.getIndex());
            }
            sb.append(this.peek);
        }
        nextChar();
        return new StringToken(sb.toString(), this.lineNo, startIndex).withMeta(Constants.INTER_META, hasInterpolation);
    }
    Token<Character> token = new CharToken(this.peek, this.lineNo, this.iterator.getIndex());
    nextChar();
    return token;
}
Also used : Variable(com.googlecode.aviator.lexer.token.Variable) BigDecimal(java.math.BigDecimal) StringToken(com.googlecode.aviator.lexer.token.StringToken) CompileExpressionErrorException(com.googlecode.aviator.exception.CompileExpressionErrorException) NumberToken(com.googlecode.aviator.lexer.token.NumberToken) CharToken(com.googlecode.aviator.lexer.token.CharToken) BigInteger(java.math.BigInteger) ExpressionSyntaxErrorException(com.googlecode.aviator.exception.ExpressionSyntaxErrorException)

Example 4 with NumberToken

use of com.googlecode.aviator.lexer.token.NumberToken in project aviatorscript by killme2008.

the class LoadIR method evalWithoutDispatch.

public void evalWithoutDispatch(final InterpretContext context) {
    if (this.token == null) {
        return;
    }
    if (this.inConstantPool) {
        final AviatorObject constant = context.loadConstant(this.token);
        assert (constant != null);
        context.push(constant);
        return;
    }
    // load token to stack
    switch(this.token.getType()) {
        case Number:
            // load numbers
            NumberToken numberToken = (NumberToken) this.token;
            Number number = numberToken.getNumber();
            if (TypeUtils.isBigInt(number)) {
                context.push(AviatorBigInt.valueOf(this.token.getLexeme()));
            } else if (TypeUtils.isDecimal(number)) {
                context.push(AviatorDecimal.valueOf(context.getEnv(), this.token.getLexeme()));
            } else if (TypeUtils.isDouble(number)) {
                context.push(AviatorDouble.valueOf(number.doubleValue()));
            } else {
                context.push(AviatorLong.valueOf(number.longValue()));
            }
            break;
        case String:
            context.push(new AviatorString((String) this.token.getValue(null), true, this.token.getMeta(Constants.INTER_META, true), this.token.getLineNo()));
            break;
        case Pattern:
            context.push(new AviatorPattern((String) this.token.getValue(null)));
            break;
        case Variable:
            if (this.token == Variable.TRUE) {
                context.push(AviatorBoolean.TRUE);
            } else if (this.token == Variable.FALSE) {
                context.push(AviatorBoolean.FALSE);
            } else if (this.token == Variable.NIL) {
                context.push(AviatorNil.NIL);
            } else {
                AviatorJavaType var;
                if (this.meta != null) {
                    var = context.loadVar(this.meta);
                    assert (var != null);
                } else {
                    var = new AviatorJavaType(this.token.getLexeme());
                }
                context.push(var);
            }
            break;
        default:
            throw new ExpressionRuntimeException("Can't load " + this.token);
    }
}
Also used : AviatorObject(com.googlecode.aviator.runtime.type.AviatorObject) AviatorPattern(com.googlecode.aviator.runtime.type.AviatorPattern) ExpressionRuntimeException(com.googlecode.aviator.exception.ExpressionRuntimeException) AviatorString(com.googlecode.aviator.runtime.type.AviatorString) NumberToken(com.googlecode.aviator.lexer.token.NumberToken) AviatorJavaType(com.googlecode.aviator.runtime.type.AviatorJavaType) AviatorString(com.googlecode.aviator.runtime.type.AviatorString)

Example 5 with NumberToken

use of com.googlecode.aviator.lexer.token.NumberToken in project aviatorscript by killme2008.

the class ASMCodeGeneratorUnitTest method testOnBitNot2.

@Test
public void testOnBitNot2() throws Exception {
    this.codeGenerator.onConstant(new NumberToken(3L, "3"));
    this.codeGenerator.onBitNot(null);
    Object result = eval(new HashMap<String, Object>());
    assertEquals(-4L, result);
}
Also used : NumberToken(com.googlecode.aviator.lexer.token.NumberToken) Test(org.junit.Test)

Aggregations

NumberToken (com.googlecode.aviator.lexer.token.NumberToken)15 Test (org.junit.Test)7 Variable (com.googlecode.aviator.lexer.token.Variable)6 StringToken (com.googlecode.aviator.lexer.token.StringToken)3 AviatorObject (com.googlecode.aviator.runtime.type.AviatorObject)3 AviatorPattern (com.googlecode.aviator.runtime.type.AviatorPattern)3 AviatorString (com.googlecode.aviator.runtime.type.AviatorString)3 HashMap (java.util.HashMap)3 Expression (com.googlecode.aviator.Expression)2 CompileExpressionErrorException (com.googlecode.aviator.exception.CompileExpressionErrorException)2 AviatorNumber (com.googlecode.aviator.runtime.type.AviatorNumber)2 ExpressionRuntimeException (com.googlecode.aviator.exception.ExpressionRuntimeException)1 ExpressionSyntaxErrorException (com.googlecode.aviator.exception.ExpressionSyntaxErrorException)1 CharToken (com.googlecode.aviator.lexer.token.CharToken)1 PatternToken (com.googlecode.aviator.lexer.token.PatternToken)1 AviatorBoolean (com.googlecode.aviator.runtime.type.AviatorBoolean)1 AviatorJavaType (com.googlecode.aviator.runtime.type.AviatorJavaType)1 AviatorRuntimeJavaType (com.googlecode.aviator.runtime.type.AviatorRuntimeJavaType)1 BigDecimal (java.math.BigDecimal)1 BigInteger (java.math.BigInteger)1