xo-expression: + binding_path + assoc w/ each Variable

This commit is contained in:
Roland Conybeare 2024-07-02 16:57:07 -04:00
commit 14796663b1
8 changed files with 105 additions and 3 deletions

View file

@ -12,6 +12,21 @@ namespace xo {
namespace ast {
class Environment : public ref::Refcount {
public:
/** true if this is toplevel (global) environment.
* Toplevel environment doesn't have slot numbers.
*
* Variables that bind in the global environment have unique
* names, which we rely on instead of slot numbers.
**/
virtual bool is_global_env() const = 0;
/** lookup binding path for @p vname in this environment.
*
* Reports ingredients needed to address variable at runtime,
* in runtime analog of this environment
**/
virtual binding_path lookup_binding(const std::string & vname) const = 0;
/** lookup variable-expression @p vname in this environment.
* returns llvm::Value representing code that produces a value for vname
**/

View file

@ -7,6 +7,7 @@
#include "Environment.hpp"
#include <map>
#include <string>
namespace xo {
namespace ast {
@ -23,7 +24,16 @@ namespace xo {
// ----- Environment -----
virtual ref::brw<Expression> lookup_var(const std::string & vname) const {
virtual bool is_global_env() const override { return true; }
virtual binding_path lookup_binding(const std::string & vname) const override {
/* i_link: -1 for global environment
* j_slot: not used
*/
return { -1, 0 };
}
virtual ref::brw<Expression> lookup_var(const std::string & vname) const override {
auto ix = global_map_.find(vname);
if (ix == global_map_.end()) {

View file

@ -47,6 +47,10 @@ namespace xo {
// ----- Environment -----
virtual bool is_global_env() const override { return false; }
virtual binding_path lookup_binding(const std::string & vname) const override;
virtual ref::brw<Expression> lookup_var(const std::string & target) const override {
for (const auto & arg : argv_) {
if (arg->name() == target)
@ -61,7 +65,7 @@ namespace xo {
private:
LocalEnv(const std::vector<ref::rp<Variable>> & argv)
: argv_(argv) {}
: origin_{nullptr}, argv_(argv) {}
private:
/** Lambnda for which this environment created.

View file

@ -6,6 +6,7 @@
#pragma once
#include "Expression.hpp"
#include "binding_path.hpp"
namespace xo {
namespace ast {
@ -42,7 +43,7 @@ namespace xo {
return 1;
}
virtual void attach_envs(ref::brw<Environment> /*p*/) override {}
virtual void attach_envs(ref::brw<Environment> /*p*/) override;
virtual void display(std::ostream & os) const override;
@ -55,6 +56,10 @@ namespace xo {
private:
/** variable name **/
std::string name_;
/** navigate environment via this path to find runtime memory
* location for this variable
**/
binding_path path_;
}; /*Variable*/
inline ref::rp<Variable>

View file

@ -0,0 +1,29 @@
/* file binding_path.hpp
*
* author: Roland Conybeare, Jul 2024
*/
#pragma once
namespace xo {
namespace ast {
/** @class path
*
* @brief path from the *use* of a variable to the environment
* providing its location.
**/
struct binding_path {
/** @of parent links to traverse. -1 if global **/
int i_link_ = -1;
/** for variables bound in some local environment:
* slot# within that environment.
*
* Ignored if @ref i_link_ is -1
**/
int j_slot_ = 0;
}; /*binding_path*/
} /*namespace ast*/
} /*namespace xo*/
/* end binding_path.hpp */

View file

@ -7,6 +7,7 @@ set(SELF_SRCS
Lambda.cpp
Variable.cpp
IfExpr.cpp
LocalEnv.cpp
)
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})

View file

@ -0,0 +1,31 @@
/* file LocalEnv.cpp
*
* author: Roland Conybeare
*/
#include "LocalEnv.hpp"
namespace xo {
namespace ast {
binding_path
LocalEnv::lookup_binding(const std::string & vname) const
{
int j_slot = 0;
for (const auto & arg : argv_) {
if (arg->name() == vname)
return { 0 /*i_link*/, j_slot };
++j_slot;
}
auto tmp = parent_env_->lookup_binding(vname);
if (tmp.i_link_ == -1)
return tmp;
else
return { tmp.i_link_ + 1, tmp.j_slot_ };
} /*lookup_binding*/
} /*namespace ast*/
} /*namespace xo*/
/* end LocalEnv.cpp */

View file

@ -1,9 +1,16 @@
/* @file Variable.cpp */
#include "Variable.hpp"
#include "Environment.hpp"
namespace xo {
namespace ast {
void
Variable::attach_envs(ref::brw<Environment> e) {
/** e makes accessible all enclosing lexical scopes **/
this->path_ = e->lookup_binding(this->name_);
} /*attach_envs*/
void
Variable::display(std::ostream & os) const {
os << "<Variable"