Actually call on_reset callback
[lsnes.git] / include / library / mathexpr.hpp
blob2da37f3f88f1656d72489ac425630cab4bb334fa
1 #ifndef _library__mathexpr__hpp__included__
2 #define _library__mathexpr__hpp__included__
4 #include <functional>
5 #include <vector>
6 #include <stdexcept>
7 #include "gc.hpp"
8 #include "mathexpr-error.hpp"
9 #include <set>
11 namespace mathexpr
13 struct typeinfo;
14 struct mathexpr;
16 struct value
18 typeinfo* type;
19 void* _value;
22 struct _format
24 enum _type
26 BOOLEAN,
27 BINARY,
28 OCTAL,
29 DECIMAL,
30 HEXADECIMAL,
31 STRING,
32 DEFAULT,
33 } type;
34 bool showsign;
35 bool fillzeros;
36 int width;
37 int precision;
38 bool uppercasehex;
41 struct operinfo
43 operinfo(std::string funcname);
44 operinfo(std::string opername, unsigned _operands, int _percedence, bool _rtl = false);
45 virtual ~operinfo();
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.
54 struct typeinfo
56 virtual ~typeinfo();
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)
74 void* p = allocate();
75 try {
76 copy(p, src);
77 } catch(...) {
78 deallocate(p);
79 throw;
81 return p;
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)
96 ~operinfo_wrapper()
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& {
105 auto r = f();
106 return *(T*)r._value;
109 *(T*)(target._value) = fn(_promises);
111 private:
112 T (*fn)(std::vector<std::function<T&()>> promises);
115 template<class T> struct opfun_info
117 std::string name;
118 T (*_fn)(std::vector<std::function<T&()>> promises);
119 bool is_operator;
120 unsigned operands;
121 int precedence;
122 bool rtl;
125 template<class T> struct operinfo_set
127 operinfo_set(std::initializer_list<opfun_info<T>> list)
129 for(auto i : list) {
130 if(i.is_operator)
131 set.insert(new operinfo_wrapper<T>(i.name, i.operands, i.precedence,
132 i.rtl, i._fn));
133 else
134 set.insert(new operinfo_wrapper<T>(i.name, i._fn));
137 ~operinfo_set()
139 for(auto i : set)
140 delete i;
142 std::set<operinfo*>& get_set()
144 return set;
146 private:
147 std::set<operinfo*> set;
150 template<class T> struct typeinfo_wrapper : public typeinfo
152 struct unsigned_tag {};
153 struct signed_tag {};
154 struct float_tag {};
155 struct boolean_tag {};
156 ~typeinfo_wrapper()
159 void* allocate()
161 return new T;
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)
185 delete (T*)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();
219 for(auto i : tmp)
220 ret.insert(i);
221 return ret;
225 class mathexpr : public GC::item
227 public:
228 enum eval_state
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);
251 //Dtor.
252 ~mathexpr();
253 //Copy ctor.
254 mathexpr(const mathexpr& m);
255 mathexpr& operator=(const mathexpr& m);
256 //Evaluate. Returns pointer to internal state.
257 value evaluate();
258 //Get type.
259 typeinfo& get_type() { return type; }
260 //Reset.
261 void reset();
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);
265 protected:
266 void trace();
267 private:
268 void mark_error_and_throw(error::errorcode _errcode, const std::string& _error);
269 eval_state state;
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;
280 #endif