|
PH Logo
Logo intepreter modeled after UCB Logo.
|
00001 /* 00002 * ConstructorVerbs.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 #include "TokenStream.h" 00018 00019 #include <boost/lexical_cast.hpp> 00020 00021 using namespace std; 00022 using namespace boost; 00023 00024 namespace phlogo { 00025 00026 void Verbs::catenateWords(TokenStream *ts, const char *sep) { 00027 00028 string w = getWord(ts); 00029 00030 if (ts->withinSubExpression()) { 00031 while (ts->hasMoreSubExpression()) { 00032 w += (sep == 0 ? "" : sep) + getWord(ts); 00033 } 00034 } 00035 else { 00036 pThing thing; 00037 _itp->getNextThing(_world, ts, &thing); 00038 if (thing->isWord()) 00039 w += (sep == 0 ? "" : sep) + thing->getWord(); 00040 else if (thing->isList()) { 00041 for (tListArray::const_iterator i=thing->getList().begin(); i != thing->getList().end(); i++) { 00042 if ((*i)->isWord()) 00043 w += (sep == 0 ? "" : sep) + (*i)->getWord(); 00044 else 00045 w += (sep == 0 ? "" : sep) + (*i)->getList().str(); 00046 } 00047 } 00048 } 00049 00050 // consumed all the data, return the verb. 00051 _world->allocResult()->set(w); 00052 00053 } 00054 00055 void Verbs::word(TokenStream *ts) { 00056 00057 catenateWords(ts, 0); 00058 00059 } 00060 00061 void Verbs::sentence(TokenStream *ts) { 00062 00063 catenateWords(ts, " "); 00064 00065 } 00066 00067 void Verbs::list(TokenStream *ts) { 00068 00069 List list = _world->allocResult()->allocList(); 00070 00071 list.addString(getWord(ts)); 00072 if (ts->withinSubExpression()) { 00073 while (ts->hasMoreSubExpression()) { 00074 list.addString(getWord(ts)); 00075 } 00076 } 00077 else { 00078 list.addString(getWord(ts)); 00079 } 00080 00081 } 00082 00083 00084 void Verbs::listput(TokenStream *ts, bool front) { 00085 00086 pThing thing; 00087 _itp->getNextThing(_world, ts, &thing); 00088 00089 pThing thing2; 00090 _itp->getNextThing(_world, ts, &thing2); 00091 if (!thing2->isList()) 00092 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() ); 00093 00094 // append to the start of the list 00095 if (front) 00096 thing2->getList().push_front(thing); 00097 else 00098 thing2->getList().push_back(thing); 00099 _world->setResult(thing2); 00100 00101 } 00102 00103 00104 void Verbs::fput(TokenStream *ts) { 00105 00106 listput(ts, true); 00107 00108 } 00109 00110 void Verbs::lput(TokenStream *ts) { 00111 00112 listput(ts, false); 00113 00114 } 00115 00116 void Verbs::array(TokenStream *ts) { 00117 00118 _world->allocResult()->allocArray(getLong(ts)); 00119 00120 } 00121 00122 void Verbs::mdarray(TokenStream *ts) { 00123 00124 pThing thing; 00125 _itp->getNextThing(_world, ts, &thing); 00126 if (!thing->isList()) 00127 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() ); 00128 if (thing->getList().size() != 2) 00129 BOOST_THROW_EXCEPTION( incorrect_list_size_exception() ); 00130 00131 int xsize = boost::lexical_cast<int>(thing->getList().get(0)->getWord()); 00132 int ysize = boost::lexical_cast<int>(thing->getList().get(1)->getWord()); 00133 00134 Array array = _world->allocResult()->allocArray(xsize); 00135 for (int x=0; x < xsize; x++) { 00136 pThing thing(new Thing()); 00137 thing->allocArray(ysize); 00138 array.set(x, thing); 00139 } 00140 } 00141 00142 void Verbs::listtoarray(TokenStream *ts) { 00143 00144 pThing thing; 00145 _itp->getNextThing(_world, ts, &thing); 00146 if (!thing->isList()) 00147 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() ); 00148 _world->allocResult()->allocArray(*thing->getList().getVector()); 00149 00150 } 00151 00152 void Verbs::arraytolist(TokenStream *ts) { 00153 00154 pThing thing; 00155 _itp->getNextThing(_world, ts, &thing); 00156 if (!thing->isArray()) 00157 BOOST_THROW_EXCEPTION( no_array_in_thing_exception() ); 00158 00159 _world->allocResult()->allocList(*thing->getArray().getVector()); 00160 00161 } 00162 00163 void Verbs::combine(TokenStream *ts) { 00164 00165 pThing thing; 00166 _itp->getNextThing(_world, ts, &thing); 00167 00168 pThing thing2; 00169 _itp->getNextThing(_world, ts, &thing2); 00170 00171 if (thing2->isList()) { 00172 thing2->getList().push_front(thing); 00173 _world->setResult(thing2); 00174 } 00175 else { 00176 string w = thing->getWord() + thing2->getWord(); 00177 _world->allocResult()->set(w); 00178 } 00179 00180 } 00181 00182 void Verbs::reverse(TokenStream *ts) { 00183 00184 pThing thing; 00185 _itp->getNextThing(_world, ts, &thing); 00186 if (!thing->isList()) 00187 BOOST_THROW_EXCEPTION( no_list_in_thing_exception() ); 00188 00189 List l2 = _world->allocResult()->allocList(); 00190 for (tListArray::reverse_iterator i=thing->getList().rbegin(); 00191 i != thing->getList().rend(); i++) 00192 l2.add(*i); 00193 00194 } 00195 00196 int Verbs::gSymbol = 1; 00197 00198 void Verbs::gensym(TokenStream *ts) { 00199 00200 _world->allocResult()->set("g" + boost::lexical_cast<string>(gSymbol)); 00201 gSymbol++; 00202 00203 } 00204 00205 }
1.7.4