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