OSDN Git Service

save point.
authorvisor <visor@users.sourceforge.jp>
Tue, 19 Aug 2014 15:14:31 +0000 (00:14 +0900)
committervisor <visor@users.sourceforge.jp>
Tue, 19 Aug 2014 15:14:31 +0000 (00:14 +0900)
lib/ml.cc
lib/ml.h
modules/ml-string.cc
modules/ml-struct.cc
modules/ml-struct.h
modules/ml-texp.cc
modules/ml-texp.h

index 9d566a4..0b256a3 100644 (file)
--- a/lib/ml.cc
+++ b/lib/ml.cc
@@ -417,20 +417,28 @@ bool  equal (MNode* a, MNode* b) {
     }
 }
 
-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 ();
index faacabd..e43e48d 100644 (file)
--- a/lib/ml.h
+++ b/lib/ml.h
@@ -302,7 +302,9 @@ inline void  newMNodeCdr (MNode*& cell) {
     cell = x;
 }
 
+MNode*  newMNode_vector (MotorVector* vec);
 MNode*  newMNode_vector ();
+MNode*  newMNode_table (MotorVar* tbl);
 MNode*  newMNode_table ();
 
 class  MNodePtr {
index 5de20d7..2131375 100644 (file)
@@ -1,5 +1,6 @@
 #include "ml-string.h"
 #include "ml.h"
+#include "ml-texp.h"
 #include "mlenv.h"
 #include "motorenv.h"
 #include "motoroutput.h"
@@ -541,7 +542,8 @@ MNode*  ml_regexp_split (MNode* cell, MlEnv* mlenv) {
 
 /*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
@@ -550,12 +552,15 @@ MNode*  ml_split (MNode* cell, MlEnv* mlenv) {
     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}
     };
 
@@ -563,7 +568,15 @@ MNode*  ml_split (MNode* cell, MlEnv* mlenv) {
     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);
@@ -573,7 +586,7 @@ MNode*  ml_split (MNode* cell, MlEnv* mlenv) {
        size_t  m = wt.length () + 1;
 
        bool  (WSplitter::*nfn)();
-       if (keep)
+       if (flagKeep)
            nfn = &WSplitter::nextSep;
        else
            nfn = &WSplitter::next;
@@ -583,7 +596,7 @@ MNode*  ml_split (MNode* cell, MlEnv* mlenv) {
            if (m == 0)
                throw (uErrorRegexp);
        }
-       if (keep)
+       if (flagKeep)
            ans.append (newMNode_str (new ustring (sp.cur ())));
     } catch (boost::regex_error& err) {
        throw (uErrorRegexp);
index d856518..e85feed 100644 (file)
@@ -470,14 +470,17 @@ MNode*  ml_doarray (MNode* cell, MlEnv* mlenv) {
 }
 
 /*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;
@@ -488,7 +491,7 @@ MNode*  ml_dolist (MNode* cell, MlEnv* mlenv) {
     MNode*  a;
     MNodePtr  ans;
     MNodePtr  h;
-    int  i, n;
+    int  i;
     bool  kp;
     std::vector<MNode*>  params;
     std::vector<MNode*>  keywords;
index 5b61365..7160d60 100644 (file)
@@ -14,7 +14,7 @@ MNode*  ml_otherwise (MNode* cell, MlEnv* mlenv);
 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);
index 065297e..9e7ac9c 100644 (file)
@@ -257,6 +257,101 @@ MNode*  ml_vector_to_list (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, &params, 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
 
@@ -359,7 +454,7 @@ MNode*  ml_table_to_list (MNode* cell, MlEnv* mlenv) {
     if (arg)
        throw (uErrorWrongNumber);
 
-    if (! e ()->isVector ()) {
+    if (! e ()->isTable ()) {
        throw (uErrorWrongType);
     }
     MotorVar::iterator  b = e ()->table->begin ();
@@ -369,3 +464,51 @@ MNode*  ml_table_to_list (MNode* cell, MlEnv* mlenv) {
     }
     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, &params, 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 ();
+}
index 4b31234..2dc5e18 100644 (file)
@@ -2,8 +2,80 @@
 #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);
@@ -13,9 +85,11 @@ MNode*  ml_vector_pop (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 */