#include "tinyexpr.h"
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Go to the source code of this file.
|
| static te_expr * | new_expr (const int type, const te_expr *parameters[]) |
| |
| void | te_free_parameters (te_expr *n) |
| |
| void | te_free (te_expr *n) |
| |
| static double | pi (void) |
| |
| static double | e (void) |
| |
| static double | fac (double a) |
| |
| static double | ncr (double n, double r) |
| |
| static double | npr (double n, double r) |
| |
| static const te_variable * | find_builtin (const char *name, int len) |
| |
| static const te_variable * | find_lookup (const state *s, const char *name, int len) |
| |
| static double | add (double a, double b) |
| |
| static double | sub (double a, double b) |
| |
| static double | mul (double a, double b) |
| |
| static double | divide (double a, double b) |
| |
| static double | negate (double a) |
| |
| static double | comma (double a, double b) |
| |
| void | next_token (state *s) |
| |
| static te_expr * | list (state *s) |
| |
| static te_expr * | expr (state *s) |
| |
| static te_expr * | power (state *s) |
| |
| static te_expr * | base (state *s) |
| |
| static te_expr * | factor (state *s) |
| |
| static te_expr * | term (state *s) |
| |
| double | te_eval (const te_expr *n) |
| |
| static void | optimize (te_expr *n) |
| |
| te_expr * | te_compile (const char *expression, const te_variable *variables, int var_count, int *error) |
| |
| double | te_interp (const char *expression, int *error) |
| |
| static void | pn (const te_expr *n, int depth) |
| |
| void | te_print (const te_expr *n) |
| |
◆ ARITY
◆ INFINITY
| #define INFINITY (1.0 / 0.0) |
◆ IS_CLOSURE
| #define IS_CLOSURE |
( |
|
TYPE | ) |
(((TYPE) &TE_CLOSURE0) != 0) |
◆ IS_FUNCTION
◆ IS_PURE
◆ NAN
◆ NEW_EXPR
◆ TE_FUN
| #define TE_FUN |
( |
|
... | ) |
((double (*)(__VA_ARGS__)) n->function) |
◆ TYPE_MASK
| #define TYPE_MASK |
( |
|
TYPE | ) |
((TYPE) &0x0000001F) |
◆ state
◆ te_fun2
| typedef double(* te_fun2) (double, double) |
◆ anonymous enum
| Enumerator |
|---|
| TOK_NULL | |
| TOK_ERROR | |
| TOK_END | |
| TOK_SEP | |
| TOK_OPEN | |
| TOK_CLOSE | |
| TOK_NUMBER | |
| TOK_VARIABLE | |
| TOK_INFIX | |
Definition at line 56 of file tinyexpr.c.
◆ anonymous enum
◆ add()
| static double add |
( |
double |
a, |
|
|
double |
b |
|
) |
| |
|
static |
◆ base()
Definition at line 357 of file tinyexpr.c.
357 {
358
360 int arity;
361
367 break;
368
373 break;
374
386 } else {
388 }
389 }
390 break;
391
400 break;
401
415
421
424 } else {
426 for (
i = 0;
i < arity;
i++) {
430 break;
431 }
432 }
435 } else {
437 }
438 }
439
440 break;
441
447 } else {
449 }
450 break;
451
452 default:
456 break;
457 }
458
459 return ret;
460}
static te_expr * expr(state *s)
static te_expr * power(state *s)
void next_token(state *s)
static te_expr * new_expr(const int type, const te_expr *parameters[])
static te_expr * list(state *s)
◆ comma()
| static double comma |
( |
double |
a, |
|
|
double |
b |
|
) |
| |
|
static |
Definition at line 248 of file tinyexpr.c.
248 {
249 (void) a;
250 return b;
251}
◆ divide()
| static double divide |
( |
double |
a, |
|
|
double |
b |
|
) |
| |
|
static |
◆ e()
Definition at line 136 of file tinyexpr.c.
136{ return 2.71828182845904523536; }
◆ expr()
Definition at line 553 of file tinyexpr.c.
553 {
554
556
562 }
563
564 return ret;
565}
static te_expr * term(state *s)
static double sub(double a, double b)
double(* te_fun2)(double, double)
#define NEW_EXPR(type,...)
◆ fac()
| static double fac |
( |
double |
a | ) |
|
|
static |
Definition at line 137 of file tinyexpr.c.
137 {
138 if (a < 0.0)
140 if (a > UINT_MAX)
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)
148 }
149 return (double) result;
150}
◆ factor()
Definition at line 524 of file tinyexpr.c.
524 {
525
527
533 }
534
535 return ret;
536}
◆ find_builtin()
| static const te_variable * find_builtin |
( |
const char * |
name, |
|
|
int |
len |
|
) |
| |
|
static |
Definition at line 207 of file tinyexpr.c.
207 {
208 int imin = 0;
210
211
212 while (imax >= imin) {
213 const int i = (imin + ((imax - imin) / 2));
221 } else {
223 }
224 }
225
226 return 0;
227}
static const te_variable functions[]
◆ find_lookup()
| static const te_variable * find_lookup |
( |
const state * |
s, |
|
|
const char * |
name, |
|
|
int |
len |
|
) |
| |
|
static |
Definition at line 229 of file tinyexpr.c.
229 {
230 int iters;
233 return 0;
234
236 if (strncmp(
name, var->
name, len) == 0 && var->
name[len] ==
'\0') {
237 return var;
238 }
239 }
240 return 0;
241}
const te_variable * lookup
◆ list()
Definition at line 567 of file tinyexpr.c.
567 {
568
570
575 }
576
577 return ret;
578}
static double comma(double a, double b)
◆ mul()
| static double mul |
( |
double |
a, |
|
|
double |
b |
|
) |
| |
|
static |
◆ ncr()
| static double ncr |
( |
double |
n, |
|
|
double |
r |
|
) |
| |
|
static |
Definition at line 151 of file tinyexpr.c.
151 {
152 if (
n < 0.0 || r < 0.0 ||
n < r)
154 if (
n > UINT_MAX || r > UINT_MAX)
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))
163 result *= un - ur +
i;
165 }
166 return result;
167}
◆ negate()
| static double negate |
( |
double |
a | ) |
|
|
static |
◆ new_expr()
| static te_expr * new_expr |
( |
const int |
type, |
|
|
const te_expr * |
parameters[] |
|
) |
| |
|
static |
Definition at line 93 of file tinyexpr.c.
93 {
95 const int psize = sizeof(void *) * arity;
98 memset(ret, 0, size);
99 if (arity && parameters) {
101 }
104 return ret;
105}
◆ next_token()
| void next_token |
( |
state * |
s | ) |
|
Definition at line 253 of file tinyexpr.c.
253 {
255
256 do {
257
260 return;
261 }
262
263
264 if ((s->
next[0] >=
'0' && s->
next[0] <=
'9') || s->
next[0] ==
'.') {
267 } else {
268
269 if (isalpha(s->
next[0])) {
270 const char *start;
272 while (isalpha(s->
next[0]) || isdigit(s->
next[0]) || (s->
next[0] ==
'_'))
274
276 if (!var)
278
279 if (!var) {
281 } else {
286 break;
287
297
308 break;
309 }
310 }
311
312 } else {
313
314 switch (s->
next++[0]) {
315 case '+':
318 break;
319 case '-':
322 break;
323 case '*':
326 break;
327 case '/':
330 break;
331 case '^':
334 break;
335 case '%':
338 break;
342 case ' ':
343 case '\t':
344 case '\n':
345 case '\r': break;
347 }
348 }
349 }
351}
static const te_variable * find_builtin(const char *name, int len)
static const te_variable * find_lookup(const state *s, const char *name, int len)
static double mul(double a, double b)
static double divide(double a, double b)
◆ npr()
| static double npr |
( |
double |
n, |
|
|
double |
r |
|
) |
| |
|
static |
Definition at line 168 of file tinyexpr.c.
static double ncr(double n, double r)
static double fac(double a)
◆ optimize()
| static void optimize |
( |
te_expr * |
n | ) |
|
|
static |
Definition at line 638 of file tinyexpr.c.
638 {
639
641 return;
643 return;
644
645
647 const int arity =
ARITY(
n->type);
648 int known = 1;
650 for (
i = 0;
i < arity; ++
i) {
653 known = 0;
654 }
655 }
656 if (known) {
661 }
662 }
663}
double te_eval(const te_expr *n)
void te_free_parameters(te_expr *n)
◆ pi()
| static double pi |
( |
void |
| ) |
|
|
static |
Definition at line 135 of file tinyexpr.c.
135{ return 3.14159265358979323846; }
◆ pn()
| static void pn |
( |
const te_expr * |
n, |
|
|
int |
depth |
|
) |
| |
|
static |
Definition at line 702 of file tinyexpr.c.
702 {
704 printf("%*s", depth, "");
705
708 case TE_VARIABLE: printf(
"bound %p\n",
n->bound);
break;
709
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}
static void pn(const te_expr *n, int depth)
◆ power()
Definition at line 462 of file tinyexpr.c.
462 {
463
464 int sign = 1;
467 sign = -sign;
469 }
470
472
473 if (sign == 1) {
475 } else {
478 }
479
480 return ret;
481}
static double negate(double a)
static te_expr * base(state *s)
◆ sub()
| static double sub |
( |
double |
a, |
|
|
double |
b |
|
) |
| |
|
static |
◆ te_compile()
| te_expr * te_compile |
( |
const char * |
expression, |
|
|
const te_variable * |
variables, |
|
|
int |
var_count, |
|
|
int * |
error |
|
) |
| |
Definition at line 665 of file tinyexpr.c.
665 {
670
673
676 if (error) {
678 if (*error == 0)
679 *error = 1;
680 }
681 return 0;
682 } else {
684 if (error)
685 *error = 0;
686 return root;
687 }
688}
◆ te_eval()
| double te_eval |
( |
const te_expr * |
n | ) |
|
Definition at line 583 of file tinyexpr.c.
583 {
586
590
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));
609 }
610
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));
629 }
630
632 }
633}
◆ te_free()
◆ te_free_parameters()
| void te_free_parameters |
( |
te_expr * |
n | ) |
|
Definition at line 107 of file tinyexpr.c.
107 {
109 return;
125 }
126}
◆ te_interp()
| double te_interp |
( |
const char * |
expression, |
|
|
int * |
error |
|
) |
| |
Definition at line 690 of file tinyexpr.c.
690 {
692 double ret;
696 } else {
698 }
699 return ret;
700}
te_expr * te_compile(const char *expression, const te_variable *variables, int var_count, int *error)
◆ te_print()
◆ term()
Definition at line 539 of file tinyexpr.c.
539 {
540
542
548 }
549
550 return ret;
551}
static te_expr * factor(state *s)
◆ functions
Definition at line 175 of file tinyexpr.c.
175 {
176
190#ifdef TE_NAT_LOG
192#else
194#endif
205 {0, 0, 0, 0}};
static double npr(double n, double r)