diff --git a/src/DataFilter.cpp b/src/DataFilter.cpp index 2773886ff..ecae77900 100644 --- a/src/DataFilter.cpp +++ b/src/DataFilter.cpp @@ -207,7 +207,7 @@ Leaf::isDynamic(Leaf *leaf) { return leaf->isDynamic(leaf->cond.l) || leaf->isDynamic(leaf->lvalue.l) || - leaf->isDynamic(leaf->rvalue.l); + (leaf->rvalue.l && leaf->isDynamic(leaf->rvalue.l)); break; } case Leaf::Vector : @@ -610,7 +610,7 @@ void Leaf::color(Leaf *leaf, QTextDocument *document) { leaf->color(leaf->cond.l, document); leaf->color(leaf->lvalue.l, document); - leaf->color(leaf->rvalue.l, document); + if (leaf->rvalue.l) leaf->color(leaf->rvalue.l, document); return; } break; @@ -701,10 +701,16 @@ Leaf::toString() case Leaf::Conditional : qDebug()<<"cond"; { - return QString("%1?%2:%3") - .arg(cond.l->toString()) - .arg(lvalue.l->toString()) - .arg(rvalue.l->toString()); + if (rvalue.l) { + return QString("%1?%2:%3") + .arg(cond.l->toString()) + .arg(lvalue.l->toString()) + .arg(rvalue.l->toString()); + } else { + return QString("%1?%2") + .arg(cond.l->toString()) + .arg(lvalue.l->toString()); + } } break; case Leaf::Parameters : @@ -768,7 +774,7 @@ void Leaf::print(Leaf *leaf, int level) { leaf->print(leaf->cond.l, level+1); leaf->print(leaf->lvalue.l, level+1); - leaf->print(leaf->rvalue.l, level+1); + if (leaf->rvalue.l) leaf->print(leaf->rvalue.l, level+1); } break; case Leaf::Parameters : @@ -1173,7 +1179,7 @@ void Leaf::validateFilter(DataFilter *df, Leaf *leaf) // three expressions to validate validateFilter(df, leaf->cond.l); validateFilter(df, leaf->lvalue.l); - validateFilter(df, leaf->rvalue.l); + if (leaf->rvalue.l) validateFilter(df, leaf->rvalue.l); } break; @@ -2302,13 +2308,18 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte break; // - // CONDITIONAL TERNARY + // CONDITIONAL TERNARY / IF .. ELSE .. // case Leaf::Conditional : { Result cond = eval(context, df, leaf->cond.l, x, m, p); if (cond.isNumber && cond.number) return eval(context, df, leaf->lvalue.l, x, m, p); - else return eval(context, df, leaf->rvalue.l, x, m, p); + else { + + // conditional may not have an else clause! + if (leaf->rvalue.l) return eval(context, df, leaf->rvalue.l, x, m, p); + else return Result(0); + } } break; diff --git a/src/DataFilter.l b/src/DataFilter.l index 5ade3698d..b91f07eed 100644 --- a/src/DataFilter.l +++ b/src/DataFilter.l @@ -48,6 +48,9 @@ int DataFiltercolumn = 1; "?:" DataFilterlval.op = ELVIS; return ELVIS; "<-" DataFilterlval.op = ASSIGN; return ASSIGN; +[Ii][Ff] DataFilterlval.op = IF_; return IF_; +[Ee][Ll][Ss][Ee] DataFilterlval.op = ELSE_; return ELSE_; + [Mm][Aa][Tt][Cc][Hh][Ee][Ss] DataFilterlval.op = MATCHES; return MATCHES; [Bb][Ee][Gg][Ii][Nn][Ss][Ww][Ii][Tt][Hh] DataFilterlval.op = BEGINSWITH; return BEGINSWITH; [Ee][Nn][Dd][Ss][Ww][Ii][Tt][Hh] DataFilterlval.op = ENDSWITH; return ENDSWITH; diff --git a/src/DataFilter.y b/src/DataFilter.y index 2581c1307..73993dec4 100644 --- a/src/DataFilter.y +++ b/src/DataFilter.y @@ -57,6 +57,7 @@ extern Leaf *DataFilterroot; // root node for parsed statement %token BEST TIZ CONFIG CONST_ DATERANGE // comparative operators +%token IF_ ELSE_ %token EQ NEQ LT LTE GT GTE ELVIS ASSIGN %token ADD SUBTRACT DIVIDE MULTIPLY POW %token MATCHES ENDSWITH BEGINSWITH CONTAINS @@ -71,7 +72,7 @@ extern Leaf *DataFilterroot; // root node for parsed statement %locations -%type symbol literal lexpr cexpr expr parms block statement; +%type symbol literal lexpr cexpr expr parms block statement expression; %type statements %right '?' ':' @@ -85,10 +86,14 @@ extern Leaf *DataFilterroot; // root node for parsed statement %start filter; %% -filter: lexpr { DataFilterroot = $1; } +filter: statement { DataFilterroot = $1; } | block { DataFilterroot = $1; } ; +expression: statement ';' { $$ = $1; } + | block { $$ = $1; } + ; + block: '{' statements '}' { $$ = new Leaf(@1.first_column, @3.last_column); $$->type = Leaf::Compound; $$->lvalue.b = $2; @@ -100,6 +105,22 @@ statements: statement ';' { $$ = new QList(); $$->append($1 ; statement: lexpr { $$ = $1; } + + | IF_ '(' lexpr ')' expression { $$ = new Leaf(@1.first_column, @5.last_column); + $$->type = Leaf::Conditional; + $$->op = 0; + $$->lvalue.l = $5; + $$->rvalue.l = NULL; + $$->cond.l = $3; + } + | IF_ '(' lexpr ')' expression ELSE_ expression { $$ = new Leaf(@1.first_column, @5.last_column); + $$->type = Leaf::Conditional; + $$->op = 0; + $$->lvalue.l = $5; + $$->rvalue.l = $7; + $$->cond.l = $3; + } + | symbol ASSIGN lexpr { $$ = new Leaf(@1.first_column, @3.last_column); $$->type = Leaf::Operation;