tinyexpr.c 21 KB

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