summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/entry.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
committerKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
commitbab45528d65eaafe68a705dbb2a57075c7b7cbd8 (patch)
tree10b4ae2b5195c8dede153ab89359ec00f55f325f /Build/source/utils/asymptote/entry.cc
parent8643d90372e9c31e0f461c15c596b60a545bd7d3 (diff)
asymptote 1.72 sources (not integrated into build yet)
git-svn-id: svn://tug.org/texlive/trunk@13110 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/entry.cc')
-rw-r--r--Build/source/utils/asymptote/entry.cc365
1 files changed, 365 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/entry.cc b/Build/source/utils/asymptote/entry.cc
new file mode 100644
index 00000000000..99869abb87a
--- /dev/null
+++ b/Build/source/utils/asymptote/entry.cc
@@ -0,0 +1,365 @@
+/*****
+ * entry.cc
+ * Andy Hammerlindl 2002/08/29
+ *
+ * All variables, built-in functions and user-defined functions reside
+ * within the same namespace. To keep track of all these, table of
+ * "entries" is used.
+ *****/
+
+#include <iostream>
+
+#include <cmath>
+#include <utility>
+#include "entry.h"
+#include "coder.h"
+
+using types::signature;
+
+namespace trans {
+
+bool entry::pr::check(action act, coder &c) {
+ // We assume PUBLIC permissions and one's without an associated record are not
+ // stored.
+ assert(perm!=PUBLIC && r!=0);
+ return c.inTranslation(r->getLevel()) ||
+ (perm == RESTRICTED && act != WRITE);
+}
+
+void entry::pr::report(action act, position pos, coder &c) {
+ if (!c.inTranslation(r->getLevel())) {
+ if (perm == PRIVATE) {
+ em.error(pos);
+ em << "accessing private field outside of structure";
+ }
+ else if (perm == RESTRICTED && act == WRITE) {
+ em.error(pos);
+ em << "modifying non-public field outside of structure";
+ }
+ }
+}
+
+entry::entry(entry &e1, entry &e2) : where(e2.where), pos(e2.pos) {
+ perms.insert(perms.end(), e1.perms.begin(), e1.perms.end());
+ perms.insert(perms.end(), e2.perms.begin(), e2.perms.end());
+}
+
+entry::entry(entry &base, permission perm, record *r)
+ : where(base.where), pos(base.pos) {
+ perms.insert(perms.end(), base.perms.begin(), base.perms.end());
+ addPerm(perm, r);
+}
+
+bool entry::checkPerm(action act, coder &c) {
+ for (mem::list<pr>::iterator p=perms.begin(); p != perms.end(); ++p)
+ if (!p->check(act, c))
+ return false;
+ return true;
+}
+
+void entry::reportPerm(action act, position pos, coder &c) {
+ for (mem::list<pr>::iterator p=perms.begin(); p != perms.end(); ++p)
+ p->report(act, pos, c);
+}
+
+
+varEntry::varEntry(varEntry &qv, varEntry &v)
+ : entry(qv,v), t(v.t),
+ location(new qualifiedAccess(qv.location, qv.getLevel(), v.location)) {}
+
+frame *varEntry::getLevel() {
+ record *r=dynamic_cast<record *>(t);
+ assert(r);
+ return r->getLevel();
+}
+
+void varEntry::encode(action act, position pos, coder &c) {
+ reportPerm(act, pos, c);
+ getLocation()->encode(act, pos, c);
+}
+
+void varEntry::encode(action act, position pos, coder &c, frame *top) {
+ reportPerm(act, pos, c);
+ getLocation()->encode(act, pos, c, top);
+}
+
+varEntry *qualifyVarEntry(varEntry *qv, varEntry *v)
+{
+ return qv ? (v ? new varEntry(*qv,*v) : qv) : v;
+}
+
+
+bool tenv::add(symbol *dest,
+ names_t::value_type &x, varEntry *qualifier, coder &c)
+{
+ if (!x.second.empty()) {
+ tyEntry *ent=x.second.front();
+ if (ent->checkPerm(READ, c)) {
+ enter(dest, qualifyTyEntry(qualifier, ent));
+ return true;
+ }
+ }
+ return false;
+}
+
+void tenv::add(tenv& source, varEntry *qualifier, coder &c) {
+ // Enter each distinct (unshadowed) name,type pair.
+ for(names_t::iterator p = source.names.begin(); p != source.names.end(); ++p)
+ add(p->first, *p, qualifier, c);
+}
+
+bool tenv::add(symbol *src, symbol *dest,
+ tenv& source, varEntry *qualifier, coder &c) {
+ names_t::iterator p = source.names.find(src);
+ if (p != source.names.end())
+ return add(dest, *p, qualifier, c);
+ else
+ return false;
+}
+
+#ifdef NOHASH //{{{
+void venv::add(venv& source, varEntry *qualifier, coder &c)
+{
+ // Enter each distinct (unshadowed) name,type pair.
+ for(names_t::iterator p = source.names.begin();
+ p != source.names.end();
+ ++p)
+ add(p->first, p->first, source, qualifier, c);
+}
+
+bool venv::add(symbol *src, symbol *dest,
+ venv& source, varEntry *qualifier, coder &c)
+{
+ bool added=false;
+ name_t &list=source.names[src];
+ types::overloaded set; // To keep track of what is shadowed.
+
+ for(name_iterator p = list.begin();
+ p != list.end();
+ ++p) {
+ varEntry *v=*p;
+ if (!equivalent(v->getType(), &set)) {
+ set.addDistinct(v->getType(), src->special);
+ if (v->checkPerm(READ, c)) {
+ enter(dest, qualifyVarEntry(qualifier, v));
+ added=true;
+ }
+ }
+ }
+
+ return added;
+}
+
+varEntry *venv::lookByType(symbol *name, ty *t)
+{
+ // Find first applicable function.
+ name_t &list = names[name];
+ for(name_iterator p = list.begin();
+ p != list.end();
+ ++p) {
+ if (equivalent((*p)->getType(), t))
+ return *p;
+ }
+ return 0;
+}
+
+void venv::list(record *module)
+{
+ bool where=settings::getSetting<bool>("where");
+ // List all functions and variables.
+ for(names_t::iterator N = names.begin(); N != names.end(); ++N) {
+ symbol *s=N->first;
+ name_t &list=names[s];
+ for(name_iterator p = list.begin(); p != list.end(); ++p) {
+ if(!module || (*p)->whereDefined() == module) {
+ if(where) cout << (*p)->getPos();
+ (*p)->getType()->printVar(cout, s);
+ cout << ";\n";
+ }
+ }
+ }
+ flush(cout);
+}
+
+varEntry *venv::lookInTopScope(symbol *name, ty *t)
+{
+ scope_t &scope = scopes.front();
+ for (scope_iterator p = scope.lower_bound(name);
+ p != scope.upper_bound(name);
+ ++p) {
+ if (name == p->first &&
+ equivalent(t, p->second->getType(), name->special))
+ return p->second;
+ }
+ return 0;
+}
+
+ty *venv::getType(symbol *name)
+{
+ types::overloaded set;
+
+ // Find all applicable functions in scope.
+ name_t &list = names[name];
+
+ for(name_iterator p = list.begin();
+ p != list.end();
+ ++p) {
+ set.addDistinct((*p)->getType(), name->special);
+ }
+
+ return set.simplify();
+}
+// }}}
+#else // {{{
+
+ostream& operator<< (ostream& out, const venv::key &k) {
+ k.t->printVar(out, k.name);
+ return out;
+}
+
+#if TEST_COLLISION
+bool venv::keyeq::operator()(const key k, const key l) const {
+ keyhash kh;
+ if (kh(k)==kh(l)) {
+ if (base(k,l))
+ return true;
+ else {
+ cerr << "collision: " << endl;
+ cerr << " " << k << " -> " << kh(k) << endl;
+ cerr << " " << l << " -> " << kh(l) << endl;
+ }
+ }
+ return false;
+}
+#else
+bool venv::keyeq::operator()(const key k, const key l) const {
+#if 0
+ cerr << "k.t = " << k.t << " " << k << endl;
+ cerr << "l.t = " << l.t << " " << l << endl;
+#endif
+ return k.name==l.name &&
+ (k.name->special ? equivalent(k.t, l.t) :
+ equivalent(k.t->getSignature(),
+ l.t->getSignature()));
+}
+#endif
+
+void venv::remove(key k) {
+ //cerr << "removing: " << k << endl;
+ value *&val=all[k];
+ assert(val);
+ if (val->next) {
+ val->next->shadowed=false;
+ value *temp=val->next;
+ val->next=0;
+ val=temp;
+ }
+ else
+ all.erase(k);
+
+ // Don't erase it from scopes.top() as that will be popped of the stack at
+ // the end of endScope anyway.
+
+ names[k.name].pop_front();
+}
+
+void venv::enter(symbol *name, varEntry *v) {
+ assert(!scopes.empty());
+ key k(name, v);
+#ifdef DEBUG_ENTRY
+ cout << "entering: " << k << " (t=" << k.t << ")" << endl;
+#endif
+ value *val=new value(v);
+
+#ifdef DEBUG_ENTRY
+ keymap::iterator p=all.find(k);
+ if (p!=all.end()) {
+ cout << " over: " << p->first << endl;
+ }
+#endif
+
+ val->next=all[k];
+ if (val->next)
+ val->next->shadowed=true;
+
+ all[k]=val;
+ scopes.top().insert(keymultimap::value_type(k,val));
+ names[k.name].push_front(val);
+}
+
+void venv::add(venv& source, varEntry *qualifier, coder &c)
+{
+ // Enter each distinct (unshadowed) name,type pair.
+ for(keymap::iterator p = source.all.begin(); p != source.all.end(); ++p) {
+ varEntry *v=p->second->v;
+ if (v->checkPerm(READ, c))
+ enter(p->first.name, qualifyVarEntry(qualifier, v));
+ }
+}
+
+bool venv::add(symbol *src, symbol *dest,
+ venv& source, varEntry *qualifier, coder &c)
+{
+ bool added=false;
+ values &list=source.names[src];
+
+ for (values::iterator p=list.begin(); p!=list.end(); ++p)
+ if (!(*p)->shadowed) {
+ varEntry *v=(*p)->v;
+ if (v->checkPerm(READ, c)) {
+ enter(dest, qualifyVarEntry(qualifier, v));
+ added=true;
+ }
+ }
+
+ return added;
+}
+
+
+ty *venv::getType(symbol *name)
+{
+ //cerr << "getType: " << *name << endl;
+ types::overloaded set;
+ values &list=names[name];
+
+ for (values::iterator p=list.begin(); p!=list.end(); ++p)
+ if (!(*p)->shadowed)
+ set.add((*p)->v->getType());
+
+ return set.simplify();
+}
+
+void venv::listValues(symbol *name, values &vals, record *module)
+{
+ ostream& out=cout;
+
+ bool where=settings::getSetting<bool>("where");
+ for(values::iterator p = vals.begin(); p != vals.end(); ++p) {
+ if(!module || (*p)->v->whereDefined() == module) {
+ if(where) out << (*p)->v->getPos();
+ if ((*p)->shadowed)
+ out << " <shadowed> ";
+ (*p)->v->getType()->printVar(out, name);
+ out << ";\n";
+ }
+ }
+ flush(out);
+}
+
+void venv::list(record *module)
+{
+ // List all functions and variables.
+ for(namemap::iterator N = names.begin(); N != names.end(); ++N)
+ listValues(N->first, N->second,module);
+}
+
+void venv::completions(mem::list<symbol *>& l, string start)
+{
+ for(namemap::iterator N = names.begin(); N != names.end(); ++N)
+ if (prefix(start, *(N->first)) && !N->second.empty())
+ l.push_back(N->first);
+}
+
+#endif // }}}
+
+} // namespace trans