Commit 2ed48c7a authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

expr: added operator ! (NOT).

parent e1fbeae8
......@@ -3,6 +3,10 @@
* Using CDI library version 1.9.2
* Version 1.9.2 release
2017-11-21 Uwe Schulzweida
* expr: added operator ! (NOT)
2017-11-17 Uwe Schulzweida
* rotuvb changed behavior in different versions [Bug #8084]
......
......@@ -726,6 +726,7 @@ nodeType *expr(int init, int oper, nodeType *p1, nodeType *p2)
case LEG: coper = "<=>"; break;
case AND: coper = "&&"; break;
case OR: coper = "||"; break;
default: cdoAbort("Internal error, expr operator >%c< not implemented!\n", oper);
}
}
......@@ -1143,6 +1144,81 @@ nodeType *ex_uminus(int init, nodeType *p1)
return p;
}
static
nodeType *ex_not_var(int init, nodeType *p1)
{
size_t ngp = p1->param.ngp;
size_t nlev = p1->param.nlev;
size_t nmiss = p1->param.nmiss;
double missval = p1->param.missval;
nodeType *p = (nodeType*) Calloc(1, sizeof(nodeType));
p->type = typeVar;
p->ltmpobj = true;
p->u.var.nm = strdup(tmpvnm);
param_meta_copy(&p->param, &p1->param);
p->param.name = p->u.var.nm;
if ( ! init )
{
p->param.data = (double*) Malloc(ngp*nlev*sizeof(double));
double *restrict pdata = p->param.data;
const double *restrict p1data = p1->param.data;
if ( nmiss > 0 )
{
for ( size_t i = 0; i < ngp*nlev; ++i )
pdata[i] = DBL_IS_EQUAL(p1data[i], missval) ? missval : !(p1data[i]);
}
else
{
for ( size_t i = 0; i < ngp*nlev; ++i )
pdata[i] = !(p1data[i]);
}
p->param.nmiss = nmiss;
}
if ( p1->ltmpobj ) node_delete(p1);
return p;
}
static
nodeType *ex_not_con(nodeType *p1)
{
nodeType *p = (nodeType*) Calloc(1, sizeof(nodeType));
p->type = typeCon;
p->ltmpobj = true;
p->u.con.value = !(p1->u.con.value);
return p;
}
static
nodeType *ex_not(int init, nodeType *p1)
{
nodeType *p = NULL;
if ( p1->type == typeVar )
{
if ( cdoVerbose ) cdoPrint("\t%s\tneg\t- (%s)", ExIn[init], p1->u.var.nm);
p = ex_not_var(init, p1);
}
else if ( p1->type == typeCon )
{
if ( cdoVerbose ) cdoPrint("\t%s\tneg\t- (%g)", ExIn[init], p1->u.con.value);
p = ex_not_con(p1);
}
else
cdoAbort("Internal problem!");
return p;
}
static
nodeType *ex_ifelse(int init, nodeType *p1, nodeType *p2, nodeType *p3)
{
......@@ -1651,6 +1727,12 @@ nodeType *expr_run(nodeType *p, parse_param_t *parse_arg)
{
rnode = ex_uminus(init, expr_run(p->u.opr.op[0], parse_arg));
break;
}
case NOT:
{
rnode = ex_not(init, expr_run(p->u.opr.op[0], parse_arg));
break;
}
case '?':
......
This diff is collapsed.
......@@ -95,6 +95,7 @@ M_E {
"!=" return NE;
"&&" return AND;
"||" return OR;
"!" return NOT;
"?" return QUESTION;
":" return COLON;
......
This diff is collapsed.
......@@ -61,7 +61,8 @@ extern int yydebug;
NE = 271,
GT = 272,
LT = 273,
UMINUS = 274
UMINUS = 274,
NOT = 275
};
#endif
/* Tokens. */
......@@ -82,6 +83,7 @@ extern int yydebug;
#define GT 272
#define LT 273
#define UMINUS 274
#define NOT 275
/* Value type. */
......
......@@ -49,7 +49,7 @@ void freeNode(nodeType *p);
%left LEG GE LE EQ NE GT LT
%left '+' '-'
%left '*' '/'
%precedence UMINUS
%precedence UMINUS NOT
%right '^'
%type <nPtr> stmt expr stmt_list ternary
......@@ -84,7 +84,8 @@ stmt_list:
expr:
CONSTANT { $$ = expr_con($1); }
| VARIABLE { $$ = expr_var($1); }
| '-' expr %prec UMINUS { $$ = expr_opr(UMINUS, 1, $2); }
| '-' expr %prec UMINUS { $$ = expr_opr(UMINUS, 1, $2); }
| NOT expr %prec NOT { $$ = expr_opr(NOT, 1, $2); }
| expr '+' expr { $$ = expr_opr('+', 2, $1, $3); }
| expr '-' expr { $$ = expr_opr('-', 2, $1, $3); }
| expr '*' expr { $$ = expr_opr('*', 2, $1, $3); }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment