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()){