Annotation of parser3/src/classes/math.C, revision 1.3
1.1 parser 1: /** @file
2: Parser: @b math parser class.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
5:
6: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
7: */
1.3 ! parser 8: static const char *RCSId="$Id: math.C,v 1.2 2001/07/06 11:13:35 parser Exp $";
1.1 parser 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:
16: // defines
17:
1.3 ! parser 18: #define PI 3.1415926535
1.1 parser 19: #define MATH_CLASS_NAME "math"
20:
21: // class
22:
23: class MMath : public Methoded {
24: public:
25: MMath(Pool& pool);
26: public: // Methoded
27: bool used_directly() { return true; }
28: };
29:
30: // methods
31:
32: static void _random(Request& r, const String& method_name, MethodParams *params) {
33: Pool& pool=r.pool();
34:
1.3 ! parser 35: Value& range=params->as_junction(0, "range must be expression");
1.1 parser 36: uint max=(uint)r.process(range).as_double();
37: if(max<=1)
38: PTHROW(0, 0,
39: &method_name,
40: "bad range [0..%u]", max);
41:
42: r.write_no_lang(*new(pool) VInt(pool, rand()%max));
43: }
44:
45:
46: typedef double (*math1_func_ptr)(double);
47: static double round(double param) { return floor(param+0.5); }
48: static double sign(double param) { return param > 0 ? 1 : ( param < 0 ? -1 : 0 ); }
1.3 ! parser 49: static double trunc(double param) { return param > 0? floor(param) : ceil(param); }
! 50: static double frac(double param) { return param-trunc(param); }
! 51: static double degrees(double param) { return param /PI *180; }
! 52: static double radians(double param) { return param /180 *PI; }
1.1 parser 53:
54: static void math1(Request& r,
55: const String& method_name, MethodParams *params,
56: math1_func_ptr func) {
57: Pool& pool=r.pool();
1.3 ! parser 58: Value& param=params->as_junction(0, "parameter must be expression");
1.1 parser 59:
60: Value& result=*new(pool) VDouble(pool, (*func)(r.process(param).as_double()));
61: result.set_name(method_name);
62: r.write_no_lang(result);
63: }
64:
65: #define MATH1(name) \
66: static void _##name(Request& r, const String& method_name, MethodParams *params) {\
67: math1(r, method_name, params, &name);\
68: }
69: #define MATH1P(name_parser, name_c) \
70: static void _##name_parser(Request& r, const String& method_name, MethodParams *params) {\
71: math1(r, method_name, params, &name_c);\
72: }
73: MATH1(round); MATH1(floor); MATH1P(ceiling, ceil);
1.3 ! parser 74: MATH1(trunc); MATH1(frac);
1.1 parser 75: MATH1P(abs, fabs); MATH1(sign);
76: MATH1(exp); MATH1(log);
77: MATH1(sin); MATH1(asin);
78: MATH1(cos); MATH1(acos);
79: MATH1(tan); MATH1(atan);
1.3 ! parser 80: MATH1(degrees); MATH1(radians);
1.1 parser 81: MATH1(sqrt);
82:
83:
84: typedef double (*math2_func_ptr)(double, double);
85: static void math2(Request& r,
86: const String& method_name, MethodParams *params,
87: math2_func_ptr func) {
88: Pool& pool=r.pool();
1.3 ! parser 89: Value& a=params->as_junction(0, "parameter must be expression");
! 90: Value& b=params->as_junction(1, "parameter must be expression");
1.1 parser 91:
92: Value& result=*new(pool) VDouble(pool, (*func)(
93: r.process(a).as_double(),
94: r.process(b).as_double()));
95: result.set_name(method_name);
96: r.write_no_lang(result);
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:
107: MMath::MMath(Pool& apool) : Methoded(apool) {
108: set_name(*NEW String(pool(), MATH_CLASS_NAME));
109:
110:
111: // setting seed
112: srand(getpid()+time(NULL)); rand();
113:
114: // ^FUNC(expr)
115: #define ADD1(name) \
116: add_native_method(#name, Method::CT_STATIC, _##name, 1, 1)
117:
118: ADD1(round); ADD1(floor); ADD1(ceiling);
1.3 ! parser 119: ADD1(trunc); ADD1(frac);
1.1 parser 120: ADD1(abs); ADD1(sign);
121: ADD1(exp); ADD1(log);
122: ADD1(sin); ADD1(asin);
123: ADD1(cos); ADD1(acos);
124: ADD1(tan); ADD1(atan);
1.3 ! parser 125: ADD1(degrees); ADD1(radians);
1.1 parser 126: ADD1(sqrt);
1.3 ! parser 127: ADD1(random);
1.1 parser 128:
129: #define ADD2(name) \
130: add_native_method(#name, Method::CT_STATIC, _##name, 2, 2)
131:
132: // ^pow(x;y)
133: ADD2(pow);
134:
135: }
136:
1.2 parser 137: // global variables
138:
139: Methoded *math_base_class;
140: Hash *math_consts;
141:
1.1 parser 142: // creator
143:
144: Methoded *MMath_create(Pool& pool) {
1.2 parser 145: math_consts=new(pool) Hash(pool);
146: math_consts->put(
147: *new(pool) String(pool, "PI"),
1.3 ! parser 148: new(pool) VDouble(pool, PI));
1.2 parser 149:
150: return math_base_class=new(pool) MMath(pool);
1.1 parser 151: }
E-mail: