PH Logo
Logo intepreter modeled after UCB Logo.
/Users/paul/Documents/phlogo/core/ConstructorVerbs.cpp
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 }
 All Classes Functions