mirror of
				https://github.com/eledio-devices/thirdparty-tinyexpr.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Refactoring.
This commit is contained in:
		
							
								
								
									
										31
									
								
								test.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								test.c
									
									
									
									
									
								
							| @@ -35,12 +35,7 @@ typedef struct { | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void test_results() { | void test_results() { | ||||||
|  |  | ||||||
|     test_case cases[] = { |     test_case cases[] = { | ||||||
|         {"1", 1}, |         {"1", 1}, | ||||||
|         {"(1)", 1}, |         {"(1)", 1}, | ||||||
| @@ -117,6 +112,7 @@ void test_results() { | |||||||
|  |  | ||||||
|         {"1,2", 2}, |         {"1,2", 2}, | ||||||
|         {"1,2+1", 3}, |         {"1,2+1", 3}, | ||||||
|  |         {"1+1,2+2,2+1", 3}, | ||||||
|         {"1,2,3", 3}, |         {"1,2,3", 3}, | ||||||
|         {"(1,2),3", 3}, |         {"(1,2),3", 3}, | ||||||
|         {"1,(2,3)", 3}, |         {"1,(2,3)", 3}, | ||||||
| @@ -155,8 +151,6 @@ void test_results() { | |||||||
|  |  | ||||||
|  |  | ||||||
| void test_syntax() { | void test_syntax() { | ||||||
|  |  | ||||||
|  |  | ||||||
|     test_case errors[] = { |     test_case errors[] = { | ||||||
|         {"", 1}, |         {"", 1}, | ||||||
|         {"1+", 2}, |         {"1+", 2}, | ||||||
| @@ -293,7 +287,7 @@ void test_variables() { | |||||||
|  |  | ||||||
|  |  | ||||||
| #define cross_check(a, b) do {\ | #define cross_check(a, b) do {\ | ||||||
|     expr = te_compile((a), &lookup, 1, &err);\ |     expr = te_compile((a), lookup, 2, &err);\ | ||||||
|     lfequal(te_eval(expr), (b));\ |     lfequal(te_eval(expr), (b));\ | ||||||
|     lok(!err);\ |     lok(!err);\ | ||||||
|     te_free(expr);\ |     te_free(expr);\ | ||||||
| @@ -301,8 +295,8 @@ void test_variables() { | |||||||
|  |  | ||||||
| void test_functions() { | void test_functions() { | ||||||
|  |  | ||||||
|     double x; |     double x, y; | ||||||
|     te_variable lookup = {"x", &x}; |     te_variable lookup[] = {{"x", &x}, {"y", &y}}; | ||||||
|  |  | ||||||
|     int err; |     int err; | ||||||
|     te_expr *expr; |     te_expr *expr; | ||||||
| @@ -324,6 +318,12 @@ void test_functions() { | |||||||
|         cross_check("sqrt x", sqrt(x)); |         cross_check("sqrt x", sqrt(x)); | ||||||
|         cross_check("tan x", tan(x)); |         cross_check("tan x", tan(x)); | ||||||
|         cross_check("tanh x", tanh(x)); |         cross_check("tanh x", tanh(x)); | ||||||
|  |  | ||||||
|  |         for (y = -2; y < 2; y += .2) { | ||||||
|  |             if (fabs(x) < 0.01) break; | ||||||
|  |             cross_check("atan2(x,y)", atan2(x, y)); | ||||||
|  |             cross_check("pow(x,y)", pow(x, y)); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -351,10 +351,10 @@ void test_dynamic() { | |||||||
|     te_variable lookup[] = { |     te_variable lookup[] = { | ||||||
|         {"x", &x}, |         {"x", &x}, | ||||||
|         {"f", &f}, |         {"f", &f}, | ||||||
|         {"test0", test0, TE_FUN | 0}, |         {"test0", test0, TE_FUNCTION0}, | ||||||
|         {"test1", test1, TE_FUN | 1}, |         {"test1", test1, TE_FUNCTION1}, | ||||||
|         {"test2", test2, TE_FUN | 2}, |         {"test2", test2, TE_FUNCTION2}, | ||||||
|         {"test3", test3, TE_FUN | 3}, |         {"test3", test3, TE_FUNCTION3}, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     test_case cases[] = { |     test_case cases[] = { | ||||||
| @@ -366,7 +366,10 @@ void test_dynamic() { | |||||||
|         {"f+test0", 11}, |         {"f+test0", 11}, | ||||||
|         {"test0+test0", 12}, |         {"test0+test0", 12}, | ||||||
|         {"test0()+test0", 12}, |         {"test0()+test0", 12}, | ||||||
|  |         {"test0+test0()", 12}, | ||||||
|  |         {"test0()+(0)+test0()", 12}, | ||||||
|         {"test1 test0", 12}, |         {"test1 test0", 12}, | ||||||
|  |         {"test1(test0)", 12}, | ||||||
|         {"test1 f", 10}, |         {"test1 f", 10}, | ||||||
|         {"test1 x", 4}, |         {"test1 x", 4}, | ||||||
|         {"test2 (test0, x)", 8}, |         {"test2 (test0, x)", 8}, | ||||||
|   | |||||||
							
								
								
									
										147
									
								
								tinyexpr.c
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								tinyexpr.c
									
									
									
									
									
								
							| @@ -29,12 +29,17 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  |  | ||||||
|  |  | ||||||
| enum {TOK_NULL, TOK_END, TOK_OPEN, TOK_CLOSE, TOK_NUMBER, TOK_INFIX, | #define TE_MASK_ARIT 0x00000007 /* Three bits, Arity, max is 8 */ | ||||||
|     TOK_VARIABLE, TOK_SEP, TOK_ERROR, TOK_FUNCTION0, TOK_FUNCTION1, | #define TE_FLAG_TYPE 0x00000018 /* Two bits, 1 = constant, 2 = variable, 3 = function */ | ||||||
|     TOK_FUNCTION2, TOK_FUNCTION3, TOK_FUNCTION4, TOK_FUNCTION5, TOK_FUNCTION6, |  | ||||||
|     TOK_FUNCTION7 | enum { | ||||||
|  |     TOK_NULL, TOK_ERROR, TOK_END, TOK_SEP, | ||||||
|  |     TOK_OPEN, TOK_CLOSE, TOK_NUMBER, TOK_VARIABLE, TOK_INFIX, | ||||||
|  |     TOK_FUNCTION0, TOK_FUNCTION1, TOK_FUNCTION2, TOK_FUNCTION3, | ||||||
|  |     TOK_FUNCTION4, TOK_FUNCTION5, TOK_FUNCTION6, TOK_FUNCTION7 | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | enum { TE_CONSTANT = TE_FUNCTION7+1}; | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct state { | typedef struct state { | ||||||
| @@ -48,26 +53,14 @@ typedef struct state { | |||||||
| } state; | } state; | ||||||
|  |  | ||||||
|  |  | ||||||
| static int te_get_type(const int type) { |  | ||||||
|     if(type == 0) return TE_VAR; |  | ||||||
|     return type & TE_FLAG_TYPE; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static int te_get_arity(const int type) { |  | ||||||
|     return type & TE_MASK_ARIT; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | #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 *members[]) { | ||||||
|     int member_count = te_get_arity(type); |     const int arity = ARITY(type); | ||||||
|     size_t member_size = sizeof(te_expr*) * member_count; |     te_expr *ret = malloc(sizeof(te_expr) + sizeof(te_expr*) * arity); | ||||||
|     te_expr *ret = malloc(sizeof(te_expr) + member_size); |     if (arity && members) { | ||||||
|     ret->member_count = member_count; |         memcpy(ret->members, members, sizeof(te_expr*) * arity); | ||||||
|     if(!members) { |  | ||||||
|         memset(ret->members, 0, member_size); |  | ||||||
|     } else { |  | ||||||
|         memcpy(ret->members, members, member_size); |  | ||||||
|     } |     } | ||||||
|     ret->type = type; |     ret->type = type; | ||||||
|     ret->bound = 0; |     ret->bound = 0; | ||||||
| @@ -76,9 +69,16 @@ static te_expr *new_expr(const int type, const te_expr *members[]) { | |||||||
|  |  | ||||||
|  |  | ||||||
| void te_free(te_expr *n) { | void te_free(te_expr *n) { | ||||||
|     int i; |  | ||||||
|     if (!n) return; |     if (!n) return; | ||||||
|     for(i = n->member_count - 1; i >= 0; i--) te_free(n->members[i]); |     switch (n->type) { | ||||||
|  |         case TE_FUNCTION7: te_free(n->members[6]); | ||||||
|  |         case TE_FUNCTION6: te_free(n->members[5]); | ||||||
|  |         case TE_FUNCTION5: te_free(n->members[4]); | ||||||
|  |         case TE_FUNCTION4: te_free(n->members[3]); | ||||||
|  |         case TE_FUNCTION3: te_free(n->members[2]); | ||||||
|  |         case TE_FUNCTION2: te_free(n->members[1]); | ||||||
|  |         case TE_FUNCTION1: te_free(n->members[0]); | ||||||
|  |     } | ||||||
|     free(n); |     free(n); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -88,26 +88,26 @@ static const double e  = 2.71828182845904523536; | |||||||
|  |  | ||||||
| static const te_variable functions[] = { | static const te_variable functions[] = { | ||||||
|     /* must be in alphabetical order */ |     /* must be in alphabetical order */ | ||||||
|     {"abs", fabs,     TE_FUN | 1}, |     {"abs", fabs,     TE_FUNCTION1}, | ||||||
|     {"acos", acos,    TE_FUN | 1}, |     {"acos", acos,    TE_FUNCTION1}, | ||||||
|     {"asin", asin,    TE_FUN | 1}, |     {"asin", asin,    TE_FUNCTION1}, | ||||||
|     {"atan", atan,    TE_FUN | 1}, |     {"atan", atan,    TE_FUNCTION1}, | ||||||
|     {"atan2", atan2,  TE_FUN | 2}, |     {"atan2", atan2,  TE_FUNCTION2}, | ||||||
|     {"ceil", ceil,    TE_FUN | 1}, |     {"ceil", ceil,    TE_FUNCTION1}, | ||||||
|     {"cos", cos,      TE_FUN | 1}, |     {"cos", cos,      TE_FUNCTION1}, | ||||||
|     {"cosh", cosh,    TE_FUN | 1}, |     {"cosh", cosh,    TE_FUNCTION1}, | ||||||
|     {"e", &e,         TE_VAR}, |     {"e", &e,         TE_VARIABLE}, | ||||||
|     {"exp", exp,      TE_FUN | 1}, |     {"exp", exp,      TE_FUNCTION1}, | ||||||
|     {"floor", floor,  TE_FUN | 1}, |     {"floor", floor,  TE_FUNCTION1}, | ||||||
|     {"ln", log,       TE_FUN | 1}, |     {"ln", log,       TE_FUNCTION1}, | ||||||
|     {"log", log10,    TE_FUN | 1}, |     {"log", log10,    TE_FUNCTION1}, | ||||||
|     {"pi", &pi,       TE_VAR}, |     {"pi", &pi,       TE_VARIABLE}, | ||||||
|     {"pow", pow,      TE_FUN | 2}, |     {"pow", pow,      TE_FUNCTION2}, | ||||||
|     {"sin", sin,      TE_FUN | 1}, |     {"sin", sin,      TE_FUNCTION1}, | ||||||
|     {"sinh", sinh,    TE_FUN | 1}, |     {"sinh", sinh,    TE_FUNCTION1}, | ||||||
|     {"sqrt", sqrt,    TE_FUN | 1}, |     {"sqrt", sqrt,    TE_FUNCTION1}, | ||||||
|     {"tan", tan,      TE_FUN | 1}, |     {"tan", tan,      TE_FUNCTION1}, | ||||||
|     {"tanh", tanh,    TE_FUN | 1}, |     {"tanh", tanh,    TE_FUNCTION1}, | ||||||
|     {0} |     {0} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -132,7 +132,6 @@ static const te_variable *find_builtin(const char *name, int len) { | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| static const te_variable *find_lookup(const state *s, const char *name, int len) { | static const te_variable *find_lookup(const state *s, const char *name, int len) { | ||||||
|     int i; |     int i; | ||||||
|     if (!s->lookup) return 0; |     if (!s->lookup) return 0; | ||||||
| @@ -171,7 +170,6 @@ void next_token(state *s) { | |||||||
|         } else { |         } else { | ||||||
|             /* Look for a variable or builtin function call. */ |             /* Look for a variable or builtin function call. */ | ||||||
|             if (s->next[0] >= 'a' && s->next[0] <= 'z') { |             if (s->next[0] >= 'a' && s->next[0] <= 'z') { | ||||||
|                 int arity, type; |  | ||||||
|                 const char *start; |                 const char *start; | ||||||
|                 start = s->next; |                 start = s->next; | ||||||
|                 while ((s->next[0] >= 'a' && s->next[0] <= 'z') || (s->next[0] >= '0' && s->next[0] <= '9')) s->next++; |                 while ((s->next[0] >= 'a' && s->next[0] <= 'z') || (s->next[0] >= '0' && s->next[0] <= '9')) s->next++; | ||||||
| @@ -182,16 +180,15 @@ void next_token(state *s) { | |||||||
|                 if (!var) { |                 if (!var) { | ||||||
|                     s->type = TOK_ERROR; |                     s->type = TOK_ERROR; | ||||||
|                 } else { |                 } else { | ||||||
|                     type = te_get_type(var->type); |                     switch(var->type) | ||||||
|                     arity = te_get_arity(var->type); |  | ||||||
|                     switch(type) |  | ||||||
|                     { |                     { | ||||||
|                         case TE_VAR: |                         case TE_VARIABLE: | ||||||
|                             s->type = TOK_VARIABLE; |                             s->type = TOK_VARIABLE; | ||||||
|                             s->bound = var->value; break; |                             s->bound = var->address; break; | ||||||
|                         case TE_FUN: |                         case TE_FUNCTION0: case TE_FUNCTION1: case TE_FUNCTION2: case TE_FUNCTION3: | ||||||
|                             s->type = TOK_FUNCTION0 + arity; |                         case TE_FUNCTION4: case TE_FUNCTION5: case TE_FUNCTION6: case TE_FUNCTION7: | ||||||
|                             s->fun.f0 = (void*)var->value; |                             s->type = TOK_FUNCTION0 + ARITY(var->type); | ||||||
|  |                             s->fun.f0 = (void*)var->address; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -227,19 +224,19 @@ static te_expr *base(state *s) { | |||||||
|  |  | ||||||
|     switch (s->type) { |     switch (s->type) { | ||||||
|         case TOK_NUMBER: |         case TOK_NUMBER: | ||||||
|             ret = new_expr(TE_CONST, 0); |             ret = new_expr(TE_CONSTANT, 0); | ||||||
|             ret->value = s->value; |             ret->value = s->value; | ||||||
|             next_token(s); |             next_token(s); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case TOK_VARIABLE: |         case TOK_VARIABLE: | ||||||
|             ret = new_expr(TE_VAR, 0); |             ret = new_expr(TE_VARIABLE, 0); | ||||||
|             ret->bound = s->bound; |             ret->bound = s->bound; | ||||||
|             next_token(s); |             next_token(s); | ||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case TOK_FUNCTION0: |         case TOK_FUNCTION0: | ||||||
|             ret = new_expr(TE_FUN, 0); |             ret = new_expr(TE_FUNCTION0, 0); | ||||||
|             ret->fun.f0 = s->fun.f0; |             ret->fun.f0 = s->fun.f0; | ||||||
|             next_token(s); |             next_token(s); | ||||||
|             if (s->type == TOK_OPEN) { |             if (s->type == TOK_OPEN) { | ||||||
| @@ -253,7 +250,7 @@ static te_expr *base(state *s) { | |||||||
|             break; |             break; | ||||||
|  |  | ||||||
|         case TOK_FUNCTION1: |         case TOK_FUNCTION1: | ||||||
|             ret = new_expr(TE_FUN | 1, 0); |             ret = new_expr(TE_FUNCTION1, 0); | ||||||
|             ret->fun.f0 = s->fun.f0; |             ret->fun.f0 = s->fun.f0; | ||||||
|  |  | ||||||
|             next_token(s); |             next_token(s); | ||||||
| @@ -264,7 +261,7 @@ static te_expr *base(state *s) { | |||||||
|         case TOK_FUNCTION5: case TOK_FUNCTION6: case TOK_FUNCTION7: |         case TOK_FUNCTION5: case TOK_FUNCTION6: case TOK_FUNCTION7: | ||||||
|             arity = s->type - TOK_FUNCTION0; |             arity = s->type - TOK_FUNCTION0; | ||||||
|  |  | ||||||
|             ret = new_expr(TE_FUN | arity, 0); |             ret = new_expr(TE_FUNCTION0 + arity, 0); | ||||||
|             ret->fun.f0 = s->fun.f0; |             ret->fun.f0 = s->fun.f0; | ||||||
|             next_token(s); |             next_token(s); | ||||||
|  |  | ||||||
| @@ -322,7 +319,7 @@ static te_expr *power(state *s) { | |||||||
|     if (sign == 1) { |     if (sign == 1) { | ||||||
|         ret = base(s); |         ret = base(s); | ||||||
|     } else { |     } else { | ||||||
|         ret = new_expr(TE_FUN | 1, (const te_expr*[]){base(s)}); |         ret = new_expr(TE_FUNCTION1, (const te_expr*[]){base(s)}); | ||||||
|         ret->fun.f1 = negate; |         ret->fun.f1 = negate; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -337,7 +334,7 @@ static te_expr *factor(state *s) { | |||||||
|     while (s->type == TOK_INFIX && (s->fun.f2 == pow)) { |     while (s->type == TOK_INFIX && (s->fun.f2 == pow)) { | ||||||
|         te_fun2 t = s->fun.f2; |         te_fun2 t = s->fun.f2; | ||||||
|         next_token(s); |         next_token(s); | ||||||
|         ret = new_expr(TE_FUN | 2, (const te_expr*[]){ret, power(s)}); |         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, power(s)}); | ||||||
|         ret->fun.f2 = t; |         ret->fun.f2 = t; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -352,7 +349,7 @@ static te_expr *term(state *s) { | |||||||
|     while (s->type == TOK_INFIX && (s->fun.f2 == mul || s->fun.f2 == divide || s->fun.f2 == fmod)) { |     while (s->type == TOK_INFIX && (s->fun.f2 == mul || s->fun.f2 == divide || s->fun.f2 == fmod)) { | ||||||
|         te_fun2 t = s->fun.f2; |         te_fun2 t = s->fun.f2; | ||||||
|         next_token(s); |         next_token(s); | ||||||
|         ret = new_expr(TE_FUN | 2, (const te_expr*[]){ret, factor(s)}); |         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, factor(s)}); | ||||||
|         ret->fun.f2 = t; |         ret->fun.f2 = t; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -367,7 +364,7 @@ static te_expr *expr(state *s) { | |||||||
|     while (s->type == TOK_INFIX && (s->fun.f2 == add || s->fun.f2 == sub)) { |     while (s->type == TOK_INFIX && (s->fun.f2 == add || s->fun.f2 == sub)) { | ||||||
|         te_fun2 t = s->fun.f2; |         te_fun2 t = s->fun.f2; | ||||||
|         next_token(s); |         next_token(s); | ||||||
|         ret = new_expr(TE_FUN | 2, (const te_expr*[]){ret, term(s)}); |         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, term(s)}); | ||||||
|         ret->fun.f2 = t; |         ret->fun.f2 = t; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -381,7 +378,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_FUN | 2, (const te_expr*[]){ret, expr(s)}); |         ret = new_expr(TE_FUNCTION2, (const te_expr*[]){ret, expr(s)}); | ||||||
|         ret->fun.f2 = comma; |         ret->fun.f2 = comma; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -390,11 +387,14 @@ static te_expr *list(state *s) { | |||||||
|  |  | ||||||
|  |  | ||||||
| double te_eval(const te_expr *n) { | double te_eval(const te_expr *n) { | ||||||
|     switch(te_get_type(n->type)) { |     if (!n) return 0.0/0.0; | ||||||
|         case TE_CONST: return n->value; |  | ||||||
|         case TE_VAR: return *n->bound; |     switch(n->type) { | ||||||
|         case TE_FUN: |         case TE_CONSTANT: return n->value; | ||||||
|         switch(te_get_arity(n->type)) { |         case TE_VARIABLE: return *n->bound; | ||||||
|  |         case TE_FUNCTION0: case TE_FUNCTION1: case TE_FUNCTION2: case TE_FUNCTION3: | ||||||
|  |         case TE_FUNCTION4: case TE_FUNCTION5: case TE_FUNCTION6: case TE_FUNCTION7: | ||||||
|  |         switch(ARITY(n->type)) { | ||||||
|             #define m(e) te_eval(n->members[e]) |             #define m(e) te_eval(n->members[e]) | ||||||
|             case 0: return n->fun.f0(); |             case 0: return n->fun.f0(); | ||||||
|             case 1: return n->fun.f1(m(0)); |             case 1: return n->fun.f1(m(0)); | ||||||
| @@ -482,11 +482,12 @@ static void pn (const te_expr *n, int depth) { | |||||||
|     int i, arity; |     int i, arity; | ||||||
|     printf("%*s", depth, ""); |     printf("%*s", depth, ""); | ||||||
|  |  | ||||||
|     switch(te_get_type(n->type)) { |     switch(n->type) { | ||||||
|     case TE_CONST: printf("%f\n", n->value); break; |     case TE_CONSTANT: printf("%f\n", n->value); break; | ||||||
|     case TE_VAR: printf("bound %p\n", n->bound); break; |     case TE_VARIABLE: printf("bound %p\n", n->bound); break; | ||||||
|     case TE_FUN: |     case TE_FUNCTION0: case TE_FUNCTION1: case TE_FUNCTION2: case TE_FUNCTION3: | ||||||
|          arity = te_get_arity(n->type); |     case TE_FUNCTION4: case TE_FUNCTION5: case TE_FUNCTION6: case TE_FUNCTION7: | ||||||
|  |          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->members[i]); | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								tinyexpr.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tinyexpr.h
									
									
									
									
									
								
							| @@ -47,20 +47,20 @@ typedef union | |||||||
|  |  | ||||||
| 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; te_fun fun;}; | ||||||
|     int member_count; |  | ||||||
|     struct te_expr *members[]; |     struct te_expr *members[]; | ||||||
| } te_expr; | } te_expr; | ||||||
|  |  | ||||||
|  |  | ||||||
| #define TE_MASK_ARIT 0x00000007 /* Three bits, Arity, max is 8 */ | enum { | ||||||
| #define TE_FLAG_TYPE 0x00000018 /* Two bits, 1 = constant, 2 = variable, 3 = function */ |     TE_VARIABLE = 0, | ||||||
|  |     TE_FUNCTION0, TE_FUNCTION1, TE_FUNCTION2, TE_FUNCTION3, | ||||||
| enum { TE_CONST = 1 << 3, TE_VAR = 2 << 3, TE_FUN = 3 << 3}; |     TE_FUNCTION4, TE_FUNCTION5, TE_FUNCTION6, TE_FUNCTION7 | ||||||
|  | }; | ||||||
|  |  | ||||||
| typedef struct te_variable { | typedef struct te_variable { | ||||||
|     const char *name; |     const char *name; | ||||||
|     const void *value; |     const void *address; | ||||||
|     int type; |     int type; | ||||||
| } te_variable; | } te_variable; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user