mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
AnimExpression: support for unary not.
This commit is contained in:
parent
22756d168b
commit
ab85e2967a
3 changed files with 53 additions and 57 deletions
|
@ -208,9 +208,11 @@ AnimExpression::Token AnimExpression::consumeNot(const QString& str, QString::co
|
|||
Expr → Term Expr'
|
||||
Expr' → '||' Term Expr'
|
||||
| ε
|
||||
Term → Factor Term'
|
||||
Term' → '&&' Term'
|
||||
Term → Unary Term'
|
||||
Term' → '&&' Unary Term'
|
||||
| ε
|
||||
Unary → '!' Unary
|
||||
| Factor
|
||||
Factor → INT
|
||||
| BOOL
|
||||
| FLOAT
|
||||
|
@ -249,9 +251,9 @@ bool AnimExpression::parseExprPrime(const QString& str, QString::const_iterator&
|
|||
}
|
||||
}
|
||||
|
||||
// Term → Factor Term'
|
||||
// Term → Unary Term'
|
||||
bool AnimExpression::parseTerm(const QString& str, QString::const_iterator& iter) {
|
||||
if (!parseFactor(str, iter)) {
|
||||
if (!parseUnary(str, iter)) {
|
||||
return false;
|
||||
}
|
||||
if (!parseTermPrime(str, iter)) {
|
||||
|
@ -260,11 +262,11 @@ bool AnimExpression::parseTerm(const QString& str, QString::const_iterator& iter
|
|||
return true;
|
||||
}
|
||||
|
||||
// Term' → '&&' Term' | ε
|
||||
// Term' → '&&' Unary Term' | ε
|
||||
bool AnimExpression::parseTermPrime(const QString& str, QString::const_iterator& iter) {
|
||||
auto token = consumeToken(str, iter);
|
||||
if (token.type == Token::And) {
|
||||
if (!parseTerm(str, iter)) {
|
||||
if (!parseUnary(str, iter)) {
|
||||
unconsumeToken(token);
|
||||
return false;
|
||||
}
|
||||
|
@ -280,6 +282,24 @@ bool AnimExpression::parseTermPrime(const QString& str, QString::const_iterator&
|
|||
}
|
||||
}
|
||||
|
||||
// Unary → '!' Unary | Factor
|
||||
bool AnimExpression::parseUnary(const QString& str, QString::const_iterator& iter) {
|
||||
|
||||
auto token = consumeToken(str, iter);
|
||||
if (token.type == Token::Not) {
|
||||
if (!parseUnary(str, iter)) {
|
||||
unconsumeToken(token);
|
||||
return false;
|
||||
}
|
||||
_opCodes.push_back(OpCode {OpCode::Not});
|
||||
return true;
|
||||
}
|
||||
unconsumeToken(token);
|
||||
|
||||
return parseFactor(str, iter);
|
||||
}
|
||||
|
||||
|
||||
// Factor → INT | BOOL | FLOAT | IDENTIFIER | '(' Expr ')'
|
||||
bool AnimExpression::parseFactor(const QString& str, QString::const_iterator& iter) {
|
||||
auto token = consumeToken(str, iter);
|
||||
|
|
|
@ -119,6 +119,7 @@ protected:
|
|||
bool parseExprPrime(const QString& str, QString::const_iterator& iter);
|
||||
bool parseTerm(const QString& str, QString::const_iterator& iter);
|
||||
bool parseTermPrime(const QString& str, QString::const_iterator& iter);
|
||||
bool parseUnary(const QString& str, QString::const_iterator& iter);
|
||||
bool parseFactor(const QString& str, QString::const_iterator& iter);
|
||||
|
||||
OpCode evaluate(const AnimVariantMap& map) const;
|
||||
|
|
|
@ -522,43 +522,19 @@ void AnimTests::testExpressionParser() {
|
|||
QVERIFY(e._opCodes[4].type == AnimExpression::OpCode::And);
|
||||
}
|
||||
|
||||
/*
|
||||
e = AnimExpression("2 + 3");
|
||||
QVERIFY(e._opCodes.size() == 3);
|
||||
if (e._opCodes.size() == 3) {
|
||||
QVERIFY(e._opCodes[0].type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(e._opCodes[0].intVal == 2);
|
||||
QVERIFY(e._opCodes[1].type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(e._opCodes[1].intVal == 3);
|
||||
QVERIFY(e._opCodes[2].type == AnimExpression::OpCode::Add);
|
||||
e = AnimExpression("!(true || false) && true");
|
||||
QVERIFY(e._opCodes.size() == 6);
|
||||
if (e._opCodes.size() == 6) {
|
||||
QVERIFY(e._opCodes[0].type == AnimExpression::OpCode::Bool);
|
||||
QVERIFY(e._opCodes[0].intVal == (int)true);
|
||||
QVERIFY(e._opCodes[1].type == AnimExpression::OpCode::Bool);
|
||||
QVERIFY(e._opCodes[1].intVal == (int)false);
|
||||
QVERIFY(e._opCodes[2].type == AnimExpression::OpCode::Or);
|
||||
QVERIFY(e._opCodes[3].type == AnimExpression::OpCode::Not);
|
||||
QVERIFY(e._opCodes[4].type == AnimExpression::OpCode::Bool);
|
||||
QVERIFY(e._opCodes[4].intVal == (int)true);
|
||||
QVERIFY(e._opCodes[5].type == AnimExpression::OpCode::And);
|
||||
}
|
||||
|
||||
e = AnimExpression("2 + 3 * 10");
|
||||
QVERIFY(e._opCodes.size() == 5);
|
||||
if (e._opCodes.size() == 5) {
|
||||
QVERIFY(e._opCodes[0].type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(e._opCodes[0].intVal == 2);
|
||||
QVERIFY(e._opCodes[1].type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(e._opCodes[1].intVal == 3);
|
||||
QVERIFY(e._opCodes[2].type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(e._opCodes[2].intVal == 10);
|
||||
QVERIFY(e._opCodes[3].type == AnimExpression::OpCode::Multiply);
|
||||
QVERIFY(e._opCodes[4].type == AnimExpression::OpCode::Add);
|
||||
}
|
||||
|
||||
e = AnimExpression("(2 + 3) * 10");
|
||||
QVERIFY(e._opCodes.size() == 5);
|
||||
if (e._opCodes.size() == 5) {
|
||||
QVERIFY(e._opCodes[0].type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(e._opCodes[0].intVal == 2);
|
||||
QVERIFY(e._opCodes[1].type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(e._opCodes[1].intVal == 3);
|
||||
QVERIFY(e._opCodes[2].type == AnimExpression::OpCode::Add);
|
||||
QVERIFY(e._opCodes[3].type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(e._opCodes[3].intVal == 10);
|
||||
QVERIFY(e._opCodes[4].type == AnimExpression::OpCode::Multiply);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#define TEST_BOOL_EXPR(EXPR) \
|
||||
|
@ -630,23 +606,22 @@ void AnimTests::testExpressionEvaluator() {
|
|||
TEST_BOOL_EXPR(f || false);
|
||||
TEST_BOOL_EXPR(f || true);
|
||||
|
||||
/*
|
||||
result = AnimExpression("(2 + 3) * (5 + 3)").evaluate(vars);
|
||||
QVERIFY(result.type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(result.intVal == (2 + 3) * (5 + 3));
|
||||
TEST_BOOL_EXPR(!true);
|
||||
TEST_BOOL_EXPR(!false);
|
||||
TEST_BOOL_EXPR(!true || true);
|
||||
|
||||
result = AnimExpression("(ten + twenty) * 5").evaluate(vars);
|
||||
QVERIFY(result.type == AnimExpression::OpCode::Int);
|
||||
QVERIFY(result.intVal == (10 + 20) * 5);
|
||||
TEST_BOOL_EXPR(!true && !false || !true);
|
||||
TEST_BOOL_EXPR(!true && !false || true);
|
||||
TEST_BOOL_EXPR(!true && false || !true);
|
||||
TEST_BOOL_EXPR(!true && false || true);
|
||||
TEST_BOOL_EXPR(true && !false || !true);
|
||||
TEST_BOOL_EXPR(true && !false || true);
|
||||
TEST_BOOL_EXPR(true && false || !true);
|
||||
TEST_BOOL_EXPR(true && false || true);
|
||||
|
||||
result = AnimExpression("(ten + twenty) * 5.0").evaluate(vars);
|
||||
QVERIFY(result.type == AnimExpression::OpCode::Float);
|
||||
QVERIFY(result.floatVal == (10 + 20) * 5.0f);
|
||||
|
||||
result = AnimExpression("five * forty").evaluate(vars);
|
||||
QVERIFY(result.type == AnimExpression::OpCode::Float);
|
||||
QVERIFY(result.floatVal == 5.0f * 40.0f);
|
||||
*/
|
||||
TEST_BOOL_EXPR(!(true && f) || !t);
|
||||
TEST_BOOL_EXPR(!!!(t) && (!!f || true));
|
||||
TEST_BOOL_EXPR(!(true && f) && true);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue