diff options
Diffstat (limited to 'linden/indra/llmath/llcalcparser.h')
-rw-r--r-- | linden/indra/llmath/llcalcparser.h | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/linden/indra/llmath/llcalcparser.h b/linden/indra/llmath/llcalcparser.h index c405b62..d8acc1f 100644 --- a/linden/indra/llmath/llcalcparser.h +++ b/linden/indra/llmath/llcalcparser.h | |||
@@ -10,24 +10,37 @@ | |||
10 | #ifndef LL_CALCPARSER_H | 10 | #ifndef LL_CALCPARSER_H |
11 | #define LL_CALCPARSER_H | 11 | #define LL_CALCPARSER_H |
12 | 12 | ||
13 | #include <boost/version.hpp> | ||
14 | #if BOOST_VERSION >= 103600 | ||
15 | #include <boost/spirit/include/classic_attribute.hpp> | ||
16 | #include <boost/spirit/include/classic_core.hpp> | ||
17 | #include <boost/spirit/include/classic_error_handling.hpp> | ||
18 | #include <boost/spirit/include/classic_position_iterator.hpp> | ||
19 | #include <boost/spirit/include/phoenix1_binders.hpp> | ||
20 | #include <boost/spirit/include/classic_symbols.hpp> | ||
21 | using namespace boost::spirit::classic; | ||
22 | #else | ||
13 | #include <boost/spirit/attribute.hpp> | 23 | #include <boost/spirit/attribute.hpp> |
14 | #include <boost/spirit/core.hpp> | 24 | #include <boost/spirit/core.hpp> |
15 | #include <boost/spirit/error_handling.hpp> | 25 | #include <boost/spirit/error_handling.hpp> |
16 | #include <boost/spirit/iterator/position_iterator.hpp> | 26 | #include <boost/spirit/iterator/position_iterator.hpp> |
17 | #include <boost/spirit/phoenix/binders.hpp> | 27 | #include <boost/spirit/phoenix/binders.hpp> |
18 | //#include <boost/spirit/symbols/symbols.hpp> | 28 | #include <boost/spirit/symbols/symbols.hpp> |
29 | using namespace boost::spirit; | ||
30 | #endif | ||
31 | |||
19 | #include <map> | 32 | #include <map> |
20 | #include <string> | 33 | #include <string> |
21 | 34 | ||
22 | #include "llcalc.h" | 35 | #include "llcalc.h" |
23 | #include "llmath.h" | 36 | #include "llmath.h" |
24 | 37 | ||
25 | struct LLCalcParser : boost::spirit::grammar<LLCalcParser> | 38 | struct LLCalcParser : grammar<LLCalcParser> |
26 | { | 39 | { |
27 | LLCalcParser(F32& result, LLCalc::calc_map_t* constants, LLCalc::calc_map_t* vars) : | 40 | LLCalcParser(F32& result, LLCalc::calc_map_t* constants, LLCalc::calc_map_t* vars) : |
28 | mResult(result), mConstants(constants), mVariables(vars) {}; | 41 | mResult(result), mConstants(constants), mVariables(vars) {}; |
29 | 42 | ||
30 | struct value_closure : boost::spirit::closure<value_closure, F32> | 43 | struct value_closure : closure<value_closure, F32> |
31 | { | 44 | { |
32 | member1 value; | 45 | member1 value; |
33 | }; | 46 | }; |
@@ -36,21 +49,20 @@ struct LLCalcParser : boost::spirit::grammar<LLCalcParser> | |||
36 | struct definition | 49 | struct definition |
37 | { | 50 | { |
38 | // Rule declarations | 51 | // Rule declarations |
39 | boost::spirit::rule<ScannerT> statement, identifier; | 52 | rule<ScannerT> statement, identifier; |
40 | boost::spirit::rule<ScannerT, value_closure::context_t> expression, term, | 53 | rule<ScannerT, value_closure::context_t> expression, term, |
41 | power, | 54 | power, |
42 | unary_expr, | 55 | unary_expr, |
43 | factor, | 56 | factor, |
44 | /*unary_func, | 57 | unary_func, |
45 | /binary_func,*/ | 58 | binary_func, |
46 | group; | 59 | group; |
47 | 60 | ||
48 | // start() should return the starting symbol | 61 | // start() should return the starting symbol |
49 | boost::spirit::rule<ScannerT> const& start() const { return statement; } | 62 | rule<ScannerT> const& start() const { return statement; } |
50 | 63 | ||
51 | definition(LLCalcParser const& self) | 64 | definition(LLCalcParser const& self) |
52 | { | 65 | { |
53 | using namespace boost::spirit; | ||
54 | using namespace phoenix; | 66 | using namespace phoenix; |
55 | 67 | ||
56 | assertion<std::string> assert_domain("Domain error"); | 68 | assertion<std::string> assert_domain("Domain error"); |
@@ -64,30 +76,30 @@ struct LLCalcParser : boost::spirit::grammar<LLCalcParser> | |||
64 | group = | 76 | group = |
65 | '(' >> expression[group.value = arg1] >> assert_syntax(ch_p(')')) | 77 | '(' >> expression[group.value = arg1] >> assert_syntax(ch_p(')')) |
66 | ; | 78 | ; |
67 | 79 | ||
68 | /*unary_func = | 80 | unary_func = |
69 | ((str_p("SIN") >> '(' >> expression[unary_func.value = bind(&sin)(DEG_TO_RAD * arg1)]) | | 81 | ((str_p("SIN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sin)(self,arg1)]) | |
70 | (str_p("COS") >> '(' >> expression[unary_func.value = bind(&cos)(DEG_TO_RAD * arg1)]) | | 82 | (str_p("COS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_cos)(self,arg1)]) | |
71 | (str_p("TAN") >> '(' >> expression[unary_func.value = bind(&tan)(DEG_TO_RAD * arg1)]) | | 83 | (str_p("TAN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_tan)(self,arg1)]) | |
72 | (str_p("ASIN") >> '(' >> expression[unary_func.value = (bind(&asin)(arg1)) * RAD_TO_DEG]) | | 84 | (str_p("ASIN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_asin)(self,arg1)]) | |
73 | (str_p("ACOS") >> '(' >> expression[unary_func.value = bind(&acos)(arg1) * RAD_TO_DEG]) | | 85 | (str_p("ACOS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_acos)(self,arg1)]) | |
74 | (str_p("ATAN") >> '(' >> expression[unary_func.value = bind(&atan)(arg1) * RAD_TO_DEG]) | | 86 | (str_p("ATAN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_atan)(self,arg1)]) | |
75 | (str_p("SQRT") >> '(' >> expression[unary_func.value = bind(&sqrt)(arg1)]) | | 87 | (str_p("SQRT") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sqrt)(self,arg1)]) | |
76 | (str_p("LOG") >> '(' >> expression[unary_func.value = bind(&log)(arg1)]) | | 88 | (str_p("LOG") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_log)(self,arg1)]) | |
77 | (str_p("EXP") >> '(' >> expression[unary_func.value = bind(&exp)(arg1)]) | | 89 | (str_p("EXP") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_exp)(self,arg1)]) | |
78 | (str_p("ABS") >> '(' >> expression[unary_func.value = bind(&fabs)(arg1)]) | 90 | (str_p("ABS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_fabs)(self,arg1)]) |
79 | ) >> assert_syntax(ch_p(')')) | 91 | ) >> assert_syntax(ch_p(')')) |
80 | ; | 92 | ; |
81 | 93 | ||
82 | binary_func = | 94 | binary_func = |
83 | ((str_p("ATAN2") >> '(' >> expression[binary_func.value = arg1] >> ',' >> | 95 | ((str_p("ATAN2") >> '(' >> expression[binary_func.value = arg1] >> ',' >> |
84 | expression[binary_func.value = bind(&atan2)(binary_func.value, arg1) * RAD_TO_DEG]) | | 96 | expression[binary_func.value = bind(&LLCalcParser::_atan2)(self, binary_func.value, arg1)]) | |
85 | (str_p("MIN") >> '(' >> expression[binary_func.value = arg1] >> ',' >> | 97 | (str_p("MIN") >> '(' >> expression[binary_func.value = arg1] >> ',' >> |
86 | expression[binary_func.value = bind(&LLCalcParser::min)(self, binary_func.value, arg1)]) | | 98 | expression[binary_func.value = bind(&LLCalcParser::min)(self, binary_func.value, arg1)]) | |
87 | (str_p("MAX") >> '(' >> expression[binary_func.value = arg1] >> ',' >> | 99 | (str_p("MAX") >> '(' >> expression[binary_func.value = arg1] >> ',' >> |
88 | expression[binary_func.value = bind(&LLCalcParser::max)(self, binary_func.value, arg1)]) | 100 | expression[binary_func.value = bind(&LLCalcParser::max)(self, binary_func.value, arg1)]) |
89 | ) >> assert_syntax(ch_p(')')) | 101 | ) >> assert_syntax(ch_p(')')) |
90 | ;*/ | 102 | ; |
91 | 103 | ||
92 | // *TODO: Localisation of the decimal point? | 104 | // *TODO: Localisation of the decimal point? |
93 | // Problem, LLLineEditor::postvalidateFloat accepts a comma when appropriate | 105 | // Problem, LLLineEditor::postvalidateFloat accepts a comma when appropriate |
@@ -96,8 +108,8 @@ struct LLCalcParser : boost::spirit::grammar<LLCalcParser> | |||
96 | factor = | 108 | factor = |
97 | (ureal_p[factor.value = arg1] | | 109 | (ureal_p[factor.value = arg1] | |
98 | group[factor.value = arg1] | | 110 | group[factor.value = arg1] | |
99 | /*unary_func[factor.value = arg1] | | 111 | unary_func[factor.value = arg1] | |
100 | binary_func[factor.value = arg1] |*/ | 112 | binary_func[factor.value = arg1] | |
101 | // Lookup throws an Unknown Symbol error if it is unknown, while this works fine, | 113 | // Lookup throws an Unknown Symbol error if it is unknown, while this works fine, |
102 | // would be "neater" to handle symbol lookup from here with an assertive parser. | 114 | // would be "neater" to handle symbol lookup from here with an assertive parser. |
103 | // constants_p[factor.value = arg1]| | 115 | // constants_p[factor.value = arg1]| |
@@ -144,6 +156,22 @@ private: | |||
144 | F32 max(const F32& a, const F32& b) const { return llmax(a, b); } | 156 | F32 max(const F32& a, const F32& b) const { return llmax(a, b); } |
145 | 157 | ||
146 | bool checkNaN(const F32& a) const { return !llisnan(a); } | 158 | bool checkNaN(const F32& a) const { return !llisnan(a); } |
159 | |||
160 | //FIX* non ambigious function fix making SIN() work for calc -Cryogenic Blitz | ||
161 | F32 _sin(const F32& a) const { return sin(DEG_TO_RAD * a); } | ||
162 | F32 _cos(const F32& a) const { return cos(DEG_TO_RAD * a); } | ||
163 | F32 _tan(const F32& a) const { return tan(DEG_TO_RAD * a); } | ||
164 | F32 _asin(const F32& a) const { return asin(a * RAD_TO_DEG); } | ||
165 | F32 _acos(const F32& a) const { return acos(a * RAD_TO_DEG); } | ||
166 | F32 _atan(const F32& a) const { return atan(a * RAD_TO_DEG); } | ||
167 | F32 _sqrt(const F32& a) const { return sqrt(a); } | ||
168 | F32 _log(const F32& a) const { return log(a); } | ||
169 | F32 _exp(const F32& a) const { return exp(a); } | ||
170 | F32 _fabs(const F32& a) const { return fabs(a) * RAD_TO_DEG; } | ||
171 | |||
172 | F32 _atan2(const F32& a,const F32& b) const { return atan2(a,b); } | ||
173 | |||
174 | |||
147 | 175 | ||
148 | LLCalc::calc_map_t* mConstants; | 176 | LLCalc::calc_map_t* mConstants; |
149 | LLCalc::calc_map_t* mVariables; | 177 | LLCalc::calc_map_t* mVariables; |