Exemple #1
0
QVector<Type> RppLexer::lex(const TokenContainer &tokenContainer)
{
    QVector<Type> tokenTypes;
    const int numTokens = tokenContainer.count();
    tokenTypes.reserve(numTokens);
    QByteArray text = tokenContainer.fullText();
    m_buffer = text.constData();
    for(int t=0; t<numTokens; ++t) {
        TokenEngine::Token token = tokenContainer.token(t);
        tokenTypes.append(indentify(token.start, token.length));
    }
    return tokenTypes;
}
/*
    Recursively evaluates an Expression
*/
int RppTreeEvaluator::evaluateExpression(Expression *expression)
{
    if (IntLiteral *e = expression->toIntLiteral()) {
        return e->value();
    } else if (StringLiteral *e = expression->toStringLiteral()) {
        return e->value().size();
    } else if (MacroReference *e = expression->toMacroReference()) {
       switch(e->type()) {
           case MacroReference::DefinedRef: {
               return m_activeDefinitions->contains(e->name().fullText()) ? 1 : 0;
           } case MacroReference::ValueRef: {
               const QByteArray identifier = e->name().fullText();
               if (m_activeDefinitions->contains(identifier)) {
                   int token = e->name().containerIndex(0);
                   TokenContainer value = evaluateMacro(e->name().tokenContainer(token), token);
                   return QString(QLatin1String(value.fullText())).toInt(0, 0);
               } else {
                   return 0; // error
               }
           }
           default: Q_ASSERT(0);
        }
    } else if (MacroFunctionReference *e = expression->toMacroFunctionReference()) {
        Q_UNUSED(e);
        //TODO handle MacroFunctionReference
//        DefineDirective *def = e->findDefinition(e->name());
//        Q_ASSERT(def->toMacroFunctionDefinition());
//        qWarning("not implemented yet");
        return 0;
    } else if (UnaryExpression *e = expression->toUnaryExpression()) {
        int result = evaluateExpression(e->expression());
        switch (e->op()) {
            case '+': return + result;
            case '-': return - result;
            case '!': return ! result;
            case '~': return ~ result;
            default:  Q_ASSERT(0);
        }
    } else if (BinaryExpression *e = expression->toBinaryExpression()) {
        int v1 = evaluateExpression(e->leftExpression());
        int v2 = evaluateExpression(e->rightExpression());

        switch (e->op()) {
            case '/': { return v2 ? v1 / v2 : 0; } //avoid division by zero
            case '*':                  return v1 * v2;
            case '%': { return v2 ? v1 % v2 : 0; } //avoid modulus by zero
            case '+':                  return v1 + v2;
            case '-':                  return v1 - v2;
            case '<':                  return v1 < v2;
            case '>':                  return v1 > v2;
            case '&':                  return v1 & v2;
            case '^':                  return v1 ^ v2;
            case '|':                  return v1 | v2;
            case Expression::LtEqOp:   return v1 <= v2;
            case Expression::GtEqOp:   return v1 >= v2;
            case Expression::EqOp:     return v1 == v2;
            case Expression::NotEqOp:  return v1 != v2;
            case Expression::AndOp:    return v1 && v2;
            case Expression::OrOp:     return v1 || v2;
            case Expression::LShiftOp: return v1 << v2;
            case Expression::RShiftOp: return v1 >> v2;
            default:    Q_ASSERT(0);
        }

    } else if ( ConditionalExpression *e = expression->toConditionalExpression()){