1 |
/* |
2 |
* HT Editor |
3 |
* stdfuncs.cc |
4 |
* |
5 |
* Copyright (C) 2003 Stefan Weyergraf |
6 |
* |
7 |
* This program is free software; you can redistribute it and/or modify |
8 |
* it under the terms of the GNU General Public License version 2 as |
9 |
* published by the Free Software Foundation. |
10 |
* |
11 |
* This program is distributed in the hope that it will be useful, |
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
* GNU General Public License for more details. |
15 |
* |
16 |
* You should have received a copy of the GNU General Public License |
17 |
* along with this program; if not, write to the Free Software |
18 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 |
*/ |
20 |
|
21 |
#include "tools/except.h" |
22 |
#include "debug/stdfuncs.h" |
23 |
|
24 |
#define declareIntOperator1(NAME, CODE...) \ |
25 |
class NAME: public PFunction {\ |
26 |
public:\ |
27 |
virtual EvalType getReturnType() const { return ET_INTEGER;}\ |
28 |
virtual SInt64 * evalInteger() const\ |
29 |
{\ |
30 |
sint64 arg0 = ((Function *)mArgs[0])->evalInteger()->value;\ |
31 |
CODE\ |
32 |
}\ |
33 |
};\ |
34 |
static Function *create##NAME() { return new NAME(); } |
35 |
|
36 |
/**/ |
37 |
#define declareIntOperator2(NAME, CODE...) \ |
38 |
class NAME: public PFunction {\ |
39 |
public:\ |
40 |
virtual EvalType getReturnType() const { return ET_INTEGER;}\ |
41 |
virtual SInt64 * evalInteger() const\ |
42 |
{\ |
43 |
sint64 arg0 = ((Function *)mArgs[0])->evalInteger()->value;\ |
44 |
sint64 arg1 = ((Function *)mArgs[1])->evalInteger()->value;\ |
45 |
CODE\ |
46 |
}\ |
47 |
};\ |
48 |
static Function *create##NAME() { return new NAME(); } |
49 |
|
50 |
/**/ |
51 |
#define declareFloatOperator2(NAME, CODE...) \ |
52 |
class NAME: public PFunction {\ |
53 |
public:\ |
54 |
virtual EvalType getReturnType() const { return ET_FLOAT;}\ |
55 |
virtual Float * evalFloat() const\ |
56 |
{\ |
57 |
double arg0 = ((Function *)mArgs[0])->evalFloat()->value;\ |
58 |
double arg1 = ((Function *)mArgs[1])->evalFloat()->value;\ |
59 |
CODE\ |
60 |
}\ |
61 |
};\ |
62 |
static Function *create##NAME() { return new NAME(); } |
63 |
|
64 |
/**/ |
65 |
#define declareFloatOperator1(NAME, CODE...) \ |
66 |
class NAME: public PFunction {\ |
67 |
public:\ |
68 |
virtual EvalType getReturnType() const { return ET_FLOAT;}\ |
69 |
virtual Float * evalFloat() const\ |
70 |
{\ |
71 |
double arg0 = ((Function *)mArgs[0])->evalFloat()->value;\ |
72 |
CODE\ |
73 |
}\ |
74 |
};\ |
75 |
static Function *create##NAME() { return new NAME(); } |
76 |
|
77 |
/**/ |
78 |
#define declareIntFuncFloatFloat(NAME, CODE...) \ |
79 |
class NAME: public PFunction {\ |
80 |
public:\ |
81 |
virtual EvalType getReturnType() const { return ET_INTEGER;}\ |
82 |
virtual SInt64 * evalInteger() const\ |
83 |
{\ |
84 |
double arg0 = ((Function *)mArgs[0])->evalFloat()->value;\ |
85 |
double arg1 = ((Function *)mArgs[1])->evalFloat()->value;\ |
86 |
CODE\ |
87 |
}\ |
88 |
};\ |
89 |
static Function *create##NAME() { return new NAME(); } |
90 |
|
91 |
/**/ |
92 |
#define declareStrOperator2(NAME, CODE...) \ |
93 |
class NAME: public PFunction {\ |
94 |
public:\ |
95 |
virtual EvalType getReturnType() const { return ET_STRING;}\ |
96 |
virtual String * evalString() const\ |
97 |
{\ |
98 |
String *arg0 = ((Function *)mArgs[0])->evalString();\ |
99 |
String *arg1 = ((Function *)mArgs[1])->evalString();\ |
100 |
CODE\ |
101 |
}\ |
102 |
};\ |
103 |
static Function *create##NAME() { return new NAME(); } |
104 |
/**/ |
105 |
|
106 |
#define declareIntFuncStrStr(NAME, CODE...) \ |
107 |
class NAME: public PFunction {\ |
108 |
public:\ |
109 |
virtual EvalType getReturnType() const { return ET_INTEGER;}\ |
110 |
virtual SInt64 * evalInteger() const\ |
111 |
{\ |
112 |
String *arg0 = ((Function *)mArgs[0])->evalString();\ |
113 |
String *arg1 = ((Function *)mArgs[1])->evalString();\ |
114 |
CODE\ |
115 |
}\ |
116 |
};\ |
117 |
static Function *create##NAME() { return new NAME(); } |
118 |
/**/ |
119 |
|
120 |
/* integer functions */ |
121 |
declareIntOperator2(MulFuncInt, return new SInt64(arg0 * arg1); ); |
122 |
declareIntOperator2(DivFuncInt, |
123 |
if (!arg1) throw MsgException("division by zero"); |
124 |
return new SInt64(arg0 / arg1); |
125 |
); |
126 |
declareIntOperator2(RemFuncInt, |
127 |
if (!arg1) throw MsgException("division by zero"); |
128 |
return new SInt64(arg0 % arg1); |
129 |
); |
130 |
declareIntOperator2(AddFuncInt, return new SInt64(arg0 + arg1); ); |
131 |
declareIntOperator2(SubFuncInt, return new SInt64(arg0 - arg1); ); |
132 |
declareIntOperator2(AndFuncInt, return new SInt64(arg0 & arg1); ); |
133 |
declareIntOperator2(OrFuncInt, return new SInt64(arg0 | arg1); ); |
134 |
declareIntOperator2(XorFuncInt, return new SInt64(arg0 ^ arg1); ); |
135 |
declareIntOperator2(ShlFuncInt, return new SInt64((uint64)arg0 << arg1); ); |
136 |
declareIntOperator2(ShrFuncInt, return new SInt64((uint64)arg0 >> arg1); ); |
137 |
declareIntOperator2(PowFuncInt, |
138 |
sint64 b = arg0; |
139 |
sint64 e = arg1; |
140 |
sint64 r = 1; |
141 |
int ln2_e = -1; |
142 |
uint64 uarg1 = arg1; |
143 |
while (uarg1) { |
144 |
uarg1 >>= 1; |
145 |
ln2_e ++; |
146 |
} |
147 |
uint64 mask = 1L << ln2_e; |
148 |
while (1) { |
149 |
if (e & mask) r *= b; |
150 |
mask >>= 1; |
151 |
if (!mask) break; |
152 |
r = r*r; |
153 |
} |
154 |
return new SInt64(r); |
155 |
); |
156 |
declareIntOperator2(MaxFuncInt, return new SInt64((arg1>arg0) ? arg1 : arg0); ); |
157 |
declareIntOperator2(MinFuncInt, return new SInt64((arg1<arg0) ? arg1 : arg0); ); |
158 |
|
159 |
declareIntOperator2(LAndFuncInt, return new SInt64(arg0 && arg1); ); |
160 |
declareIntOperator2(LOrFuncInt, return new SInt64(arg0 || arg1); ); |
161 |
declareIntOperator2(LXorFuncInt, return new SInt64((arg0 && !arg1) || (!arg0 && arg1)); ); |
162 |
|
163 |
declareIntOperator2(LTFuncInt, return new SInt64(arg0 < arg1); ); |
164 |
declareIntOperator2(GTFuncInt, return new SInt64(arg0 > arg1); ); |
165 |
declareIntOperator2(LEFuncInt, return new SInt64(arg0 <= arg1); ); |
166 |
declareIntOperator2(GEFuncInt, return new SInt64(arg0 >= arg1); ); |
167 |
declareIntOperator2(EQFuncInt, return new SInt64(arg0 == arg1); ); |
168 |
declareIntOperator2(NEFuncInt, return new SInt64(arg0 != arg1); ); |
169 |
declareIntOperator2(GcdFuncInt, |
170 |
while (arg1) { |
171 |
sint64 temp = arg1; |
172 |
arg1 = arg0 % arg1; |
173 |
arg0 = temp; |
174 |
} |
175 |
return new SInt64((arg0<0) ? -arg0 : arg0); |
176 |
); |
177 |
|
178 |
declareIntOperator2(BinCoeffFuncInt, |
179 |
// calculate (n k) = n! / (n-k)! / k! |
180 |
uint64 n = arg0; |
181 |
uint64 k = arg1; |
182 |
uint64 r = 1; |
183 |
for (uint64 i = n; i>n-k; i--) { |
184 |
r *= i; |
185 |
} |
186 |
for (uint64 i = 2; i<=k; i++) { |
187 |
r /= i; |
188 |
} |
189 |
return new SInt64(r); |
190 |
); |
191 |
|
192 |
declareIntOperator1(FacFuncInt, |
193 |
if (arg0 < 0) throw MsgException("invalid argument (must be >= 0)"); |
194 |
// 0! = 1! |
195 |
if (arg0 == 0) arg0 = 1; |
196 |
uint64 r = arg0; |
197 |
while (arg0-- > 2) { |
198 |
r *= arg0; |
199 |
} |
200 |
return new SInt64(r); |
201 |
); |
202 |
declareIntOperator1(NegateFuncInt, return new SInt64(-arg0); ); |
203 |
|
204 |
/* float functions */ |
205 |
declareFloatOperator2(MulFuncFloat, return new Float(arg0 * arg1); ); |
206 |
declareFloatOperator2(DivFuncFloat, |
207 |
if (!arg1) throw MsgException("division by zero"); |
208 |
return new Float(arg0 / arg1); |
209 |
); |
210 |
declareFloatOperator2(AddFuncFloat, return new Float(arg0 + arg1); ); |
211 |
declareFloatOperator2(SubFuncFloat, return new Float(arg0 - arg1); ); |
212 |
declareFloatOperator2(PowFuncFloat, return new Float(pow(arg0, arg1)); ); |
213 |
|
214 |
declareFloatOperator2(MaxFuncFloat, return new Float((arg1>arg0) ? arg1 : arg0); ); |
215 |
declareFloatOperator2(MinFuncFloat, return new Float((arg1<arg0) ? arg1 : arg0); ); |
216 |
|
217 |
declareFloatOperator1(SqrtFuncFloat, return new Float(sqrt(arg0)); ); |
218 |
declareFloatOperator1(ExpFuncFloat, return new Float(exp(arg0)); ); |
219 |
declareFloatOperator1(LogFuncFloat, return new Float(log(arg0)); ); |
220 |
declareFloatOperator1(CeilFuncFloat, return new Float(ceil(arg0)); ); |
221 |
declareFloatOperator1(FloorFuncFloat, return new Float(floor(arg0)); ); |
222 |
declareFloatOperator1(SinFuncFloat, return new Float(sin(arg0)); ); |
223 |
declareFloatOperator1(CosFuncFloat, return new Float(cos(arg0)); ); |
224 |
declareFloatOperator1(TanFuncFloat, return new Float(tan(arg0)); ); |
225 |
declareFloatOperator1(ASinFuncFloat, return new Float(asin(arg0)); ); |
226 |
declareFloatOperator1(ACosFuncFloat, return new Float(acos(arg0)); ); |
227 |
declareFloatOperator1(ATanFuncFloat, return new Float(atan(arg0)); ); |
228 |
|
229 |
declareFloatOperator1(NegateFuncFloat, return new Float(-arg0); ); |
230 |
|
231 |
declareIntFuncFloatFloat(LTFuncFloat, return new SInt64(arg0 < arg1); ); |
232 |
declareIntFuncFloatFloat(GTFuncFloat, return new SInt64(arg0 > arg1); ); |
233 |
declareIntFuncFloatFloat(LEFuncFloat, return new SInt64(arg0 <= arg1); ); |
234 |
declareIntFuncFloatFloat(GEFuncFloat, return new SInt64(arg0 >= arg1); ); |
235 |
declareIntFuncFloatFloat(EQFuncFloat, return new SInt64(arg0 == arg1); ); |
236 |
declareIntFuncFloatFloat(NEFuncFloat, return new SInt64(arg0 != arg1); ); |
237 |
/* string functions */ |
238 |
declareStrOperator2(ConcatFuncStr, |
239 |
String *r = new String(arg0); |
240 |
r->append(arg1); |
241 |
return r; |
242 |
); |
243 |
|
244 |
declareIntFuncStrStr(LTFuncStr, return new SInt64(arg0 < arg1); ); |
245 |
declareIntFuncStrStr(GTFuncStr, return new SInt64(arg0 > arg1); ); |
246 |
declareIntFuncStrStr(LEFuncStr, return new SInt64(arg0 <= arg1); ); |
247 |
declareIntFuncStrStr(GEFuncStr, return new SInt64(arg0 >= arg1); ); |
248 |
declareIntFuncStrStr(EQFuncStr, return new SInt64(arg0->compareTo(arg1) == 0); ); |
249 |
declareIntFuncStrStr(NEFuncStr, return new SInt64(arg0->compareTo(arg1) != 0); ); |
250 |
|
251 |
/* special functions */ |
252 |
class MiniIf: public PFunction { |
253 |
public: |
254 |
virtual EvalType getReturnType() const |
255 |
{ |
256 |
if (mArgs.count() != 3) throw MsgException("exactly 3 parameters required"); |
257 |
EvalType arg1t = ((Function *)mArgs[1])->getReturnType(); |
258 |
EvalType arg2t = ((Function *)mArgs[2])->getReturnType(); |
259 |
if ((arg1t == ET_STRING) || (arg2t == ET_STRING)) return ET_STRING; |
260 |
if ((arg1t == ET_FLOAT) || (arg2t == ET_FLOAT)) return ET_FLOAT; |
261 |
return ET_INTEGER; |
262 |
} |
263 |
|
264 |
virtual SInt64 *evalInteger() const |
265 |
{ |
266 |
if (mArgs.count() != 3) throw MsgException("exactly 3 parameters required"); |
267 |
sint64 arg0 = ((Function *)mArgs[0])->evalInteger()->value; |
268 |
return new SInt64(arg0 ? |
269 |
((Function *)mArgs[1])->evalInteger()->value : |
270 |
((Function *)mArgs[2])->evalInteger()->value); |
271 |
} |
272 |
|
273 |
virtual Float *evalFloat() const |
274 |
{ |
275 |
if (mArgs.count() != 3) throw MsgException("exactly 3 parameters required"); |
276 |
sint64 arg0 = ((Function *)mArgs[0])->evalInteger()->value; |
277 |
return new Float(arg0 ? |
278 |
((Function *)mArgs[1])->evalFloat()->value : |
279 |
((Function *)mArgs[2])->evalFloat()->value); |
280 |
} |
281 |
|
282 |
virtual String *evalString() const |
283 |
{ |
284 |
if (mArgs.count() != 3) throw MsgException("exactly 3 parameters required"); |
285 |
sint64 arg0 = ((Function *)mArgs[0])->evalInteger()->value; |
286 |
return new String(arg0 ? |
287 |
((Function *)mArgs[1])->evalString() : |
288 |
((Function *)mArgs[2])->evalString()); |
289 |
} |
290 |
}; |
291 |
static Function *createMiniIf() { return new MiniIf(); } |
292 |
|
293 |
/**/ |
294 |
class TypeOfInt: public PFunction { |
295 |
public: |
296 |
virtual EvalType getReturnType() const { return ET_STRING; } |
297 |
virtual String *evalString() const { return new String("integer"); } |
298 |
}; |
299 |
static Function *createTypeOfInt() { return new TypeOfInt(); } |
300 |
|
301 |
/**/ |
302 |
class TypeOfFloat: public PFunction { |
303 |
public: |
304 |
virtual EvalType getReturnType() const { return ET_STRING; } |
305 |
virtual String *evalString() const { return new String("float"); } |
306 |
}; |
307 |
static Function *createTypeOfFloat() { return new TypeOfFloat(); } |
308 |
|
309 |
/**/ |
310 |
class TypeOfStr: public PFunction { |
311 |
public: |
312 |
virtual EvalType getReturnType() const { return ET_STRING; } |
313 |
virtual String *evalString() const { return new String("string"); } |
314 |
}; |
315 |
static Function *createTypeOfStr() { return new TypeOfStr(); } |
316 |
|
317 |
/**/ |
318 |
FunctionDesc gStdEvalFunctions[] = |
319 |
{ |
320 |
{ "*", 2, {ET_INTEGER, ET_INTEGER}, &createMulFuncInt }, |
321 |
{ "/", 2, {ET_INTEGER, ET_INTEGER}, &createDivFuncInt }, |
322 |
{ "%", 2, {ET_INTEGER, ET_INTEGER}, &createRemFuncInt }, |
323 |
{ "+", 2, {ET_INTEGER, ET_INTEGER}, &createAddFuncInt }, |
324 |
{ "-", 2, {ET_INTEGER, ET_INTEGER}, &createSubFuncInt }, |
325 |
{ "&", 2, {ET_INTEGER, ET_INTEGER}, &createAndFuncInt }, |
326 |
{ "|", 2, {ET_INTEGER, ET_INTEGER}, &createOrFuncInt }, |
327 |
{ "^", 2, {ET_INTEGER, ET_INTEGER}, &createXorFuncInt }, |
328 |
{ "**", 2, {ET_INTEGER, ET_INTEGER}, &createPowFuncInt }, |
329 |
{ "max",2, {ET_INTEGER, ET_INTEGER}, &createMaxFuncInt }, |
330 |
{ "min",2, {ET_INTEGER, ET_INTEGER}, &createMinFuncInt }, |
331 |
{ "<<", 2, {ET_INTEGER, ET_INTEGER}, &createShlFuncInt }, |
332 |
{ ">>", 2, {ET_INTEGER, ET_INTEGER}, &createShrFuncInt }, |
333 |
{ "&&", 2, {ET_INTEGER, ET_INTEGER}, &createLAndFuncInt }, |
334 |
{ "||", 2, {ET_INTEGER, ET_INTEGER}, &createLOrFuncInt }, |
335 |
{ "^^", 2, {ET_INTEGER, ET_INTEGER}, &createLXorFuncInt }, |
336 |
|
337 |
{ "<", 2, {ET_INTEGER, ET_INTEGER}, &createLTFuncInt }, |
338 |
{ ">", 2, {ET_INTEGER, ET_INTEGER}, &createGTFuncInt }, |
339 |
{ "<=", 2, {ET_INTEGER, ET_INTEGER}, &createLEFuncInt }, |
340 |
{ ">=", 2, {ET_INTEGER, ET_INTEGER}, &createGEFuncInt }, |
341 |
{ "==", 2, {ET_INTEGER, ET_INTEGER}, &createEQFuncInt }, |
342 |
{ "!=", 2, {ET_INTEGER, ET_INTEGER}, &createNEFuncInt }, |
343 |
{ "gcd",2, {ET_INTEGER, ET_INTEGER}, &createGcdFuncInt }, |
344 |
{ "bincoeff",2, {ET_INTEGER, ET_INTEGER}, &createBinCoeffFuncInt }, |
345 |
{ "-", 1, {ET_INTEGER}, &createNegateFuncInt }, |
346 |
{ "fac",1, {ET_INTEGER}, &createFacFuncInt }, |
347 |
|
348 |
{ "*", 2, {ET_FLOAT, ET_FLOAT}, &createMulFuncFloat }, |
349 |
{ "/", 2, {ET_FLOAT, ET_FLOAT}, &createDivFuncFloat }, |
350 |
{ "+", 2, {ET_FLOAT, ET_FLOAT}, &createAddFuncFloat }, |
351 |
{ "-", 2, {ET_FLOAT, ET_FLOAT}, &createSubFuncFloat }, |
352 |
{ "**", 2, {ET_FLOAT, ET_FLOAT}, &createPowFuncFloat }, |
353 |
{ "max",2, {ET_FLOAT, ET_FLOAT}, &createMaxFuncFloat }, |
354 |
{ "min",2, {ET_FLOAT, ET_FLOAT}, &createMinFuncFloat }, |
355 |
|
356 |
{ "<", 2, {ET_FLOAT, ET_FLOAT}, &createLTFuncFloat }, |
357 |
{ ">", 2, {ET_FLOAT, ET_FLOAT}, &createGTFuncFloat }, |
358 |
{ "<=", 2, {ET_FLOAT, ET_FLOAT}, &createLEFuncFloat }, |
359 |
{ ">=", 2, {ET_FLOAT, ET_FLOAT}, &createGEFuncFloat }, |
360 |
{ "==", 2, {ET_FLOAT, ET_FLOAT}, &createEQFuncFloat }, |
361 |
{ "!=", 2, {ET_FLOAT, ET_FLOAT}, &createNEFuncFloat }, |
362 |
{ "sqrt", 1, {ET_FLOAT}, &createSqrtFuncFloat }, |
363 |
{ "exp", 1, {ET_FLOAT}, &createExpFuncFloat }, |
364 |
{ "log", 1, {ET_FLOAT}, &createLogFuncFloat }, |
365 |
|
366 |
// FIXME: should return int, not float (use float2int) |
367 |
{ "ceil", 1, {ET_FLOAT}, &createCeilFuncFloat }, |
368 |
// FIXME: should return int, not float (use float2int) |
369 |
{ "floor", 1, {ET_FLOAT}, &createFloorFuncFloat }, |
370 |
|
371 |
{ "sin", 1, {ET_FLOAT}, &createSinFuncFloat }, |
372 |
{ "cos", 1, {ET_FLOAT}, &createCosFuncFloat }, |
373 |
{ "tan", 1, {ET_FLOAT}, &createTanFuncFloat }, |
374 |
{ "asin", 1, {ET_FLOAT}, &createASinFuncFloat }, |
375 |
{ "acos", 1, {ET_FLOAT}, &createACosFuncFloat }, |
376 |
{ "atan", 1, {ET_FLOAT}, &createATanFuncFloat }, |
377 |
{ "-", 1, {ET_FLOAT}, &createNegateFuncFloat }, |
378 |
|
379 |
{ ".", 2, {ET_STRING, ET_STRING}, &createConcatFuncStr }, |
380 |
{ "<", 2, {ET_STRING, ET_STRING}, &createLTFuncStr }, |
381 |
{ ">", 2, {ET_STRING, ET_STRING}, &createGTFuncStr }, |
382 |
{ "<=", 2, {ET_STRING, ET_STRING}, &createLEFuncStr }, |
383 |
{ ">=", 2, {ET_STRING, ET_STRING}, &createGEFuncStr }, |
384 |
{ "==", 2, {ET_STRING, ET_STRING}, &createEQFuncStr }, |
385 |
{ "!=", 2, {ET_STRING, ET_STRING}, &createNEFuncStr }, |
386 |
|
387 |
{ "?:", 2, {ET_INTEGER, ET_VARARGS}, &createMiniIf }, |
388 |
{ "typeof", 1, {ET_INTEGER}, &createTypeOfInt }, |
389 |
{ "typeof", 1, {ET_FLOAT}, &createTypeOfFloat }, |
390 |
{ "typeof", 1, {ET_STRING}, &createTypeOfStr }, |
391 |
|
392 |
{ NULL } |
393 |
}; |