mirror of
				https://github.com/eledio-devices/thirdparty-tinyexpr.git
				synced 2025-10-31 16:14:16 +01:00 
			
		
		
		
	Refactoring.
This commit is contained in:
		| @@ -33,8 +33,9 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | typedef double (*function1)(double); | ||||||
|  |  | ||||||
| void bench(const char *expr, te_fun1 func) { | void bench(const char *expr, function1 func) { | ||||||
|     int i, j; |     int i, j; | ||||||
|     volatile double d; |     volatile double d; | ||||||
|     double tmp; |     double tmp; | ||||||
|   | |||||||
							
								
								
									
										110
									
								
								tinyexpr.c
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								tinyexpr.c
									
									
									
									
									
								
							| @@ -29,6 +29,15 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  |  | ||||||
|  |  | ||||||
|  | typedef double (*te_fun0)(void); | ||||||
|  | typedef double (*te_fun1)(double); | ||||||
|  | typedef double (*te_fun2)(double, double); | ||||||
|  | typedef double (*te_fun3)(double, double, double); | ||||||
|  | typedef double (*te_fun4)(double, double, double, double); | ||||||
|  | typedef double (*te_fun5)(double, double, double, double, double); | ||||||
|  | typedef double (*te_fun6)(double, double, double, double, double, double); | ||||||
|  | typedef double (*te_fun7)(double, double, double, double, double, double, double); | ||||||
|  |  | ||||||
| enum { | enum { | ||||||
|     TOK_NULL, TOK_ERROR, TOK_END, TOK_SEP, |     TOK_NULL, TOK_ERROR, TOK_END, TOK_SEP, | ||||||
|     TOK_OPEN, TOK_CLOSE, TOK_NUMBER, TOK_VARIABLE, TOK_INFIX, |     TOK_OPEN, TOK_CLOSE, TOK_NUMBER, TOK_VARIABLE, TOK_INFIX, | ||||||
| @@ -43,21 +52,21 @@ typedef struct state { | |||||||
|     const char *start; |     const char *start; | ||||||
|     const char *next; |     const char *next; | ||||||
|     int type; |     int type; | ||||||
|     union {double value; te_fun fun; const double *bound;}; |     union {double value; const double *bound; const void *function;}; | ||||||
|  |  | ||||||
|     const te_variable *lookup; |     const te_variable *lookup; | ||||||
|     int lookup_len; |     int lookup_len; | ||||||
| } state; | } state; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define ARITY(TYPE) (((TYPE) < TE_FUNCTION0 || (TYPE) > TE_FUNCTION7) ? 0 : ((TYPE)-TE_FUNCTION0)) | #define ARITY(TYPE) (((TYPE) < TE_FUNCTION0 || (TYPE) > TE_FUNCTION7) ? 0 : ((TYPE)-TE_FUNCTION0)) | ||||||
|  |  | ||||||
| static te_expr *new_expr(const int type, const te_expr *members[]) { | static te_expr *new_expr(const int type, const te_expr *parameters[]) { | ||||||
|     const int arity = ARITY(type); |     const int arity = ARITY(type); | ||||||
|     te_expr *ret = malloc(sizeof(te_expr) + sizeof(te_expr*) * arity); |     const int psize = sizeof(te_expr*) * arity; | ||||||
|     if (arity && members) { |     te_expr *ret = malloc(sizeof(te_expr) + psize); | ||||||
|         memcpy(ret->members, members, sizeof(te_expr*) * arity); |     if (arity && parameters) { | ||||||
|  |         memcpy(ret->parameters, parameters, psize); | ||||||
|     } |     } | ||||||
|     ret->type = type; |     ret->type = type; | ||||||
|     ret->bound = 0; |     ret->bound = 0; | ||||||
| @@ -68,13 +77,13 @@ static te_expr *new_expr(const int type, const te_expr *members[]) { | |||||||
| void te_free(te_expr *n) { | void te_free(te_expr *n) { | ||||||
|     if (!n) return; |     if (!n) return; | ||||||
|     switch (n->type) { |     switch (n->type) { | ||||||
|         case TE_FUNCTION7: te_free(n->members[6]); |         case TE_FUNCTION7: te_free(n->parameters[6]); | ||||||
|         case TE_FUNCTION6: te_free(n->members[5]); |         case TE_FUNCTION6: te_free(n->parameters[5]); | ||||||
|         case TE_FUNCTION5: te_free(n->members[4]); |         case TE_FUNCTION5: te_free(n->parameters[4]); | ||||||
|         case TE_FUNCTION4: te_free(n->members[3]); |         case TE_FUNCTION4: te_free(n->parameters[3]); | ||||||
|         case TE_FUNCTION3: te_free(n->members[2]); |         case TE_FUNCTION3: te_free(n->parameters[2]); | ||||||
|         case TE_FUNCTION2: te_free(n->members[1]); |         case TE_FUNCTION2: te_free(n->parameters[1]); | ||||||
|         case TE_FUNCTION1: te_free(n->members[0]); |         case TE_FUNCTION1: te_free(n->parameters[0]); | ||||||
|     } |     } | ||||||
|     free(n); |     free(n); | ||||||
| } | } | ||||||
| @@ -185,19 +194,19 @@ void next_token(state *s) { | |||||||
|                         case TE_FUNCTION0: case TE_FUNCTION1: case TE_FUNCTION2: case TE_FUNCTION3: |                         case TE_FUNCTION0: case TE_FUNCTION1: case TE_FUNCTION2: case TE_FUNCTION3: | ||||||
|                         case TE_FUNCTION4: case TE_FUNCTION5: case TE_FUNCTION6: case TE_FUNCTION7: |                         case TE_FUNCTION4: case TE_FUNCTION5: case TE_FUNCTION6: case TE_FUNCTION7: | ||||||
|                             s->type = TOK_FUNCTION0 + ARITY(var->type); |                             s->type = TOK_FUNCTION0 + ARITY(var->type); | ||||||
|                             s->fun.f0 = (void*)var->address; |                             s->function = var->address; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|             } else { |             } else { | ||||||
|                 /* Look for an operator or special character. */ |                 /* Look for an operator or special character. */ | ||||||
|                 switch (s->next++[0]) { |                 switch (s->next++[0]) { | ||||||
|                     case '+': s->type = TOK_INFIX; s->fun.f2 = add; break; |                     case '+': s->type = TOK_INFIX; s->function = add; break; | ||||||
|                     case '-': s->type = TOK_INFIX; s->fun.f2 = sub; break; |                     case '-': s->type = TOK_INFIX; s->function = sub; break; | ||||||
|                     case '*': s->type = TOK_INFIX; s->fun.f2 = mul; break; |                     case '*': s->type = TOK_INFIX; s->function = mul; break; | ||||||
|                     case '/': s->type = TOK_INFIX; s->fun.f2 = divide; break; |                     case '/': s->type = TOK_INFIX; s->function = divide; break; | ||||||
|                     case '^': s->type = TOK_INFIX; s->fun.f2 = pow; break; |                     case '^': s->type = TOK_INFIX; s->function = pow; break; | ||||||
|                     case '%': s->type = TOK_INFIX; s->fun.f2 = fmod; break; |                     case '%': s->type = TOK_INFIX; s->function = fmod; break; | ||||||
|                     case '(': s->type = TOK_OPEN; break; |                     case '(': s->type = TOK_OPEN; break; | ||||||
|                     case ')': s->type = TOK_CLOSE; break; |                     case ')': s->type = TOK_CLOSE; break; | ||||||
|                     case ',': s->type = TOK_SEP; break; |                     case ',': s->type = TOK_SEP; break; | ||||||
| @@ -215,7 +224,7 @@ static te_expr *expr(state *s); | |||||||
| static te_expr *power(state *s); | static te_expr *power(state *s); | ||||||
|  |  | ||||||
| static te_expr *base(state *s) { | static te_expr *base(state *s) { | ||||||
|     /* <base>      =    <constant> | <variable> | <function-0> {"(" ")"} | <function-1> <power> | <function-2> "(" <expr> "," <expr> ")" | "(" <list> ")" */ |     /* <base>      =    <constant> | <variable> | <function-0> {"(" ")"} | <function-1> <power> | <function-X> "(" <expr> {"," <expr>} ")" | "(" <list> ")" */ | ||||||
|     te_expr *ret; |     te_expr *ret; | ||||||
|     int arity; |     int arity; | ||||||
|  |  | ||||||
| @@ -234,7 +243,7 @@ static te_expr *base(state *s) { | |||||||
|  |  | ||||||
|         case TOK_FUNCTION0: |         case TOK_FUNCTION0: | ||||||
|             ret = new_expr(TE_FUNCTION0, 0); |             ret = new_expr(TE_FUNCTION0, 0); | ||||||
|             ret->fun.f0 = s->fun.f0; |             ret->function = s->function; | ||||||
|             next_token(s); |             next_token(s); | ||||||
|             if (s->type == TOK_OPEN) { |             if (s->type == TOK_OPEN) { | ||||||
|                 next_token(s); |                 next_token(s); | ||||||
| @@ -248,10 +257,9 @@ static te_expr *base(state *s) { | |||||||
|  |  | ||||||
|         case TOK_FUNCTION1: |         case TOK_FUNCTION1: | ||||||
|             ret = new_expr(TE_FUNCTION1, 0); |             ret = new_expr(TE_FUNCTION1, 0); | ||||||
|             ret->fun.f0 = s->fun.f0; |             ret->function = s->function; | ||||||
|  |  | ||||||
|             next_token(s); |             next_token(s); | ||||||
|             ret->members[0] = power(s); |             ret->parameters[0] = power(s); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case TOK_FUNCTION2: case TOK_FUNCTION3: case TOK_FUNCTION4: |         case TOK_FUNCTION2: case TOK_FUNCTION3: case TOK_FUNCTION4: | ||||||
| @@ -259,7 +267,7 @@ static te_expr *base(state *s) { | |||||||
|             arity = s->type - TOK_FUNCTION0; |             arity = s->type - TOK_FUNCTION0; | ||||||
|  |  | ||||||
|             ret = new_expr(TE_FUNCTION0 + arity, 0); |             ret = new_expr(TE_FUNCTION0 + arity, 0); | ||||||
|             ret->fun.f0 = s->fun.f0; |             ret->function = s->function; | ||||||
|             next_token(s); |             next_token(s); | ||||||
|  |  | ||||||
|             if (s->type != TOK_OPEN) { |             if (s->type != TOK_OPEN) { | ||||||
| @@ -268,7 +276,7 @@ static te_expr *base(state *s) { | |||||||
|                 int i; |                 int i; | ||||||
|                 for(i = 0; i < arity; i++) { |                 for(i = 0; i < arity; i++) { | ||||||
|                     next_token(s); |                     next_token(s); | ||||||
|                     ret->members[i] = expr(s); |                     ret->parameters[i] = expr(s); | ||||||
|                     if(s->type != TOK_SEP) { |                     if(s->type != TOK_SEP) { | ||||||
|                         break; |                         break; | ||||||
|                     } |                     } | ||||||
| @@ -306,8 +314,8 @@ 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->fun.f2 == add || s->fun.f2 == sub)) { |     while (s->type == TOK_INFIX && (s->function == add || s->function == sub)) { | ||||||
|         if (s->fun.f2 == sub) sign = -sign; |         if (s->function == sub) sign = -sign; | ||||||
|         next_token(s); |         next_token(s); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -317,7 +325,7 @@ static te_expr *power(state *s) { | |||||||
|         ret = base(s); |         ret = base(s); | ||||||
|     } else { |     } else { | ||||||
|         ret = new_expr(TE_FUNCTION1, (const te_expr*[]){base(s)}); |         ret = new_expr(TE_FUNCTION1, (const te_expr*[]){base(s)}); | ||||||
|         ret->fun.f1 = negate; |         ret->function = negate; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ret; |     return ret; | ||||||
| @@ -328,11 +336,11 @@ static te_expr *factor(state *s) { | |||||||
|     /* <factor>    =    <power> {"^" <power>} */ |     /* <factor>    =    <power> {"^" <power>} */ | ||||||
|     te_expr *ret = power(s); |     te_expr *ret = power(s); | ||||||
|  |  | ||||||
|     while (s->type == TOK_INFIX && (s->fun.f2 == pow)) { |     while (s->type == TOK_INFIX && (s->function == pow)) { | ||||||
|         te_fun2 t = s->fun.f2; |         te_fun2 t = s->function; | ||||||
|         next_token(s); |         next_token(s); | ||||||
|         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, power(s)}); |         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, power(s)}); | ||||||
|         ret->fun.f2 = t; |         ret->function = t; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ret; |     return ret; | ||||||
| @@ -343,11 +351,11 @@ static te_expr *term(state *s) { | |||||||
|     /* <term>      =    <factor> {("*" | "/" | "%") <factor>} */ |     /* <term>      =    <factor> {("*" | "/" | "%") <factor>} */ | ||||||
|     te_expr *ret = factor(s); |     te_expr *ret = factor(s); | ||||||
|  |  | ||||||
|     while (s->type == TOK_INFIX && (s->fun.f2 == mul || s->fun.f2 == divide || s->fun.f2 == fmod)) { |     while (s->type == TOK_INFIX && (s->function == mul || s->function == divide || s->function == fmod)) { | ||||||
|         te_fun2 t = s->fun.f2; |         te_fun2 t = s->function; | ||||||
|         next_token(s); |         next_token(s); | ||||||
|         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, factor(s)}); |         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, factor(s)}); | ||||||
|         ret->fun.f2 = t; |         ret->function = t; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ret; |     return ret; | ||||||
| @@ -358,11 +366,11 @@ static te_expr *expr(state *s) { | |||||||
|     /* <expr>      =    <term> {("+" | "-") <term>} */ |     /* <expr>      =    <term> {("+" | "-") <term>} */ | ||||||
|     te_expr *ret = term(s); |     te_expr *ret = term(s); | ||||||
|  |  | ||||||
|     while (s->type == TOK_INFIX && (s->fun.f2 == add || s->fun.f2 == sub)) { |     while (s->type == TOK_INFIX && (s->function == add || s->function == sub)) { | ||||||
|         te_fun2 t = s->fun.f2; |         te_fun2 t = s->function; | ||||||
|         next_token(s); |         next_token(s); | ||||||
|         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, term(s)}); |         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, term(s)}); | ||||||
|         ret->fun.f2 = t; |         ret->function = t; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ret; |     return ret; | ||||||
| @@ -376,7 +384,7 @@ static te_expr *list(state *s) { | |||||||
|     while (s->type == TOK_SEP) { |     while (s->type == TOK_SEP) { | ||||||
|         next_token(s); |         next_token(s); | ||||||
|         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, expr(s)}); |         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, expr(s)}); | ||||||
|         ret->fun.f2 = comma; |         ret->function = comma; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ret; |     return ret; | ||||||
| @@ -392,15 +400,15 @@ double te_eval(const te_expr *n) { | |||||||
|         case TE_FUNCTION0: case TE_FUNCTION1: case TE_FUNCTION2: case TE_FUNCTION3: |         case TE_FUNCTION0: case TE_FUNCTION1: case TE_FUNCTION2: case TE_FUNCTION3: | ||||||
|         case TE_FUNCTION4: case TE_FUNCTION5: case TE_FUNCTION6: case TE_FUNCTION7: |         case TE_FUNCTION4: case TE_FUNCTION5: case TE_FUNCTION6: case TE_FUNCTION7: | ||||||
|         switch(ARITY(n->type)) { |         switch(ARITY(n->type)) { | ||||||
|             #define m(e) te_eval(n->members[e]) |             #define m(e) te_eval(n->parameters[e]) | ||||||
|             case 0: return n->fun.f0(); |             case 0: return ((te_fun0)(n->function))(); | ||||||
|             case 1: return n->fun.f1(m(0)); |             case 1: return ((te_fun1)(n->function))(m(0)); | ||||||
|             case 2: return n->fun.f2(m(0), m(1)); |             case 2: return ((te_fun2)(n->function))(m(0), m(1)); | ||||||
|             case 3: return n->fun.f3(m(0), m(1), m(2)); |             case 3: return ((te_fun3)(n->function))(m(0), m(1), m(2)); | ||||||
|             case 4: return n->fun.f4(m(0), m(1), m(2), m(3)); |             case 4: return ((te_fun4)(n->function))(m(0), m(1), m(2), m(3)); | ||||||
|             case 5: return n->fun.f5(m(0), m(1), m(2), m(3), m(4)); |             case 5: return ((te_fun5)(n->function))(m(0), m(1), m(2), m(3), m(4)); | ||||||
|             case 6: return n->fun.f6(m(0), m(1), m(2), m(3), m(4), m(5)); |             case 6: return ((te_fun6)(n->function))(m(0), m(1), m(2), m(3), m(4), m(5)); | ||||||
|             case 7: return n->fun.f7(m(0), m(1), m(2), m(3), m(4), m(5), m(6)); |             case 7: return ((te_fun7)(n->function))(m(0), m(1), m(2), m(3), m(4), m(5), m(6)); | ||||||
|             default: return 0.0/0.0; |             default: return 0.0/0.0; | ||||||
|             #undef m |             #undef m | ||||||
|         } |         } | ||||||
| @@ -487,11 +495,11 @@ static void pn (const te_expr *n, int depth) { | |||||||
|          arity = ARITY(n->type); |          arity = ARITY(n->type); | ||||||
|          printf("f%d", arity); |          printf("f%d", arity); | ||||||
|          for(i = 0; i < arity; i++) { |          for(i = 0; i < arity; i++) { | ||||||
|              printf(" %p", n->members[i]); |              printf(" %p", n->parameters[i]); | ||||||
|          } |          } | ||||||
|          printf("\n"); |          printf("\n"); | ||||||
|          for(i = 0; i < arity; i++) { |          for(i = 0; i < arity; i++) { | ||||||
|              pn(n->members[i], depth + 1); |              pn(n->parameters[i], depth + 1); | ||||||
|          } |          } | ||||||
|          break; |          break; | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								tinyexpr.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								tinyexpr.h
									
									
									
									
									
								
							| @@ -31,24 +31,11 @@ extern "C" { | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef double (*te_fun0)(void); |  | ||||||
| typedef double (*te_fun1)(double); |  | ||||||
| typedef double (*te_fun2)(double, double); |  | ||||||
| typedef double (*te_fun3)(double, double, double); |  | ||||||
| typedef double (*te_fun4)(double, double, double, double); |  | ||||||
| typedef double (*te_fun5)(double, double, double, double, double); |  | ||||||
| typedef double (*te_fun6)(double, double, double, double, double, double); |  | ||||||
| typedef double (*te_fun7)(double, double, double, double, double, double, double); |  | ||||||
|  |  | ||||||
| typedef union |  | ||||||
| { |  | ||||||
|     te_fun0 f0; te_fun1 f1; te_fun2 f2; te_fun3 f3; te_fun4 f4; te_fun5 f5; te_fun6 f6; te_fun7 f7; |  | ||||||
| } te_fun; |  | ||||||
|  |  | ||||||
| typedef struct te_expr { | typedef struct te_expr { | ||||||
|     int type; |     int type; | ||||||
|     union {double value; const double *bound; te_fun fun;}; |     union {double value; const double *bound; const void *function;}; | ||||||
|     struct te_expr *members[]; |     struct te_expr *parameters[]; | ||||||
| } te_expr; | } te_expr; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user