summaryrefslogtreecommitdiff
path: root/src/scope.h
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-02-04 19:55:27 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-02-04 19:55:27 -0400
commit2d941730b1c60342be5b108d2d654723b3b7c2cb (patch)
tree6a3f4b7305857e85d2684670492007bafc3668d0 /src/scope.h
parent73cf3b01fbd50c3a8a4fd96ff69643c28394d8fe (diff)
downloadfork-ledger-2d941730b1c60342be5b108d2d654723b3b7c2cb.tar.gz
fork-ledger-2d941730b1c60342be5b108d2d654723b3b7c2cb.tar.bz2
fork-ledger-2d941730b1c60342be5b108d2d654723b3b7c2cb.zip
Largely removed all of Ledger's use of global variables, for the REPL's sake.
Diffstat (limited to 'src/scope.h')
-rw-r--r--src/scope.h77
1 files changed, 60 insertions, 17 deletions
diff --git a/src/scope.h b/src/scope.h
index 174d52fe..3d1e5108 100644
--- a/src/scope.h
+++ b/src/scope.h
@@ -105,23 +105,6 @@ public:
}
};
-
-template <typename T>
-inline T& find_scope(child_scope_t& scope, bool skip_this = true)
-{
- for (scope_t * ptr = (skip_this ? scope.parent : &scope); ptr; ) {
- T * sought = dynamic_cast<T *>(ptr);
- if (sought)
- return *sought;
- if (child_scope_t * scope = dynamic_cast<child_scope_t *>(ptr))
- ptr = scope->parent;
- else
- ptr = NULL;
- }
- throw_(std::runtime_error, "Could not find scope");
- return reinterpret_cast<T&>(scope); // never executed
-}
-
/**
* @brief Brief
*
@@ -209,6 +192,66 @@ public:
*
* Long.
*/
+class bind_scope_t : public child_scope_t
+{
+ bind_scope_t();
+
+public:
+ scope_t& grandchild;
+
+ explicit bind_scope_t(scope_t& _parent,
+ scope_t& _grandchild)
+ : child_scope_t(_parent), grandchild(_grandchild) {
+ TRACE_CTOR(bind_scope_t, "scope_t&, scope_t&");
+ }
+ virtual ~bind_scope_t() {
+ TRACE_DTOR(bind_scope_t);
+ }
+
+ virtual expr_t::ptr_op_t lookup(const string& name) {
+ if (expr_t::ptr_op_t def = grandchild.lookup(name))
+ return def;
+ return child_scope_t::lookup(name);
+ }
+};
+
+/**
+ * @brief Brief
+ *
+ * Long.
+ */
+template <typename T>
+T * search_scope(scope_t * ptr)
+{
+ 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))
+ return sought;
+ return search_scope<T>(scope->parent);
+ }
+ else if (child_scope_t * scope = dynamic_cast<child_scope_t *>(ptr)) {
+ return search_scope<T>(scope->parent);
+ }
+ return NULL;
+}
+
+template <typename T>
+inline T& find_scope(child_scope_t& scope, bool skip_this = true)
+{
+ if (T * sought = search_scope<T>(skip_this ? scope.parent : &scope))
+ return *sought;
+
+ throw_(std::runtime_error, "Could not find scope");
+ return reinterpret_cast<T&>(scope); // never executed
+}
+
+/**
+ * @brief Brief
+ *
+ * Long.
+ */
template <typename T>
class ptr_t : public noncopyable
{