xo-expression: + Expression::nested_layer()

This commit is contained in:
Roland Conybeare 2024-07-03 16:18:26 -04:00
commit 91a5a2b844
10 changed files with 61 additions and 2 deletions

View file

@ -63,6 +63,19 @@ namespace xo {
return n; return n;
} }
virtual std::size_t visit_layer(VisitFn visitor_fn) override {
std::size_t n = 1;
visitor_fn(this);
n += fn_->visit_layer(visitor_fn);
for (const auto & arg : argv_)
n += arg->visit_layer(visitor_fn);
return n;
}
virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override { virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override {
this->fn_ = fn_->xform_layer(xform_fn); this->fn_ = fn_->xform_layer(xform_fn);

View file

@ -56,6 +56,11 @@ namespace xo {
return 1; return 1;
} }
virtual std::size_t visit_layer(VisitFn visitor_fn) override {
visitor_fn(this);
return 1;
}
virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override { virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override {
return xform_fn(this); return xform_fn(this);
} }

View file

@ -6,10 +6,12 @@
#pragma once #pragma once
#include "xo/refcnt/Refcounted.hpp" #include "xo/refcnt/Refcounted.hpp"
#include "Variable.hpp" #include "binding_path.hpp"
namespace xo { namespace xo {
namespace ast { namespace ast {
class Expression;
class Environment : public ref::Refcount { class Environment : public ref::Refcount {
public: public:
/** true if this is toplevel (global) environment. /** true if this is toplevel (global) environment.

View file

@ -61,6 +61,13 @@ namespace xo {
**/ **/
virtual std::size_t visit_preorder(VisitFn visitor_fn) = 0; virtual std::size_t visit_preorder(VisitFn visitor_fn) = 0;
/** visit each Expression node in this AST,
* including immediately-nested Lambda nodes;
* but do not recurse into the params/body of such nested Lambdas.
* Returns the number of nodes visited
**/
virtual std::size_t visit_layer(VisitFn visitor_fn) = 0;
/** traverse ast @ref visit_preorder but do not visit Lambdas **/ /** traverse ast @ref visit_preorder but do not visit Lambdas **/
virtual ref::rp<Expression> xform_layer(TransformFn visitor_fn) = 0; virtual ref::rp<Expression> xform_layer(TransformFn visitor_fn) = 0;

View file

@ -67,6 +67,18 @@ namespace xo {
return n; return n;
} }
virtual std::size_t visit_layer(VisitFn visitor_fn) override {
std::size_t n = 1;
visitor_fn(this);
n += this->test_->visit_layer(visitor_fn);
n += this->when_true_->visit_layer(visitor_fn);
n += this->when_false_->visit_layer(visitor_fn);
return n;
}
virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override { virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override {
this->test_ = this->test_->xform_layer(xform_fn); this->test_ = this->test_->xform_layer(xform_fn);
this->when_true_ = this->when_true_->xform_layer(xform_fn); this->when_true_ = this->when_true_->xform_layer(xform_fn);

View file

@ -69,6 +69,14 @@ namespace xo {
return n; return n;
} }
virtual std::size_t visit_layer(VisitFn visitor_fn) override {
std::size_t n = 1;
visitor_fn(this);
return n;
}
virtual ref::rp<Expression> xform_layer(TransformFn /*xform_fn*/) override { virtual ref::rp<Expression> xform_layer(TransformFn /*xform_fn*/) override {
/* a layer is bounded by lambdas, don't enter them */ /* a layer is bounded by lambdas, don't enter them */
return this; return this;

View file

@ -6,6 +6,8 @@
#pragma once #pragma once
#include "Environment.hpp" #include "Environment.hpp"
#include "Variable.hpp"
#include "xo/reflect/TypeDescr.hpp"
namespace xo { namespace xo {
namespace ast { namespace ast {

View file

@ -57,6 +57,11 @@ namespace xo {
return 1; return 1;
} }
virtual std::size_t visit_layer(VisitFn visitor_fn) override {
visitor_fn(this);
return 1;
}
virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override { virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override {
return xform_fn(this); return xform_fn(this);
} }

View file

@ -48,6 +48,11 @@ namespace xo {
return 1; return 1;
} }
virtual std::size_t visit_layer(VisitFn visitor_fn) override {
visitor_fn(this);
return 1;
}
virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override { virtual ref::rp<Expression> xform_layer(TransformFn xform_fn) override {
return xform_fn(this); return xform_fn(this);
} }

View file

@ -112,7 +112,7 @@ namespace xo {
return var.get(); return var.get();
} else { } else {
/* substitute already-encountered var_map[] member */ /* substitute already-encountered var_map[] member */
return ix->second; return ix->second.get();
} }
} else { } else {
return x.get(); return x.get();