xo-expression: + Expression::attach_envs()
This commit is contained in:
parent
d836f13b88
commit
a877af562a
8 changed files with 83 additions and 13 deletions
|
|
@ -49,6 +49,13 @@ namespace xo {
|
|||
return n;
|
||||
}
|
||||
|
||||
virtual void attach_envs(ref::brw<Environment> p) override {
|
||||
fn_->attach_envs(p);
|
||||
|
||||
for (const auto & arg : argv_)
|
||||
arg->attach_envs(p);
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & os) const override;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -33,6 +33,12 @@ namespace xo {
|
|||
virtual TypeDescr value_td() const = 0;
|
||||
/** reflection-tagged pointer to literal value of this constant **/
|
||||
virtual TaggedPtr value_tp() const = 0;
|
||||
|
||||
// ----- Expression -----
|
||||
|
||||
virtual void attach_envs(ref::brw<Environment> /*p*/) override {}
|
||||
|
||||
|
||||
}; /*ConstantInterface*/
|
||||
|
||||
} /*namespace ast*/
|
||||
|
|
|
|||
|
|
@ -9,9 +9,14 @@
|
|||
#include "xo/refcnt/Refcounted.hpp"
|
||||
#include "exprtype.hpp"
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
namespace xo {
|
||||
namespace ast {
|
||||
class Variable; /* see Variable.hpp */
|
||||
class Lambda; /* see Lamnbda.hpp */
|
||||
class Environment; /* see Environment.hpp */
|
||||
|
||||
/** @class Expression
|
||||
* @brief abstract syntax tree for an EGAD program
|
||||
*
|
||||
|
|
@ -47,6 +52,22 @@ namespace xo {
|
|||
**/
|
||||
virtual std::size_t visit_preorder(VisitFn visitor_fn) = 0;
|
||||
|
||||
/** attach an environment to each lambda expression X in this subtree,
|
||||
* that will:
|
||||
* - resolve names matching X's arguments (formal parameters) to
|
||||
* from @p X.argv
|
||||
* - resolve free variables from @p parent
|
||||
**/
|
||||
virtual void attach_envs(ref::brw<Environment> parent) = 0;
|
||||
|
||||
/** append to *p_set the set of free variables in this expression.
|
||||
* returns the number of free variables introduced
|
||||
*
|
||||
* @param env stack of lexcically-enclosing lamnbda expressions,
|
||||
* in nesting order, i.e. outermost first, innertmost last
|
||||
**/
|
||||
//virtual std::int32_t find_free_vars(std::vector<ref::brw<Lambda>> env) = 0;
|
||||
|
||||
/** write human-readable representation to stream **/
|
||||
virtual void display(std::ostream & os) const = 0;
|
||||
/** human-readable string representation **/
|
||||
|
|
|
|||
|
|
@ -51,6 +51,20 @@ namespace xo {
|
|||
return n;
|
||||
}
|
||||
|
||||
virtual void attach_envs(ref::brw<Environment> p) override {
|
||||
test_->attach_envs(p);
|
||||
when_true_->attach_envs(p);
|
||||
when_false_->attach_envs(p);
|
||||
}
|
||||
|
||||
#ifdef NOT_USING
|
||||
virtual std::int32_t find_free_vars(std::set<ref::brw<Variable>> * p_set) override {
|
||||
return (test_->find_free_vars(p_set)
|
||||
+ when_true_->find_free_vars(p_set)
|
||||
+ when_false_->find_free_vars(p_set));
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void display(std::ostream & os) const override;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "Expression.hpp"
|
||||
#include "FunctionInterface.hpp"
|
||||
#include "Variable.hpp"
|
||||
#include "LocalEnv.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
//#include <cstdint>
|
||||
|
|
@ -35,16 +36,16 @@ namespace xo {
|
|||
}
|
||||
|
||||
const std::string & type_str() const { return type_str_; }
|
||||
const std::vector<ref::rp<Variable>> & argv() const { return argv_; }
|
||||
const std::vector<ref::rp<Variable>> & argv() const { return local_env_->argv(); }
|
||||
const ref::rp<Expression> & body() const { return body_; }
|
||||
|
||||
// ----- FunctionInterface -----
|
||||
|
||||
virtual const std::string & name() const override { return name_; }
|
||||
/** return number of arguments expected by this function **/
|
||||
virtual int n_arg() const override { return argv_.size(); }
|
||||
virtual int n_arg() const override { return local_env_->n_arg(); }
|
||||
virtual TypeDescr fn_retval() const override { return body_->valuetype(); }
|
||||
virtual TypeDescr fn_arg(uint32_t i) const override { return argv_[i]->valuetype(); }
|
||||
virtual TypeDescr fn_arg(uint32_t i) const override { return local_env_->fn_arg(i); }
|
||||
|
||||
// ----- Expression -----
|
||||
|
||||
|
|
@ -53,7 +54,7 @@ namespace xo {
|
|||
|
||||
visitor_fn(this);
|
||||
|
||||
for (const auto & arg : argv_)
|
||||
for (const auto & arg : local_env_->argv())
|
||||
n += arg->visit_preorder(visitor_fn);
|
||||
|
||||
n += body_->visit_preorder(visitor_fn);
|
||||
|
|
@ -61,6 +62,10 @@ namespace xo {
|
|||
return n;
|
||||
}
|
||||
|
||||
virtual void attach_envs(ref::brw<Environment> p) override {
|
||||
local_env_->assign_parent(p);
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & os) const override;
|
||||
|
||||
private:
|
||||
|
|
@ -69,7 +74,7 @@ namespace xo {
|
|||
**/
|
||||
Lambda(const std::string & name,
|
||||
TypeDescr lambda_type,
|
||||
const std::vector<ref::rp<Variable>> & argv,
|
||||
const ref::rp<LocalEnv> & local_env,
|
||||
const ref::rp<Expression> & body);
|
||||
|
||||
private:
|
||||
|
|
@ -85,10 +90,16 @@ namespace xo {
|
|||
* "double(double,double)" for function of two doubles that returns a double
|
||||
**/
|
||||
std::string type_str_;
|
||||
/** formal argument names **/
|
||||
std::vector<ref::rp<Variable>> argv_;
|
||||
/** function body **/
|
||||
ref::rp<Expression> body_;
|
||||
|
||||
/** established (once) by @ref attach_envs.
|
||||
*
|
||||
* @note data dependency on ancestor expressions that don't exist yet
|
||||
* when Lambda constructor runs, so we need to assign @ref local_env_
|
||||
* later.
|
||||
**/
|
||||
ref::rp<LocalEnv> local_env_;
|
||||
}; /*Lambda*/
|
||||
|
||||
inline ref::rp<Lambda>
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ namespace xo {
|
|||
return 1;
|
||||
}
|
||||
|
||||
virtual void attach_envs(ref::brw<Environment> /*p*/) override {}
|
||||
|
||||
private:
|
||||
}; /*PrimitiveInterface*/
|
||||
} /*namespace ast*/
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ namespace xo {
|
|||
return 1;
|
||||
}
|
||||
|
||||
virtual void attach_envs(ref::brw<Environment> /*p*/) override {}
|
||||
|
||||
#ifdef NOT_USING
|
||||
virtual std::int32_t find_free_vars(std::set<ref::brw<Variable>> * p_set) override {
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual void display(std::ostream & os) const override;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -41,23 +41,23 @@ namespace xo {
|
|||
|
||||
return new Lambda(name,
|
||||
lambda_td,
|
||||
argv,
|
||||
LocalEnv::make(argv),
|
||||
body);
|
||||
} /*make*/
|
||||
|
||||
Lambda::Lambda(const std::string & name,
|
||||
TypeDescr lambda_type,
|
||||
const std::vector<rp<Variable>> & argv,
|
||||
const rp<LocalEnv> & local_env,
|
||||
const ref::rp<Expression> & body)
|
||||
: FunctionInterface(exprtype::lambda, lambda_type),
|
||||
name_{name},
|
||||
argv_{argv},
|
||||
body_{body}
|
||||
body_{body},
|
||||
local_env_{local_env}
|
||||
{
|
||||
stringstream ss;
|
||||
ss << "double";
|
||||
ss << "(";
|
||||
for (std::size_t i = 0; i < argv.size(); ++i) {
|
||||
for (std::size_t i = 0, n = this->n_arg(); i < n; ++i) {
|
||||
if (i > 0)
|
||||
ss << ",";
|
||||
ss << "double";
|
||||
|
|
@ -65,13 +65,15 @@ namespace xo {
|
|||
ss << ")";
|
||||
|
||||
type_str_ = ss.str();
|
||||
|
||||
body_->attach_envs(local_env_);
|
||||
} /*ctor*/
|
||||
|
||||
void
|
||||
Lambda::display(std::ostream & os) const {
|
||||
os << "<Lambda"
|
||||
<< xtag("name", name_)
|
||||
<< xtag("argv", argv_)
|
||||
<< xtag("argv", local_env_->argv())
|
||||
<< xtag("body", body_)
|
||||
<< ">";
|
||||
} /*display*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue