1 #ifndef _library__mathexpr__hpp__included__
2 #define _library__mathexpr__hpp__included__
8 #include "mathexpr-error.hpp"
43 operinfo(std::string funcname
);
44 operinfo(std::string opername
, unsigned _operands
, int _percedence
, bool _rtl
= false);
46 virtual void evaluate(value target
, std::vector
<std::function
<value()>> promises
) = 0;
47 const std::string fnname
;
48 const bool is_operator
;
49 const unsigned operands
; //Only for operators (max 2 operands).
50 const int precedence
; //Higher binds more tightly.
51 const bool rtl
; //If true, Right-to-left associvity.
57 virtual void* allocate() = 0;
58 virtual void* parse(const std::string
& str
, bool string
) = 0;
59 virtual void parse_u(void* obj
, uint64_t v
) = 0;
60 virtual void parse_s(void* obj
, int64_t v
) = 0;
61 virtual void parse_f(void* obj
, double v
) = 0;
62 virtual void parse_b(void* obj
, bool v
) = 0;
63 virtual void scale(void* val
, uint64_t scale
) = 0;
64 virtual void deallocate(void* obj
) = 0;
65 virtual void copy(void* target
, void* source
) = 0;
66 virtual std::string
tostring(void* obj
) = 0;
67 virtual std::string
format(void* obj
, _format fmt
) = 0;
68 virtual uint64_t tounsigned(void* obj
) = 0;
69 virtual int64_t tosigned(void* obj
) = 0;
70 virtual bool toboolean(void* obj
) = 0;
71 virtual std::set
<operinfo
*> operations() = 0;
72 void* copy_allocate(void* src
)
85 template<class T
> struct operinfo_wrapper
: public operinfo
87 operinfo_wrapper(std::string funcname
, T (*_fn
)(std::vector
<std::function
<T
&()>> promises
))
88 : operinfo(funcname
), fn(_fn
)
91 operinfo_wrapper(std::string opername
, unsigned _operands
, int _percedence
, bool _rtl
,
92 T (*_fn
)(std::vector
<std::function
<T
&()>> promises
))
93 : operinfo(opername
, _operands
, _percedence
, _rtl
), fn(_fn
)
99 void evaluate(value target
, std::vector
<std::function
<value()>> promises
)
101 std::vector
<std::function
<T
&()>> _promises
;
102 for(auto i
: promises
) {
103 std::function
<value()> f
= i
;
104 _promises
.push_back([f
, this]() -> T
& {
106 return *(T
*)r
._value
;
109 *(T
*)(target
._value
) = fn(_promises
);
112 T (*fn
)(std::vector
<std::function
<T
&()>> promises
);
115 template<class T
> struct opfun_info
118 T (*_fn
)(std::vector
<std::function
<T
&()>> promises
);
125 template<class T
> struct operinfo_set
127 operinfo_set(std::initializer_list
<opfun_info
<T
>> list
)
131 set
.insert(new operinfo_wrapper
<T
>(i
.name
, i
.operands
, i
.precedence
,
134 set
.insert(new operinfo_wrapper
<T
>(i
.name
, i
._fn
));
142 std::set
<operinfo
*>& get_set()
147 std::set
<operinfo
*> set
;
150 template<class T
> struct typeinfo_wrapper
: public typeinfo
152 struct unsigned_tag
{};
153 struct signed_tag
{};
155 struct boolean_tag
{};
163 void* parse(const std::string
& str
, bool string
)
165 return new T(str
, string
);
167 void parse_u(void* obj
, uint64_t v
)
169 *(T
*)obj
= T(unsigned_tag(), v
);
171 void parse_s(void* obj
, int64_t v
)
173 *(T
*)obj
= T(signed_tag(), v
);
175 void parse_f(void* obj
, double v
)
177 *(T
*)obj
= T(float_tag(), v
);
179 void parse_b(void* obj
, bool b
)
181 *(T
*)obj
= T(boolean_tag(), b
);
183 void deallocate(void* obj
)
187 void copy(void* target
, void* source
)
189 *(T
*)target
= *(T
*)source
;
191 std::string
tostring(void* obj
)
193 return ((T
*)obj
)->tostring();
195 std::string
format(void* obj
, _format fmt
)
197 return ((T
*)obj
)->format(fmt
);
199 uint64_t tounsigned(void* obj
)
201 return ((T
*)obj
)->tounsigned();
203 int64_t tosigned(void* obj
)
205 return ((T
*)obj
)->tosigned();
207 bool toboolean(void* obj
)
209 return ((T
*)obj
)->toboolean();
211 void scale(void* val
, uint64_t _scale
)
213 return ((T
*)val
)->scale(_scale
);
215 std::set
<operinfo
*> operations()
217 std::set
<operinfo
*> ret
;
218 auto tmp
= T::operations();
225 class mathexpr
: public GC::item
230 TO_BE_EVALUATED
, //Not even attempted to evaluate yet.
231 EVALUATING
, //Evaluation in progress.
232 EVALUATED
, //Evaluation completed, value available.
233 FIXED
, //This operand has fixed value.
234 UNDEFINED
, //This operand has undefined value.
235 FAILED
, //Evaluation failed.
236 FORWARD
, //Forward evaluation to first of args.
237 FORWARD_EVALING
, //Forward evaluation to first of args, evaluating.
238 FORWARD_EVALD
, //Forward evaluation to first of args, evaluated.
240 //Undefined value of specified type.
241 mathexpr(typeinfo
* _type
);
242 //Forward evaluation.
243 mathexpr(typeinfo
* _type
, GC::pointer
<mathexpr
> fwd
);
244 //Value of specified type.
245 mathexpr(value value
);
246 //Value of specified type.
247 mathexpr(typeinfo
* _type
, const std::string
& value
, bool string
);
248 //Specified Operator.
249 mathexpr(typeinfo
* _type
, operinfo
* fn
, std::vector
<GC::pointer
<mathexpr
>> _args
,
250 bool _owns_operator
= false);
254 mathexpr(const mathexpr
& m
);
255 mathexpr
& operator=(const mathexpr
& m
);
256 //Evaluate. Returns pointer to internal state.
259 typeinfo
& get_type() { return type
; }
262 //Parse an expression.
263 static GC::pointer
<mathexpr
> parse(typeinfo
& _type
, const std::string
& expr
,
264 std::function
<GC::pointer
<mathexpr
>(const std::string
&)> vars
);
268 void mark_error_and_throw(error::errorcode _errcode
, const std::string
& _error
);
270 typeinfo
& type
; //Type of value.
271 void* _value
; //Value if state is EVALUATED or FIXED.
272 operinfo
* fn
; //Function (if state is TO_BE_EVALUATED, EVALUATING or EVALUATED)
273 error::errorcode errcode
; //Error code if state is FAILED.
274 std::string _error
; //Error message if state is FAILED.
275 std::vector
<mathexpr
*> arguments
;
276 mutable bool owns_operator
;