Added limited floating point support

This commit is contained in:
Anthony J. Thibault 2015-11-01 15:51:57 -08:00
parent 340096d457
commit 7f0fc4f6eb
3 changed files with 41 additions and 4 deletions

View file

@ -151,6 +151,21 @@ AnimExpression::Token AnimExpression::consumeIdentifier(const QString& str, QStr
return Token(QStringRef(const_cast<const QString*>(&str), pos, len));
}
// TODO: not very efficient or accruate, but it's close enough for now.
static float computeFractionalPart(int fractionalPart)
{
float frac = (float)fractionalPart;
while (fractionalPart) {
fractionalPart /= 10;
frac /= 10.0f;
}
return frac;
}
static float computeFloat(int whole, int fraction) {
return (float)whole + computeFractionalPart(fraction);
}
AnimExpression::Token AnimExpression::consumeNumber(const QString& str, QString::const_iterator& iter) const {
assert(iter != str.end());
assert(iter->isDigit());
@ -158,10 +173,31 @@ AnimExpression::Token AnimExpression::consumeNumber(const QString& str, QString:
while (iter->isDigit() && iter != str.end()) {
++iter;
}
// parse whole integer part
int pos = (int)(begin - str.begin());
int len = (int)(iter - begin);
QString sub = QStringRef(const_cast<const QString*>(&str), pos, len).toString();
return Token(sub.toInt());
int whole = sub.toInt();
// parse optional fractional part
if (iter->unicode() == '.') {
iter++;
auto begin = iter;
while (iter->isDigit() && iter != str.end()) {
++iter;
}
int pos = (int)(begin - str.begin());
int len = (int)(iter - begin);
QString sub = QStringRef(const_cast<const QString*>(&str), pos, len).toString();
int fraction = sub.toInt();
return Token(computeFloat(whole, fraction));
} else {
return Token(whole);
}
}
AnimExpression::Token AnimExpression::consumeAnd(const QString& str, QString::const_iterator& iter) const {

View file

@ -50,6 +50,7 @@ protected:
Token(Type type) : type(type) {}
Token(const QStringRef& strRef) : type(Type::Identifier), strVal(strRef.toString()) {}
Token(int val) : type(Type::LiteralInt), intVal(val) {}
Token(float val) : type(Type::LiteralFloat), floatVal(val) {}
Type type = End;
QString strVal;
int intVal;

View file

@ -325,7 +325,7 @@ void AnimTests::testAccumulateTimeWithParameters(float startFrame, float endFram
triggers.clear();
void AnimTests::testTokenizer() {
QString str = "(10 + x) >= 20 && (y != !z)";
QString str = "(10 + x) >= 20.1 && (y != !z)";
AnimExpression e("");
auto iter = str.cbegin();
AnimExpression::Token token = e.consumeToken(str, iter);
@ -343,8 +343,8 @@ void AnimTests::testTokenizer() {
token = e.consumeToken(str, iter);
QVERIFY(token.type == AnimExpression::Token::GreaterThanEqual);
token = e.consumeToken(str, iter);
QVERIFY(token.type == AnimExpression::Token::LiteralInt);
QVERIFY(token.intVal == 20);
QVERIFY(token.type == AnimExpression::Token::LiteralFloat);
QVERIFY(fabsf(token.floatVal - 20.1f) < 0.0001f);
token = e.consumeToken(str, iter);
QVERIFY(token.type == AnimExpression::Token::And);
token = e.consumeToken(str, iter);