6 #include "util_const.h"
7 #include "util_string.h"
8 #include "util_check.h"
10 #include <boost/unordered_map.hpp>
15 static MNode* callFunc (MNode* cell, MlEnv* mlenv) {
19 const ustring* name = ptr_symbol (cell->car ());
24 if (! (name && *name == uQuote))
25 mlenv->logSexp (cell);
27 bcell = mlenv->currentCell;
28 mlenv->currentCell = cell;
30 if (mlenv->searchFTable (*name, t)) {
32 ans = t->fn (cell, mlenv);
33 } else if (mlenv->searchMTable (*name, t)) {
35 mlenv->pushMStack (t);
36 ans = t->fn (cell, mlenv);
38 } else if (mlenv->searchSTable (*name, t, u)) {
40 ans = t->sfn (cell, mlenv, u);
41 } else if ((sexp = mlenv->getVar (*name)) && isLambda (sexp)) {
43 MNode* a = cell->cdr ();
45 list.append (eval (a->car (), mlenv));
49 if (mlenv->mlPool->nodebugFunc.get (*name)) {
50 AutoBackupBool autoBackup (&mlenv->mlPool->nolog);
51 mlenv->mlPool->nolog = true;
52 ans = execDefun (mlenv, sexp, list (), *name);
54 ans = execDefun (mlenv, sexp, list (), *name);
57 ans = execDefun (mlenv, sexp, list (), *name);
61 throw (ustring ("undefined function"));
63 mlenv->currentCell = bcell;
65 return ans.release ();
68 MNode* eval (MNode* cell, MlEnv* mlenv) {
76 && cell->car ()->isSym ()
77 && (cell->cdr () == NULL || cell->cdr ()->isCons ())) {
78 return callFunc (cell, mlenv);
80 throw (cell->dump_string_short () + ustring (": error"));
86 const ustring* u = ptr_symbol (cell);
87 if (u->length () > 0) {
94 return mlenv->getVar (*u);
96 case MNode::MC_DOUBLE:
98 case MNode::MC_VECTOR:
99 return vectorDup (cell);
100 case MNode::MC_TABLE:
101 return tableDup (cell);
105 return NULL; // not reached
108 MNode* vectorDup (MNode* c) {
111 MotorVector::iterator b, e;
113 assert (c && c->isVector ());
114 x = newMNode_vector ();
116 b = c->vector->begin ();
117 e = c->vector->end ();
118 for (; b < e; ++ b) {
119 x->vectorPush ((*b) ());
121 return ans.release ();
124 MNode* vectorEval (MNode* c, MlEnv* mlenv) {
127 MotorVector::iterator b, e;
129 assert (c && c->isVector ());
130 x = newMNode_vector ();
132 b = c->vector->begin ();
133 e = c->vector->end ();
134 for (; b < e; ++ b) {
136 std::cerr << "eval:" << to_string ((*b) ()) << "\n";
138 x->vectorPush (eval ((*b) (), mlenv));
140 return ans.release ();
143 MNode* tableDup (MNode* c) {
146 MotorVar::iterator b, e;
148 assert (c && c->isTable ());
149 x = newMNode_table ();
151 b = c->table->begin ();
152 e = c->table->end ();
153 for (; b != e; ++ b) {
154 x->tablePut ((*b).first, (*b).second ());
157 return ans.release ();
160 MNode* tableEval (MNode* c, MlEnv* mlenv) {
163 MotorVar::iterator b, e;
165 assert (c && c->isTable ());
166 x = newMNode_table ();
168 b = c->table->begin ();
169 e = c->table->end ();
170 for (; b != e; ++ b) {
172 // std::cerr << "eval:" << to_string ((*b) ()) << "\n";
174 x->tablePut ((*b).first, eval ((*b).second (), mlenv)); // テーブルのキーは、文字列。
177 return ans.release ();
180 double eval_double (MNode* cell, MlEnv* mlenv) {
182 p = eval (cell, mlenv);
183 return to_double (p ());
186 int eval_int (MNode* cell, MlEnv* mlenv) {
188 p = eval (cell, mlenv);
189 return to_int (p ());
192 int64_t eval_int64 (MNode* cell, MlEnv* mlenv) {
194 p = eval (cell, mlenv);
195 return to_int64 (p ());
198 ustring eval_str (MNode* cell, MlEnv* mlenv) {
200 p = eval (cell, mlenv);
201 return to_string (p ());
204 ustring eval_text1 (MNode* cell, MlEnv* mlenv) {
206 p = eval (cell, mlenv);
207 return to_text1 (p ());
210 ustring eval_asciiword (MNode* cell, MlEnv* mlenv) {
212 p = eval (cell, mlenv);
213 return to_asciiword (p ());
216 bool eval_bool (MNode* cell, MlEnv* mlenv) {
218 p = eval (cell, mlenv);
219 return to_bool (p ());
222 ustring eval_file (MNode* cell, MlEnv* mlenv) {
223 ustring ans = eval_str (cell, mlenv);
224 if (! checkFilename (ans)) // XXX dummy
229 MNode* progn (MNode* arg, MlEnv* mlenv) {
235 assert (arg->isCons ());
236 while (arg && ! mlenv->breaksym ()) {
238 ans = eval (arg->car (), mlenv);
239 if (mlenv->breaksym ())
240 return mlenv->breakval ();
246 if (mlenv->breaksym ())
247 return mlenv->breakval ();
248 return ans.release ();
251 void progn_ex (MNode* arg, MlEnv* mlenv) {
254 assert (arg && arg->isCons ());
255 if (arg->cdr () && arg->cdr ()->isCons ()) {
257 mlenv->mlPool->resetProg ();
258 while (arg && ! mlenv->breaksym ()) {
259 if (arg->car () && arg->car ()->isCons ()) {
260 ans = eval (arg->car (), mlenv);
261 if (mlenv->breaksym ()) {
262 mlenv->setBreak (NULL, NULL);
271 void checkDefun (MNode* arg, ustring& name, MNode*& sexp) {
277 throw (uErrorWrongNumber);
279 throw (ustring (CharConst ("bad name.")));
281 name = arg->car ()->to_string ();
282 nextNodeNonNil (arg);
287 if ((param && ! param->isNil () && ! param->isCons ())
288 || (body && ! body->isNil () && ! body->isCons ())) {
289 throw (uErrorWrongType);
291 for (a = param; a && a->isCons (); nextNode (a)) {
292 if (! a->car () || ! a->car ()->isSym ())
293 throw (param->dump_string () + uErrorBadType);
297 MNode* newLambda (MNode* cell) {
298 if (! cell || ! cell->isCons ())
299 throw (uErrorSyntax);
301 MNode* ans = new MNode;
303 ans->set_car (newMNode_sym (new ustring (uLambda)));
309 MNode* buildArgs (int start, const std::vector<ustring>& args) {
312 for (; start < args.size (); start ++) {
313 ans.append (newMNode_str (new ustring (args[start])));
315 return ans.release ();
318 MNode* buildArgs (int start, const std::vector<ustring>& args, const ustring& arg2) {
321 ans.append (newMNode_str (new ustring (arg2)));
322 for (; start < args.size (); start ++) {
323 ans.append (newMNode_str (new ustring (args[start])));
325 return ans.release ();
328 MNode* buildArgs (const ustring& arg1) {
331 ans.append (newMNode_str (new ustring (arg1)));
332 return ans.release ();
335 class KwList: public boost::unordered_map<ustring, std::pair<bool,MNode*> > {
339 void insertVar (const ustring& name, bool f) {
341 insert (KwList::value_type (name, std::pair<bool,MNode*> (f, NULL)));
343 void setVar (const ustring& name, MNode* val) {
344 KwList::iterator it = find (name);
347 it->second.second = val;
350 MNode* getVar (const ustring& name) {
351 KwList::iterator it = find (name);
355 return it->second.second;
358 bool defined (const ustring& name) {
359 KwList::iterator it = find (name);
360 return (it != end ());
362 bool definedBoolType (const ustring& name) {
363 KwList::iterator it = find (name);
364 return (it != end () && it->second.first);
368 bool checkDefunArgs (MNode* lambda, MNode* values) {
369 MNode* sexp = lambda->cdr ();
371 AutoDelete<KwList> kwlist;
376 for (param = sexp->car (); param; nextNode (param)) {
377 u = ptr_symbol (param->car ());
378 if (match (*u, CharConst ("&rest"))) {
380 } else if (match (*u, CharConst ("&key"))) {
382 return false; // &key appeared.
388 kwlist ()->insertVar (*u, true);
394 for (param = sexp->car (); param;) {
396 if (kwlist () && values && values->car ()->isSym ()
397 && (u = ptr_symbol (values->car ()))->length () > 0
399 && kwlist ()->defined (k = ustring (u->begin () + 1, u->end ()))) {
401 } else if (u && u->length () > 0
403 && kwlist ()->defined (k = ustring (u->begin () + 1, u->end ()))) {
406 } else if (match (*(u = ptr_symbol (param->car ())), CharConst ("&rest"))) {
411 // throw (sexp->car ()->dump_string_short () + uErrorBadParamDef);
415 } else if (match (*u, CharConst ("&key"))) {
429 if (kwlist () && values && values->car ()->isSym ()
430 && (u = ptr_symbol (values->car ()))->length () > 0
432 && kwlist ()->defined (k = ustring (u->begin () + 1, u->end ()))) {
434 } else if (u && u->length () > 0
436 && kwlist ()->defined (ustring (u->begin () + 1, u->end ()))) {
446 MNode* execDefun (MlEnv* mlenv, MotorVar* pool, const ustring& name, MNode* values) {
447 MNode* sexp = pool->getVar (name);
448 if (isLambda (sexp)) {
449 return execDefun (mlenv, sexp, values, name);
454 MNode* execDefun (MlEnv* mlenv, MNode* lambda, MNode* values, const ustring& name) {
455 assert (isLambda (lambda));
456 MNode* sexp = lambda->cdr ();
458 MNode* body = sexp->cdr ();
460 AutoDelete<KwList> kwlist;
464 MNode* values0 = values;
466 mlenv->beginLocal ();
467 // it is assumed that param is a list of symbols.
468 for (param = sexp->car (); param; nextNode (param)) {
469 u = ptr_symbol (param->car ());
470 if (match (*u, CharConst ("&rest"))) {
472 } else if (match (*u, CharConst ("&key"))) {
474 throw (sexp->car ()->dump_string_short () + uErrorBadParamDef);
480 kwlist ()->insertVar (*u, true);
481 mlenv->setLocalVar (*u, NULL);
488 for (param = sexp->car (); param;) {
490 if (kwlist () && values && values->car () && values->car ()->isSym ()
491 && (u = ptr_symbol (values->car ()))->length () > 0
493 && kwlist ()->defined (k = ustring (u->begin () + 1, u->end ()))) {
494 mlenv->setLocalVar (k, mlTrue);
496 } else if (u && u->length () > 0
498 && kwlist ()->defined (k = ustring (u->begin () + 1, u->end ()))) {
501 mlenv->setLocalVar (k, values->car ());
503 mlenv->setLocalVar (k, NULL);
505 } else if (match (*(u = ptr_symbol (param->car ())), CharConst ("&rest"))) {
508 mlenv->setLocalVar (*ptr_symbol (param->car ()), values);
511 throw (sexp->car ()->dump_string_short () + uErrorBadParamDef);
514 } else if (match (*u, CharConst ("&key"))) {
522 mlenv->setLocalVar (*u, values->car ());
524 mlenv->setLocalVar (*u, NULL);
532 if (kwlist () && values && values->car ()->isSym ()
533 && (u = ptr_symbol (values->car ()))->length () > 0
535 && kwlist ()->defined (k = ustring (u->begin () + 1, u->end ()))) {
536 mlenv->setLocalVar (k, mlTrue);
538 } else if (u && u->length () > 0
540 && kwlist ()->defined (ustring (u->begin () + 1, u->end ()))) {
543 mlenv->setLocalVar (k, values->car ());
545 mlenv->setLocalVar (k, NULL);
548 // throw (uErrorWrongNumber);
549 // throw (lambda->dump_string_short () + values0->dump_string_short () + ": " + uErrorWrongNumber);
552 a ()->set_car (newMNode_sym (new ustring (name)));
553 a ()->set_cdr (values0);
554 throw (a ()->dump_string_short () + ": " + uErrorWrongNumber);
558 ans = progn (body, mlenv);
559 mlenv->stopBreak (lambda->car ());
562 return ans.release ();
565 void onErrorFn (MNode* fn, MlEnv* mlenv) {
570 ag ()->set_car (mlenv->currentCell ());
571 v = execDefun (mlenv, fn, ag (), uEmpty);
574 void setParams (MNode* list, int nparam, std::vector<MNode*>* params, paramList *kwlist, std::vector<MNode*>* keywords, MNode** rest, bool padding) {
583 for (i = 0; kwlist[i].name; i ++) {
584 kw->insertVar (ustring (kwlist[i].name, kwlist[i].namelen), kwlist[i].fbool);
590 if (a && kw && a->isSym () && (u = ptr_symbol (a)) && u->size () > 0) {
593 name = ustring (u->begin () + 1, u->end ());
594 if (kw->defined (name)) {
597 kw->setVar (name, list->car ());
601 throw (uErrorWrongNumber);
605 throw (uQ2 + *u + uQ2 + uErrorBadParam);
609 name = ustring (u->begin () + 1, u->end ());
610 if (kw->definedBoolType (name)) {
612 kw->setVar (name, mlTrue);
615 throw (uQ2 + *u + uQ2 + uErrorBadParam);
623 if (params && (params->size () < nparam || (nparam == 0 && rest == NULL))) {
625 params->push_back (a);
636 throw (uErrorWrongNumber);
639 if (params && params->size () < nparam) {
641 while (params->size () < nparam) {
642 params->push_back (NULL);
646 throw (uErrorWrongNumber);
650 if (kwlist && keywords) {
651 for (i = 0; kwlist[i].name; i ++) {
652 keywords->push_back (kw->getVar (ustring (kwlist[i].name, kwlist[i].namelen)));