00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <basix/routine.hpp>
00014 #include <basix/string.hpp>
00015 #include <basix/tuple.hpp>
00016 #include <basix/alias.hpp>
00017 namespace mmx {
00018
00019
00020
00021
00022
00023 vector<generic>
00024 type_name (const vector<nat>& ids) {
00025 nat i, n= N(ids);
00026 vector<generic> ret= fill<generic> (n);
00027 for (i=0; i<n; i++)
00028 ret[i]= type_name (ids[i]);
00029 return ret;
00030 }
00031
00032
00033
00034
00035
00036 generic
00037 routine_rep::apply () const {
00038 return apply (vec<generic> ());
00039 }
00040
00041 generic
00042 routine_rep::apply (const generic& g1) const {
00043 return apply (vec<generic> (g1));
00044 }
00045
00046 generic
00047 routine_rep::apply (const generic& g1, const generic& g2) const {
00048 return apply (vec<generic> (g1, g2));
00049 }
00050
00051 generic
00052 routine_rep::apply (const vector<generic>& v) const {
00053 mmerr << "name= " << name << "\n";
00054 mmerr << "args= " << v << "\n";
00055 ERROR ("not implemented (apply)");
00056 return generic ();
00057 }
00058
00059 vector<nat>
00060 routine_rep::signature () const {
00061 ERROR ("not implemented (signature)");
00062 return vec<nat> ();
00063 }
00064
00065 void
00066 routine_rep::overload (const routine& fun) const {
00067 ERROR ("not implemented (overload)");
00068 }
00069
00070 bool
00071 routine_rep::is_overloaded () const {
00072 return false;
00073 }
00074
00075 vector<routine>
00076 routine_rep::meanings () const {
00077 ERROR ("not implemented (meanings)");
00078 }
00079
00080 generic
00081 routine_rep::function_body () const {
00082 return "native";
00083 }
00084
00085 generic
00086 routine_rep::function_type () const {
00087 return gen (GEN_FUNCTION_TYPE, type_name (signature ()));
00088 }
00089
00090 routine
00091 routine_rep::clone () const {
00092 ERROR ("not implemented (clone)");
00093 return routine (this, true);
00094 }
00095
00096
00097
00098
00099
00100 class identity_routine_rep: public routine_rep {
00101 vector<nat> sig;
00102 public:
00103 identity_routine_rep (const vector<nat>& sig2):
00104 routine_rep (GEN_IDENTITY), sig (sig2) {}
00105 generic apply (const generic& x) const { return x; }
00106 generic apply (const vector<generic>& v) const {
00107 ASSERT (N(v) == 1, "one argument expected"); return apply (v[0]); }
00108 vector<nat> signature () const { return sig; }
00109 };
00110
00111 routine
00112 identity_routine (const vector<nat>& sig) {
00113
00114
00115 ASSERT (N(sig) == 2, "identity routine should take one argument");
00116 return new identity_routine_rep (sig);
00117 }
00118
00119
00120
00121
00122
00123 class composed_routine_rep: public routine_rep {
00124 routine fun;
00125 const vector<routine> args;
00126 vector<nat> sig;
00127 public:
00128 composed_routine_rep (const routine& fun2, const vector<routine>& args2):
00129 routine_rep (gen (GEN_COMPOSE, fun2->name, as_generic (flatten (args2)))),
00130 fun (fun2), args (args2)
00131 {
00132 sig= copy (fun->signature ());
00133 if (N(sig) != 0) {
00134 ASSERT (N(sig) == N(args)+1,
00135 "numbers of arguments don't match (composed_routine_rep)");
00136 for (nat i=0; i<N(args); i++) {
00137 const vector<nat> sub_sig= args[i]->signature ();
00138 ASSERT (N(sub_sig) == 2,
00139 "routine with one argument expected (composed_routine_rep)");
00140 ASSERT (read (sig, i+1) == sub_sig[0] || read (sig, i+1) == 0,
00141 "type mismatch (composed_routine_rep)");
00142 sig[i+1]= sub_sig[1];
00143 }
00144 }
00145 }
00146 generic apply (const generic& x) const {
00147 ASSERT (N(args) == 1, "arity one expected");
00148 return fun->apply (args[0]->apply (x));
00149 }
00150 generic apply (const generic& x, const generic& y) const {
00151 ASSERT (N(args) == 2, "arity two expected");
00152 return fun->apply (args[0]->apply (x), args[1]->apply (y));
00153 }
00154 generic apply (const vector<generic>& v) const {
00155 nat i, n= N(v);
00156 ASSERT (N(args) == n, "arity " * as_string (n) * " expected");
00157 vector<generic> w= fill<generic> (n);
00158 for (i=0; i<n; i++)
00159 w[i]= args[i]->apply (v[i]);
00160 return fun->apply (w);
00161 }
00162 vector<nat> signature () const { return sig; }
00163 };
00164
00165 routine
00166 compose (const routine& fun, const vector<routine>& args) {
00167
00168
00169
00170 if (exact_eq (fun->name, GEN_IDENTITY) && N(args) == 1)
00171 return args [0];
00172 for (nat i=0; i<N(args); i++) {
00173 if (exact_neq (args[i]->name, GEN_IDENTITY))
00174 return new composed_routine_rep (fun, args);
00175 }
00176 return fun;
00177 }
00178
00179
00180
00181
00182
00183 class change_signature_routine_rep: public routine_rep {
00184 routine r;
00185 vector<nat> sig;
00186 public:
00187 change_signature_routine_rep (const routine& r2, const vector<nat>& sig2):
00188 routine_rep (r2->name), r (r2), sig (sig2) {}
00189 generic apply () const {
00190 return r->apply (); }
00191 generic apply (const generic& x1) const {
00192 return r->apply (x1); }
00193 generic apply (const generic& x1, const generic& x2) const {
00194 return r->apply (x1, x2); }
00195 generic apply (const vector<generic>& v) const {
00196 return r->apply (v); }
00197 vector<nat> signature () const { return sig; }
00198 };
00199
00200 routine
00201 change_signature (const routine& r, const vector<nat>& sig) {
00202 return new change_signature_routine_rep (r, sig);
00203 }
00204
00205
00206
00207
00208
00209 class default_routine_rep: public routine_rep {
00210 public:
00211 default_routine_rep (const generic& name): routine_rep (name) {}
00212 generic apply (const vector<generic>& v) const {
00213 return current_ev->apply (GEN_APPLY, cons (name, v)); }
00214 vector<nat> signature () const { return vec<nat> (); }
00215 };
00216
00217 routine
00218 default_routine (const generic& name) {
00219 if (is<routine> (name))
00220 return as<routine> (name);
00221 if (is<alias<routine> > (name))
00222 return get_alias (as<alias<routine> > (name));
00223 return new default_routine_rep (name);
00224 }
00225
00226
00227
00228
00229
00230 class integrate_routine_rep: public routine_rep {
00231 routine fun;
00232 public:
00233 integrate_routine_rep (const routine& fun2):
00234 routine_rep (gen (GEN_INTEGRATE, fun2->name)), fun (fun2) {}
00235 generic apply () const {
00236 return integrate (fun->apply ()); }
00237 generic apply (const generic& x1) const {
00238 return integrate (fun->apply (x1)); }
00239 generic apply (const generic& x1, const generic& x2) const {
00240 return integrate (fun->apply (x1, x2)); }
00241 generic apply (const vector<generic>& v) const {
00242 return integrate (fun->apply (v)); }
00243 vector<nat> signature () const {
00244 return fun->signature (); }
00245 };
00246
00247 routine
00248 integrate (const routine& r) {
00249 return new integrate_routine_rep (r);
00250 }
00251
00252 }