@@ -225,6 +225,19 @@ static double divide(double a, double b) {return a / b;}
225225static double negate (double a ) {return - a ;}
226226static double comma (double a , double b ) {(void )a ; return b ;}
227227
228+ static double greater (double a , double b ) {return a > b ;}
229+ static double greater_eq (double a , double b ) {return a >= b ;}
230+ static double lower (double a , double b ) {return a < b ;}
231+ static double lower_eq (double a , double b ) {return a <= b ;}
232+ static double equal (double a , double b ) {return a == b ;}
233+ static double not_equal (double a , double b ) {return a != b ;}
234+ static double logical_and (double a , double b ) {return a != 0.0 && b != 0.0 ;}
235+ static double logical_or (double a , double b ) {return a != 0.0 || b != 0.0 ;}
236+ static double logical_not (double a ) {return a == 0.0 ;}
237+ static double logical_notnot (double a ) {return a != 0.0 ;}
238+ static double negate_logical_not (double a ) {return - (a == 0.0 );}
239+ static double negate_logical_notnot (double a ) {return - (a != 0.0 );}
240+
228241
229242void next_token (state * s ) {
230243 s -> type = TOK_NULL ;
@@ -281,6 +294,51 @@ void next_token(state *s) {
281294 case '/' : s -> type = TOK_INFIX ; s -> function = divide ; break ;
282295 case '^' : s -> type = TOK_INFIX ; s -> function = pow ; break ;
283296 case '%' : s -> type = TOK_INFIX ; s -> function = fmod ; break ;
297+ case '!' :
298+ if (s -> next ++ [0 ] == '=' ) {
299+ s -> type = TOK_INFIX ; s -> function = not_equal ;
300+ } else {
301+ s -> next -- ;
302+ s -> type = TOK_INFIX ; s -> function = logical_not ;
303+ }
304+ break ;
305+ case '=' :
306+ if (s -> next ++ [0 ] == '=' ) {
307+ s -> type = TOK_INFIX ; s -> function = equal ;
308+ } else {
309+ s -> type = TOK_ERROR ;
310+ }
311+ break ;
312+ case '<' :
313+ if (s -> next ++ [0 ] == '=' ) {
314+ s -> type = TOK_INFIX ; s -> function = lower_eq ;
315+ } else {
316+ s -> next -- ;
317+ s -> type = TOK_INFIX ; s -> function = lower ;
318+ }
319+ break ;
320+ case '>' :
321+ if (s -> next ++ [0 ] == '=' ) {
322+ s -> type = TOK_INFIX ; s -> function = greater_eq ;
323+ } else {
324+ s -> next -- ;
325+ s -> type = TOK_INFIX ; s -> function = greater ;
326+ }
327+ break ;
328+ case '&' :
329+ if (s -> next ++ [0 ] == '&' ) {
330+ s -> type = TOK_INFIX ; s -> function = logical_and ;
331+ } else {
332+ s -> type = TOK_ERROR ;
333+ }
334+ break ;
335+ case '|' :
336+ if (s -> next ++ [0 ] == '|' ) {
337+ s -> type = TOK_INFIX ; s -> function = logical_or ;
338+ } else {
339+ s -> type = TOK_ERROR ;
340+ }
341+ break ;
284342 case '(' : s -> type = TOK_OPEN ; break ;
285343 case ')' : s -> type = TOK_CLOSE ; break ;
286344 case ',' : s -> type = TOK_SEP ; break ;
@@ -393,20 +451,48 @@ static te_expr *base(state *s) {
393451
394452
395453static te_expr * power (state * s ) {
396- /* <power> = {("-" | "+")} <base> */
454+ /* <power> = {("-" | "+" | "!" )} <base> */
397455 int sign = 1 ;
398456 while (s -> type == TOK_INFIX && (s -> function == add || s -> function == sub )) {
399457 if (s -> function == sub ) sign = - sign ;
400458 next_token (s );
401459 }
402460
461+ int logical = 0 ;
462+ while (s -> type == TOK_INFIX && (s -> function == add || s -> function == sub || s -> function == logical_not )) {
463+ if (s -> function == logical_not ) {
464+ if (logical == 0 ) {
465+ logical = -1 ;
466+ } else {
467+ logical = - logical ;
468+ }
469+ }
470+ next_token (s );
471+ }
472+
403473 te_expr * ret ;
404474
405475 if (sign == 1 ) {
406- ret = base (s );
476+ if (logical == 0 ) {
477+ ret = base (s );
478+ } else if (logical == -1 ) {
479+ ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , base (s ));
480+ ret -> function = logical_not ;
481+ } else {
482+ ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , base (s ));
483+ ret -> function = logical_notnot ;
484+ }
407485 } else {
408- ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , base (s ));
409- ret -> function = negate ;
486+ if (logical == 0 ) {
487+ ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , base (s ));
488+ ret -> function = negate ;
489+ } else if (logical == -1 ) {
490+ ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , base (s ));
491+ ret -> function = negate_logical_not ;
492+ } else {
493+ ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , base (s ));
494+ ret -> function = negate_logical_notnot ;
495+ }
410496 }
411497
412498 return ret ;
@@ -417,14 +503,16 @@ static te_expr *factor(state *s) {
417503 /* <factor> = <power> {"^" <power>} */
418504 te_expr * ret = power (s );
419505
420- int neg = 0 ;
506+ const void * left_function = NULL ;
421507 te_expr * insertion = 0 ;
422508
423- if (ret -> type == (TE_FUNCTION1 | TE_FLAG_PURE ) && ret -> function == negate ) {
509+ if (ret -> type == (TE_FUNCTION1 | TE_FLAG_PURE ) &&
510+ (ret -> function == negate || ret -> function == logical_not || ret -> function == logical_notnot ||
511+ ret -> function == negate_logical_not || ret -> function == negate_logical_notnot )) {
512+ left_function = ret -> function ;
424513 te_expr * se = ret -> parameters [0 ];
425514 free (ret );
426515 ret = se ;
427- neg = 1 ;
428516 }
429517
430518 while (s -> type == TOK_INFIX && (s -> function == pow )) {
@@ -444,9 +532,9 @@ static te_expr *factor(state *s) {
444532 }
445533 }
446534
447- if (neg ) {
535+ if (left_function ) {
448536 ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , ret );
449- ret -> function = negate ;
537+ ret -> function = left_function ;
450538 }
451539
452540 return ret ;
@@ -484,7 +572,7 @@ static te_expr *term(state *s) {
484572}
485573
486574
487- static te_expr * expr (state * s ) {
575+ static te_expr * sum_expr (state * s ) {
488576 /* <expr> = <term> {("+" | "-") <term>} */
489577 te_expr * ret = term (s );
490578
@@ -499,6 +587,37 @@ static te_expr *expr(state *s) {
499587}
500588
501589
590+ static te_expr * test_expr (state * s ) {
591+ /* <expr> = <sum_expr> {(">" | ">=" | "<" | "<=" | "==" | "!=") <sum_expr>} */
592+ te_expr * ret = sum_expr (s );
593+
594+ while (s -> type == TOK_INFIX && (s -> function == greater || s -> function == greater_eq ||
595+ s -> function == lower || s -> function == lower_eq || s -> function == equal || s -> function == not_equal )) {
596+ te_fun2 t = s -> function ;
597+ next_token (s );
598+ ret = NEW_EXPR (TE_FUNCTION2 | TE_FLAG_PURE , ret , sum_expr (s ));
599+ ret -> function = t ;
600+ }
601+
602+ return ret ;
603+ }
604+
605+
606+ static te_expr * expr (state * s ) {
607+ /* <expr> = <test_expr> {("&&" | "||") <test_expr>} */
608+ te_expr * ret = test_expr (s );
609+
610+ while (s -> type == TOK_INFIX && (s -> function == logical_and || s -> function == logical_or )) {
611+ te_fun2 t = s -> function ;
612+ next_token (s );
613+ ret = NEW_EXPR (TE_FUNCTION2 | TE_FLAG_PURE , ret , test_expr (s ));
614+ ret -> function = t ;
615+ }
616+
617+ return ret ;
618+ }
619+
620+
502621static te_expr * list (state * s ) {
503622 /* <list> = <expr> {"," <expr>} */
504623 te_expr * ret = expr (s );
0 commit comments