mirror of
				https://github.com/eledio-devices/thirdparty-tinyexpr.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	Fixed right-to-left interpreter and repeated unary operators
This commit is contained in:
		
							
								
								
									
										22
									
								
								test.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								test.c
									
									
									
									
									
								
							| @@ -684,6 +684,17 @@ void test_logic() { | |||||||
|             {"0 || 0", 0}, |             {"0 || 0", 0}, | ||||||
|             {"!0", 1}, |             {"!0", 1}, | ||||||
|             {"!1", 0}, |             {"!1", 0}, | ||||||
|  |             {"!2", 0}, | ||||||
|  |  | ||||||
|  |             {"!-2", 0}, | ||||||
|  |             {"-!2", 0}, | ||||||
|  |             {"!!0", 0}, | ||||||
|  |             {"!!1", 1}, | ||||||
|  |             {"!!2", 1}, | ||||||
|  |             {"!!-2", 1}, | ||||||
|  |             {"!-!2", 1}, | ||||||
|  |             {"-!!2", -1}, | ||||||
|  |             {"--!!2", 1}, | ||||||
|  |  | ||||||
|             {"1 < 2", 1}, |             {"1 < 2", 1}, | ||||||
|             {"2 < 2", 0}, |             {"2 < 2", 0}, | ||||||
| @@ -724,6 +735,17 @@ void test_logic() { | |||||||
|             {"5+!(5 < 4)+10", 16}, |             {"5+!(5 < 4)+10", 16}, | ||||||
|             {"5+!(5 < 4+10)", 5}, |             {"5+!(5 < 4+10)", 5}, | ||||||
|             {"!(5+5 < 4)+10", 11}, |             {"!(5+5 < 4)+10", 11}, | ||||||
|  |  | ||||||
|  | #ifdef TE_POW_FROM_RIGHT | ||||||
|  |             {"!0^2", 1}, | ||||||
|  |             {"!0^-1", 0}, | ||||||
|  |             {"-!0^2", -1}, | ||||||
|  | #else | ||||||
|  |             {"!0^2", 1}, | ||||||
|  |             {"!0^-1", 1}, | ||||||
|  |             {"-!0^2", 1}, | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										64
									
								
								tinyexpr.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								tinyexpr.c
									
									
									
									
									
								
							| @@ -231,9 +231,12 @@ static double lower(double a, double b) {return a < b;} | |||||||
| static double lower_eq(double a, double b) {return a <= b;} | static double lower_eq(double a, double b) {return a <= b;} | ||||||
| static double equal(double a, double b) {return a == b;} | static double equal(double a, double b) {return a == b;} | ||||||
| static double not_equal(double a, double b) {return a != b;} | static double not_equal(double a, double b) {return a != b;} | ||||||
| static double logical_and(double a, double b) {return (int)a != 0 && (int)b != 0;} | static double logical_and(double a, double b) {return a != 0.0 && b != 0.0;} | ||||||
| static double logical_or(double a, double b) {return (int)a != 0 || (int)b != 0;} | static double logical_or(double a, double b) {return a != 0.0 || b != 0.0;} | ||||||
| static double logical_not(double a) {return (int)a == 0;} | static double logical_not(double a) {return a == 0.0;} | ||||||
|  | static double logical_notnot(double a) {return a != 0.0;} | ||||||
|  | static double negate_logical_not(double a) {return -(a == 0.0);} | ||||||
|  | static double negate_logical_notnot(double a) {return -(a != 0.0);} | ||||||
|  |  | ||||||
|  |  | ||||||
| void next_token(state *s) { | void next_token(state *s) { | ||||||
| @@ -450,23 +453,46 @@ static te_expr *base(state *s) { | |||||||
| static te_expr *power(state *s) { | static te_expr *power(state *s) { | ||||||
|     /* <power>     =    {("-" | "+" | "!")} <base> */ |     /* <power>     =    {("-" | "+" | "!")} <base> */ | ||||||
|     int sign = 1; |     int sign = 1; | ||||||
|  |     while (s->type == TOK_INFIX && (s->function == add || s->function == sub)) { | ||||||
|  |         if (s->function == sub) sign = -sign; | ||||||
|  |         next_token(s); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     int logical = 0; |     int logical = 0; | ||||||
|     while (s->type == TOK_INFIX && (s->function == add || s->function == sub || s->function == logical_not)) { |     while (s->type == TOK_INFIX && (s->function == add || s->function == sub || s->function == logical_not)) { | ||||||
|         if (s->function == sub) sign = -sign; |         if (s->function == logical_not) { | ||||||
|         if (s->function == logical_not) logical = 1; |             if (logical == 0) { | ||||||
|  |                 logical = -1; | ||||||
|  |             } else { | ||||||
|  |                 logical = -logical; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         next_token(s); |         next_token(s); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     te_expr *ret; |     te_expr *ret; | ||||||
|  |  | ||||||
|     if (logical) { |     if (sign == 1) { | ||||||
|  |         if (logical == 0) { | ||||||
|  |             ret = base(s); | ||||||
|  |         } else if (logical == -1) { | ||||||
|             ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s)); |             ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s)); | ||||||
|             ret->function = logical_not; |             ret->function = logical_not; | ||||||
|     } else if (sign == 1) { |  | ||||||
|         ret = base(s); |  | ||||||
|         } else { |         } else { | ||||||
|  |             ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s)); | ||||||
|  |             ret->function = logical_notnot; | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         if (logical == 0) { | ||||||
|             ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s)); |             ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s)); | ||||||
|             ret->function = negate; |             ret->function = negate; | ||||||
|  |         } else if (logical == -1) { | ||||||
|  |             ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s)); | ||||||
|  |             ret->function = negate_logical_not; | ||||||
|  |         } else { | ||||||
|  |             ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s)); | ||||||
|  |             ret->function = negate_logical_notnot; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ret; |     return ret; | ||||||
| @@ -477,20 +503,16 @@ static te_expr *factor(state *s) { | |||||||
|     /* <factor>    =    <power> {"^" <power>} */ |     /* <factor>    =    <power> {"^" <power>} */ | ||||||
|     te_expr *ret = power(s); |     te_expr *ret = power(s); | ||||||
|  |  | ||||||
|     int neg = 0; |     const void *left_function = NULL; | ||||||
|     int lnot = 0; |  | ||||||
|     te_expr *insertion = 0; |     te_expr *insertion = 0; | ||||||
|  |  | ||||||
|     if (ret->type == (TE_FUNCTION1 | TE_FLAG_PURE)) { |     if (ret->type == (TE_FUNCTION1 | TE_FLAG_PURE) && | ||||||
|  |         (ret->function == negate || ret->function == logical_not || ret->function == logical_notnot || | ||||||
|  |         ret->function == negate_logical_not || ret->function == negate_logical_notnot)) { | ||||||
|  |         left_function = ret->function; | ||||||
|         te_expr *se = ret->parameters[0]; |         te_expr *se = ret->parameters[0]; | ||||||
|         free(ret); |         free(ret); | ||||||
|         ret = se; |         ret = se; | ||||||
|  |  | ||||||
|         if (ret->function == negate) { |  | ||||||
|             neg = 1; |  | ||||||
|         } else if (ret->function == logical_not) { |  | ||||||
|             lnot = 1; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     while (s->type == TOK_INFIX && (s->function == pow)) { |     while (s->type == TOK_INFIX && (s->function == pow)) { | ||||||
| @@ -510,13 +532,9 @@ static te_expr *factor(state *s) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (neg) { |     if (left_function) { | ||||||
|         ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, ret); |         ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, ret); | ||||||
|         ret->function = negate; |         ret->function = left_function; | ||||||
|     } |  | ||||||
|     if (lnot) { |  | ||||||
|         ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, ret); |  | ||||||
|         ret->function = logical_not; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ret; |     return ret; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user