annotate eval.c @ 1985:b2bc62fdecc0 libavcodec

move the 0x80 vector outside of the function, thus saving the compiler the trouble of having to initialize each byte on the stack individually
author melanson
date Tue, 27 Apr 2004 04:06:24 +0000
parents 2152760d08ad
children 0934621b6453
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
1 /*
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
2 * simple arithmetic expression evaluator
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
3 *
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
4 * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
5 *
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
6 * This library is free software; you can redistribute it and/or
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
9 * version 2 of the License, or (at your option) any later version.
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
10 *
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
11 * This library is distributed in the hope that it will be useful,
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
14 * Lesser General Public License for more details.
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
15 *
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
17 * License along with this library; if not, write to the Free Software
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
19 *
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
20 */
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
21
1106
1e39f273ecd6 per file doxy
michaelni
parents: 1057
diff changeset
22 /**
1e39f273ecd6 per file doxy
michaelni
parents: 1057
diff changeset
23 * @file eval.c
1e39f273ecd6 per file doxy
michaelni
parents: 1057
diff changeset
24 * simple arithmetic expression evaluator.
1e39f273ecd6 per file doxy
michaelni
parents: 1057
diff changeset
25 *
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
26 * see http://joe.hotchkiss.com/programming/eval/eval.html
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
27 */
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
28
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
29 #include "avcodec.h"
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
30 #include "mpegvideo.h"
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
31
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
32 #include <stdio.h>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
33 #include <stdlib.h>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
34 #include <string.h>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
35 #include <math.h>
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
36
614
b786f15df503 NAN doesnt exist on FreeBSD patch by (R?mi Guyomarch <rguyom at pobox dot com>)
michaelni
parents: 612
diff changeset
37 #ifndef NAN
b786f15df503 NAN doesnt exist on FreeBSD patch by (R?mi Guyomarch <rguyom at pobox dot com>)
michaelni
parents: 612
diff changeset
38 #define NAN 0
b786f15df503 NAN doesnt exist on FreeBSD patch by (R?mi Guyomarch <rguyom at pobox dot com>)
michaelni
parents: 612
diff changeset
39 #endif
b786f15df503 NAN doesnt exist on FreeBSD patch by (R?mi Guyomarch <rguyom at pobox dot com>)
michaelni
parents: 612
diff changeset
40
627
79c43f519d02 undefined M_PI / M_E fix
michaelni
parents: 614
diff changeset
41 #ifndef M_PI
79c43f519d02 undefined M_PI / M_E fix
michaelni
parents: 614
diff changeset
42 #define M_PI 3.14159265358979323846
79c43f519d02 undefined M_PI / M_E fix
michaelni
parents: 614
diff changeset
43 #endif
79c43f519d02 undefined M_PI / M_E fix
michaelni
parents: 614
diff changeset
44
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
45 #define STACK_SIZE 100
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
46
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
47 typedef struct Parser{
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
48 double stack[STACK_SIZE];
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
49 int stack_index;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
50 char *s;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
51 double *const_value;
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
52 const char **const_name; // NULL terminated
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
53 double (**func1)(void *, double a); // NULL terminated
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
54 const char **func1_name; // NULL terminated
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
55 double (**func2)(void *, double a, double b); // NULL terminated
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
56 char **func2_name; // NULL terminated
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
57 void *opaque;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
58 } Parser;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
59
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
60 static void evalExpression(Parser *p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
61
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
62 static void push(Parser *p, double d){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
63 if(p->stack_index+1>= STACK_SIZE){
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1106
diff changeset
64 av_log(NULL, AV_LOG_ERROR, "stack overflow in the parser\n");
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
65 return;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
66 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
67 p->stack[ p->stack_index++ ]= d;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
68 //printf("push %f\n", d); fflush(stdout);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
69 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
70
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
71 static double pop(Parser *p){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
72 if(p->stack_index<=0){
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1106
diff changeset
73 av_log(NULL, AV_LOG_ERROR, "stack underflow in the parser\n");
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
74 return NAN;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
75 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
76 //printf("pop\n"); fflush(stdout);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
77 return p->stack[ --p->stack_index ];
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
78 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
79
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
80 static int strmatch(const char *s, const char *prefix){
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
81 int i;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
82 for(i=0; prefix[i]; i++){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
83 if(prefix[i] != s[i]) return 0;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
84 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
85 return 1;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
86 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
87
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
88 static void evalPrimary(Parser *p){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
89 double d, d2=NAN;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
90 char *next= p->s;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
91 int i;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
92
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
93 /* number */
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
94 d= strtod(p->s, &next);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
95 if(next != p->s){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
96 push(p, d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
97 p->s= next;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
98 return;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
99 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
100
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
101 /* named constants */
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
102 for(i=0; p->const_name[i]; i++){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
103 if(strmatch(p->s, p->const_name[i])){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
104 push(p, p->const_value[i]);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
105 p->s+= strlen(p->const_name[i]);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
106 return;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
107 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
108 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
109
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
110 p->s= strchr(p->s, '(');
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
111 if(p->s==NULL){
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1106
diff changeset
112 av_log(NULL, AV_LOG_ERROR, "Parser: missing ( in \"%s\"\n", next);
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
113 return;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
114 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
115 p->s++; // "("
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
116 evalExpression(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
117 d= pop(p);
1815
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
118 if(p->s[0]== ','){
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
119 p->s++; // ","
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
120 evalExpression(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
121 d2= pop(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
122 }
1815
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
123 if(p->s[0] != ')'){
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
124 av_log(NULL, AV_LOG_ERROR, "Parser: missing ) in \"%s\"\n", next);
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
125 return;
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
126 }
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
127 p->s++; // ")"
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
128
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
129 if( strmatch(next, "sinh" ) ) d= sinh(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
130 else if( strmatch(next, "cosh" ) ) d= cosh(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
131 else if( strmatch(next, "tanh" ) ) d= tanh(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
132 else if( strmatch(next, "sin" ) ) d= sin(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
133 else if( strmatch(next, "cos" ) ) d= cos(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
134 else if( strmatch(next, "tan" ) ) d= tan(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
135 else if( strmatch(next, "exp" ) ) d= exp(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
136 else if( strmatch(next, "log" ) ) d= log(d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
137 else if( strmatch(next, "squish") ) d= 1/(1+exp(4*d));
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
138 else if( strmatch(next, "gauss" ) ) d= exp(-d*d/2)/sqrt(2*M_PI);
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
139 else if( strmatch(next, "abs" ) ) d= fabs(d);
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
140 else if( strmatch(next, "max" ) ) d= d > d2 ? d : d2;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
141 else if( strmatch(next, "min" ) ) d= d < d2 ? d : d2;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
142 else if( strmatch(next, "gt" ) ) d= d > d2 ? 1.0 : 0.0;
1815
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
143 else if( strmatch(next, "gte" ) ) d= d >= d2 ? 1.0 : 0.0;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
144 else if( strmatch(next, "lt" ) ) d= d > d2 ? 0.0 : 1.0;
1815
2152760d08ad avoid negative array indices
alex
parents: 1598
diff changeset
145 else if( strmatch(next, "lte" ) ) d= d >= d2 ? 0.0 : 1.0;
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
146 else if( strmatch(next, "eq" ) ) d= d == d2 ? 1.0 : 0.0;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
147 // else if( strmatch(next, "l1" ) ) d= 1 + d2*(d - 1);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
148 // else if( strmatch(next, "sq01" ) ) d= (d >= 0.0 && d <=1.0) ? 1.0 : 0.0;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
149 else{
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
150 int error=1;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
151 for(i=0; p->func1_name && p->func1_name[i]; i++){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
152 if(strmatch(next, p->func1_name[i])){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
153 d= p->func1[i](p->opaque, d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
154 error=0;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
155 break;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
156 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
157 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
158
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
159 for(i=0; p->func2_name && p->func2_name[i]; i++){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
160 if(strmatch(next, p->func2_name[i])){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
161 d= p->func2[i](p->opaque, d, d2);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
162 error=0;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
163 break;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
164 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
165 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
166
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
167 if(error){
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1106
diff changeset
168 av_log(NULL, AV_LOG_ERROR, "Parser: unknown function in \"%s\"\n", next);
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
169 return;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
170 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
171 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
172
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
173 push(p, d);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
174 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
175
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
176 static void evalPow(Parser *p){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
177 int neg= 0;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
178 if(p->s[0]=='+') p->s++;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
179
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
180 if(p->s[0]=='-'){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
181 neg= 1;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
182 p->s++;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
183 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
184
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
185 if(p->s[0]=='('){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
186 p->s++;;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
187 evalExpression(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
188
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
189 if(p->s[0]!=')')
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1106
diff changeset
190 av_log(NULL, AV_LOG_ERROR, "Parser: missing )\n");
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
191 p->s++;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
192 }else{
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
193 evalPrimary(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
194 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
195
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
196 if(neg) push(p, -pop(p));
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
197 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
198
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
199 static void evalFactor(Parser *p){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
200 evalPow(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
201 while(p->s[0]=='^'){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
202 double d;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
203
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
204 p->s++;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
205 evalPow(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
206 d= pop(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
207 push(p, pow(pop(p), d));
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
208 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
209 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
210
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
211 static void evalTerm(Parser *p){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
212 evalFactor(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
213 while(p->s[0]=='*' || p->s[0]=='/'){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
214 int inv= p->s[0]=='/';
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
215 double d;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
216
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
217 p->s++;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
218 evalFactor(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
219 d= pop(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
220 if(inv) d= 1.0/d;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
221 push(p, d * pop(p));
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
222 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
223 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
224
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
225 static void evalExpression(Parser *p){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
226 evalTerm(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
227 while(p->s[0]=='+' || p->s[0]=='-'){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
228 int sign= p->s[0]=='-';
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
229 double d;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
230
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
231 p->s++;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
232 evalTerm(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
233 d= pop(p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
234 if(sign) d= -d;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
235 push(p, d + pop(p));
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
236 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
237 }
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
238
1057
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
239 double ff_eval(char *s, double *const_value, const char **const_name,
bb5de8a59da8 * static,const,compiler warning cleanup
kabi
parents: 627
diff changeset
240 double (**func1)(void *, double), const char **func1_name,
612
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
241 double (**func2)(void *, double, double), char **func2_name,
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
242 void *opaque){
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
243 Parser p;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
244
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
245 p.stack_index=0;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
246 p.s= s;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
247 p.const_value= const_value;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
248 p.const_name = const_name;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
249 p.func1 = func1;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
250 p.func1_name = func1_name;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
251 p.func2 = func2;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
252 p.func2_name = func2_name;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
253 p.opaque = opaque;
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
254
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
255 evalExpression(&p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
256 return pop(&p);
c0005de2be59 new ratecontrol code
michaelni
parents:
diff changeset
257 }