Search in sources :

Example 1 with ExpressionSegment

use of com.googlecode.aviator.runtime.type.string.ExpressionSegment in project aviatorscript by killme2008.

the class AviatorEvaluatorInstance method compileStringSegments.

/**
 * Compile a string to string segments, if string doesn't have a interpolation,returns an empty
 * list.
 *
 * @param lexeme
 * @param sourceFile
 * @param lineNo;
 * @return
 */
public StringSegments compileStringSegments(final String lexeme, final String sourceFile, final int lineNo) {
    List<StringSegment> segs = new ArrayList<StringSegment>();
    boolean hasInterpolationOrEscaped = false;
    StringCharacterIterator it = new StringCharacterIterator(lexeme);
    char ch = it.current(), prev = StringCharacterIterator.DONE;
    int lastInterPos = 0;
    int i = 1;
    for (; ; ) {
        if (ch == '#') {
            if (prev == '\\') {
                // # is escaped, skip the backslash.
                final String segStr = lexeme.substring(lastInterPos, i - 2);
                segs.add(new LiteralSegment(segStr));
                lastInterPos = i - 1;
                hasInterpolationOrEscaped = true;
            } else {
                // # is not escaped.
                prev = ch;
                ch = it.next();
                i++;
                if (ch == '{') {
                    // Find a interpolation position.
                    if (i - 2 > lastInterPos) {
                        final String segStr = lexeme.substring(lastInterPos, i - 2);
                        segs.add(new LiteralSegment(segStr));
                    }
                    try {
                        ExpressionLexer lexer = new ExpressionLexer(this, lexeme.substring(i));
                        lexer.setLineNo(lineNo);
                        ExpressionParser parser = new ExpressionParser(this, lexer, newCodeGenerator(sourceFile, false));
                        Expression exp = parser.parse(false);
                        final Token<?> lookhead = parser.getLookhead();
                        if (lookhead == null || (lookhead.getType() != TokenType.Char || ((CharToken) lookhead).getCh() != '}')) {
                            parser.reportSyntaxError("expect '}' to complete string interpolation");
                        }
                        int expStrLen = lookhead.getStartIndex() + 1;
                        while (expStrLen-- > 0) {
                            prev = ch;
                            ch = it.next();
                            i++;
                        }
                        Token<?> previousToken = null;
                        if (parser.getParsedTokens() == 2 && (previousToken = parser.getPrevToken()) != null && previousToken.getType() == TokenType.Variable) {
                            // special case for inline variable.
                            if (previousToken == Variable.TRUE) {
                                segs.add(new LiteralSegment("true"));
                            } else if (previousToken == Variable.FALSE) {
                                segs.add(new LiteralSegment("false"));
                            } else if (previousToken == Variable.NIL) {
                                segs.add(new LiteralSegment("null"));
                            } else {
                                segs.add(new VarSegment(parser.getSymbolTable().reserve(previousToken.getLexeme()).getLexeme()));
                            }
                        } else {
                            segs.add(new ExpressionSegment(exp));
                        }
                        hasInterpolationOrEscaped = true;
                        lastInterPos = i;
                    } catch (Throwable t) {
                        throw new CompileExpressionErrorException("Fail to compile string interpolation: " + lexeme, t);
                    }
                // End of interpolation
                }
            // End of # is not escaped.
            }
        }
        if (ch == StringCharacterIterator.DONE) {
            if (i - 1 > lastInterPos) {
                final String segStr = lexeme.substring(lastInterPos, i - 1);
                segs.add(new LiteralSegment(segStr));
            }
            break;
        }
        prev = ch;
        ch = it.next();
        i++;
    }
    if (hasInterpolationOrEscaped) {
        return new StringSegments(segs, lexeme.length() * 2 / 3);
    } else {
        return new StringSegments(Collections.<StringSegment>emptyList(), 0);
    }
}
Also used : ArrayList(java.util.ArrayList) LiteralSegment(com.googlecode.aviator.runtime.type.string.LiteralSegment) ExpressionSegment(com.googlecode.aviator.runtime.type.string.ExpressionSegment) StringSegment(com.googlecode.aviator.runtime.type.string.StringSegment) VarSegment(com.googlecode.aviator.runtime.type.string.VarSegment) StringCharacterIterator(java.text.StringCharacterIterator) ExpressionLexer(com.googlecode.aviator.lexer.ExpressionLexer) CompileExpressionErrorException(com.googlecode.aviator.exception.CompileExpressionErrorException) CharToken(com.googlecode.aviator.lexer.token.CharToken) ExpressionParser(com.googlecode.aviator.parser.ExpressionParser)

Aggregations

CompileExpressionErrorException (com.googlecode.aviator.exception.CompileExpressionErrorException)1 ExpressionLexer (com.googlecode.aviator.lexer.ExpressionLexer)1 CharToken (com.googlecode.aviator.lexer.token.CharToken)1 ExpressionParser (com.googlecode.aviator.parser.ExpressionParser)1 ExpressionSegment (com.googlecode.aviator.runtime.type.string.ExpressionSegment)1 LiteralSegment (com.googlecode.aviator.runtime.type.string.LiteralSegment)1 StringSegment (com.googlecode.aviator.runtime.type.string.StringSegment)1 VarSegment (com.googlecode.aviator.runtime.type.string.VarSegment)1 StringCharacterIterator (java.text.StringCharacterIterator)1 ArrayList (java.util.ArrayList)1