00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <mmxlight/base_evaluator.hpp>
00014 #include <basix/routine.hpp>
00015 #include <basix/primitive.hpp>
00016 #include <basix/literal.hpp>
00017 #include <basix/alias.hpp>
00018 #include <basix/tuple.hpp>
00019 namespace mmx {
00020
00021
00022
00023
00024
00025 evaluator
00026 base_evaluator () {
00027 return new base_evaluator_rep ();
00028 }
00029
00030 evaluator
00031 base_evaluator (const evaluator& ev) {
00032 return new base_evaluator_rep (ev);
00033 }
00034
00035
00036
00037
00038
00039 void*
00040 base_evaluator_rep::get_internal_data () const {
00041 return (void*) &env;
00042 }
00043
00044 environment
00045 get_environment (const evaluator& ev) {
00046 return *((environment*) ev->get_internal_data ());
00047 }
00048
00049 void
00050 set_environment_type (const evaluator& ev, nat tp) {
00051 environment_rep* env= inside (get_environment (ev));
00052 env->env_type= tp;
00053 }
00054
00055 nat
00056 get_environment_type (const evaluator& ev) {
00057 return get_environment (ev) -> env_type;
00058 }
00059
00060
00061
00062
00063
00064 void
00065 base_evaluator_rep::set (const generic& var, const generic& val) const {
00066 base_evaluator_rep* me= const_cast<base_evaluator_rep*> (this);
00067 me->env [var]= val;
00068 }
00069
00070 void
00071 base_evaluator_rep::reset (const generic& var) const {
00072 base_evaluator_rep* me= const_cast<base_evaluator_rep*> (this);
00073 mmx::reset (me->env, var);
00074 }
00075
00076 void
00077 base_evaluator_rep::overload (const generic& var, const generic& val,
00078 nat pen) const
00079 {
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 base_evaluator_rep* me= const_cast<base_evaluator_rep*> (this);
00098 if (is<routine> (val)) {
00099 routine f= as<routine> (val);
00100 if (f->is_overloaded ()) {
00101 vector<routine> rs= f->meanings ();
00102 for (nat i=0; i<N(rs); i++)
00103 overload (var, as<generic> (rs[i]), pen);
00104 return;
00105 }
00106 if (exact_eq (var, GEN_NEW)) {
00107 const vector<nat> ids= f->signature ();
00108 ASSERT (N(ids) == 2, "constructor should take one argument");
00109 me->env [as<generic> (ids[1])]= val;
00110 }
00111 else if (exact_eq (var, GEN_CONVERT) || exact_eq (var, GEN_UPGRADE) ||
00112 exact_eq (var, GEN_DOWNGRADE) || exact_eq (var, GEN_REWRITE))
00113 {
00114 const vector<nat> ids= f->signature ();
00115 ASSERT (N(ids) == 2, "converter should take one argument");
00116 nat src = ids[1], dest= ids[0];
00117 if (src == dest) return;
00118 nat trv= 0;
00119 if (exact_eq (var, GEN_DOWNGRADE) || exact_eq (var, GEN_REWRITE))
00120 trv += 2;
00121 if (exact_eq (var, GEN_UPGRADE) || exact_eq (var, GEN_REWRITE))
00122 trv += 1;
00123 inside (env) -> set_converter (src, dest, val, trv, pen);
00124
00125
00126 }
00127
00128
00129
00130
00131 else {
00132 if (!env->contains (var) ||
00133 !is<routine> (env[var]) ||
00134 N(f->signature ()) == 0)
00135 me->env [var]= make_abstract (overloaded_routine (var, env));
00136 routine r= as<routine> (read (me->env, var));
00137 if (r->ref_count != 2) {
00138
00139
00140
00141
00142
00143 r= r->clone ();
00144 me->env [var]= as<generic> (r);
00145
00146 }
00147
00148 r->overload (f);
00149
00150 }
00151 }
00152 else me->env [var]= val;
00153 }
00154
00155 bool
00156 base_evaluator_rep::contains (const generic& var) const {
00157 return env->contains (var);
00158 }
00159
00160 generic
00161 base_evaluator_rep::get (const generic& var) const {
00162 return env [var];
00163 }
00164
00165 bool
00166 base_evaluator_rep::get (const generic& var, generic& val) const {
00167 return env->get (var, val);
00168 }
00169
00170
00171
00172
00173
00174 generic
00175 base_evaluator_rep::eval (const generic& x) const {
00176 #ifdef BASIX_ENABLE_EXCEPTIONS
00177 try {
00178 #endif
00179 if (is<literal> (x)) {
00180 generic r;
00181 if (env->get (x, r)) return r;
00182 if (env->contains (gen (GEN_METHOD, x))) {
00183 generic sym ("." * literal_to_string (x));
00184 return eval (gen (sym, generic (GEN_THIS)));
00185 }
00186 if (x == GEN_THIS) ERROR ("not inside method");
00187 return x;
00188 }
00189 else if (is<compound> (x)) {
00190 const vector<generic> v= compound_to_vector (x);
00191 nat n= N(v);
00192
00193
00194
00195
00196
00197 switch (n) {
00198 case 0:
00199 return x;
00200 case 1:
00201 {
00202 generic fun= eval (v[0]);
00203 if (is<primitive> (fun))
00204 return as<primitive> (fun) -> apply (x);
00205 else if (is<routine> (fun))
00206 return as<routine> (fun) -> apply ();
00207 else if (is<alias<routine> > (fun))
00208 return get_alias (as<alias<routine> > (fun)) -> apply ();
00209 else return apply (GEN_APPLY, fun);
00210 }
00211 case 2:
00212 {
00213 generic fun= eval (v[0]);
00214 if (is<primitive> (fun))
00215 return as<primitive> (fun) -> apply (x);
00216 else {
00217 generic a1= eval (v[1]);
00218
00219 if (is<exception> (a1)) return a1;
00220 if (is<routine> (fun))
00221 return as<routine> (fun) -> apply (a1);
00222 else if (is<alias<routine> > (fun))
00223 return get_alias (as<alias<routine> > (fun)) -> apply (a1);
00224 else return apply (GEN_APPLY, fun, a1);
00225 }
00226 }
00227 case 3:
00228 {
00229 generic fun= eval (v[0]);
00230 if (is<primitive> (fun))
00231 return as<primitive> (fun) -> apply (x);
00232 else {
00233 generic a1= eval (v[1]);
00234 if (is<exception> (a1)) return a1;
00235 generic a2= eval (v[2]);
00236 if (is<exception> (a2)) return a2;
00237 if (is<routine> (fun))
00238 return as<routine> (fun) -> apply (a1, a2);
00239 else if (is<alias<routine> > (fun))
00240 return get_alias (as<alias<routine> > (fun)) -> apply (a1, a2);
00241 else return apply (GEN_APPLY, vec (fun, a1, a2));
00242 }
00243 }
00244 default:
00245 {
00246 generic fun= eval (v[0]);
00247 if (is<primitive> (fun))
00248 return as<primitive> (fun) -> apply (x);
00249 else {
00250 vector<generic> args= eval_cdr (v);
00251 if (N(args)>0 && is<exception> (args[N(args)-1]))
00252 return args[N(args)-1];
00253 if (is<routine> (fun))
00254 return as<routine> (fun) -> apply (args);
00255 else if (is<alias<routine> > (fun))
00256 return get_alias (as<alias<routine> > (fun)) -> apply (args);
00257 else return apply (GEN_APPLY, cons (fun, args));
00258 }
00259 }
00260 }
00261 }
00262 else return construct (x);
00263 #ifdef BASIX_ENABLE_EXCEPTIONS
00264 }
00265 catch (const exception& err) {
00266 generic msg= *err;
00267 generic ret= append (range (msg, 0, N(msg)-1), gen (x));
00268 return as<generic> (exception (ret));
00269 }
00270 #endif
00271 }
00272
00273 vector<generic>
00274 base_evaluator_rep::eval_cdr (const vector<generic>& v) const {
00275 nat n= N(v)-1;
00276 vector<generic> w= fill<generic> (n);
00277 for (nat i=0; i<n; i++) {
00278 w[i]= eval (v[i+1]);
00279 if (is<exception> (w[i])) return range (w, 0, i+1);
00280 }
00281 return w;
00282 }
00283
00284
00285
00286
00287
00288 inline bool
00289 is_grouped (const generic& x) {
00290 return is_tuple_type (type (x)) || is<iterator<generic> > (x);
00291 }
00292
00293 generic
00294 base_evaluator_rep::construct (const generic& x) const {
00295 generic the_fun= env->get (as<generic> (type (x)));
00296 if (is<routine> (the_fun))
00297 return as<routine> (the_fun)->apply (x);
00298 return x;
00299 }
00300
00301 generic
00302 base_evaluator_rep::apply (const generic& fun) const {
00303 generic the_fun;
00304 if (!env->get (fun, the_fun)) return gen (fun);
00305 return as<routine> (the_fun) -> apply ();
00306 }
00307
00308 generic
00309 base_evaluator_rep::apply (const generic& fun, const generic& x1) const {
00310 generic the_fun;
00311 if (!env->get (fun, the_fun)) {
00312 if (is_grouped (x1))
00313 return equalize (fun, vec<generic> (x1));
00314 return gen (fun, x1);
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 return as<routine> (the_fun)->apply (x1);
00329 }
00330
00331 generic
00332 base_evaluator_rep::apply (const generic& fun,
00333 const generic& x1, const generic& x2) const
00334 {
00335 if (fun == GEN_TRANSTYPE) return eval (gen (fun, x1, x2));
00336 generic the_fun;
00337 if (!env->get (fun, the_fun)) {
00338 if (is_grouped (x1) || is_grouped (x2))
00339 return equalize (fun, vec<generic> (x1, x2));
00340 return gen (fun, x1, x2);
00341 }
00342 return as<routine> (the_fun)->apply (x1, x2);
00343 }
00344
00345 generic
00346 base_evaluator_rep::apply (const generic& fun,
00347 const vector<generic>& v) const {
00348 if (fun == GEN_TRANSTYPE) return eval (gen (fun, v));
00349 generic the_fun;
00350 if (!env->get (fun, the_fun)) {
00351 for (nat i=0; i<N(v); i++)
00352 if (is_tuple_type (type (v[i])) || is<iterator<generic> > (v[i]))
00353 return equalize (fun, v);
00354 return gen (fun, v);
00355 }
00356 return as<routine> (the_fun)->apply (v);
00357 }
00358
00359 }