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