summaryrefslogtreecommitdiff
path: root/src/scope.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/scope.h')
-rw-r--r--src/scope.h102
1 files changed, 76 insertions, 26 deletions
diff --git a/src/scope.h b/src/scope.h
index a7b3c5cb..c43d73d6 100644
--- a/src/scope.h
+++ b/src/scope.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2010, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2012, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -70,8 +70,7 @@ struct symbol_t
TRACE_CTOR(symbol_t, "symbol_t::kind_t, string");
}
symbol_t(const symbol_t& sym)
- : kind(sym.kind), name(sym.name),
- definition(sym.definition) {
+ : kind(sym.kind), name(sym.name), definition(sym.definition) {
TRACE_CTOR(symbol_t, "copy");
}
~symbol_t() throw() {
@@ -81,6 +80,9 @@ struct symbol_t
bool operator<(const symbol_t& sym) const {
return kind < sym.kind || name < sym.name;
}
+ bool operator==(const symbol_t& sym) const {
+ return kind == sym.kind || name == sym.name;
+ }
#if defined(HAVE_BOOST_SERIALIZATION)
private:
@@ -97,10 +99,13 @@ private:
#endif // HAVE_BOOST_SERIALIZATION
};
+class empty_scope_t;
+
class scope_t
{
public:
- static scope_t * default_scope;
+ static scope_t * default_scope;
+ static empty_scope_t * empty_scope;
explicit scope_t() {
TRACE_CTOR(scope_t, "");
@@ -134,6 +139,24 @@ private:
#endif // HAVE_BOOST_SERIALIZATION
};
+class empty_scope_t : public scope_t
+{
+public:
+ empty_scope_t() {
+ TRACE_CTOR(empty_scope_t, "");
+ }
+ ~empty_scope_t() throw() {
+ TRACE_DTOR(empty_scope_t);
+ }
+
+ virtual string description() {
+ return _("<empty>");
+ }
+ virtual expr_t::ptr_op_t lookup(const symbol_t::kind_t, const string&) {
+ return NULL;
+ }
+};
+
class child_scope_t : public noncopyable, public scope_t
{
public:
@@ -142,8 +165,7 @@ public:
explicit child_scope_t() : parent(NULL) {
TRACE_CTOR(child_scope_t, "");
}
- explicit child_scope_t(scope_t& _parent)
- : parent(&_parent) {
+ explicit child_scope_t(scope_t& _parent) : parent(&_parent) {
TRACE_CTOR(child_scope_t, "scope_t&");
}
virtual ~child_scope_t() {
@@ -187,6 +209,8 @@ public:
explicit bind_scope_t(scope_t& _parent,
scope_t& _grandchild)
: child_scope_t(_parent), grandchild(_grandchild) {
+ DEBUG("scope.symbols",
+ "Binding scope " << &_parent << " with " << &_grandchild);
TRACE_CTOR(bind_scope_t, "scope_t&, scope_t&");
}
virtual ~bind_scope_t() {
@@ -225,15 +249,19 @@ private:
};
template <typename T>
-T * search_scope(scope_t * ptr)
+T * search_scope(scope_t * ptr, bool prefer_direct_parents = false)
{
+ DEBUG("scope.search", "Searching scope " << ptr->description());
+
if (T * sought = dynamic_cast<T *>(ptr))
return sought;
if (bind_scope_t * scope = dynamic_cast<bind_scope_t *>(ptr)) {
- if (T * sought = search_scope<T>(&scope->grandchild))
+ if (T * sought = search_scope<T>(prefer_direct_parents ?
+ scope->parent : &scope->grandchild))
return sought;
- return search_scope<T>(scope->parent);
+ return search_scope<T>(prefer_direct_parents ?
+ &scope->grandchild : scope->parent);
}
else if (child_scope_t * child_scope = dynamic_cast<child_scope_t *>(ptr)) {
return search_scope<T>(child_scope->parent);
@@ -242,9 +270,21 @@ T * search_scope(scope_t * ptr)
}
template <typename T>
-inline T& find_scope(child_scope_t& scope, bool skip_this = true)
+inline T& find_scope(child_scope_t& scope, bool skip_this = true,
+ bool prefer_direct_parents = false)
+{
+ if (T * sought = search_scope<T>(skip_this ? scope.parent : &scope,
+ prefer_direct_parents))
+ return *sought;
+
+ throw_(std::runtime_error, _("Could not find scope"));
+ return reinterpret_cast<T&>(scope); // never executed
+}
+
+template <typename T>
+inline T& find_scope(scope_t& scope, bool prefer_direct_parents = false)
{
- if (T * sought = search_scope<T>(skip_this ? scope.parent : &scope))
+ if (T * sought = search_scope<T>(&scope, prefer_direct_parents))
return *sought;
throw_(std::runtime_error, _("Could not find scope"));
@@ -258,7 +298,7 @@ class symbol_scope_t : public child_scope_t
optional<symbol_map> symbols;
public:
- explicit symbol_scope_t() {
+ explicit symbol_scope_t() : child_scope_t() {
TRACE_CTOR(symbol_scope_t, "");
}
explicit symbol_scope_t(scope_t& _parent) : child_scope_t(_parent) {
@@ -347,13 +387,8 @@ protected:
class call_scope_t : public context_scope_t
{
-#if defined(DEBUG_ON)
public:
-#endif
value_t args;
-#if defined(DEBUG_ON)
-private:
-#endif
mutable void * ptr;
value_t& resolve(const std::size_t index,
@@ -370,17 +405,12 @@ public:
: context_scope_t(_parent, _parent.type_context(),
_parent.type_required()),
ptr(NULL), locus(_locus), depth(_depth) {
- TRACE_CTOR(call_scope_t,
- "scope_t&, value_t::type_t, bool, expr_t::ptr_op_t *, int");
+ TRACE_CTOR(call_scope_t, "scope_t&, expr_t::ptr_op_t *, const int");
}
virtual ~call_scope_t() {
TRACE_DTOR(call_scope_t);
}
- virtual string description() {
- return context_scope_t::description();
- }
-
void set_args(const value_t& _args) {
args = _args;
}
@@ -453,7 +483,7 @@ public:
#if defined(HAVE_BOOST_SERIALIZATION)
protected:
- explicit call_scope_t() {
+ explicit call_scope_t() : depth(0) {
TRACE_CTOR(call_scope_t, "");
}
@@ -635,6 +665,21 @@ call_scope_t::get<expr_t::ptr_op_t>(std::size_t index, bool) {
return args[index].as_any<expr_t::ptr_op_t>();
}
+inline string join_args(call_scope_t& args) {
+ std::ostringstream buf;
+ bool first = true;
+
+ for (std::size_t i = 0; i < args.size(); i++) {
+ if (first)
+ first = false;
+ else
+ buf << ' ';
+ buf << args[i];
+ }
+
+ return buf.str();
+}
+
class value_scope_t : public child_scope_t
{
value_t value;
@@ -645,7 +690,12 @@ class value_scope_t : public child_scope_t
public:
value_scope_t(scope_t& _parent, const value_t& _value)
- : child_scope_t(_parent), value(_value) {}
+ : child_scope_t(_parent), value(_value) {
+ TRACE_CTOR(value_scope_t, "scope_t&, value_t");
+ }
+ ~value_scope_t() throw() {
+ TRACE_DTOR(value_scope_t);
+ }
virtual string description() {
return parent->description();
@@ -660,7 +710,7 @@ public:
if (name == "value")
return MAKE_FUNCTOR(value_scope_t::get_value);
- return NULL;
+ return child_scope_t::lookup(kind, name);
}
};