diff options
author | John Wiegley <johnw@newartisans.com> | 2009-02-04 19:55:27 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-02-04 19:55:27 -0400 |
commit | 2d941730b1c60342be5b108d2d654723b3b7c2cb (patch) | |
tree | 6a3f4b7305857e85d2684670492007bafc3668d0 /src/scope.h | |
parent | 73cf3b01fbd50c3a8a4fd96ff69643c28394d8fe (diff) | |
download | fork-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.h | 77 |
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 { |