Annotation of parser3/src/classes/math.C, revision 1.8
1.1 parser 1: /** @file
2: Parser: @b math parser class.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
1.6 parser 5: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
1.1 parser 6:
1.8 ! paf 7: $Id: math.C,v 1.7 2001/10/19 12:43:29 parser Exp $
1.1 parser 8: */
9:
10: #include "pa_config_includes.h"
11: #include "pa_common.h"
12: #include "pa_vint.h"
1.2 parser 13: #include "pa_vmath.h"
1.1 parser 14: #include "pa_request.h"
15:
1.5 parser 16: #ifdef WIN32
17: # include <windows.h>
18: #endif
19:
1.1 parser 20: // defines
21:
1.3 parser 22: #define PI 3.1415926535
1.1 parser 23: #define MATH_CLASS_NAME "math"
24:
25: // class
26:
27: class MMath : public Methoded {
28: public:
29: MMath(Pool& pool);
1.5 parser 30: void configure_admin(Request& r);
31:
1.1 parser 32: public: // Methoded
33: bool used_directly() { return true; }
34: };
35:
36: // methods
1.5 parser 37: static unsigned int randomizer=0;
1.1 parser 38: static void _random(Request& r, const String& method_name, MethodParams *params) {
39: Pool& pool=r.pool();
40:
1.3 parser 41: Value& range=params->as_junction(0, "range must be expression");
1.1 parser 42: uint max=(uint)r.process(range).as_double();
43: if(max<=1)
1.7 parser 44: throw Exception(0, 0,
1.1 parser 45: &method_name,
46: "bad range [0..%u]", max);
47:
1.5 parser 48: Value& result=*new(pool) VInt(pool, (int)(
49: ((double)((randomizer=rand())% RAND_MAX)) / RAND_MAX * (max + 1)));
1.4 parser 50: result.set_name(method_name);
51: r.write_no_lang(result);
1.1 parser 52: }
53:
54:
55: typedef double (*math1_func_ptr)(double);
1.3 parser 56: static double frac(double param) { return param-trunc(param); }
57: static double degrees(double param) { return param /PI *180; }
58: static double radians(double param) { return param /180 *PI; }
1.1 parser 59:
60: static void math1(Request& r,
61: const String& method_name, MethodParams *params,
62: math1_func_ptr func) {
63: Pool& pool=r.pool();
1.3 parser 64: Value& param=params->as_junction(0, "parameter must be expression");
1.1 parser 65:
66: Value& result=*new(pool) VDouble(pool, (*func)(r.process(param).as_double()));
67: result.set_name(method_name);
68: r.write_no_lang(result);
69: }
70:
71: #define MATH1(name) \
72: static void _##name(Request& r, const String& method_name, MethodParams *params) {\
73: math1(r, method_name, params, &name);\
74: }
75: #define MATH1P(name_parser, name_c) \
76: static void _##name_parser(Request& r, const String& method_name, MethodParams *params) {\
77: math1(r, method_name, params, &name_c);\
78: }
79: MATH1(round); MATH1(floor); MATH1P(ceiling, ceil);
1.3 parser 80: MATH1(trunc); MATH1(frac);
1.1 parser 81: MATH1P(abs, fabs); MATH1(sign);
82: MATH1(exp); MATH1(log);
83: MATH1(sin); MATH1(asin);
84: MATH1(cos); MATH1(acos);
85: MATH1(tan); MATH1(atan);
1.3 parser 86: MATH1(degrees); MATH1(radians);
1.1 parser 87: MATH1(sqrt);
88:
89:
90: typedef double (*math2_func_ptr)(double, double);
91: static void math2(Request& r,
92: const String& method_name, MethodParams *params,
93: math2_func_ptr func) {
94: Pool& pool=r.pool();
1.3 parser 95: Value& a=params->as_junction(0, "parameter must be expression");
96: Value& b=params->as_junction(1, "parameter must be expression");
1.1 parser 97:
98: Value& result=*new(pool) VDouble(pool, (*func)(
99: r.process(a).as_double(),
100: r.process(b).as_double()));
101: result.set_name(method_name);
102: r.write_no_lang(result);
103: }
104:
105: #define MATH2(name) \
106: static void _##name(Request& r, const String& method_name, MethodParams *params) {\
107: math2(r, method_name, params, &name);\
108: }
109: MATH2(pow);
110:
111: // constructor
112:
113: MMath::MMath(Pool& apool) : Methoded(apool) {
114: set_name(*NEW String(pool(), MATH_CLASS_NAME));
115:
116: // ^FUNC(expr)
117: #define ADD1(name) \
118: add_native_method(#name, Method::CT_STATIC, _##name, 1, 1)
119:
120: ADD1(round); ADD1(floor); ADD1(ceiling);
1.3 parser 121: ADD1(trunc); ADD1(frac);
1.1 parser 122: ADD1(abs); ADD1(sign);
123: ADD1(exp); ADD1(log);
124: ADD1(sin); ADD1(asin);
125: ADD1(cos); ADD1(acos);
126: ADD1(tan); ADD1(atan);
1.3 parser 127: ADD1(degrees); ADD1(radians);
1.1 parser 128: ADD1(sqrt);
1.3 parser 129: ADD1(random);
1.1 parser 130:
131: #define ADD2(name) \
132: add_native_method(#name, Method::CT_STATIC, _##name, 2, 2)
133:
134: // ^pow(x;y)
135: ADD2(pow);
136:
1.5 parser 137: }
138:
139: // in MSVC each thread has it's own pseudo-random sequence
140: // in win32 apache each thread can handle multiple requests
141: // so to get proper randoms we remember random generated in one thread
142: void MMath::configure_admin(Request&) {
143: // setting seed
144: srand(
145: randomizer ^
146: #ifdef WIN32
147: GetCurrentThreadId() ^
148: #else
149: getpid() ^
150: #endif
151: (unsigned int)time(NULL)
152: );
153: if(!randomizer)
154: randomizer=rand();
1.1 parser 155: }
156:
1.2 parser 157: // global variables
158:
159: Methoded *math_base_class;
160: Hash *math_consts;
161:
1.1 parser 162: // creator
163:
164: Methoded *MMath_create(Pool& pool) {
1.2 parser 165: math_consts=new(pool) Hash(pool);
166: math_consts->put(
167: *new(pool) String(pool, "PI"),
1.3 parser 168: new(pool) VDouble(pool, PI));
1.2 parser 169:
170: return math_base_class=new(pool) MMath(pool);
1.1 parser 171: }
E-mail: