From 4b0a2cff2a7413c1662ec8d3d20404347d107538 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 3 Jul 2024 16:20:18 -0400 Subject: [PATCH] xo-expression: + Lambda::nested_lambda_map --- include/xo/expression/GlobalEnv.hpp | 2 +- include/xo/expression/Lambda.hpp | 3 +++ include/xo/expression/binding_path.hpp | 4 ++-- src/expression/Lambda.cpp | 21 ++++++++++++++++++++- src/expression/Variable.cpp | 6 +++++- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/include/xo/expression/GlobalEnv.hpp b/include/xo/expression/GlobalEnv.hpp index 08eb9355..010dc296 100644 --- a/include/xo/expression/GlobalEnv.hpp +++ b/include/xo/expression/GlobalEnv.hpp @@ -26,7 +26,7 @@ namespace xo { virtual bool is_global_env() const override { return true; } - virtual binding_path lookup_binding(const std::string & vname) const override { + virtual binding_path lookup_binding(const std::string & /*vname*/) const override { /* i_link: -1 for global environment * j_slot: not used */ diff --git a/include/xo/expression/Lambda.hpp b/include/xo/expression/Lambda.hpp index 3a3de6ac..91366ca9 100644 --- a/include/xo/expression/Lambda.hpp +++ b/include/xo/expression/Lambda.hpp @@ -135,6 +135,9 @@ namespace xo { **/ std::map> layer_var_map_; + /** all lambdas nested once inside this lambda's body **/ + std::map> nested_lambda_map_; + /** established (once) by @ref attach_envs. * * @note data dependency on ancestor expressions that don't exist yet diff --git a/include/xo/expression/binding_path.hpp b/include/xo/expression/binding_path.hpp index a3692ed1..7aef8c51 100644 --- a/include/xo/expression/binding_path.hpp +++ b/include/xo/expression/binding_path.hpp @@ -13,8 +13,8 @@ namespace xo { * providing its location. **/ struct binding_path { - /** @of parent links to traverse. -1 if global **/ - int i_link_ = -1; + /** @of parent links to traverse. -1 if global. -2 if sentinel **/ + int i_link_ = -2; /** for variables bound in some local environment: * slot# within that environment. * diff --git a/src/expression/Lambda.cpp b/src/expression/Lambda.cpp index fba94694..320e1eda 100644 --- a/src/expression/Lambda.cpp +++ b/src/expression/Lambda.cpp @@ -83,7 +83,7 @@ namespace xo { * Motivation is to unify Variables that would use the same * binding_path to resolve their runtime location. */ - std::map> var_map; + std::map> var_map; for (const auto & arg : local_env_->argv()) { /* each arg name can appear at most once @@ -148,6 +148,24 @@ namespace xo { this->free_var_set_ = this->calc_free_variables(); + std::map> nested_lambda_map; + + this->body_->visit_layer + ([&nested_lambda_map] + (ref::brw expr) + { + if (expr->extype() == exprtype::lambda) { + ref::brw lm = Lambda::from(expr); + + nested_lambda_map[lm->name()] = lm.get(); + } + }); + + this->nested_lambda_map_ = std::move(nested_lambda_map); + + /* in particular: + * - establish binding path for each variable + */ this->body_->attach_envs(local_env_); } /*ctor*/ @@ -155,6 +173,7 @@ namespace xo { Lambda::attach_envs(ref::brw p) { local_env_->assign_parent(p); + /** establish a binding path for each variable **/ } void diff --git a/src/expression/Variable.cpp b/src/expression/Variable.cpp index 71d47655..766e0c67 100644 --- a/src/expression/Variable.cpp +++ b/src/expression/Variable.cpp @@ -8,7 +8,11 @@ namespace xo { void Variable::attach_envs(ref::brw e) { /** e makes accessible all enclosing lexical scopes **/ - this->path_ = e->lookup_binding(this->name_); + if (this->path_.i_link_ == -2 /*sentinel*/) { + this->path_ = e->lookup_binding(this->name_); + } else { + /* have already established binding for this Variable */ + } } /*attach_envs*/ void