tinyexpr.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. // SPDX-License-Identifier: Zlib
  2. /*
  3. * TINYEXPR - Tiny recursive descent parser and evaluation engine in C
  4. *
  5. * Copyright (c) 2015-2020 Lewis Van Winkle
  6. *
  7. * http://CodePlea.com
  8. *
  9. * This software is provided 'as-is', without any express or implied
  10. * warranty. In no event will the authors be held liable for any damages
  11. * arising from the use of this software.
  12. *
  13. * Permission is granted to anyone to use this software for any purpose,
  14. * including commercial applications, and to alter it and redistribute it
  15. * freely, subject to the following restrictions:
  16. *
  17. * 1. The origin of this software must not be misrepresented; you must not
  18. * claim that you wrote the original software. If you use this software
  19. * in a product, an acknowledgement in the product documentation would be
  20. * appreciated but is not required.
  21. * 2. Altered source versions must be plainly marked as such, and must not be
  22. * misrepresented as being the original software.
  23. * 3. This notice may not be removed or altered from any source distribution.
  24. */
  25. /* COMPILE TIME OPTIONS */
  26. /* Exponentiation associativity:
  27. For a^b^c = (a^b)^c and -a^b = (-a)^b do nothing.
  28. For a^b^c = a^(b^c) and -a^b = -(a^b) uncomment the next line.*/
  29. /* #define TE_POW_FROM_RIGHT */
  30. /* Logarithms
  31. For log = base 10 log do nothing
  32. For log = natural log uncomment the next line. */
  33. /* #define TE_NAT_LOG */
  34. #include "tinyexpr.h"
  35. #include <stdlib.h>
  36. #include <math.h>
  37. #include <string.h>
  38. #include <stdio.h>
  39. #include <ctype.h>
  40. #include <limits.h>
  41. #ifndef NAN
  42. #define NAN (0.0 / 0.0)
  43. #endif
  44. #ifndef INFINITY
  45. #define INFINITY (1.0 / 0.0)
  46. #endif
  47. typedef double (*te_fun2)(double, double);
  48. enum {
  49. TOK_NULL = TE_CLOSURE7 + 1,
  50. TOK_ERROR,
  51. TOK_END,
  52. TOK_SEP,
  53. TOK_OPEN,
  54. TOK_CLOSE,
  55. TOK_NUMBER,
  56. TOK_VARIABLE,
  57. TOK_INFIX
  58. };
  59. enum {
  60. TE_CONSTANT = 1
  61. };
  62. typedef struct state {
  63. const char* start;
  64. const char* next;
  65. int type;
  66. union {
  67. double value;
  68. const double* bound;
  69. const void* function;
  70. };
  71. void* context;
  72. const te_variable* lookup;
  73. int lookup_len;
  74. } state;
  75. #define TYPE_MASK(TYPE) ((TYPE) & 0x0000001F)
  76. #define IS_PURE(TYPE) (((TYPE) & TE_FLAG_PURE) != 0)
  77. #define IS_FUNCTION(TYPE) (((TYPE) & TE_FUNCTION0) != 0)
  78. #define IS_CLOSURE(TYPE) (((TYPE) & TE_CLOSURE0) != 0)
  79. #define ARITY(TYPE) (((TYPE) & (TE_FUNCTION0 | TE_CLOSURE0)) ? ((TYPE) & 0x00000007) : 0)
  80. #define NEW_EXPR(type, ...) new_expr((type), (const te_expr*[]){__VA_ARGS__})
  81. static te_expr* new_expr(const int type, const te_expr* parameters[]) {
  82. const int arity = ARITY(type);
  83. const int psize = sizeof(void*) * arity;
  84. const int size =
  85. (sizeof(te_expr) - sizeof(void*)) + psize + (IS_CLOSURE(type) ? sizeof(void*) : 0);
  86. te_expr* ret = malloc(size);
  87. memset(ret, 0, size);
  88. if(arity && parameters) {
  89. memcpy(ret->parameters, parameters, psize);
  90. }
  91. ret->type = type;
  92. ret->bound = 0;
  93. return ret;
  94. }
  95. void te_free_parameters(te_expr* n) {
  96. if(!n) return;
  97. switch(TYPE_MASK(n->type)) {
  98. case TE_FUNCTION7:
  99. case TE_CLOSURE7:
  100. te_free(n->parameters[6]); /* Falls through. */
  101. case TE_FUNCTION6:
  102. case TE_CLOSURE6:
  103. te_free(n->parameters[5]); /* Falls through. */
  104. case TE_FUNCTION5:
  105. case TE_CLOSURE5:
  106. te_free(n->parameters[4]); /* Falls through. */
  107. case TE_FUNCTION4:
  108. case TE_CLOSURE4:
  109. te_free(n->parameters[3]); /* Falls through. */
  110. case TE_FUNCTION3:
  111. case TE_CLOSURE3:
  112. te_free(n->parameters[2]); /* Falls through. */
  113. case TE_FUNCTION2:
  114. case TE_CLOSURE2:
  115. te_free(n->parameters[1]); /* Falls through. */
  116. case TE_FUNCTION1:
  117. case TE_CLOSURE1:
  118. te_free(n->parameters[0]);
  119. }
  120. }
  121. void te_free(te_expr* n) {
  122. if(!n) return;
  123. te_free_parameters(n);
  124. free(n);
  125. }
  126. static double pi(void) {
  127. return 3.14159265358979323846;
  128. }
  129. static double e(void) {
  130. return 2.71828182845904523536;
  131. }
  132. static double fac(double a) { /* simplest version of fac */
  133. if(a < (double)0.0) return NAN;
  134. if(a > UINT_MAX) return INFINITY;
  135. unsigned int ua = (unsigned int)(a);
  136. unsigned long int result = 1, i;
  137. for(i = 1; i <= ua; i++) {
  138. if(i > ULONG_MAX / result) return INFINITY;
  139. result *= i;
  140. }
  141. return (double)result;
  142. }
  143. static double ncr(double n, double r) {
  144. if(n < (double)0.0 || r < (double)0.0 || n < r) return NAN;
  145. if(n > UINT_MAX || r > UINT_MAX) return INFINITY;
  146. unsigned long int un = (unsigned int)(n), ur = (unsigned int)(r), i;
  147. unsigned long int result = 1;
  148. if(ur > un / 2) ur = un - ur;
  149. for(i = 1; i <= ur; i++) {
  150. if(result > ULONG_MAX / (un - ur + i)) return INFINITY;
  151. result *= un - ur + i;
  152. result /= i;
  153. }
  154. return result;
  155. }
  156. static double npr(double n, double r) {
  157. return ncr(n, r) * fac(r);
  158. }
  159. #ifdef _MSC_VER
  160. #pragma function(ceil)
  161. #pragma function(floor)
  162. #endif
  163. static const te_variable functions[] = {
  164. /* must be in alphabetical order */
  165. {"abs", fabs, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  166. {"acos", acos, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  167. {"asin", asin, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  168. {"atan", atan, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  169. {"atan2", atan2, TE_FUNCTION2 | TE_FLAG_PURE, 0},
  170. {"ceil", ceil, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  171. {"cos", cos, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  172. {"cosh", cosh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  173. {"e", e, TE_FUNCTION0 | TE_FLAG_PURE, 0},
  174. {"exp", exp, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  175. {"fac", fac, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  176. {"floor", floor, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  177. {"ln", log, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  178. #ifdef TE_NAT_LOG
  179. {"log", log, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  180. #else
  181. {"log", log10, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  182. #endif
  183. {"log10", log10, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  184. {"ncr", ncr, TE_FUNCTION2 | TE_FLAG_PURE, 0},
  185. {"npr", npr, TE_FUNCTION2 | TE_FLAG_PURE, 0},
  186. {"pi", pi, TE_FUNCTION0 | TE_FLAG_PURE, 0},
  187. {"pow", pow, TE_FUNCTION2 | TE_FLAG_PURE, 0},
  188. {"sin", sin, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  189. {"sinh", sinh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  190. {"sqrt", sqrt, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  191. {"tan", tan, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  192. {"tanh", tanh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  193. {0, 0, 0, 0}};
  194. static const te_variable* find_builtin(const char* name, int len) {
  195. int imin = 0;
  196. int imax = sizeof(functions) / sizeof(te_variable) - 2;
  197. /*Binary search.*/
  198. while(imax >= imin) {
  199. const int i = (imin + ((imax - imin) / 2));
  200. int c = strncmp(name, functions[i].name, len);
  201. if(!c) c = '\0' - functions[i].name[len];
  202. if(c == 0) {
  203. return functions + i;
  204. } else if(c > 0) {
  205. imin = i + 1;
  206. } else {
  207. imax = i - 1;
  208. }
  209. }
  210. return 0;
  211. }
  212. static const te_variable* find_lookup(const state* s, const char* name, int len) {
  213. int iters;
  214. const te_variable* var;
  215. if(!s->lookup) return 0;
  216. for(var = s->lookup, iters = s->lookup_len; iters; ++var, --iters) {
  217. if(strncmp(name, var->name, len) == 0 && var->name[len] == '\0') {
  218. return var;
  219. }
  220. }
  221. return 0;
  222. }
  223. static double add(double a, double b) {
  224. return a + b;
  225. }
  226. static double sub(double a, double b) {
  227. return a - b;
  228. }
  229. static double mul(double a, double b) {
  230. return a * b;
  231. }
  232. static double divide(double a, double b) {
  233. return a / b;
  234. }
  235. static double negate(double a) {
  236. return -a;
  237. }
  238. static double comma(double a, double b) {
  239. (void)a;
  240. return b;
  241. }
  242. void next_token(state* s) {
  243. s->type = TOK_NULL;
  244. do {
  245. if(!*s->next) {
  246. s->type = TOK_END;
  247. return;
  248. }
  249. /* Try reading a number. */
  250. if((s->next[0] >= '0' && s->next[0] <= '9') || s->next[0] == '.') {
  251. s->value = strtof(s->next, (char**)&s->next);
  252. s->type = TOK_NUMBER;
  253. } else {
  254. /* Look for a variable or builtin function call. */
  255. if(isalpha((int)s->next[0])) {
  256. const char* start;
  257. start = s->next;
  258. while(isalpha((int)s->next[0]) || isdigit((int)s->next[0]) || (s->next[0] == '_'))
  259. s->next++;
  260. const te_variable* var = find_lookup(s, start, s->next - start);
  261. if(!var) var = find_builtin(start, s->next - start);
  262. if(!var) {
  263. s->type = TOK_ERROR;
  264. } else {
  265. switch(TYPE_MASK(var->type)) {
  266. case TE_VARIABLE:
  267. s->type = TOK_VARIABLE;
  268. s->bound = var->address;
  269. break;
  270. case TE_CLOSURE0:
  271. case TE_CLOSURE1:
  272. case TE_CLOSURE2:
  273. case TE_CLOSURE3: /* Falls through. */
  274. case TE_CLOSURE4:
  275. case TE_CLOSURE5:
  276. case TE_CLOSURE6:
  277. case TE_CLOSURE7: /* Falls through. */
  278. s->context = var->context; /* Falls through. */
  279. case TE_FUNCTION0:
  280. case TE_FUNCTION1:
  281. case TE_FUNCTION2:
  282. case TE_FUNCTION3: /* Falls through. */
  283. case TE_FUNCTION4:
  284. case TE_FUNCTION5:
  285. case TE_FUNCTION6:
  286. case TE_FUNCTION7: /* Falls through. */
  287. s->type = var->type;
  288. s->function = var->address;
  289. break;
  290. }
  291. }
  292. } else {
  293. /* Look for an operator or special character. */
  294. switch(s->next++[0]) {
  295. case '+':
  296. s->type = TOK_INFIX;
  297. s->function = add;
  298. break;
  299. case '-':
  300. s->type = TOK_INFIX;
  301. s->function = sub;
  302. break;
  303. case '*':
  304. s->type = TOK_INFIX;
  305. s->function = mul;
  306. break;
  307. case '/':
  308. s->type = TOK_INFIX;
  309. s->function = divide;
  310. break;
  311. case '^':
  312. s->type = TOK_INFIX;
  313. s->function = pow;
  314. break;
  315. case '%':
  316. s->type = TOK_INFIX;
  317. s->function = fmod;
  318. break;
  319. case '(':
  320. s->type = TOK_OPEN;
  321. break;
  322. case ')':
  323. s->type = TOK_CLOSE;
  324. break;
  325. case ',':
  326. s->type = TOK_SEP;
  327. break;
  328. case ' ':
  329. case '\t':
  330. case '\n':
  331. case '\r':
  332. break;
  333. default:
  334. s->type = TOK_ERROR;
  335. break;
  336. }
  337. }
  338. }
  339. } while(s->type == TOK_NULL);
  340. }
  341. static te_expr* list(state* s);
  342. static te_expr* expr(state* s);
  343. static te_expr* power(state* s);
  344. static te_expr* base(state* s) {
  345. /* <base> = <constant> | <variable> | <function-0> {"(" ")"} | <function-1> <power> | <function-X> "(" <expr> {"," <expr>} ")" | "(" <list> ")" */
  346. te_expr* ret;
  347. int arity;
  348. switch(TYPE_MASK(s->type)) {
  349. case TOK_NUMBER:
  350. ret = new_expr(TE_CONSTANT, 0);
  351. ret->value = s->value;
  352. next_token(s);
  353. break;
  354. case TOK_VARIABLE:
  355. ret = new_expr(TE_VARIABLE, 0);
  356. ret->bound = s->bound;
  357. next_token(s);
  358. break;
  359. case TE_FUNCTION0:
  360. case TE_CLOSURE0:
  361. ret = new_expr(s->type, 0);
  362. ret->function = s->function;
  363. if(IS_CLOSURE(s->type)) ret->parameters[0] = s->context;
  364. next_token(s);
  365. if(s->type == TOK_OPEN) {
  366. next_token(s);
  367. if(s->type != TOK_CLOSE) {
  368. s->type = TOK_ERROR;
  369. } else {
  370. next_token(s);
  371. }
  372. }
  373. break;
  374. case TE_FUNCTION1:
  375. case TE_CLOSURE1:
  376. ret = new_expr(s->type, 0);
  377. ret->function = s->function;
  378. if(IS_CLOSURE(s->type)) ret->parameters[1] = s->context;
  379. next_token(s);
  380. ret->parameters[0] = power(s);
  381. break;
  382. case TE_FUNCTION2:
  383. case TE_FUNCTION3:
  384. case TE_FUNCTION4:
  385. case TE_FUNCTION5:
  386. case TE_FUNCTION6:
  387. case TE_FUNCTION7:
  388. case TE_CLOSURE2:
  389. case TE_CLOSURE3:
  390. case TE_CLOSURE4:
  391. case TE_CLOSURE5:
  392. case TE_CLOSURE6:
  393. case TE_CLOSURE7:
  394. arity = ARITY(s->type);
  395. ret = new_expr(s->type, 0);
  396. ret->function = s->function;
  397. if(IS_CLOSURE(s->type)) ret->parameters[arity] = s->context;
  398. next_token(s);
  399. if(s->type != TOK_OPEN) {
  400. s->type = TOK_ERROR;
  401. } else {
  402. int i;
  403. for(i = 0; i < arity; i++) {
  404. next_token(s);
  405. ret->parameters[i] = expr(s);
  406. if(s->type != TOK_SEP) {
  407. break;
  408. }
  409. }
  410. if(s->type != TOK_CLOSE || i != arity - 1) {
  411. s->type = TOK_ERROR;
  412. } else {
  413. next_token(s);
  414. }
  415. }
  416. break;
  417. case TOK_OPEN:
  418. next_token(s);
  419. ret = list(s);
  420. if(s->type != TOK_CLOSE) {
  421. s->type = TOK_ERROR;
  422. } else {
  423. next_token(s);
  424. }
  425. break;
  426. default:
  427. ret = new_expr(0, 0);
  428. s->type = TOK_ERROR;
  429. ret->value = NAN;
  430. break;
  431. }
  432. return ret;
  433. }
  434. static te_expr* power(state* s) {
  435. /* <power> = {("-" | "+")} <base> */
  436. int sign = 1;
  437. while(s->type == TOK_INFIX && (s->function == add || s->function == sub)) {
  438. if(s->function == sub) sign = -sign;
  439. next_token(s);
  440. }
  441. te_expr* ret;
  442. if(sign == 1) {
  443. ret = base(s);
  444. } else {
  445. ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, base(s));
  446. ret->function = negate;
  447. }
  448. return ret;
  449. }
  450. #ifdef TE_POW_FROM_RIGHT
  451. static te_expr* factor(state* s) {
  452. /* <factor> = <power> {"^" <power>} */
  453. te_expr* ret = power(s);
  454. int neg = 0;
  455. if(ret->type == (TE_FUNCTION1 | TE_FLAG_PURE) && ret->function == negate) {
  456. te_expr* se = ret->parameters[0];
  457. free(ret);
  458. ret = se;
  459. neg = 1;
  460. }
  461. te_expr* insertion = 0;
  462. while(s->type == TOK_INFIX && (s->function == pow)) {
  463. te_fun2 t = s->function;
  464. next_token(s);
  465. if(insertion) {
  466. /* Make exponentiation go right-to-left. */
  467. te_expr* insert =
  468. NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, insertion->parameters[1], power(s));
  469. insert->function = t;
  470. insertion->parameters[1] = insert;
  471. insertion = insert;
  472. } else {
  473. ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, power(s));
  474. ret->function = t;
  475. insertion = ret;
  476. }
  477. }
  478. if(neg) {
  479. ret = NEW_EXPR(TE_FUNCTION1 | TE_FLAG_PURE, ret);
  480. ret->function = negate;
  481. }
  482. return ret;
  483. }
  484. #else
  485. static te_expr* factor(state* s) {
  486. /* <factor> = <power> {"^" <power>} */
  487. te_expr* ret = power(s);
  488. while(s->type == TOK_INFIX && (s->function == pow)) {
  489. te_fun2 t = s->function;
  490. next_token(s);
  491. ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, power(s));
  492. ret->function = t;
  493. }
  494. return ret;
  495. }
  496. #endif
  497. static te_expr* term(state* s) {
  498. /* <term> = <factor> {("*" | "/" | "%") <factor>} */
  499. te_expr* ret = factor(s);
  500. while(s->type == TOK_INFIX &&
  501. (s->function == mul || s->function == divide || s->function == fmod)) {
  502. te_fun2 t = s->function;
  503. next_token(s);
  504. ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, factor(s));
  505. ret->function = t;
  506. }
  507. return ret;
  508. }
  509. static te_expr* expr(state* s) {
  510. /* <expr> = <term> {("+" | "-") <term>} */
  511. te_expr* ret = term(s);
  512. while(s->type == TOK_INFIX && (s->function == add || s->function == sub)) {
  513. te_fun2 t = s->function;
  514. next_token(s);
  515. ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, term(s));
  516. ret->function = t;
  517. }
  518. return ret;
  519. }
  520. static te_expr* list(state* s) {
  521. /* <list> = <expr> {"," <expr>} */
  522. te_expr* ret = expr(s);
  523. while(s->type == TOK_SEP) {
  524. next_token(s);
  525. ret = NEW_EXPR(TE_FUNCTION2 | TE_FLAG_PURE, ret, expr(s));
  526. ret->function = comma;
  527. }
  528. return ret;
  529. }
  530. #define TE_FUN(...) ((double (*)(__VA_ARGS__))n->function)
  531. #define M(e) te_eval(n->parameters[e])
  532. double te_eval(const te_expr* n) {
  533. if(!n) return NAN;
  534. switch(TYPE_MASK(n->type)) {
  535. case TE_CONSTANT:
  536. return n->value;
  537. case TE_VARIABLE:
  538. return *n->bound;
  539. case TE_FUNCTION0:
  540. case TE_FUNCTION1:
  541. case TE_FUNCTION2:
  542. case TE_FUNCTION3:
  543. case TE_FUNCTION4:
  544. case TE_FUNCTION5:
  545. case TE_FUNCTION6:
  546. case TE_FUNCTION7:
  547. switch(ARITY(n->type)) {
  548. case 0:
  549. return TE_FUN(void)();
  550. case 1:
  551. return TE_FUN(double)(M(0));
  552. case 2:
  553. return TE_FUN(double, double)(M(0), M(1));
  554. case 3:
  555. return TE_FUN(double, double, double)(M(0), M(1), M(2));
  556. case 4:
  557. return TE_FUN(double, double, double, double)(M(0), M(1), M(2), M(3));
  558. case 5:
  559. return TE_FUN(double, double, double, double, double)(M(0), M(1), M(2), M(3), M(4));
  560. case 6:
  561. return TE_FUN(double, double, double, double, double, double)(
  562. M(0), M(1), M(2), M(3), M(4), M(5));
  563. case 7:
  564. return TE_FUN(double, double, double, double, double, double, double)(
  565. M(0), M(1), M(2), M(3), M(4), M(5), M(6));
  566. default:
  567. return NAN;
  568. }
  569. case TE_CLOSURE0:
  570. case TE_CLOSURE1:
  571. case TE_CLOSURE2:
  572. case TE_CLOSURE3:
  573. case TE_CLOSURE4:
  574. case TE_CLOSURE5:
  575. case TE_CLOSURE6:
  576. case TE_CLOSURE7:
  577. switch(ARITY(n->type)) {
  578. case 0:
  579. return TE_FUN(void*)(n->parameters[0]);
  580. case 1:
  581. return TE_FUN(void*, double)(n->parameters[1], M(0));
  582. case 2:
  583. return TE_FUN(void*, double, double)(n->parameters[2], M(0), M(1));
  584. case 3:
  585. return TE_FUN(void*, double, double, double)(n->parameters[3], M(0), M(1), M(2));
  586. case 4:
  587. return TE_FUN(void*, double, double, double, double)(
  588. n->parameters[4], M(0), M(1), M(2), M(3));
  589. case 5:
  590. return TE_FUN(void*, double, double, double, double, double)(
  591. n->parameters[5], M(0), M(1), M(2), M(3), M(4));
  592. case 6:
  593. return TE_FUN(void*, double, double, double, double, double, double)(
  594. n->parameters[6], M(0), M(1), M(2), M(3), M(4), M(5));
  595. case 7:
  596. return TE_FUN(void*, double, double, double, double, double, double, double)(
  597. n->parameters[7], M(0), M(1), M(2), M(3), M(4), M(5), M(6));
  598. default:
  599. return NAN;
  600. }
  601. default:
  602. return NAN;
  603. }
  604. }
  605. #undef TE_FUN
  606. #undef M
  607. static void optimize(te_expr* n) {
  608. /* Evaluates as much as possible. */
  609. if(n->type == TE_CONSTANT) return;
  610. if(n->type == TE_VARIABLE) return;
  611. /* Only optimize out functions flagged as pure. */
  612. if(IS_PURE(n->type)) {
  613. const int arity = ARITY(n->type);
  614. int known = 1;
  615. int i;
  616. for(i = 0; i < arity; ++i) {
  617. optimize(n->parameters[i]);
  618. if(((te_expr*)(n->parameters[i]))->type != TE_CONSTANT) {
  619. known = 0;
  620. }
  621. }
  622. if(known) {
  623. const double value = te_eval(n);
  624. te_free_parameters(n);
  625. n->type = TE_CONSTANT;
  626. n->value = value;
  627. }
  628. }
  629. }
  630. te_expr*
  631. te_compile(const char* expression, const te_variable* variables, int var_count, int* error) {
  632. state s;
  633. s.start = s.next = expression;
  634. s.lookup = variables;
  635. s.lookup_len = var_count;
  636. next_token(&s);
  637. te_expr* root = list(&s);
  638. if(s.type != TOK_END) {
  639. te_free(root);
  640. if(error) {
  641. *error = (s.next - s.start);
  642. if(*error == 0) *error = 1;
  643. }
  644. return 0;
  645. } else {
  646. optimize(root);
  647. if(error) *error = 0;
  648. return root;
  649. }
  650. }
  651. double te_interp(const char* expression, int* error) {
  652. te_expr* n = te_compile(expression, 0, 0, error);
  653. double ret;
  654. if(n) {
  655. ret = te_eval(n);
  656. te_free(n);
  657. } else {
  658. ret = NAN;
  659. }
  660. return ret;
  661. }
  662. static void pn(const te_expr* n, int depth) {
  663. int i, arity;
  664. printf("%*s", depth, "");
  665. switch(TYPE_MASK(n->type)) {
  666. case TE_CONSTANT:
  667. printf("%f\n", n->value);
  668. break;
  669. case TE_VARIABLE:
  670. printf("bound %p\n", n->bound);
  671. break;
  672. case TE_FUNCTION0:
  673. case TE_FUNCTION1:
  674. case TE_FUNCTION2:
  675. case TE_FUNCTION3:
  676. case TE_FUNCTION4:
  677. case TE_FUNCTION5:
  678. case TE_FUNCTION6:
  679. case TE_FUNCTION7:
  680. case TE_CLOSURE0:
  681. case TE_CLOSURE1:
  682. case TE_CLOSURE2:
  683. case TE_CLOSURE3:
  684. case TE_CLOSURE4:
  685. case TE_CLOSURE5:
  686. case TE_CLOSURE6:
  687. case TE_CLOSURE7:
  688. arity = ARITY(n->type);
  689. printf("f%d", arity);
  690. for(i = 0; i < arity; i++) {
  691. printf(" %p", n->parameters[i]);
  692. }
  693. printf("\n");
  694. for(i = 0; i < arity; i++) {
  695. pn(n->parameters[i], depth + 1);
  696. }
  697. break;
  698. }
  699. }
  700. void te_print(const te_expr* n) {
  701. pn(n, 0);
  702. }