DataFilter if/else support

.. Added if else logic but could not avoid
   needing the statement to be terminated with a
   semi-colon (;)

.. so examples are:

   if (TSS>100) TSS; else 0;

   if (TSS>100) {
      temp <- TSS;
      temp;
   } else {
      temp <- BikeScore;
      temp;
   }

.. Doesn't add much beyond the existing conditional statement
   using '?' and ':' but is a lot more readable (!)
This commit is contained in:
Mark Liversedge
2015-12-05 20:51:45 +00:00
parent 282445abc9
commit 4cb26cf27c
3 changed files with 47 additions and 12 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -57,6 +57,7 @@ extern Leaf *DataFilterroot; // root node for parsed statement
%token <function> BEST TIZ CONFIG CONST_ DATERANGE
// comparative operators
%token <op> IF_ ELSE_
%token <op> EQ NEQ LT LTE GT GTE ELVIS ASSIGN
%token <op> ADD SUBTRACT DIVIDE MULTIPLY POW
%token <op> MATCHES ENDSWITH BEGINSWITH CONTAINS
@@ -71,7 +72,7 @@ extern Leaf *DataFilterroot; // root node for parsed statement
%locations
%type <leaf> symbol literal lexpr cexpr expr parms block statement;
%type <leaf> symbol literal lexpr cexpr expr parms block statement expression;
%type <comp> 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<Leaf*>(); $$->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;