60
static void evalExpression(Parser *p);
62
static void push(Parser *p, double d){
63
if(p->stack_index+1>= STACK_SIZE){
64
av_log(NULL, AV_LOG_ERROR, "stack overflow in the parser\n");
67
p->stack[ p->stack_index++ ]= d;
68
//printf("push %f\n", d); fflush(stdout);
71
static double pop(Parser *p){
72
if(p->stack_index<=0){
73
av_log(NULL, AV_LOG_ERROR, "stack underflow in the parser\n");
76
//printf("pop\n"); fflush(stdout);
77
return p->stack[ --p->stack_index ];
57
static double evalExpression(Parser *p);
80
59
static int strmatch(const char *s, const char *prefix){
94
73
d= strtod(p->s, &next);
101
79
/* named constants */
102
for(i=0; p->const_name[i]; i++){
80
for(i=0; p->const_name && p->const_name[i]; i++){
103
81
if(strmatch(p->s, p->const_name[i])){
104
push(p, p->const_value[i]);
105
82
p->s+= strlen(p->const_name[i]);
83
return p->const_value[i];
110
87
p->s= strchr(p->s, '(');
112
89
av_log(NULL, AV_LOG_ERROR, "Parser: missing ( in \"%s\"\n", next);
118
94
if(p->s[0]== ','){
96
d2= evalExpression(p);
123
98
if(p->s[0] != ')'){
124
99
av_log(NULL, AV_LOG_ERROR, "Parser: missing ) in \"%s\"\n", next);
144
119
else if( strmatch(next, "lt" ) ) d= d > d2 ? 0.0 : 1.0;
145
120
else if( strmatch(next, "lte" ) ) d= d >= d2 ? 0.0 : 1.0;
146
121
else if( strmatch(next, "eq" ) ) d= d == d2 ? 1.0 : 0.0;
122
else if( strmatch(next, "(" ) ) d= d;
147
123
// else if( strmatch(next, "l1" ) ) d= 1 + d2*(d - 1);
148
124
// else if( strmatch(next, "sq01" ) ) d= (d >= 0.0 && d <=1.0) ? 1.0 : 0.0;
151
126
for(i=0; p->func1_name && p->func1_name[i]; i++){
152
127
if(strmatch(next, p->func1_name[i])){
153
d= p->func1[i](p->opaque, d);
128
return p->func1[i](p->opaque, d);
159
132
for(i=0; p->func2_name && p->func2_name[i]; i++){
160
133
if(strmatch(next, p->func2_name[i])){
161
d= p->func2[i](p->opaque, d, d2);
134
return p->func2[i](p->opaque, d, d2);
168
av_log(NULL, AV_LOG_ERROR, "Parser: unknown function in \"%s\"\n", next);
138
av_log(NULL, AV_LOG_ERROR, "Parser: unknown function in \"%s\"\n", next);
176
static void evalPow(Parser *p){
178
if(p->s[0]=='+') p->s++;
190
av_log(NULL, AV_LOG_ERROR, "Parser: missing )\n");
196
if(neg) push(p, -pop(p));
145
static double evalPow(Parser *p){
146
int sign= (*p->s == '+') - (*p->s == '-');
148
return (sign|1) * evalPrimary(p);
199
static void evalFactor(Parser *p){
151
static double evalFactor(Parser *p){
152
double ret= evalPow(p);
201
153
while(p->s[0]=='^'){
207
push(p, pow(pop(p), d));
155
ret= pow(ret, evalPow(p));
211
static void evalTerm(Parser *p){
160
static double evalTerm(Parser *p){
161
double ret= evalFactor(p);
213
162
while(p->s[0]=='*' || p->s[0]=='/'){
214
int inv= p->s[0]=='/';
163
if(*p->s++ == '*') ret*= evalFactor(p);
164
else ret/= evalFactor(p);
225
static void evalExpression(Parser *p){
227
while(p->s[0]=='+' || p->s[0]=='-'){
228
int sign= p->s[0]=='-';
169
static double evalExpression(Parser *p){
172
if(p->stack_index <= 0) //protect against stack overflows
178
}while(*p->s == '+' || *p->s == '-');
239
185
double ff_eval(char *s, double *const_value, const char **const_name,
252
198
p.func2_name = func2_name;
253
199
p.opaque = opaque;
201
return evalExpression(&p);
206
static double const_values[]={
211
static const char *const_names[]={
218
printf("%f == 12.7\n", ff_eval("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL));
220
for(i=0; i<1050; i++){
222
ff_eval("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_values, const_names, NULL, NULL, NULL, NULL, NULL);
223
STOP_TIMER("ff_eval")