// ---------------------------------------------------------------------------
// - 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 <Symbol*> (obj);
// remap the object and check
if (sym != nilp) obj = sym->getobj ();
Nameset* nset = dynamic_cast <Nameset*> (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;
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1