xo-expression: Lambda caches free var set + ::needs_closure() method
This commit is contained in:
parent
b7db7c5454
commit
97264b726f
2 changed files with 24 additions and 8 deletions
|
|
@ -39,6 +39,8 @@ namespace xo {
|
|||
const std::vector<ref::rp<Variable>> & argv() const { return local_env_->argv(); }
|
||||
const ref::rp<Expression> & body() const { return body_; }
|
||||
|
||||
bool needs_closure_flag() const { return !free_var_set_.empty(); }
|
||||
|
||||
// ----- FunctionInterface -----
|
||||
|
||||
virtual const std::string & name() const override { return name_; }
|
||||
|
|
@ -50,13 +52,7 @@ namespace xo {
|
|||
// ----- Expression -----
|
||||
|
||||
virtual std::set<std::string> get_free_variables() const override {
|
||||
std::set<std::string> retval = body_->get_free_variables();
|
||||
|
||||
/* but remove formals. */
|
||||
for (const auto & var : local_env_->argv())
|
||||
retval.erase(var->name());
|
||||
|
||||
return retval;
|
||||
return this->free_var_set_;
|
||||
}
|
||||
|
||||
virtual std::size_t visit_preorder(VisitFn visitor_fn) override {
|
||||
|
|
@ -87,6 +83,9 @@ namespace xo {
|
|||
const ref::rp<LocalEnv> & local_env,
|
||||
const ref::rp<Expression> & body);
|
||||
|
||||
/** compute free-variable set for this lambda **/
|
||||
std::set<std::string> calc_free_variables() const;
|
||||
|
||||
private:
|
||||
/** lambda name. Initially supporting only form like
|
||||
* (define (foo x y z)
|
||||
|
|
@ -103,6 +102,9 @@ namespace xo {
|
|||
/** function body **/
|
||||
ref::rp<Expression> body_;
|
||||
|
||||
/** free variables for this lambda **/
|
||||
std::set<std::string> free_var_set_;
|
||||
|
||||
/** established (once) by @ref attach_envs.
|
||||
*
|
||||
* @note data dependency on ancestor expressions that don't exist yet
|
||||
|
|
|
|||
|
|
@ -45,6 +45,19 @@ namespace xo {
|
|||
body);
|
||||
} /*make*/
|
||||
|
||||
std::set<std::string>
|
||||
Lambda::calc_free_variables() const
|
||||
{
|
||||
std::set<std::string> retval
|
||||
= body_->get_free_variables();
|
||||
|
||||
/* but remove formals. */
|
||||
for (const auto & var : local_env_->argv())
|
||||
retval.erase(var->name());
|
||||
|
||||
return retval;
|
||||
} /*calc_free_variables*/
|
||||
|
||||
Lambda::Lambda(const std::string & name,
|
||||
TypeDescr lambda_type,
|
||||
const rp<LocalEnv> & local_env,
|
||||
|
|
@ -64,7 +77,8 @@ namespace xo {
|
|||
}
|
||||
ss << ")";
|
||||
|
||||
type_str_ = ss.str();
|
||||
this->type_str_ = ss.str();
|
||||
this->free_var_set_ = this->calc_free_variables();
|
||||
|
||||
body_->attach_envs(local_env_);
|
||||
} /*ctor*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue