00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __ROUTINE_HPP
00014 #define __ROUTINE_HPP
00015 #include <basix/evaluator.hpp>
00016 #include <basix/vector.hpp>
00017 #include <basix/wrap.hpp>
00018 #include <basix/compound.hpp>
00019
00021
00022 namespace mmx {
00023 class environment;
00024
00025
00026
00027
00028
00029 template<typename T>
00030 struct generic_converter {
00031 static inline T make_concrete (const generic& x) {
00032 return as<T,generic> (x); }
00033 static inline generic make_abstract (const T& x) {
00034
00035
00036 return new generic_concrete_rep<T> (x); }
00037 };
00038
00039 STMPL
00040 struct generic_converter<generic> {
00041 static inline generic make_concrete (const generic& x) {
00042 return x; }
00043 static inline generic make_abstract (const generic& x) {
00044 return x; }
00045 };
00046
00047 template<typename T> inline T
00048 make_concrete (const generic& x) {
00049 return generic_converter<T>::make_concrete (x);
00050 }
00051
00052 template<typename T> inline generic
00053 make_abstract (const T& x) {
00054 return generic_converter<T>::make_abstract (x);
00055 }
00056
00057
00058
00059
00060
00061 class routine;
00062 class routine_rep: public rep_struct {
00063 public:
00064 generic name;
00065 public:
00066 inline routine_rep (const generic& name2): name (name2) {}
00067 virtual inline ~routine_rep () {}
00068 virtual generic apply () const;
00069 virtual generic apply (const generic& g1) const;
00070 virtual generic apply (const generic& g1, const generic& g2) const;
00071 virtual generic apply (const vector<generic>& args) const;
00072 virtual vector<nat> signature () const;
00073 virtual void overload (const routine& fun) const;
00074 virtual bool is_overloaded () const;
00075 virtual vector<routine> meanings () const;
00076 virtual generic function_body () const;
00077 virtual generic function_type () const;
00078 virtual routine clone () const;
00079 };
00080
00081 class routine {
00082 INDIRECT_PROTO (routine, routine_rep)
00083 public:
00084 inline const routine_rep* operator * () const { return rep; }
00085 inline routine (): rep (NULL) {}
00086 inline generic operator () () {
00087 return rep->apply (); }
00088 inline generic operator () (const generic& g1) {
00089 return rep->apply (g1); }
00090 inline generic operator () (const generic& g1, const generic& g2) {
00091 return rep->apply (g1, g2); }
00092 inline generic operator () (const vector<generic>& v) {
00093 return rep->apply (v); }
00094 friend inline bool is_nil (const routine& fun);
00095 };
00096 INDIRECT_NULL_IMPL (routine, routine_rep)
00097
00098 inline bool is_nil (const routine& fun) {
00099 return fun.rep == NULL; }
00100 inline syntactic flatten (const routine& fun) {
00101 if (is_nil (fun)) return as_syntactic (GEN_NIL);
00102 else return as_syntactic (fun->name); }
00103
00104 WRAP_INDIRECT_IMPL(inline,routine)
00105
00106
00107
00108
00109
00110 inline generic
00111 eval (const routine& f, const vector<generic>& v) {
00112 return f->apply (v);
00113 }
00114
00115 template<typename C> inline C
00116 eval (const routine& f, const vector<C>& v) {
00117 return as<C> (f->apply (as<vector<generic> > (v)));
00118 }
00119
00120 template<typename C> vector<C>
00121 eval (const vector<routine>& f, const vector<C>& v) {
00122 vector<C> r= fill<C> (N(f));
00123 for (nat i=0; i<N(f); i++)
00124 r[i]= eval (f[i], v);
00125 return r;
00126 }
00127
00128
00129
00130
00131
00132 template<typename D>
00133 class nullary_routine_rep: public routine_rep {
00134 typedef D (*function_type) ();
00135 function_type fun;
00136 public:
00137 nullary_routine_rep (const generic& name, function_type fun2):
00138 routine_rep (name), fun (fun2) {}
00139 generic apply () const {
00140 return make_abstract<D> (fun ());
00141 }
00142 generic apply (const vector<generic>& v) const {
00143 ASSERT (N(v) == 0, "zero arguments expected");
00144 return apply ();
00145 }
00146 vector<nat> signature () const {
00147 return vec<nat> (type_information<D>::id);
00148 }
00149 };
00150
00151 template<>
00152 class nullary_routine_rep<void>: public routine_rep {
00153 typedef void (*function_type) ();
00154 function_type fun;
00155 public:
00156 nullary_routine_rep (const generic& name, function_type fun2):
00157 routine_rep (name), fun (fun2) {}
00158 generic apply () const {
00159 fun ();
00160 return void_value ();
00161 }
00162 generic apply (const vector<generic>& v) const {
00163 ASSERT (N(v) == 0, "zero arguments expected");
00164 return apply ();
00165 }
00166 vector<nat> signature () const {
00167 return vec<nat> ((nat) 0);
00168 }
00169 };
00170
00171 template<typename D> routine
00172 nullary_routine (const generic& name, D (*fun) ()) {
00173 return new nullary_routine_rep<D> (name, fun);
00174 }
00175
00176 extern generic type_name (nat id);
00177
00178 template<typename D, typename S1>
00179 class unary_routine_rep: public routine_rep {
00180 typedef D (*function_type) (const S1&);
00181 function_type fun;
00182 public:
00183 unary_routine_rep (const generic& name, function_type fun2):
00184 routine_rep (name), fun (fun2) {}
00185 generic apply (const generic& x1) const {
00186 return make_abstract<D> (fun (make_concrete<S1> (x1)));
00187 }
00188 generic apply (const vector<generic>& v) const {
00189 ASSERT (N(v) == 1, "one argument expected");
00190 return apply (v[0]);
00191 }
00192 vector<nat> signature () const {
00193 return vec<nat> (type_information<D>::id, type_information<S1>::id);
00194 }
00195 };
00196
00197 template<typename S1>
00198 class unary_routine_rep<void,S1>: public routine_rep {
00199 typedef void (*function_type) (const S1&);
00200 function_type fun;
00201 public:
00202 unary_routine_rep (const generic& name, function_type fun2):
00203 routine_rep (name), fun (fun2) {}
00204 generic apply (const generic& x1) const {
00205 fun (make_concrete<S1> (x1));
00206 return void_value ();
00207 }
00208 generic apply (const vector<generic>& v) const {
00209 ASSERT (N(v) == 1, "one argument expected");
00210 return apply (v[0]);
00211 }
00212 vector<nat> signature () const {
00213 return vec<nat> ((nat) 0, type_information<S1>::id);
00214 }
00215 };
00216
00217 template<typename D, typename S1> routine
00218 unary_routine (const generic& name, D (*fun) (const S1&)) {
00219 return new unary_routine_rep<D,S1> (name, fun);
00220 }
00221
00222 template<typename D, typename S1, typename S2>
00223 class binary_routine_rep: public routine_rep {
00224 typedef D (*function_type) (const S1&, const S2&);
00225 function_type fun;
00226 public:
00227 binary_routine_rep (const generic& name, function_type fun2):
00228 routine_rep (name), fun (fun2) {}
00229 generic apply (const generic& x1, const generic& x2) const {
00230 return make_abstract<D> (fun (make_concrete<S1> (x1),
00231 make_concrete<S2> (x2)));
00232 }
00233 generic apply (const vector<generic>& v) const {
00234 ASSERT (N(v) == 2, "two arguments expected");
00235 return apply (v[0], v[1]);
00236 }
00237 vector<nat> signature () const {
00238 return vec<nat> (type_information<D>::id,
00239 type_information<S1>::id,
00240 type_information<S2>::id);
00241 }
00242 };
00243
00244 template<typename S1, typename S2>
00245 class binary_routine_rep<void,S1,S2>: public routine_rep {
00246 typedef void (*function_type) (const S1&, const S2&);
00247 function_type fun;
00248 public:
00249 binary_routine_rep (const generic& name, function_type fun2):
00250 routine_rep (name), fun (fun2) {}
00251 generic apply (const generic& x1, const generic& x2) const {
00252 fun (make_concrete<S1> (x1), make_concrete<S2> (x2));
00253 return void_value ();
00254 }
00255 generic apply (const vector<generic>& v) const {
00256 ASSERT (N(v) == 2, "two arguments expected");
00257 return apply (v[0], v[1]);
00258 }
00259 vector<nat> signature () const {
00260 return vec<nat> ((nat) 0,
00261 type_information<S1>::id,
00262 type_information<S2>::id);
00263 }
00264 };
00265
00266 template<typename D, typename S1, typename S2> routine
00267 binary_routine (const generic& name, D (*f) (const S1&, const S2&)) {
00268 return new binary_routine_rep<D,S1,S2> (name, f);
00269 }
00270
00271 template<typename D, typename S1, typename S2, typename S3>
00272 class ternary_routine_rep: public routine_rep {
00273 typedef D (*function_type) (const S1&, const S2&, const S3&);
00274 function_type fun;
00275 public:
00276 ternary_routine_rep (const generic& name, function_type fun2):
00277 routine_rep (name), fun (fun2) {}
00278 generic apply (const vector<generic>& v) const {
00279 ASSERT (N(v) == 3, "three arguments expected");
00280 return make_abstract<D> (fun (make_concrete<S1> (v[0]),
00281 make_concrete<S2> (v[1]),
00282 make_concrete<S3> (v[2])));
00283 }
00284 vector<nat> signature () const {
00285 return vec<nat> (type_information<D>::id,
00286 type_information<S1>::id,
00287 type_information<S2>::id,
00288 type_information<S3>::id);
00289 }
00290 };
00291
00292 template<typename S1, typename S2, typename S3>
00293 class ternary_routine_rep<void,S1,S2,S3>: public routine_rep {
00294 typedef void (*function_type) (const S1&, const S2&, const S3&);
00295 function_type fun;
00296 public:
00297 ternary_routine_rep (const generic& name, function_type fun2):
00298 routine_rep (name), fun (fun2) {}
00299 generic apply (const vector<generic>& v) const {
00300 ASSERT (N(v) == 3, "three arguments expected");
00301 fun (make_concrete<S1> (v[0]),
00302 make_concrete<S2> (v[1]),
00303 make_concrete<S3> (v[2]));
00304 return void_value ();
00305 }
00306 vector<nat> signature () const {
00307 return vec<nat> ((nat) 0,
00308 type_information<S1>::id,
00309 type_information<S2>::id,
00310 type_information<S3>::id);
00311 }
00312 };
00313
00314 template<typename D, typename S1, typename S2, typename S3> routine
00315 ternary_routine (const generic& name,
00316 D (*f) (const S1&, const S2&, const S3&)) {
00317 return new ternary_routine_rep<D,S1,S2,S3> (name, f);
00318 }
00319
00320 template<typename D, typename S1, typename S2, typename S3, typename S4>
00321 class quaternary_routine_rep: public routine_rep {
00322 typedef D (*function_type) (const S1&, const S2&, const S3&, const S4&);
00323 function_type fun;
00324 public:
00325 quaternary_routine_rep (const generic& name, function_type fun2):
00326 routine_rep (name), fun (fun2) {}
00327 generic apply (const vector<generic>& v) const {
00328 ASSERT (N(v) == 4, "four arguments expected");
00329 return make_abstract<D> (fun (make_concrete<S1> (v[0]),
00330 make_concrete<S2> (v[1]),
00331 make_concrete<S3> (v[2]),
00332 make_concrete<S4> (v[3])));
00333 }
00334 vector<nat> signature () const {
00335 return vec<nat> (type_information<D>::id,
00336 type_information<S1>::id,
00337 type_information<S2>::id,
00338 type_information<S3>::id,
00339 type_information<S4>::id);
00340 }
00341 };
00342
00343 template<typename S1, typename S2, typename S3, typename S4>
00344 class quaternary_routine_rep<void,S1,S2,S3,S4>: public routine_rep {
00345 typedef void (*function_type) (const S1&, const S2&, const S3&, const S4&);
00346 function_type fun;
00347 public:
00348 quaternary_routine_rep (const generic& name, function_type fun2):
00349 routine_rep (name), fun (fun2) {}
00350 generic apply (const vector<generic>& v) const {
00351 ASSERT (N(v) == 4, "four arguments expected");
00352 fun (make_concrete<S1> (v[0]),
00353 make_concrete<S2> (v[1]),
00354 make_concrete<S3> (v[2]),
00355 make_concrete<S4> (v[3]));
00356 return void_value ();
00357 }
00358 vector<nat> signature () const {
00359 return vec<nat> ((nat) 0,
00360 type_information<S1>::id,
00361 type_information<S2>::id,
00362 type_information<S3>::id,
00363 type_information<S4>::id);
00364 }
00365 };
00366
00367 template<typename D, typename S1, typename S2, typename S3, typename S4> routine
00368 quaternary_routine (const generic& name,
00369 D (*f) (const S1&, const S2&, const S3&,const S4&)) {
00370 return new quaternary_routine_rep<D,S1,S2,S3,S4> (name, f);
00371 }
00372
00373 template<typename D, typename S1, typename S2, typename S3,
00374 typename S4, typename S5>
00375 class quintary_routine_rep: public routine_rep {
00376 typedef D (*function_type) (const S1&, const S2&, const S3&,
00377 const S4&, const S5&);
00378 function_type fun;
00379 public:
00380 quintary_routine_rep (const generic& name, function_type fun2):
00381 routine_rep (name), fun (fun2) {}
00382 generic apply (const vector<generic>& v) const {
00383 ASSERT (N(v) == 5, "five arguments expected");
00384 return make_abstract<D> (fun (make_concrete<S1> (v[0]),
00385 make_concrete<S2> (v[1]),
00386 make_concrete<S3> (v[2]),
00387 make_concrete<S4> (v[3]),
00388 make_concrete<S5> (v[4])));
00389 }
00390 vector<nat> signature () const {
00391 return vec<nat> (type_information<D>::id,
00392 type_information<S1>::id,
00393 type_information<S2>::id,
00394 type_information<S3>::id,
00395 type_information<S4>::id,
00396 type_information<S5>::id);
00397 }
00398 };
00399
00400 template<typename S1, typename S2, typename S3, typename S4, typename S5>
00401 class quintary_routine_rep<void,S1,S2,S3,S4,S5>: public routine_rep {
00402 typedef void (*function_type) (const S1&, const S2&, const S3&,
00403 const S4&, const S5&);
00404 function_type fun;
00405 public:
00406 quintary_routine_rep (const generic& name, function_type fun2):
00407 routine_rep (name), fun (fun2) {}
00408 generic apply (const vector<generic>& v) const {
00409 ASSERT (N(v) == 4, "four arguments expected");
00410 fun (make_concrete<S1> (v[0]),
00411 make_concrete<S2> (v[1]),
00412 make_concrete<S3> (v[2]),
00413 make_concrete<S4> (v[3]),
00414 make_concrete<S4> (v[4]));
00415 return void_value ();
00416 }
00417 vector<nat> signature () const {
00418 return vec<nat> ((nat) 0,
00419 type_information<S1>::id,
00420 type_information<S2>::id,
00421 type_information<S3>::id,
00422 type_information<S4>::id,
00423 type_information<S5>::id);
00424 }
00425 };
00426
00427 template<typename D, typename S1, typename S2, typename S3,
00428 typename S4, typename S5> routine
00429 quintary_routine (const generic& name,
00430 D (*f) (const S1&, const S2&, const S3&,
00431 const S4&, const S5&)) {
00432 return new quintary_routine_rep<D,S1,S2,S3,S4,S5> (name, f);
00433 }
00434
00435
00436
00437
00438
00439 routine identity_routine (const vector<nat>& sig);
00440 routine compose (const routine& fun, const vector<routine>& args);
00441 inline routine compose (const routine& fun, const routine& arg) {
00442 return compose (fun, vec (arg)); }
00443 routine change_signature (const routine& r, const vector<nat>& sig);
00444 routine default_routine (const generic& name);
00445 routine integrate (const routine& fun);
00446
00447 }
00448 #endif // __ROUTINE_HPP