interp.cc

Go to the documentation of this file.
00001 /*
00002    The lestes compiler suite
00003    Copyright (C) 2002, 2003, 2004, 2005 Miroslav Tichy
00004    Copyright (C) 2002, 2003, 2004, 2005 Petr Zika
00005    Copyright (C) 2002, 2003, 2004, 2005 Vojtech Hala
00006    Copyright (C) 2002, 2003, 2004, 2005 Jiri Kosina
00007    Copyright (C) 2002, 2003, 2004, 2005 Pavel Sanda
00008    Copyright (C) 2002, 2003, 2004, 2005 Jan Zouhar
00009    Copyright (C) 2002, 2003, 2004, 2005 Rudolf Thomas
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; version 2 of the License.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    See the full text of the GNU General Public License version 2, and
00021    the limitations in the file doc/LICENSE.
00022 
00023    By accepting the license the licensee waives any and all claims
00024    against the copyright holder(s) related in whole or in part to the
00025    work, its use, and/or the inability to use it.
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);

Generated on Mon Feb 12 18:22:36 2007 for lestes by doxygen 1.5.1-20070107