@@ -157,6 +157,50 @@ parser_newlist (struct parser_node* nl, struct parser_node* nr)
157157 }
158158}
159159
160+ namespace {
161+ struct parser_node * parser_get_rightmost_operand (struct parser_node * node)
162+ {
163+ if (node && node->type == PARSER_F2) {
164+ auto ftype = ((struct parser_f2 *)node)->ftype ;
165+ if (ftype == PARSER_CMP_CHAIN) {
166+ return parser_get_rightmost_operand (node->r );
167+ } else if (ftype == PARSER_LT || ftype == PARSER_GT ||
168+ ftype == PARSER_LEQ || ftype == PARSER_GEQ ||
169+ ftype == PARSER_EQ || ftype == PARSER_NEQ) {
170+ return node->r ;
171+ }
172+ }
173+ return nullptr ;
174+ }
175+
176+ bool parser_is_comparison (struct parser_node * node)
177+ {
178+ if (node && node->type == PARSER_F2) {
179+ auto ftype = ((struct parser_f2 *)node)->ftype ;
180+ return (ftype == PARSER_LT || ftype == PARSER_GT ||
181+ ftype == PARSER_LEQ || ftype == PARSER_GEQ ||
182+ ftype == PARSER_EQ || ftype == PARSER_NEQ ||
183+ (ftype == PARSER_CMP_CHAIN && parser_is_comparison (node->r )));
184+ } else {
185+ return false ;
186+ }
187+ }
188+ }
189+
190+ struct parser_node * parser_newcmpchain (struct parser_node * nl, enum parser_f2_t cmp,
191+ struct parser_node * nr)
192+ {
193+ /* If left side is already a comparison, this extends the chain */
194+ if (amrexpr::parser_is_comparison (nl)) {
195+ return amrexpr::parser_newf2 (amrexpr::PARSER_CMP_CHAIN, nl,
196+ amrexpr::parser_newf2 (cmp,
197+ amrexpr::parser_get_rightmost_operand (nl),
198+ nr));
199+ } else {
200+ return amrexpr::parser_newf2 (cmp, nl, nr); // Initial comparison
201+ }
202+ }
203+
160204/* ******************************************************************/
161205
162206struct amrexpr_parser *
@@ -1188,6 +1232,9 @@ parser_ast_optimize (struct parser_node*& node, std::map<std::string,double>& lo
11881232 case PARSER_F2:
11891233 parser_ast_optimize (((struct parser_f2 *)node)->l , local_consts);
11901234 parser_ast_optimize (((struct parser_f2 *)node)->r , local_consts);
1235+ if (((struct parser_f2 *)node)->ftype == PARSER_CMP_CHAIN) {
1236+ ((struct parser_f2 *)node)->ftype = PARSER_AND;
1237+ }
11911238 if (((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
11921239 ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER)
11931240 {
@@ -1197,6 +1244,54 @@ parser_ast_optimize (struct parser_node*& node, std::map<std::string,double>& lo
11971244 ((struct parser_number *)(((struct parser_f2 *)node)->r ))->value );
11981245 parser_set_number (node, v);
11991246 }
1247+ else if (((struct parser_f2 *)node)->ftype == PARSER_AND &&
1248+ ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
1249+ parser_get_number (((struct parser_f2 *)node)->r ) == 0.0 )
1250+ { // ? and false => false
1251+ parser_set_number (node, 0.0 );
1252+ }
1253+ else if (((struct parser_f2 *)node)->ftype == PARSER_AND &&
1254+ ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
1255+ parser_get_number (((struct parser_f2 *)node)->r ) != 0.0 )
1256+ { // ? and true => ?
1257+ std::memcpy (node, node->l , sizeof (struct parser_node ));
1258+ }
1259+ else if (((struct parser_f2 *)node)->ftype == PARSER_AND &&
1260+ ((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
1261+ parser_get_number (((struct parser_f2 *)node)->l ) == 0.0 )
1262+ { // false and ? => false
1263+ parser_set_number (node, 0.0 );
1264+ }
1265+ else if (((struct parser_f2 *)node)->ftype == PARSER_AND &&
1266+ ((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
1267+ parser_get_number (((struct parser_f2 *)node)->l ) != 0.0 )
1268+ { // true and ? => ?
1269+ std::memcpy (node, node->r , sizeof (struct parser_node ));
1270+ }
1271+ else if (((struct parser_f2 *)node)->ftype == PARSER_OR &&
1272+ ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
1273+ parser_get_number (((struct parser_f2 *)node)->r ) != 0.0 )
1274+ { // ? or true => true
1275+ parser_set_number (node, 1.0 );
1276+ }
1277+ else if (((struct parser_f2 *)node)->ftype == PARSER_OR &&
1278+ ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
1279+ parser_get_number (((struct parser_f2 *)node)->r ) == 0.0 )
1280+ { // ? or false => ?
1281+ std::memcpy (node, node->l , sizeof (struct parser_node ));
1282+ }
1283+ else if (((struct parser_f2 *)node)->ftype == PARSER_OR &&
1284+ ((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
1285+ parser_get_number (((struct parser_f2 *)node)->l ) != 0.0 )
1286+ { // true or ? => true
1287+ parser_set_number (node, 1.0 );
1288+ }
1289+ else if (((struct parser_f2 *)node)->ftype == PARSER_OR &&
1290+ ((struct parser_f2 *)node)->l ->type == PARSER_NUMBER &&
1291+ parser_get_number (((struct parser_f2 *)node)->l ) == 0.0 )
1292+ { // false or ? => ?
1293+ std::memcpy (node, node->r , sizeof (struct parser_node ));
1294+ }
12001295 else if (((struct parser_f2 *)node)->ftype == PARSER_POW &&
12011296 ((struct parser_f2 *)node)->r ->type == PARSER_NUMBER &&
12021297 parser_get_number (((struct parser_f2 *)node)->r ) == 0.0 )
0 commit comments