00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <lestes/common.hh>
00029 #include <lestes/ui/interp.hh>
00030 #include <lestes/ui/interp.g.hh>
00031 #include <lestes/ui/interp_actions.g.hh>
00032
00033 package(lestes);
00034 package(ui);
00035
00036 typedef ptr < l_object > lp;
00037 typedef ptr < l_atom > lap;
00038
00039 ptr < l_object > car(ptr < l_object > x)
00040 {
00041 return car_evaluator::instance()->go(x);
00042 }
00043
00044 ptr < l_object > cdr(ptr < l_object > x)
00045 {
00046 return cdr_evaluator::instance()->go(x);
00047 }
00048
00049 ptr < l_object > cons(ptr < l_object > a, ptr < l_object > d)
00050 {
00051 return l_cons::create(a, d);
00052 }
00053
00054 ptr < l_cons > extra_cons(ptr < l_object > a, ptr < l_object > d)
00055 {
00056 return l_cons::create(a, d);
00057 }
00058
00059 lp consp(lp x)
00060 {
00061 return consp_evaluator::instance()->go(x);
00062 }
00063
00064 bool endp(lp x)
00065 {
00066 return consp(x) == l_interpreter::nil_get();
00067 }
00068
00069 lp last_eval(lp x)
00070 {
00071 lp res;
00072 while (!endp(x)) {
00073 res = eval(car(x));
00074 x = cdr(x);
00075 }
00076 return res;
00077 }
00078
00079 lp list_eval(lp x)
00080 {
00081 ptr < l_cons > res, run, tmp;
00082 if (endp(x))
00083 return eval(x);
00084 run = res = extra_cons(l_interpreter::nil_get(), l_interpreter::nil_get());
00085 while (!endp(x)) {
00086 run->car_set(eval(car(x)));
00087 x = cdr(x);
00088 if (!endp(x)) {
00089 tmp = extra_cons(l_interpreter::nil_get(), l_interpreter::nil_get());
00090 run->cdr_set(tmp);
00091 run = tmp;
00092 }
00093 }
00094 run->cdr_set(eval(x));
00095 return res;
00096 }
00097
00098 lp print(lp a)
00099 {
00100 printer::instance()->go(a);
00101 return a;
00102 }
00103
00104 ptr < l_object > eval(ptr < l_object > x)
00105 {
00106 return basic_evaluator::instance()->go(x);
00107 }
00108
00109 lp lb_function::run(lp x)
00110 {
00111 return function_evaluator::instance()->go(car(x));
00112 }
00113
00114 lp lb_eq::run(lp x)
00115 {
00116 lp a = eval(car(x));
00117 lp b = eval(car(cdr(x)));
00118
00119 return a==b ? l_interpreter::t_get() : l_interpreter::nil_get();
00120 }
00121
00122 ptr < l_object > lb_car::run(ptr < l_object > args)
00123 {
00124 return car(eval(car(args)));
00125 }
00126
00127 ptr < l_object > lb_cdr::run(ptr < l_object > args)
00128 {
00129 return cdr(eval(car(args)));
00130 }
00131
00132 ptr < l_object > lb_cond::run(ptr < l_object > args)
00133 {
00134 lp res = l_interpreter::nil_get();
00135
00136 while (!endp(args)) {
00137 lp clause = car(args);
00138 args = cdr(args);
00139
00140 lp pred = eval(car(clause));
00141 if (pred != l_interpreter::nil_get()) {
00142 lp body = cdr(clause);
00143 res = endp(body) ? pred : last_eval(body);
00144 break;
00145 }
00146 }
00147
00148 return res;
00149 }
00150
00151 ptr < l_object > lb_lambda::run(ptr < l_object > a)
00152 {
00153 ptr < list < srp < l_atom > > > args = list < srp < l_atom > >::create();
00154 ptr < l_atom > rest_arg;
00155 lp body = cdr(a);
00156 lp i;
00157 for (i = car(a) ; !endp(i) ; i = cdr(i)) {
00158 args->push_back(car(i).dncast<l_atom>());
00159 }
00160 if (i != l_interpreter::nil_get())
00161 rest_arg = i.dncast<l_atom>();
00162 return l_lambda::create(args, rest_arg, body);
00163 }
00164
00165 ptr < l_object > lb_macro::run(ptr < l_object > a)
00166 {
00167 ptr < list < srp < l_atom > > > args = list < srp < l_atom > >::create();
00168 ptr < l_atom > rest_arg;
00169 lp body = cdr(a);
00170 lp i;
00171 for (i = car(a) ; !endp(i) ; i = cdr(i)) {
00172 args->push_back(car(i).dncast<l_atom>());
00173 }
00174 if (i != l_interpreter::nil_get())
00175 rest_arg = i.dncast<l_atom>();
00176 return l_macro::create(args, rest_arg, body);
00177 }
00178
00179 ptr < l_object > lb_quote::run(ptr < l_object > args)
00180 {
00181 return car(args);
00182 lstring a,b;
00183 a<b;
00184 }
00185
00186 ptr < l_object > lb_cons::run(ptr < l_object > args)
00187 {
00188 lp a = eval(car(args));
00189 lp d = eval(car(cdr(args)));
00190 return cons(a, d);
00191 }
00192
00193 ptr < l_object > lb_consp::run(ptr < l_object > args)
00194 {
00195 return consp(eval(car(args)));
00196 }
00197
00198 lp lb_set::run(lp args)
00199 {
00200 lp s = eval(car(args));
00201 lp v = eval(car(cdr(args)));
00202
00203 s.dncast<l_atom>()->set(v);
00204 return v;
00205
00206 }
00207
00208 lp lb_eval::run(lp a)
00209 {
00210 return eval(eval(car(a)));
00211 }
00212
00213 lp lb_fset::run(lp args)
00214 {
00215 lp s = eval(car(args));
00216 lp v = eval(car(cdr(args)));
00217
00218 s.dncast<l_atom>()->fset(v);
00219 return v;
00220 }
00221
00222 lp l_built_in::run(lp x)
00223 {
00224 return foo->run(x);
00225 }
00226
00227 typedef list < srp < l_atom > >::iterator lait;
00228
00229 lp l_lambda::run(lp x)
00230 {
00231 for (lait it = args_get()->begin() ;
00232 it != args_get()->end() ; ++it) {
00233 (*it)->bind(eval(car(x)));
00234 x = cdr(x);
00235 }
00236 if (rest_get()) {
00237 rest_get()->bind(list_eval(x));
00238 }
00239 lp res = last_eval(body_get());
00240 for (lait it = args_get()->begin() ;
00241 it != args_get()->end() ; ++it) {
00242 (*it)->unbind();
00243 }
00244 if (rest_get())
00245 rest_get()->unbind();
00246 return res;
00247 }
00248
00249 lp l_macro::run(lp x)
00250 {
00251 for (lait it = args_get()->begin() ;
00252 it != args_get()->end() ; ++it) {
00253 (*it)->bind((car(x)));
00254 x = cdr(x);
00255 }
00256 if (rest_get()) {
00257 rest_get()->bind((x));
00258 }
00259 lp res = last_eval(body_get());
00260 for (lait it = args_get()->begin() ;
00261 it != args_get()->end() ; ++it) {
00262 (*it)->unbind();
00263 }
00264 if (rest_get())
00265 rest_get()->unbind();
00266 return eval(res);
00267 }
00268
00269 void l_atom::bind(lp x)
00270 {
00271 lassert(x);
00272 vstack->push(x);
00273 }
00274
00275 void l_atom::unbind()
00276 {
00277 lassert(!vstack->empty());
00278 vstack->pop();
00279 }
00280
00281 void l_atom::set(lp x)
00282 {
00283 if (vstack->empty())
00284 bind(x);
00285 else
00286 vstack->top()=x;
00287 }
00288
00289 void l_atom::fbind(lp x)
00290 {
00291 lassert(x);
00292 fstack->push(x);
00293 }
00294
00295 void l_atom::funbind()
00296 {
00297 lassert(!fstack->empty());
00298 fstack->pop();
00299 }
00300
00301 void l_atom::fset(lp x)
00302 {
00303 if (fstack->empty())
00304 fbind(x);
00305 else
00306 fstack->top()=x;
00307 }
00308
00309 lstring l_string::unescape(lstring str)
00310 {
00311 char s[str.size()+1];
00312 const char *p = str.c_str();
00313 char *q = s;
00314
00315 for ( ; *p ; ++p) {
00316 if (*p == '\\')
00317 switch (*++p) {
00318 case 'a':
00319 *q++ = '\a';
00320 break;
00321 case 'b':
00322 *q++ = '\b';
00323 break;
00324 case 't':
00325 *q++ = '\t';
00326 break;
00327 case 'f':
00328 *q++ = '\f';
00329 break;
00330 case 'v':
00331 *q++ = '\v';
00332 break;
00333 case 'r':
00334 *q++ = '\r';
00335 break;
00336 case 'n':
00337 *q++ = '\n';
00338 break;
00339 case 'e':
00340 *q++ = '\033';
00341 break;
00342 }
00343 else
00344 *q++ = *p;
00345 }
00346 *q = '\0';
00347 return s;
00348 }
00349
00350 lap l_atom::instance(lstring n)
00351 {
00352 srp < l_atom > & lar = (*atoms)[n];
00353 if (lar)
00354 return lar;
00355 return lar = l_atom::create(n);
00356 }
00357
00358 void l_interpreter::init()
00359 {
00360 static bool was_here = false;
00361 if (was_here)
00362 return;
00363 was_here = true;
00364
00365 nil = l_atom::instance("nil");
00366 t = l_atom::instance("t");
00367 quote = l_atom::instance("quote");
00368 function = l_atom::instance("function");
00369 nil->bind(nil);
00370 t->bind(t);
00371
00372 #define defun(x) l_atom::instance(#x)->fbind(l_built_in::create(lb_##x::instance()))
00373 defun(quote);
00374 defun(function);
00375 defun(car);
00376 defun(cdr);
00377 defun(cons);
00378 defun(consp);
00379 defun(cond);
00380 defun(lambda);
00381 defun(macro);
00382 defun(set);
00383 defun(eq);
00384 #undef defun
00385 #define defunn(n,x) l_atom::instance(n)->fbind(l_built_in::create(lb_##x::instance()))
00386 defunn("%fset", fset);
00387 #undef defunn
00388 }
00389
00390
00391 end_package(ui);
00392 end_package(lestes);