@@ -235,6 +235,19 @@ static double divide(double a, double b) {return a / b;}
235235static double negate (double a ) {return - a ;}
236236static double comma (double a , double b ) {(void )a ; return b ;}
237237
238+ static double greater (double a , double b ) {return a > b ;}
239+ static double greater_eq (double a , double b ) {return a >= b ;}
240+ static double lower (double a , double b ) {return a < b ;}
241+ static double lower_eq (double a , double b ) {return a <= b ;}
242+ static double equal (double a , double b ) {return a == b ;}
243+ static double not_equal (double a , double b ) {return a != b ;}
244+ static double logical_and (double a , double b ) {return a != 0.0 && b != 0.0 ;}
245+ static double logical_or (double a , double b ) {return a != 0.0 || b != 0.0 ;}
246+ static double logical_not (double a ) {return a == 0.0 ;}
247+ static double logical_notnot (double a ) {return a != 0.0 ;}
248+ static double negate_logical_not (double a ) {return - (a == 0.0 );}
249+ static double negate_logical_notnot (double a ) {return - (a != 0.0 );}
250+
238251
239252static void next_token (state * s ) {
240253 s -> type = TOK_NULL ;
@@ -291,6 +304,51 @@ static void next_token(state *s) {
291304 case '/' : s -> type = TOK_INFIX ; s -> function = divide ; break ;
292305 case '^' : s -> type = TOK_INFIX ; s -> function = pow ; break ;
293306 case '%' : s -> type = TOK_INFIX ; s -> function = fmod ; break ;
307+ case '!' :
308+ if (s -> next ++ [0 ] == '=' ) {
309+ s -> type = TOK_INFIX ; s -> function = not_equal ;
310+ } else {
311+ s -> next -- ;
312+ s -> type = TOK_INFIX ; s -> function = logical_not ;
313+ }
314+ break ;
315+ case '=' :
316+ if (s -> next ++ [0 ] == '=' ) {
317+ s -> type = TOK_INFIX ; s -> function = equal ;
318+ } else {
319+ s -> type = TOK_ERROR ;
320+ }
321+ break ;
322+ case '<' :
323+ if (s -> next ++ [0 ] == '=' ) {
324+ s -> type = TOK_INFIX ; s -> function = lower_eq ;
325+ } else {
326+ s -> next -- ;
327+ s -> type = TOK_INFIX ; s -> function = lower ;
328+ }
329+ break ;
330+ case '>' :
331+ if (s -> next ++ [0 ] == '=' ) {
332+ s -> type = TOK_INFIX ; s -> function = greater_eq ;
333+ } else {
334+ s -> next -- ;
335+ s -> type = TOK_INFIX ; s -> function = greater ;
336+ }
337+ break ;
338+ case '&' :
339+ if (s -> next ++ [0 ] == '&' ) {
340+ s -> type = TOK_INFIX ; s -> function = logical_and ;
341+ } else {
342+ s -> type = TOK_ERROR ;
343+ }
344+ break ;
345+ case '|' :
346+ if (s -> next ++ [0 ] == '|' ) {
347+ s -> type = TOK_INFIX ; s -> function = logical_or ;
348+ } else {
349+ s -> type = TOK_ERROR ;
350+ }
351+ break ;
294352 case '(' : s -> type = TOK_OPEN ; break ;
295353 case ')' : s -> type = TOK_CLOSE ; break ;
296354 case ',' : s -> type = TOK_SEP ; break ;
@@ -420,25 +478,51 @@ static te_expr *base(state *s) {
420478
421479
422480static te_expr * power (state * s ) {
423- /* <power> = {("-" | "+")} <base> */
481+ /* <power> = {("-" | "+" | "!" )} <base> */
424482 int sign = 1 ;
425483 while (s -> type == TOK_INFIX && (s -> function == add || s -> function == sub )) {
426484 if (s -> function == sub ) sign = - sign ;
427485 next_token (s );
428486 }
429487
488+ int logical = 0 ;
489+ while (s -> type == TOK_INFIX && (s -> function == add || s -> function == sub || s -> function == logical_not )) {
490+ if (s -> function == logical_not ) {
491+ if (logical == 0 ) {
492+ logical = -1 ;
493+ } else {
494+ logical = - logical ;
495+ }
496+ }
497+ next_token (s );
498+ }
499+
430500 te_expr * ret ;
431501
432502 if (sign == 1 ) {
433- ret = base (s );
503+ if (logical == 0 ) {
504+ ret = base (s );
505+ } else if (logical == -1 ) {
506+ ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , base (s ));
507+ ret -> function = logical_not ;
508+ } else {
509+ ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , base (s ));
510+ ret -> function = logical_notnot ;
511+ }
434512 } else {
435513 te_expr * b = base (s );
436514 CHECK_NULL (b );
437515
438516 ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , b );
439517 CHECK_NULL (ret , te_free (b ));
440518
441- ret -> function = negate ;
519+ if (logical == 0 ) {
520+ ret -> function = negate ;
521+ } else if (logical == -1 ) {
522+ ret -> function = negate_logical_not ;
523+ } else {
524+ ret -> function = negate_logical_notnot ;
525+ }
442526 }
443527
444528 return ret ;
@@ -450,13 +534,15 @@ static te_expr *factor(state *s) {
450534 te_expr * ret = power (s );
451535 CHECK_NULL (ret );
452536
453- int neg = 0 ;
537+ const void * left_function = NULL ;
454538
455- if (ret -> type == (TE_FUNCTION1 | TE_FLAG_PURE ) && ret -> function == negate ) {
539+ if (ret -> type == (TE_FUNCTION1 | TE_FLAG_PURE ) &&
540+ (ret -> function == negate || ret -> function == logical_not || ret -> function == logical_notnot ||
541+ ret -> function == negate_logical_not || ret -> function == negate_logical_notnot )) {
542+ left_function = ret -> function ;
456543 te_expr * se = ret -> parameters [0 ];
457544 free (ret );
458545 ret = se ;
459- neg = 1 ;
460546 }
461547
462548 te_expr * insertion = 0 ;
@@ -489,12 +575,12 @@ static te_expr *factor(state *s) {
489575 }
490576 }
491577
492- if (neg ) {
578+ if (left_function ) {
493579 te_expr * prev = ret ;
494580 ret = NEW_EXPR (TE_FUNCTION1 | TE_FLAG_PURE , ret );
495581 CHECK_NULL (ret , te_free (prev ));
496582
497- ret -> function = negate ;
583+ ret -> function = left_function ;
498584 }
499585
500586 return ret ;
@@ -546,7 +632,7 @@ static te_expr *term(state *s) {
546632}
547633
548634
549- static te_expr * expr (state * s ) {
635+ static te_expr * sum_expr (state * s ) {
550636 /* <expr> = <term> {("+" | "-") <term>} */
551637 te_expr * ret = term (s );
552638 CHECK_NULL (ret );
@@ -568,6 +654,37 @@ static te_expr *expr(state *s) {
568654}
569655
570656
657+ static te_expr * test_expr (state * s ) {
658+ /* <expr> = <sum_expr> {(">" | ">=" | "<" | "<=" | "==" | "!=") <sum_expr>} */
659+ te_expr * ret = sum_expr (s );
660+
661+ while (s -> type == TOK_INFIX && (s -> function == greater || s -> function == greater_eq ||
662+ s -> function == lower || s -> function == lower_eq || s -> function == equal || s -> function == not_equal )) {
663+ te_fun2 t = s -> function ;
664+ next_token (s );
665+ ret = NEW_EXPR (TE_FUNCTION2 | TE_FLAG_PURE , ret , sum_expr (s ));
666+ ret -> function = t ;
667+ }
668+
669+ return ret ;
670+ }
671+
672+
673+ static te_expr * expr (state * s ) {
674+ /* <expr> = <test_expr> {("&&" | "||") <test_expr>} */
675+ te_expr * ret = test_expr (s );
676+
677+ while (s -> type == TOK_INFIX && (s -> function == logical_and || s -> function == logical_or )) {
678+ te_fun2 t = s -> function ;
679+ next_token (s );
680+ ret = NEW_EXPR (TE_FUNCTION2 | TE_FLAG_PURE , ret , test_expr (s ));
681+ ret -> function = t ;
682+ }
683+
684+ return ret ;
685+ }
686+
687+
571688static te_expr * list (state * s ) {
572689 /* <list> = <expr> {"," <expr>} */
573690 te_expr * ret = expr (s );
0 commit comments