2 This file is part of libmspparser
3 Copyright © 2006 Mikko Rasa, Mikkosoft Productions
4 Distributed under the LGPL
6 #ifndef MSP_PARSER_LOADER_H_
7 #define MSP_PARSER_LOADER_H_
10 #include <msp/error.h>
12 #include "statement.h"
24 virtual void execute(L &, const Statement &) const=0;
25 virtual ~LoaderAction() { }
31 class LoaderFunc0: public LoaderAction<L>
34 typedef void (L::*FuncType)();
36 LoaderFunc0(FuncType f): func(f) { }
37 void execute(L &l, const Statement &st) const
39 if(st.args.size()!=0) throw TypeError("Wrong number of arguments");
46 template<typename L, typename A0>
47 class LoaderFunc1: public LoaderAction<L>
50 typedef void (L::*FuncType)(A0);
52 LoaderFunc1(FuncType f): func(f) { }
53 void execute(L &l, const Statement &st) const
55 if(st.args.size()!=1) throw TypeError("Wrong number of arguments");
56 (l.*func)(st.args[0].get<A0>());
62 template<typename L, typename A0, typename A1>
63 class LoaderFunc2: public LoaderAction<L>
66 typedef void (L::*FuncType)(A0, A1);
68 LoaderFunc2(FuncType f): func(f) { }
69 void execute(L &l, const Statement &st) const
71 if(st.args.size()!=2) throw TypeError("Wrong number of arguments");
72 (l.*func)(st.args[0].get<A0>(), st.args[1].get<A1>());
78 template<typename L, typename A0, typename A1, typename A2>
79 class LoaderFunc3: public LoaderAction<L>
82 typedef void (L::*FuncType)(A0, A1, A2);
84 LoaderFunc3(FuncType f): func(f) { }
85 void execute(L &l, const Statement &st) const
87 if(st.args.size()!=3) throw TypeError("Wrong number of arguments");
88 (l.*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>());
94 template<typename L, typename A0, typename A1, typename A2, typename A3>
95 class LoaderFunc4: public LoaderAction<L>
98 typedef void (L::*FuncType)(A0, A1, A2, A3);
100 LoaderFunc4(FuncType f): func(f) { }
101 void execute(L &l, const Statement &st) const
103 if(st.args.size()!=4) throw TypeError("Wrong number of arguments");
104 (l.*func)(st.args[0].get<A0>(), st.args[1].get<A1>(), st.args[2].get<A2>(), st.args[3].get<A3>());
110 template<typename L, typename T>
111 class LoadValue: public LoaderAction<L>
114 typedef T L::ObjectType::*PointerType;
116 LoadValue(PointerType p): ptr(p) { }
117 void execute(L &l, const Statement &st) const
119 if(st.args.size()!=1) throw TypeError("Wrong number of arguments");
120 l.get_object().*ptr=st.args[0].get<T>();
126 template<typename L, typename S>
127 class SubLoader0: public LoaderAction<L>
130 typedef typename S::ObjectType &(L::*FuncType)();
132 SubLoader0(FuncType f): func(f) { }
133 void execute(L &l, const Statement &st) const
135 if(st.args.size()!=0) throw TypeError("Wrong number of arguments");
136 typename S::ObjectType &obj=(l.*func)();
144 template<typename L, typename S, typename A0>
145 class SubLoader1: public LoaderAction<L>
148 typedef typename S::ObjectType &(L::*FuncType)(A0);
150 SubLoader1(FuncType f): func(f) { }
151 void execute(L &l, const Statement &st) const
153 if(st.args.size()!=1) throw TypeError("Wrong number of arguments");
154 typename S::ObjectType &obj=(l.*func)(st.args[0].get<A0>());
162 template<typename C, typename L>
166 typedef C ObjectType;
168 C &get_object() { return obj; }
169 void load(const Statement &st)
171 for(std::list<Statement>::const_iterator i=st.sub.begin(); i!=st.sub.end(); ++i)
178 Statement st=p.parse();
185 for(typename ActionMap::iterator i=actions.begin(); i!=actions.end(); ++i)
189 typedef std::map<std::string, LoaderAction<L > *> ActionMap;
193 Loader(C &o): obj(o) { }
195 void add(const std::string &k, void (L::*func)())
196 { actions.insert(typename ActionMap::value_type(k, new LoaderFunc0<L>(func))); }
198 template<typename A0>
199 void add(const std::string &k, void (L::*func)(A0))
200 { actions.insert(typename ActionMap::value_type(k, new LoaderFunc1<L, A0>(func))); }
202 template<typename A0, typename A1>
203 void add(const std::string &k, void (L::*func)(A0, A1))
204 { actions.insert(typename ActionMap::value_type(k, new LoaderFunc2<L, A0, A1>(func))); }
206 template<typename A0, typename A1, typename A2>
207 void add(const std::string &k, void (L::*func)(A0, A1, A2))
208 { actions.insert(typename ActionMap::value_type(k, new LoaderFunc3<L, A0, A1, A2>(func))); }
210 template<typename A0, typename A1, typename A2, typename A3>
211 void add(const std::string &k, void (L::*func)(A0, A1, A2, A3))
212 { actions.insert(typename ActionMap::value_type(k, new LoaderFunc4<L, A0, A1, A2, A3>(func))); }
215 void add(const std::string &k, typename S::ObjectType &(L::*func)())
216 { actions.insert(typename ActionMap::value_type(k, new SubLoader0<L, S>(func))); }
218 template<typename S, typename A0>
219 void add(const std::string &k, typename S::ObjectType &(L::*func)(A0))
220 { actions.insert(typename ActionMap::value_type(k, new SubLoader1<L, S, A0>(func))); }
223 void add(const std::string &k, T C::*p)
224 { actions.insert(typename ActionMap::value_type(k, new LoadValue<L, T>(p))); }
228 void load_statement(const Statement &st)
230 typename ActionMap::iterator j=actions.find(st.keyword);
232 throw Exception(st.get_location()+": Unknown keyword '"+st.keyword+"'");
233 j->second->execute(dynamic_cast<L &>(*this), st);
237 } // namespace Parser