// --------------------------------------------------------------------------- // - Nameset.cpp - // - afnix engine - nameset class implementation - // --------------------------------------------------------------------------- // - This program is free software; you can redistribute it and/or modify - // - it provided that this copyright notice is kept intact. - // - - // - This program is distributed in the hope that it will be useful, but - // - without any warranty; without even the implied warranty of - // - merchantability or fitness for a particular purpose. In no event shall - // - the copyright holder be liable for any direct, indirect, incidental or - // - special damages arising in any way out of the use of this software. - // --------------------------------------------------------------------------- // - copyright (c) 1999-2007 amaury darsch - // --------------------------------------------------------------------------- #include "Symbol.hpp" #include "Nameset.hpp" #include "Exception.hpp" namespace afnix { // ------------------------------------------------------------------------- // - private section - // ------------------------------------------------------------------------- // the parent nameset as a quark static const long QUARK_PARENT = String::intern (".."); // ------------------------------------------------------------------------- // - class section - // ------------------------------------------------------------------------- // create a default nameset Nameset::Nameset (void) { p_parent = nilp; } // destroy this nameset Nameset::~Nameset (void) { Object::dref (p_parent); } // return the parent nameset Nameset* Nameset::getparent (void) const { rdlock (); Nameset* result = p_parent; unlock (); return result; } // set the parent nameset void Nameset::setparent (Nameset* nset) { wrlock (); if (p_parent != nilp) { remove (QUARK_PARENT); Object::dref (p_parent); } Object::iref (nset); p_parent = nset; if (nset != nilp) symcst (QUARK_PARENT, nset); unlock (); } // add a new object by name void Nameset::bind (const String& name, Object* object) { wrlock (); try { bind (name.toquark (), object); unlock (); } catch (...) { unlock (); throw; } } // return true if the name exists in this nameset bool Nameset::exists (const String& name) const { rdlock (); try { bool result = exists (name.toquark ()); unlock (); return result; } catch (...) { unlock (); throw; } } // return true if the name exists in this nameset bool Nameset::isvalid (const long quark) const { rdlock (); try { // check in the local nameset bool result = exists (quark); if (result == true) { unlock (); return result; } // check in the parent nameset if (p_parent == nilp) { unlock (); return false; } result = p_parent->isvalid (quark); unlock (); return result; } catch (...) { unlock (); throw; } } // return true if the name exists in this nameset bool Nameset::isvalid (const String& name) const { rdlock (); try { bool result = isvalid (name.toquark ()); unlock (); return result; } catch (...) { unlock (); throw; } } // return an object by name but do not evaluate Object* Nameset::find (const String& name) const { return find (name.toquark ()); } // remove an object by name void Nameset::remove (const String& name) { remove (name.toquark ()); } // create a nameset set by quark Nameset* Nameset::mknset (const long quark) { wrlock (); try { // look for an existing one if (exists (quark) == true) { Nameset* nset = getnset (quark); unlock (); return nset; } // create the result nameset and bind it Nameset* result = dup (); symcst (quark, result); return result; } catch (...) { unlock (); throw; } } // create a nameset set by name Nameset* Nameset::mknset (const String& name) { return mknset (name.toquark ()); } // get a nameset by quark Nameset* Nameset::getnset (const long quark) const { rdlock (); if (exists (quark) == false) { unlock (); throw Exception ("nameset-error", "cannot find nameset", String::qmap (quark)); } // get the object and map it - most likelly the object is a symbol Object* obj = find (quark); Symbol* sym = dynamic_cast (obj); // remap the object and check if (sym != nilp) obj = sym->getobj (); Nameset* nset = dynamic_cast (obj); if (nset == nilp) { unlock (); throw Exception ("type-error", "object is not a nameset", String::qmap (quark)); } unlock (); return nset; } // get a nameset by name Nameset* Nameset::getnset (const String& name) const { return getnset (name.toquark ()); } // create a new const symbol by quark void Nameset::symcst (const long quark, Object* object) { wrlock (); try { Symbol* sym = new Symbol (quark, object); sym->setconst (true); bind (quark, sym); unlock (); } catch (...) { unlock (); throw; } } // create a new const symbol by name void Nameset::symcst (const String& name, Object* object) { wrlock (); try { Symbol* sym = new Symbol (name, object); sym->setconst (true); bind (name, sym); unlock (); } catch (...) { unlock (); throw; } } // create a new symbol by quark void Nameset::symdef (const long quark, Object* object) { wrlock (); try { Symbol* sym = new Symbol (quark, object); bind (quark, sym); unlock (); } catch (...) { unlock (); throw; } } // create a new symbol by name void Nameset::symdef (const String& name, Object* object) { wrlock (); try { Symbol* sym = new Symbol (name, object); bind (name, sym); unlock (); } catch (...) { unlock (); throw; } } }