@@ -198,6 +198,50 @@ parser_newlist (struct parser_node* nl, struct parser_node* nr)
198198 }
199199}
200200
201+ namespace {
202+ struct parser_node * parser_get_rightmost_operand (struct parser_node * node)
203+ {
204+ if (node && node->type == PARSER_F2) {
205+ auto ftype = ((struct parser_f2 *)node)->ftype ;
206+ if (ftype == PARSER_CMP_CHAIN) {
207+ return parser_get_rightmost_operand (node->r );
208+ } else if (ftype == PARSER_LT || ftype == PARSER_GT ||
209+ ftype == PARSER_LEQ || ftype == PARSER_GEQ ||
210+ ftype == PARSER_EQ || ftype == PARSER_NEQ) {
211+ return node->r ;
212+ }
213+ }
214+ return nullptr ;
215+ }
216+
217+ bool parser_is_comparison (struct parser_node * node)
218+ {
219+ if (node && node->type == PARSER_F2) {
220+ auto ftype = ((struct parser_f2 *)node)->ftype ;
221+ return (ftype == PARSER_LT || ftype == PARSER_GT ||
222+ ftype == PARSER_LEQ || ftype == PARSER_GEQ ||
223+ ftype == PARSER_EQ || ftype == PARSER_NEQ ||
224+ (ftype == PARSER_CMP_CHAIN && parser_is_comparison (node->r )));
225+ } else {
226+ return false ;
227+ }
228+ }
229+ }
230+
231+ struct parser_node * parser_newcmpchain (struct parser_node * nl, enum parser_f2_t cmp,
232+ struct parser_node * nr)
233+ {
234+ /* If left side is already a comparison, this extends the chain */
235+ if (amrex::parser_is_comparison (nl)) {
236+ return amrex::parser_newf2 (amrex::PARSER_CMP_CHAIN, nl,
237+ amrex::parser_newf2 (cmp,
238+ amrex::parser_get_rightmost_operand (nl),
239+ nr));
240+ } else {
241+ return amrex::parser_newf2 (cmp, nl, nr); // Initial comparison
242+ }
243+ }
244+
201245/* ******************************************************************/
202246
203247struct amrex_parser *
@@ -1324,6 +1368,9 @@ parser_ast_optimize (struct parser_node*& node, std::map<std::string,double>& lo
13241368 case PARSER_F2:
13251369 parser_ast_optimize (((struct parser_f2 *)node)->l ,local_consts);
13261370 parser_ast_optimize (((struct parser_f2 *)node)->r ,local_consts);
1371+ if (((struct parser_f2 *)node)->ftype == PARSER_CMP_CHAIN) {
1372+ ((struct parser_f2 *)node)->ftype = PARSER_AND;
1373+ }
13271374 if (((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
13281375 ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER)
13291376 {
@@ -1333,6 +1380,54 @@ parser_ast_optimize (struct parser_node*& node, std::map<std::string,double>& lo
13331380 ((struct parser_number *)(((struct parser_f2 *)node)->r ))->value );
13341381 parser_set_number (node, v);
13351382 }
1383+ else if (((struct parser_f2 *)node)->ftype == PARSER_AND &&
1384+ ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
1385+ parser_get_number (((struct parser_f2 *)node)->r ) == 0.0 )
1386+ { // ? and false => false
1387+ parser_set_number (node, 0.0 );
1388+ }
1389+ else if (((struct parser_f2 *)node)->ftype == PARSER_AND &&
1390+ ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
1391+ parser_get_number (((struct parser_f2 *)node)->r ) != 0.0 )
1392+ { // ? and true => ?
1393+ std::memcpy (node, node->l , sizeof (struct parser_node ));
1394+ }
1395+ else if (((struct parser_f2 *)node)->ftype == PARSER_AND &&
1396+ ((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
1397+ parser_get_number (((struct parser_f2 *)node)->l ) == 0.0 )
1398+ { // false and ? => false
1399+ parser_set_number (node, 0.0 );
1400+ }
1401+ else if (((struct parser_f2 *)node)->ftype == PARSER_AND &&
1402+ ((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
1403+ parser_get_number (((struct parser_f2 *)node)->l ) != 0.0 )
1404+ { // true and ? => ?
1405+ std::memcpy (node, node->r , sizeof (struct parser_node ));
1406+ }
1407+ else if (((struct parser_f2 *)node)->ftype == PARSER_OR &&
1408+ ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
1409+ parser_get_number (((struct parser_f2 *)node)->r ) != 0.0 )
1410+ { // ? or true => true
1411+ parser_set_number (node, 1.0 );
1412+ }
1413+ else if (((struct parser_f2 *)node)->ftype == PARSER_OR &&
1414+ ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
1415+ parser_get_number (((struct parser_f2 *)node)->r ) == 0.0 )
1416+ { // ? or false => ?
1417+ std::memcpy (node, node->l , sizeof (struct parser_node ));
1418+ }
1419+ else if (((struct parser_f2 *)node)->ftype == PARSER_OR &&
1420+ ((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
1421+ parser_get_number (((struct parser_f2 *)node)->l ) != 0.0 )
1422+ { // true or ? => true
1423+ parser_set_number (node, 1.0 );
1424+ }
1425+ else if (((struct parser_f2 *)node)->ftype == PARSER_OR &&
1426+ ((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
1427+ parser_get_number (((struct parser_f2 *)node)->l ) == 0.0 )
1428+ { // false or ? => ?
1429+ std::memcpy (node, node->r , sizeof (struct parser_node ));
1430+ }
13361431 else if (((struct parser_f2 *)node)->ftype == PARSER_POW &&
13371432 ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
13381433 parser_get_number (((struct parser_f2 *)node)->r ) == 0.0 )
0 commit comments