}
}
-MNode* newMNode_vector () {
+MNode* newMNode_vector (MotorVector* vec) {
MNode* ans = new MNode;
ans->type = MNode::MC_VECTOR;
- ans->vector = new MotorVector;
+ ans->vector = vec;
return ans;
}
-MNode* newMNode_table () {
+MNode* newMNode_vector () {
+ return newMNode_vector (new MotorVector);
+}
+
+MNode* newMNode_table (MotorVar* tbl) {
MNode* ans = new MNode;
ans->type = MNode::MC_TABLE;
- ans->table = new MotorVar;
+ ans->table = tbl;
return ans;
}
+MNode* newMNode_table () {
+ return newMNode_table (new MotorVar);
+}
+
void MotorTexp::scan (const ustring& text, bool skip) {
uiterator b = text.begin ();
uiterator e = text.end ();
cell = x;
}
+MNode* newMNode_vector (MotorVector* vec);
MNode* newMNode_vector ();
+MNode* newMNode_table (MotorVar* tbl);
MNode* newMNode_table ();
class MNodePtr {
#include "ml-string.h"
#include "ml.h"
+#include "ml-texp.h"
#include "mlenv.h"
#include "motorenv.h"
#include "motoroutput.h"
/*DOC:
===split===
- (split REGEX STRING) -> STRING_LIST
+ (split REGEX STRING [#keep] [#i]) -> STRING_LIST
+ (split REGEX STRING #vector [#keep] [#i]) -> STRING_VECTOR
*/
//#AFUNC split ml_split
MNode* arg = cell->cdr ();
ustring reg;
ustring text;
- bool keep = false;
- MNodeList ans;
+ bool flagKeep = false;
+ bool flagVector = false;
+ ListMakerPtr ans;
std::vector<MNode*> params;
std::vector<MNode*> keywords;
static paramList kwlist[] = {
{CharConst ("keep"), true}, // 空フィールドの削除をしない
+ {CharConst ("vector"), true},
+// {CharConst ("i"), true},
{NULL, 0, 0}
};
reg = eval_str (params[0], mlenv);
text = eval_str (params[1], mlenv);
if (keywords[0] && eval_bool (keywords[0], mlenv))
- keep = true;
+ flagKeep = true;
+ if (keywords[1] && eval_bool (keywords[1], mlenv))
+ flagVector = true;
+// if (keywords[1] && eval_bool (keywords[1], mlenv))
+// flagReg |= boost::regex_constants::icase;
+ if (flagVector)
+ ans = new ListMakerVector;
+ else
+ ans = new ListMakerList;
try {
std::wstring wt = utow (text);
size_t m = wt.length () + 1;
bool (WSplitter::*nfn)();
- if (keep)
+ if (flagKeep)
nfn = &WSplitter::nextSep;
else
nfn = &WSplitter::next;
if (m == 0)
throw (uErrorRegexp);
}
- if (keep)
+ if (flagKeep)
ans.append (newMNode_str (new ustring (sp.cur ())));
} catch (boost::regex_error& err) {
throw (uErrorRegexp);
}
/*DOC:
-===dolist===
- (dolist '(VARIABLE1...) '(LIST...) [:index VARIABLE2] BODY...) -> LAST VALUE
+//===dolist===
+===list-each===
+// (dolist '(VARIABLE1...) '(LIST...) [:index VARIABLE2] BODY...) -> LAST VALUE
+ (list-each '(VARIABLE1...) '(LIST...) [:index VARIABLE2] BODY...) -> LAST VALUE
list VARIABLE1 and index VARIABLE2 is set local.
*/
-//#AFUNC dolist ml_dolist
-MNode* ml_dolist (MNode* cell, MlEnv* mlenv) {
+//#AFUNC dolist ml_list_each
+//#AFUNC list-each ml_list_each
+MNode* ml_list_each (MNode* cell, MlEnv* mlenv) {
MNode* arg = cell->cdr ();
std::vector<ustring> lv;
int it, iu;
MNode* a;
MNodePtr ans;
MNodePtr h;
- int i, n;
+ int i;
bool kp;
std::vector<MNode*> params;
std::vector<MNode*> keywords;
MNode* ml_progn (MNode* cell, MlEnv* mlenv);
MNode* ml_repeat (MNode* cell, MlEnv* mlenv);
MNode* ml_doarray (MNode* cell, MlEnv* mlenv);
-MNode* ml_dolist (MNode* cell, MlEnv* mlenv);
+MNode* ml_list_each (MNode* cell, MlEnv* mlenv);
MNode* ml_while (MNode* cell, MlEnv* mlenv);
MNode* ml_break (MNode* cell, MlEnv* mlenv);
MNode* ml_exit (MNode* cell, MlEnv* mlenv);
}
/*DOC:
+===vector-each===
+ (vector-each '(VARIABLE1...) '(VECTOR...) [:index VARIABLE2] BODY...) -> LAST VALUE
+
+*/
+//#AFUNC vector-each ml_vector_each
+MNode* ml_vector_each (MNode* cell, MlEnv* mlenv) {
+ MNode* arg = cell->cdr ();
+ std::vector<ustring> lv;
+ size_t it, iu;
+ MNodePtr vlist;
+ MNodePtr list;
+ ustring iv;
+ std::vector<MNode*> llv;
+ MNode* a;
+ MNodePtr ans;
+ MNodePtr h;
+ size_t i, n;
+ std::vector<MNode*> params;
+ std::vector<MNode*> keywords;
+ MNode* rest;
+ static paramList kwlist[] = {
+ {CharConst ("index"), false},
+ {NULL, 0, 0}
+ };
+
+ setParams (arg, 2, ¶ms, kwlist, &keywords, &rest);
+ vlist = eval (params[0], mlenv);
+ if (vlist () && vlist ()->isSym ()) {
+ lv.push_back (vlist ()->to_string ());
+ } else if (vlist () && vlist ()->isCons ()) {
+ a = vlist ();
+ while (a && a->isCons ()) {
+ lv.push_back (to_string (a->car ()));
+ nextNode (a);
+ }
+ } else {
+ throw (to_string (vlist ()) + ustring (": bad argument."));
+ }
+ list = eval (params[1], mlenv);
+ if (keywords[0])
+ iv = eval_str (keywords[0], mlenv);
+
+ a = list ();
+ iu = lv.size ();
+ for (i = 0; i < iu; i ++) {
+ if (a) {
+ MNode* e = a->car ();
+ if (e && e->isVector ()) {
+ llv.push_back (e);
+ } else {
+ throw (uErrorWrongType);
+ }
+ } else {
+ llv.push_back (NULL);
+ }
+ nextNode (a);
+ }
+
+ {
+ AutoLocalVariable autoLocal (mlenv);
+
+ for (it = 0; it < iu; it ++)
+ mlenv->defineLocalVar (lv[it]);
+ if (iv.length () > 0)
+ mlenv->defineLocalVar (iv);
+
+ if (iu > 0 && llv.size () > 0) {
+ if (llv[0]) {
+ n = llv[0]->vectorSize ();
+ } else {
+ n = 0;
+ }
+ for (i = 0; i < n; ++ i) {
+ if (iv.length () > 0) {
+ mlenv->setVar (iv, newMNode_num (i));
+ }
+ for (it = 0; it < iu; it ++) {
+ if (llv[it])
+ mlenv->setVar (lv[it], llv[it]->vectorGet (i));
+ else
+ mlenv->setVar (lv[it], NULL);
+ }
+ ans = progn (rest, mlenv);
+ if (mlenv->breaksym ()) {
+ mlenv->stopBreak (cell->car ());
+ break;
+ }
+ }
+ }
+ }
+
+ return ans.release ();
+}
+
+/*DOC:
===table===
(table CONS ...) -> TABLE
if (arg)
throw (uErrorWrongNumber);
- if (! e ()->isVector ()) {
+ if (! e ()->isTable ()) {
throw (uErrorWrongType);
}
MotorVar::iterator b = e ()->table->begin ();
}
return ans.release ();
}
+
+/*DOC:
+===table-each===
+ (table-each 'VARIABLE1 'VARIABLE2 TABLE BODY...) -> LAST VALUE
+
+*/
+//#AFUNC table-each ml_table_each
+MNode* ml_table_each (MNode* cell, MlEnv* mlenv) {
+ MNode* arg = cell->cdr ();
+ ustring vkey, vval;
+ MNodePtr tbl;
+ MNodePtr ans;
+ std::vector<MNode*> params;
+ MNode* rest;
+ static paramList kwlist[] = {
+ {NULL, 0, 0}
+ };
+
+ setParams (arg, 3, ¶ms, kwlist, NULL, &rest);
+ vkey = eval_str (params[0], mlenv);
+ vval = eval_str (params[1], mlenv);
+ tbl = eval (params[2], mlenv);
+ if (vkey.size () == 0 || vval.size () == 0) {
+ throw (uErrorBadArg);
+ }
+ if (! tbl () || ! tbl ()->isTable () ) {
+ throw (uErrorWrongType);
+ }
+
+ {
+ AutoLocalVariable autoLocal (mlenv);
+ mlenv->defineLocalVar (vkey);
+ mlenv->defineLocalVar (vval);
+ MotorVar::iterator b = tbl ()->table->begin ();
+ MotorVar::iterator t = tbl ()->table->end ();
+ for (; b != t; ++ b) {
+ mlenv->setVar (vkey, newMNode_sym (new ustring ((*b).first)));
+ mlenv->setVar (vval, (*b).second ());
+ ans = progn (rest, mlenv);
+ if (mlenv->breaksym ()) {
+ mlenv->stopBreak (cell->car ());
+ break;
+ }
+ }
+ }
+
+ return ans.release ();
+}
#define ML_TEXP_H
#include "ml.h"
+#include "motorvar.h"
class MlEnv;
+class ListMaker {
+ public:
+ ListMaker () {};
+ virtual ~ListMaker () {};
+
+ virtual void append (MNode* e) = 0;
+ virtual MNode* release () = 0;
+};
+
+class ListMakerList: public ListMaker {
+ public:
+ MNodeList ans;
+
+ ListMakerList () {};
+ virtual ~ListMakerList () {};
+
+ virtual void append (MNode* e) {
+ ans.append (e);
+ };
+ virtual MNode* release () {
+ return ans.release ();
+ };
+};
+
+class ListMakerVector: public ListMaker {
+ public:
+ MotorVector* vec;
+
+ ListMakerVector () {
+ vec = new MotorVector;
+ };
+ virtual ~ListMakerVector () {
+ delete vec;
+ };
+
+ virtual void append (MNode* e) {
+ vec->push (e);
+ };
+ virtual MNode* release () {
+ MNode* ans = newMNode_vector (vec);
+ vec = NULL;
+ return ans;
+ };
+};
+
+class ListMakerPtr {
+ public:
+ ListMaker* val;
+
+ ListMakerPtr () {
+ val = NULL;
+ };
+ virtual ~ListMakerPtr () {
+ delete val;
+ val = NULL;
+ };
+
+ virtual ListMaker* operator = (ListMaker* v) {
+ delete val;
+ val = v;
+ };
+ virtual void append (MNode* e) {
+ assert (val);
+ val->append (e);
+ };
+ virtual MNode* release () {
+ assert (val);
+ return val->release ();
+ };
+};
+
MNode* ml_vector (MNode* cell, MlEnv* mlenv);
MNode* ml_vector_get (MNode* cell, MlEnv* mlenv);
MNode* ml_vector_size (MNode* cell, MlEnv* mlenv);
MNode* ml_vector_resize (MNode* cell, MlEnv* mlenv);
MNode* ml_list_to_vector (MNode* cell, MlEnv* mlenv);
MNode* ml_vector_to_list (MNode* cell, MlEnv* mlenv);
+MNode* ml_vector_each (MNode* cell, MlEnv* mlenv);
MNode* ml_table (MNode* cell, MlEnv* mlenv);
MNode* ml_table_get (MNode* cell, MlEnv* mlenv);
MNode* ml_table_put (MNode* cell, MlEnv* mlenv);
MNode* ml_table_to_list (MNode* cell, MlEnv* mlenv);
+MNode* ml_table_each (MNode* cell, MlEnv* mlenv);
#endif /* ML_TEXP_H */