|
PH Logo
Logo intepreter modeled after UCB Logo.
|
00001 /* 00002 * Scope.cpp 00003 * 00004 * Author: Paul Hamilton 00005 * Date: 6 Jun 2011 00006 * 00007 */ 00008 00009 #include "Scope.h" 00010 00011 #include "World.h" 00012 #include "Exceptions.h" 00013 #include "Thing.h" 00014 00015 using namespace std; 00016 00017 namespace phlogo { 00018 00019 Scope::Scope() 00020 { 00021 _world = 0; 00022 _parent = 0; 00023 } 00024 00025 Scope::Scope(World *world) 00026 { 00027 _world = world; 00028 _parent = world->getScope(); 00029 _world->setScope(this); 00030 } 00031 00032 Scope::~Scope() { 00033 if (_parent) 00034 _world->setScope(_parent); 00035 } 00036 00037 void Scope::setThing(const std::string &name, const std::string &value, bool local) { 00038 00039 pThing thing(new Thing()); 00040 thing->set(value); 00041 setThing(name, thing, local); 00042 } 00043 00044 void Scope::setThing(const std::string &name, pThing value, bool local) { 00045 00046 if (local) 00047 _things[name] = value; 00048 else { 00049 // we don't automatically set a var in this scope, lookup it up first 00050 // and then if it's found, replace it's value where it's found. 00051 map<string, pThing >::iterator i = _things.find(name); 00052 if (i == _things.end()) { 00053 Scope *p = _parent; 00054 while (p) { 00055 i = p->_things.find(name); 00056 if (i != _things.end()) { 00057 p->_things[name] = value; 00058 return; 00059 } 00060 p = p->_parent; 00061 } 00062 } 00063 _things[name] = value; 00064 } 00065 } 00066 00067 pThing Scope::getThing(const string &name) 00068 { 00069 map<string, pThing >::iterator i = _things.find(name); 00070 if (i == _things.end()) { 00071 Scope *p = _parent; 00072 while (p) { 00073 i = p->_things.find(name); 00074 if (i != _things.end()) 00075 return i->second; 00076 p = p->_parent; 00077 } 00078 BOOST_THROW_EXCEPTION( no_thing_exception() << errinfo_name(name) ); 00079 } 00080 return i->second; 00081 } 00082 00083 void Scope::removeThing(const std::string &name) { 00084 map<string, pThing >::iterator i = _things.find(name); 00085 if (i != _things.end()) 00086 _things.erase(i); 00087 } 00088 00089 void Scope::removeThings() { 00090 00091 _things.clear(); 00092 00093 } 00094 00095 }
1.7.4