|
PH Logo
Logo intepreter modeled after UCB Logo.
|
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 }
1.7.4