From 9bb447d14b210fc4b8f64ea0e377eb0c4306d059 Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Sat, 5 Dec 2015 10:03:28 +0000 Subject: [PATCH] DataFilter Compound Statements { ... } .. You can now use compound statements in data filters .. A compound statement is: { s1; } evaluates to s1 { s1; s2; s3; .. sn; } evaluates to sn .. It is possible to use the recently added user defined symbols to build up processing logic: { temp <- TSS; temp > 100 } is functionally equivalent to TSS > 100 .. At present there are no control statements outside of the ? and ?: operators but these will no doubt be added in due course. --- src/DataFilter.cpp | 38 +++++++++++++++++++++++++++++++++++++- src/DataFilter.h | 3 ++- src/DataFilter.y | 15 ++++++++++++++- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/DataFilter.cpp b/src/DataFilter.cpp index aa14fea7b..8fffa3726 100644 --- a/src/DataFilter.cpp +++ b/src/DataFilter.cpp @@ -718,6 +718,12 @@ void Leaf::print(Leaf *leaf, int level) return; } switch(leaf->type) { + case Leaf::Compound: + qDebug()<<"{"; + foreach(Leaf *p, *(leaf->lvalue.b)) print(p, level+1); + qDebug()<<"}"; + break; + case Leaf::Float : qDebug()<<"float"<lvalue.f<dynamic; break; case Leaf::Integer : qDebug()<<"integer"<lvalue.i<dynamic; break; case Leaf::String : qDebug()<<"string"<<*leaf->lvalue.s<dynamic; break; @@ -782,6 +788,7 @@ static bool isCoggan(QString symbol) bool Leaf::isNumber(DataFilter *df, Leaf *leaf) { switch(leaf->type) { + case Leaf::Compound : return true; // last statement is value of block case Leaf::Float : return true; case Leaf::Integer : return true; case Leaf::String : @@ -1171,6 +1178,14 @@ void Leaf::validateFilter(DataFilter *df, Leaf *leaf) } break; + case Leaf::Compound : + { + // a list of statements, the last of which is what we + // evaluate to for the purposes of filtering etc + foreach(Leaf *p, *(leaf->lvalue.b)) validateFilter(df, p); + } + break; + default: break; } @@ -2119,7 +2134,6 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte // // UNARY EXPRESSION // - case Leaf::UnaryOperation : { // get result @@ -2280,6 +2294,9 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte } break; + // + // CONDITIONAL TERNARY + // case Leaf::Conditional : { Result cond = eval(context, df, leaf->cond.l, x, m, p); @@ -2288,6 +2305,9 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte } break; + // + // VECTORS + // case Leaf::Vector : { // places results in vector, and number is sum of all @@ -2347,6 +2367,22 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte // always return as sum number (for now) return returning; } + break; + + // + // COMPOUND EXPRESSION + // + case Leaf::Compound : + { + Result returning(0); + + // evaluate each statement + foreach(Leaf *statement, *(leaf->lvalue.b)) returning = eval(context, df, statement, x, m, p); + + // compound statements evaluate to the value of the last statement + return returning; + } + break; default: // we don't need to evaluate any lower - they are leaf nodes handled above break; diff --git a/src/DataFilter.h b/src/DataFilter.h index 2bf4b1aa3..6af681183 100644 --- a/src/DataFilter.h +++ b/src/DataFilter.h @@ -74,7 +74,7 @@ class Leaf { enum { none, Float, Integer, String, Symbol, Logical, Operation, BinaryOperation, UnaryOperation, Function, Conditional, Vector, - Parameters } type; + Parameters, Compound } type; union value { float f; @@ -82,6 +82,7 @@ class Leaf { QString *s; QString *n; Leaf *l; + QList *b; } lvalue, rvalue, cond; int op; diff --git a/src/DataFilter.y b/src/DataFilter.y index 412a52407..e351e5e4c 100644 --- a/src/DataFilter.y +++ b/src/DataFilter.y @@ -64,13 +64,15 @@ extern Leaf *DataFilterroot; // root node for parsed statement %union { Leaf *leaf; + QList *comp; int op; char function[32]; } %locations -%type symbol literal lexpr cexpr expr parms; +%type symbol literal lexpr cexpr expr parms block; +%type statements %right '?' ':' %right '[' ']' @@ -84,8 +86,19 @@ extern Leaf *DataFilterroot; // root node for parsed statement %% filter: lexpr { DataFilterroot = $1; } + | block { DataFilterroot = $1; } ; +block: '{' statements '}' { $$ = new Leaf(@1.first_column, @3.last_column); + $$->type = Leaf::Compound; + $$->lvalue.b = $2; + } + ; + +statements: lexpr ';' { $$ = new QList(); $$->append($1); } + | statements lexpr ';' { $$->append($2); } + ; + parms: lexpr { $$ = new Leaf(@1.first_column, @1.last_column); $$->type = Leaf::Parameters; $$->fparms << $1;