xo-expression: + Lambda::layer_var_map
This commit is contained in:
parent
f18c33b249
commit
89043b0d46
2 changed files with 56 additions and 38 deletions
|
|
@ -9,6 +9,7 @@
|
|||
#include "FunctionInterface.hpp"
|
||||
#include "Variable.hpp"
|
||||
#include "LocalEnv.hpp"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
//#include <cstdint>
|
||||
|
|
@ -73,9 +74,7 @@ namespace xo {
|
|||
return this;
|
||||
}
|
||||
|
||||
virtual void attach_envs(ref::brw<Environment> p) override {
|
||||
local_env_->assign_parent(p);
|
||||
}
|
||||
virtual void attach_envs(ref::brw<Environment> 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<std::string, ref::rp<Variable>> regularize_layer_vars();
|
||||
|
||||
private:
|
||||
/** lambda name. Initially supporting only form like
|
||||
|
|
@ -118,6 +117,16 @@ namespace xo {
|
|||
/** free variables for this lambda **/
|
||||
std::set<std::string> 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<std::string, ref::rp<Variable>> layer_var_map_;
|
||||
|
||||
/** established (once) by @ref attach_envs.
|
||||
*
|
||||
* @note data dependency on ancestor expressions that don't exist yet
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ namespace xo {
|
|||
return retval;
|
||||
} /*calc_free_variables*/
|
||||
|
||||
void
|
||||
std::map<std::string, ref::rp<Variable>>
|
||||
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<std::string, rp<Variable>> var_map;
|
||||
std::map<std::string, rp<Variable>> 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<Expression> x) -> ref::rp<Expression>
|
||||
{
|
||||
if (x->extype() == exprtype::variable) {
|
||||
ref::brw<Variable> 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<Expression> x) -> ref::rp<Expression>
|
||||
{
|
||||
if (x->extype() == exprtype::variable) {
|
||||
ref::brw<Variable> 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<Environment> p) {
|
||||
local_env_->assign_parent(p);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
Lambda::display(std::ostream & os) const {
|
||||
os << "<Lambda"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue