PH Logo
Logo intepreter modeled after UCB Logo.
/Users/paul/Documents/phlogo/core/DataSelectorVerbs.cpp
00001 /*
00002  *  DataSelectorVerbs.cpp
00003  *
00004  *  Author: Paul Hamilton
00005  *      Date: 13 Jun 2011
00006  *
00007  */
00008 
00009 #include "Verbs.h"
00010 
00011 #include "Interpreter.h"
00012 #include "World.h"
00013 #include "Exceptions.h"
00014 #include "List.h"
00015 #include "Thing.h"
00016 #include "Array.h"
00017 
00018 #include <boost/lexical_cast.hpp>
00019 #include <set>
00020 
00021 using namespace std;
00022 using namespace boost;
00023 
00024 namespace phlogo {
00025 
00026 void Verbs::first(TokenStream *ts) {
00027 
00028         pThing thing;
00029         _itp->getNextThing(_world, ts, &thing);
00030         
00031         // if it's a word, then the first char, otherwise the first element.
00032         if (thing->isWord())
00033                 _world->allocResult()->set(string(1, thing->getWord()[0]));
00034         else if (thing->isList())
00035                 _world->setResult(thing->getList().get(0));
00036         else
00037                 _world->setResult(thing->getArray().get(0));
00038 
00039 }
00040 
00041 void Verbs::last(TokenStream *ts) {
00042 
00043         pThing thing;
00044         _itp->getNextThing(_world, ts, &thing);
00045         
00046         // if it's a word, then the first char, otherwise the first element.
00047         if (thing->isWord()) {
00048                 string s = thing->getWord();
00049                 _world->allocResult()->set(string(1, s[s.length()-1]));
00050         }
00051         else if (thing->isList())
00052                 _world->setResult(thing->getList().get(thing->getList().size()-1));
00053         else
00054                 _world->setResult(thing->getArray().get(thing->getArray().size()-1));
00055 
00056 }
00057 
00058 void Verbs::firsts(TokenStream *ts) {
00059 
00060         pThing thing;
00061         _itp->getNextThing(_world, ts, &thing);
00062         
00063         if (!thing->isList())
00064                 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() );
00065 
00066         // get all the firsts of the elements of the lists as lists.
00067         List rlist = _world->allocResult()->allocList();
00068         for (tListArray::iterator i=thing->getList().begin(); i != thing->getList().end(); i++) {
00069                 if ((*i)->isWord())
00070                         rlist.push_back(*i);
00071                 else {
00072                         if ((*i)->getList().size() == 0)
00073                                 BOOST_THROW_EXCEPTION( empty_list_exception() );
00074                         rlist.push_back((*i)->getList().get(0));
00075                 }
00076         }
00077 
00078 }
00079 
00080 void Verbs::butfirst(TokenStream *ts) {
00081 
00082         pThing thing;
00083         _itp->getNextThing(_world, ts, &thing);
00084         
00085         // get all the firsts
00086         // if it's a word, then the first char, otherwise the first element.
00087         if (thing->isWord()) {
00088                 string s = thing->getWord();
00089                 _world->allocResult()->set(s.substr(1));
00090         }
00091         else if (thing->isList()) {
00092                 List list = _world->allocResult()->allocList();
00093         List l1 = thing->getList();
00094                 tListArray::iterator i = l1.begin();
00095                 i++;
00096                 for (; i != l1.end(); i++) {
00097             list.add(*i);               
00098         }
00099         }
00100         else {
00101                 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() );
00102         }
00103 
00104 }
00105 
00106 void Verbs::butlast(TokenStream *ts) {
00107 
00108         pThing thing;
00109         _itp->getNextThing(_world, ts, &thing);
00110         
00111         // if it's a word, then the first char, otherwise the first element.
00112         if (thing->isWord()) {
00113         
00114                 string s = thing->getWord();
00115                 _world->allocResult()->set(s.substr(0, s.length()-1));
00116                 
00117         }
00118         else if (thing->isList()) {
00119         
00120                 List list = _world->allocResult()->allocList();
00121                 tListArray::iterator i = thing->getList().begin();
00122                 for (; (i+1) != thing->getList().end(); i++)
00123                         list.add(*i);
00124 
00125         }
00126         else {
00127                 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() );
00128         }
00129 
00130 }
00131 
00132 void Verbs::butfirsts(TokenStream *ts) {
00133 
00134         pThing thing;
00135         _itp->getNextThing(_world, ts, &thing);
00136         
00137         if (!thing->isList())
00138                 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() );
00139                 
00140         // get all the firsts of the elements of the lists as lists.
00141         List rlist = _world->allocResult()->allocList();
00142         for (tListArray::iterator i=thing->getList().begin(); i != thing->getList().end(); i++) {
00143                 if (!(*i)->isList())
00144                         BOOST_THROW_EXCEPTION( no_list_exception() );
00145                 if ((*i)->getList().size() == 0)
00146                         BOOST_THROW_EXCEPTION( empty_list_exception() );
00147                 pThing thing(new Thing());
00148                 List list = thing->allocList();
00149                 tListArray::iterator j = (*i)->getList().begin();
00150                 j++;
00151                 for (; j != (*i)->getList().end(); j++)
00152                         list.add(*j);
00153                 rlist.push_back(thing);
00154         }
00155 
00156 }
00157 
00158 void Verbs::item(TokenStream *ts) {
00159 
00160         long index = getLong(ts);
00161 
00162         pThing thing;
00163         _itp->getNextThing(_world, ts, &thing);
00164         if (thing->isWord()) {
00165                 _world->allocResult()->set(thing->getWord().substr(index-1, 1));                
00166         }
00167         else if (thing->isList()) {
00168                 _world->setResult(thing->getList().get(index-1));               
00169         }
00170         else if (thing->isArray()) {
00171                 _world->setResult(thing->getArray().get(index-1));              
00172         }
00173 
00174 }
00175 
00176 void Verbs::mditem(TokenStream *ts) {
00177 
00178         pThing thing;
00179         _itp->getNextThing(_world, ts, &thing);
00180         
00181         if (!thing->isList())
00182                 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() );
00183         if (thing->getList().size() != 2)
00184                 BOOST_THROW_EXCEPTION( incorrect_list_size_exception() );
00185 
00186         int x = boost::lexical_cast<int>(thing->getList().get(0)->getWord());
00187         int y = boost::lexical_cast<int>(thing->getList().get(1)->getWord());
00188 
00189         _itp->getNextThing(_world, ts, &thing);
00190         
00191         if ((int)thing->getList().size() < x)
00192                 BOOST_THROW_EXCEPTION( bad_index_exception() );
00193         if ((int)thing->getList().get(x-1)->getList().size() < y)
00194                 BOOST_THROW_EXCEPTION( bad_index_exception() );
00195         
00196         _world->setResult(thing->getList().get(x-1)->getList().get(y-1));               
00197 
00198 }
00199 
00200 void Verbs::pick(TokenStream *ts) {
00201 
00202         pThing thing;
00203         _itp->getNextThing(_world, ts, &thing);
00204         
00205         if (!thing->isList())
00206                 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() );
00207 
00208         _world->setResult(thing->getList().get(0));             
00209 
00210 }
00211 
00212 void Verbs::remove(TokenStream *ts) {
00213 
00214         string s = getWord(ts);
00215 
00216         pThing thing;
00217         _itp->getNextThing(_world, ts, &thing);
00218         if (!thing->isList())
00219                 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() );
00220 
00221         List list = _world->allocResult()->allocList();
00222         for (tListArray::iterator i=thing->getList().begin(); i != thing->getList().end(); i++) {
00223                 if (!(*i)->isWord())
00224                         BOOST_THROW_EXCEPTION( no_word_in_thing_exception() );
00225                 if ((*i)->getWord() != s)
00226                         list.add(*i);
00227         }
00228 
00229 }
00230 
00231 void Verbs::remdup(TokenStream *ts) {
00232 
00233         pThing thing;
00234         _itp->getNextThing(_world, ts, &thing);
00235         
00236         if (!thing->isList())
00237                 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() );
00238 
00239         set<string> sofar;
00240         List list = _world->allocResult()->allocList();
00241         for (tListArray::iterator i=thing->getList().begin(); i != thing->getList().end(); i++) {
00242                 if (!(*i)->isWord())
00243                         BOOST_THROW_EXCEPTION( no_word_in_thing_exception() );
00244                 string s = (*i)->getWord();
00245                 if (sofar.find(s) == sofar.end()) {
00246                         sofar.insert(s);
00247                         list.add(*i);
00248                 }
00249         }
00250 
00251 }
00252 
00253 void Verbs::quoted(TokenStream *ts) {
00254 
00255         pThing thing;
00256         _itp->getNextThing(_world, ts, &thing);
00257         
00258         if (thing->isWord())
00259                 _world->allocResult()->set("\"" + thing->getWord());
00260         else
00261                 _world->setResult(thing);
00262 
00263 }
00264 
00265 }
 All Classes Functions