From 89043b0d46880440d3c51a8b19ca4e0dd7014bd9 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Wed, 3 Jul 2024 15:10:34 -0400 Subject: [PATCH] xo-expression: + Lambda::layer_var_map --- include/xo/expression/Lambda.hpp | 17 +++++-- src/expression/Lambda.cpp | 81 ++++++++++++++++++-------------- 2 files changed, 58 insertions(+), 40 deletions(-) diff --git a/include/xo/expression/Lambda.hpp b/include/xo/expression/Lambda.hpp index d4ec9c54..231e2043 100644 --- a/include/xo/expression/Lambda.hpp +++ b/include/xo/expression/Lambda.hpp @@ -9,6 +9,7 @@ #include "FunctionInterface.hpp" #include "Variable.hpp" #include "LocalEnv.hpp" +#include #include #include //#include @@ -73,9 +74,7 @@ namespace xo { return this; } - virtual void attach_envs(ref::brw p) override { - local_env_->assign_parent(p); - } + virtual void attach_envs(ref::brw p) override; virtual void display(std::ostream & os) const override; @@ -97,7 +96,7 @@ namespace xo { * Goal is to unify variables that can use the same binding * path to determine memory location at runtime. **/ - void regularize_layer_vars(); + std::map> regularize_layer_vars(); private: /** lambda name. Initially supporting only form like @@ -118,6 +117,16 @@ namespace xo { /** free variables for this lambda **/ std::set free_var_set_; + /** map giving unique identity to each variable appearing in this layer. + * includes: + * - formal parameters + * - free variables in @ref body_ + * excludes: + * - any variables appearing in nested lambdas + * (whether formals or free variables) + **/ + std::map> layer_var_map_; + /** established (once) by @ref attach_envs. * * @note data dependency on ancestor expressions that don't exist yet diff --git a/src/expression/Lambda.cpp b/src/expression/Lambda.cpp index 72459fe5..85f8bbcf 100644 --- a/src/expression/Lambda.cpp +++ b/src/expression/Lambda.cpp @@ -69,7 +69,7 @@ namespace xo { return retval; } /*calc_free_variables*/ - void + std::map> Lambda::regularize_layer_vars() { /* regularize local_env+body: make sure exactly one instance @@ -83,42 +83,43 @@ 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 - * in a particular lambda's parameter list - */ - assert(var_map.find(arg->name()) == var_map.end()); + for (const auto & arg : local_env_->argv()) { + /* each arg name can appear at most once + * in a particular lambda's parameter list + */ + assert(var_map.find(arg->name()) == var_map.end()); - var_map[arg->name()] = arg; - } - - body_ = body_->xform_layer - ([&var_map](ref::brw x) -> ref::rp - { - if (x->extype() == exprtype::variable) { - ref::brw var = Variable::from(x); - - auto ix = var_map.find(var->name()); - if (ix == var_map.end()) { - /* add to var_map, copy to ensure Variable - * is unique to layer - */ - - var_map[var->name()] = Variable::copy(var); - - return var.get(); - } else { - /* substitute already-encountered var_map[] member */ - return ix->second; - } - } else { - return x.get(); - } - }); + var_map[arg->name()] = arg; } + + this->body_ + = (body_->xform_layer + ([&var_map](ref::brw x) -> ref::rp + { + if (x->extype() == exprtype::variable) { + ref::brw var = Variable::from(x); + + auto ix = var_map.find(var->name()); + if (ix == var_map.end()) { + /* add to var_map, copy to ensure Variable + * not shared with any other layer + */ + + var_map[var->name()] = Variable::copy(var); + + return var.get(); + } else { + /* substitute already-encountered var_map[] member */ + return ix->second; + } + } else { + return x.get(); + } + })); + + return var_map; } /*regularize_layer_vars*/ Lambda::Lambda(const std::string & name, @@ -141,13 +142,21 @@ namespace xo { ss << ")"; this->type_str_ = ss.str(); - this->free_var_set_ = this->calc_free_variables(); - this->regularize_layer_vars(); + /* ensure variables are unique within layer for this lambda */ + this->layer_var_map_ = this->regularize_layer_vars(); + + this->free_var_set_ = this->calc_free_variables(); this->body_->attach_envs(local_env_); } /*ctor*/ + void + Lambda::attach_envs(ref::brw p) { + local_env_->assign_parent(p); + + } + void Lambda::display(std::ostream & os) const { os << "