xo-expression/xo-reader: refactor Environment -> SymbolTable

This commit is contained in:
Roland Conybeare 2025-11-19 12:42:31 -05:00
commit 800928cd69
40 changed files with 146 additions and 510 deletions

View file

@ -129,7 +129,7 @@ namespace xo {
return xform_fn(this); return xform_fn(this);
} }
virtual void attach_envs(bp<Environment> p) override; virtual void attach_envs(bp<SymbolTable> p) override;
virtual void display(std::ostream & os) const override; virtual void display(std::ostream & os) const override;
virtual std::uint32_t pretty_print(const ppindentinfo & ppii) const override; virtual std::uint32_t pretty_print(const ppindentinfo & ppii) const override;

View file

@ -37,7 +37,7 @@ namespace xo {
virtual std::size_t visit_preorder(VisitFn visitor_fn) override; virtual std::size_t visit_preorder(VisitFn visitor_fn) override;
virtual std::size_t visit_layer(VisitFn visitor_fn) override; virtual std::size_t visit_layer(VisitFn visitor_fn) override;
virtual rp<Expression> xform_layer(TransformFn xform_fn) override; virtual rp<Expression> xform_layer(TransformFn xform_fn) override;
virtual void attach_envs(bp<Environment> p) override; virtual void attach_envs(bp<SymbolTable> p) override;
virtual void display(std::ostream & os) const override; virtual void display(std::ostream & os) const override;
virtual std::uint32_t pretty_print(const ppindentinfo & ppii) const override; virtual std::uint32_t pretty_print(const ppindentinfo & ppii) const override;

View file

@ -40,7 +40,7 @@ namespace xo {
return std::set<std::string>(); return std::set<std::string>();
} }
virtual void attach_envs(bp<Environment> /*p*/) override {} virtual void attach_envs(bp<SymbolTable> /*p*/) override {}
}; /*ConstantInterface*/ }; /*ConstantInterface*/

View file

@ -61,7 +61,7 @@ namespace xo {
return xform_fn(this); return xform_fn(this);
} }
virtual void attach_envs(bp<Environment> p) override { virtual void attach_envs(bp<SymbolTable> p) override {
arg_->attach_envs(p); arg_->attach_envs(p);
} }

View file

@ -75,7 +75,7 @@ namespace xo {
return xform_fn(this); return xform_fn(this);
} }
virtual void attach_envs(bp<Environment> p) override { virtual void attach_envs(bp<SymbolTable> p) override {
rhs_->attach_envs(p); rhs_->attach_envs(p);
} }

View file

@ -13,7 +13,7 @@ namespace xo {
namespace scm { namespace scm {
class Variable; /* see Variable.hpp */ class Variable; /* see Variable.hpp */
class Lambda; /* see Lamnbda.hpp */ class Lambda; /* see Lamnbda.hpp */
class Environment; /* see Environment.hpp */ class SymbolTable; /* see SymbolTable.hpp */
/** @class Expression /** @class Expression
* @brief abstract syntax tree for an EGAD program * @brief abstract syntax tree for an EGAD program
@ -72,7 +72,7 @@ namespace xo {
* from @p X.argv * from @p X.argv
* - resolve free variables from @p parent * - resolve free variables from @p parent
**/ **/
virtual void attach_envs(bp<Environment> parent) = 0; virtual void attach_envs(bp<SymbolTable> parent) = 0;
/** append to *p_set the set of free variables in this expression. /** append to *p_set the set of free variables in this expression.
* returns the number of free variables introduced * returns the number of free variables introduced

View file

@ -1,20 +1,20 @@
/* file GlobalEnv.hpp /* file GlobalSymtab.hpp
* *
* author: Roland Conybeare, Jun 2024 * author: Roland Conybeare, Jun 2024
*/ */
#pragma once #pragma once
#include "Environment.hpp" #include "SymbolTable.hpp"
#include <map> #include <map>
#include <string> #include <string>
namespace xo { namespace xo {
namespace scm { namespace scm {
class GlobalEnv : public Environment { class GlobalSymtab : public SymbolTable {
public: public:
/** create instance. Probably only need one of these **/ /** create instance. Probably only need one of these **/
static rp<GlobalEnv> make_empty() { return new GlobalEnv(); } static rp<GlobalSymtab> make_empty() { return new GlobalSymtab(); }
bp<Expression> require_global(const std::string & vname, bp<Expression> require_global(const std::string & vname,
bp<Expression> expr); bp<Expression> expr);
@ -51,7 +51,7 @@ namespace xo {
virtual std::uint32_t pretty_print(const xo::print::ppindentinfo & ppii) const override; virtual std::uint32_t pretty_print(const xo::print::ppindentinfo & ppii) const override;
private: private:
GlobalEnv(); GlobalSymtab();
private: private:
/* for assignable globals, need to allocate memory /* for assignable globals, need to allocate memory
@ -63,4 +63,4 @@ namespace xo {
} /*namespace xo*/ } /*namespace xo*/
/* end GlobalEnv.hpp */ /* end GlobalSymtab.hpp */

View file

@ -87,7 +87,7 @@ namespace xo {
return xform_fn(this); return xform_fn(this);
} }
virtual void attach_envs(bp<Environment> p) override { virtual void attach_envs(bp<SymbolTable> p) override {
test_->attach_envs(p); test_->attach_envs(p);
when_true_->attach_envs(p); when_true_->attach_envs(p);
when_false_->attach_envs(p); when_false_->attach_envs(p);

View file

@ -8,7 +8,7 @@
#include "Expression.hpp" #include "Expression.hpp"
#include "FunctionInterface.hpp" #include "FunctionInterface.hpp"
#include "Variable.hpp" #include "Variable.hpp"
#include "LocalEnv.hpp" #include "LocalSymtab.hpp"
#include <map> #include <map>
#include <vector> #include <vector>
#include <string> #include <string>
@ -30,7 +30,7 @@ namespace xo {
**/ **/
static rp<Lambda> make(const std::string & name, static rp<Lambda> make(const std::string & name,
TypeDescr lambda_type, TypeDescr lambda_type,
const rp<LocalEnv> & local_env, const rp<LocalSymtab> & local_env,
const rp<Expression> & body); const rp<Expression> & body);
/** /**
@ -42,7 +42,7 @@ namespace xo {
static rp<Lambda> make(const std::string & name, static rp<Lambda> make(const std::string & name,
const std::vector<rp<Variable>> & argv, const std::vector<rp<Variable>> & argv,
const rp<Expression> & body, const rp<Expression> & body,
const rp<Environment> & parent_env); const rp<SymbolTable> & parent_env);
/** /**
* @p name Name for this lambda -- must be unique * @p name Name for this lambda -- must be unique
@ -50,7 +50,7 @@ namespace xo {
* @p body Expression for body of function * @p body Expression for body of function
**/ **/
static rp<Lambda> make_from_env(const std::string & name, static rp<Lambda> make_from_env(const std::string & name,
const rp<LocalEnv> & env, const rp<LocalSymtab> & env,
TypeDescr explicit_return_td, TypeDescr explicit_return_td,
const rp<Expression> & body); const rp<Expression> & body);
@ -122,7 +122,7 @@ namespace xo {
return this; return this;
} }
virtual void attach_envs(bp<Environment> p) override; virtual void attach_envs(bp<SymbolTable> p) override;
virtual void display(std::ostream & os) const override; virtual void display(std::ostream & os) const override;
virtual std::uint32_t pretty_print(const ppindentinfo & ppii) const override; virtual std::uint32_t pretty_print(const ppindentinfo & ppii) const override;
@ -138,7 +138,7 @@ namespace xo {
**/ **/
Lambda(const std::string & name, Lambda(const std::string & name,
TypeDescr lambda_type, TypeDescr lambda_type,
const rp<LocalEnv> & local_env, const rp<LocalSymtab> & local_env,
const rp<Expression> & body); const rp<Expression> & body);
/** compute free-variable set for this lambda **/ /** compute free-variable set for this lambda **/
@ -201,14 +201,14 @@ namespace xo {
* when Lambda constructor runs, so we need to assign @ref local_env_ * when Lambda constructor runs, so we need to assign @ref local_env_
* later. * later.
**/ **/
rp<LocalEnv> local_env_; rp<LocalSymtab> local_env_;
}; /*Lambda*/ }; /*Lambda*/
inline rp<Lambda> inline rp<Lambda>
make_lambda(const std::string & name, make_lambda(const std::string & name,
const std::vector<rp<Variable>> & argv, const std::vector<rp<Variable>> & argv,
const rp<Expression> & body, const rp<Expression> & body,
const rp<Environment> & parent_env) const rp<SymbolTable> & parent_env)
{ {
return Lambda::make(name, argv, body, parent_env); return Lambda::make(name, argv, body, parent_env);
} }
@ -218,7 +218,7 @@ namespace xo {
static rp<LambdaAccess> make(const std::string & name, static rp<LambdaAccess> make(const std::string & name,
const std::vector<rp<Variable>> & argv, const std::vector<rp<Variable>> & argv,
const rp<Expression> & body, const rp<Expression> & body,
const rp<Environment> & parent_env); const rp<SymbolTable> & parent_env);
static rp<LambdaAccess> make_empty(); static rp<LambdaAccess> make_empty();
/** assign body + compute derived members /** assign body + compute derived members
@ -232,7 +232,7 @@ namespace xo {
**/ **/
LambdaAccess(const std::string & name, LambdaAccess(const std::string & name,
TypeDescr lambda_type, TypeDescr lambda_type,
const rp<LocalEnv> & local_env, const rp<LocalSymtab> & local_env,
const rp<Expression> & body); const rp<Expression> & body);

View file

@ -1,11 +1,11 @@
/* file LocalEnv.hpp /* file LocalSymtab.hpp
* *
* author: Roland Conybeare, Jun 2024 * author: Roland Conybeare, Jun 2024
*/ */
#pragma once #pragma once
#include "Environment.hpp" #include "SymbolTable.hpp"
#include "Variable.hpp" #include "Variable.hpp"
#include "xo/reflect/TypeDescr.hpp" #include "xo/reflect/TypeDescr.hpp"
@ -20,20 +20,20 @@ namespace xo {
* parameters, but also links to @ref Environment for * parameters, but also links to @ref Environment for
* innermost enclosing @ref Lambda. * innermost enclosing @ref Lambda.
**/ **/
class LocalEnv : public Environment { class LocalSymtab : public SymbolTable {
public: public:
using TypeDescr = xo::reflect::TypeDescr; using TypeDescr = xo::reflect::TypeDescr;
public: public:
static rp<LocalEnv> make_empty(); static rp<LocalSymtab> make_empty();
/** named ctor idiom. Create instance with local variables per @p argv **/ /** named ctor idiom. Create instance with local variables per @p argv **/
static rp<LocalEnv> make(const std::vector<rp<Variable>> & argv, static rp<LocalSymtab> make(const std::vector<rp<Variable>> & argv,
const rp<Environment> & parent_env); const rp<SymbolTable> & parent_env);
/** Create instance with single local variable @ap argv1 **/ /** Create instance with single local variable @ap argv1 **/
static rp<LocalEnv> make1(const rp<Variable> & arg1, static rp<LocalSymtab> make1(const rp<Variable> & arg1,
const rp<Environment> & parent_env); const rp<SymbolTable> & parent_env);
/** runtime downcast. nullptr if @p x is not a LocalEnv instance **/ /** runtime downcast. nullptr if @p x is not a LocalEnv instance **/
static bp<LocalEnv> from(const bp<Environment> & x) { return bp<LocalEnv>::from(x); } static bp<LocalSymtab> from(const bp<SymbolTable> & x) { return bp<LocalSymtab>::from(x); }
Lambda * origin() const { return origin_; } Lambda * origin() const { return origin_; }
const std::vector<rp<Variable>> & argv() const { return argv_; } const std::vector<rp<Variable>> & argv() const { return argv_; }
@ -53,7 +53,7 @@ namespace xo {
} }
/** single-assign this environment's parent **/ /** single-assign this environment's parent **/
void assign_parent(bp<Environment> p); void assign_parent(bp<SymbolTable> p);
// ----- Environment ----- // ----- Environment -----
@ -91,7 +91,7 @@ namespace xo {
virtual std::uint32_t pretty_print(const print::ppindentinfo & ppii) const override; virtual std::uint32_t pretty_print(const print::ppindentinfo & ppii) const override;
private: private:
LocalEnv(const std::vector<rp<Variable>> & argv, const rp<Environment> & parent_env); LocalSymtab(const std::vector<rp<Variable>> & argv, const rp<SymbolTable> & parent_env);
private: private:
/** Lambda for which this environment created. /** Lambda for which this environment created.
@ -103,17 +103,21 @@ namespace xo {
**/ **/
Lambda * origin_ = nullptr; Lambda * origin_ = nullptr;
/** formal argument names **/ /** formal argument names.
* all variables in @ref argv_ have distinct names.
* if @c .lookup_binding(vname) returns a binding path with @c .i_link=0 and @c .j_slot=j
* then @c argv_[j]->name_ is @c vname.
**/
std::vector<rp<Variable>> argv_; std::vector<rp<Variable>> argv_;
/** parent environment. A free variable in this lambda's /** parent environment. A free variable in this lambda's
* body will be resolved by referring them to @ref parent_env_. * body will be resolved by referring them to @ref parent_env_.
**/ **/
rp<Environment> parent_env_; rp<SymbolTable> parent_env_;
}; };
} /*namespace scm*/ } /*namespace scm*/
} /*namespace xo*/ } /*namespace xo*/
/* end LocalEnv.hpp */ /* end LocalSymtab.hpp */

View file

@ -66,7 +66,7 @@ namespace xo {
return xform_fn(this); return xform_fn(this);
} }
virtual void attach_envs(bp<Environment> /*p*/) override {} virtual void attach_envs(bp<SymbolTable> /*p*/) override {}
private: private:
}; /*PrimitiveInterface*/ }; /*PrimitiveInterface*/

View file

@ -32,7 +32,7 @@ namespace xo {
/** note: borken if .expr_v_ contains any def-exprs **/ /** note: borken if .expr_v_ contains any def-exprs **/
virtual std::size_t visit_layer(VisitFn visitor_fn) override; virtual std::size_t visit_layer(VisitFn visitor_fn) override;
virtual rp<Expression> xform_layer(TransformFn visitor_fn) override; virtual rp<Expression> xform_layer(TransformFn visitor_fn) override;
virtual void attach_envs(bp<Environment> parent) override; virtual void attach_envs(bp<SymbolTable> parent) override;
// ----- from GeneralizedExpression ---- // ----- from GeneralizedExpression ----

View file

@ -1,4 +1,4 @@
/* file Environment.hpp /* file SymbolTable.hpp
* *
* author: Roland Conybeare, Jun 2024 * author: Roland Conybeare, Jun 2024
*/ */
@ -22,7 +22,7 @@ namespace xo {
* When generating code (see xo-jit): rhs can be any expression, * When generating code (see xo-jit): rhs can be any expression,
* for example a Lambda. * for example a Lambda.
**/ **/
class Environment : public ref::Refcount { class SymbolTable : public ref::Refcount {
public: public:
/** true if this is toplevel (global) environment. /** true if this is toplevel (global) environment.
* Toplevel environment doesn't have slot numbers. * Toplevel environment doesn't have slot numbers.
@ -57,7 +57,7 @@ namespace xo {
}; };
inline std::ostream & inline std::ostream &
operator<< (std::ostream & os, const Environment & x) { operator<< (std::ostream & os, const SymbolTable & x) {
x.print(os); x.print(os);
return os; return os;
} }
@ -65,4 +65,4 @@ namespace xo {
} /*namespace xo*/ } /*namespace xo*/
/* end Environment.hpp */ /* end SymbolTable.hpp */

View file

@ -64,7 +64,7 @@ namespace xo {
return xform_fn(this); return xform_fn(this);
} }
virtual void attach_envs(bp<Environment> /*p*/) override; virtual void attach_envs(bp<SymbolTable> /*p*/) override;
virtual void display(std::ostream & os) const override; virtual void display(std::ostream & os) const override;
virtual std::uint32_t pretty_print(const ppindentinfo & ppii) const override; virtual std::uint32_t pretty_print(const ppindentinfo & ppii) const override;

View file

@ -4,32 +4,32 @@
#include "xo/indentlog/print/pretty.hpp" #include "xo/indentlog/print/pretty.hpp"
#include "xo/refcnt/pretty_refcnt.hpp" #include "xo/refcnt/pretty_refcnt.hpp"
#include "LocalEnv.hpp" #include "LocalSymtab.hpp"
namespace xo { namespace xo {
namespace print { namespace print {
template <> template <>
struct ppdetail<xo::scm::Environment> { struct ppdetail<xo::scm::SymbolTable> {
static bool print_pretty(const ppindentinfo & ppii, const xo::scm::Environment & x) { static bool print_pretty(const ppindentinfo & ppii, const xo::scm::SymbolTable & x) {
return x.pretty_print(ppii); return x.pretty_print(ppii);
} }
}; };
template <> template <>
struct ppdetail<xo::scm::LocalEnv> { struct ppdetail<xo::scm::LocalSymtab> {
static bool print_pretty(const ppindentinfo & ppii, const xo::scm::LocalEnv & x) { static bool print_pretty(const ppindentinfo & ppii, const xo::scm::LocalSymtab & x) {
return x.pretty_print(ppii); return x.pretty_print(ppii);
} }
}; };
template <> template <>
struct ppdetail<xo::scm::LocalEnv*> { struct ppdetail<xo::scm::LocalSymtab*> {
static bool print_pretty(const ppindentinfo & ppii, const xo::scm::LocalEnv* x) { static bool print_pretty(const ppindentinfo & ppii, const xo::scm::LocalSymtab* x) {
if (x) { if (x) {
return x->pretty_print(ppii); return x->pretty_print(ppii);
} else { } else {
ppii.pps()->write("<nullptr "); ppii.pps()->write("<nullptr ");
ppii.pps()->write(reflect::type_name<xo::scm::LocalEnv>()); ppii.pps()->write(reflect::type_name<xo::scm::LocalSymtab>());
ppii.pps()->write(">"); ppii.pps()->write(">");
return ppii.pps()->has_margin(); return ppii.pps()->has_margin();
} }

View file

@ -149,7 +149,7 @@ namespace xo {
} }
void void
Apply::attach_envs(bp<Environment> p) { Apply::attach_envs(bp<SymbolTable> p) {
fn_->attach_envs(p); fn_->attach_envs(p);
for (const auto & arg : argv_) for (const auto & arg : argv_)

View file

@ -77,7 +77,7 @@ namespace xo {
} }
void void
AssignExpr::attach_envs(bp<Environment> p) { AssignExpr::attach_envs(bp<SymbolTable> p) {
lhs_->attach_envs(p); lhs_->attach_envs(p);
rhs_->attach_envs(p); rhs_->attach_envs(p);
} }

View file

@ -11,8 +11,8 @@ set(SELF_SRCS
Variable.cpp Variable.cpp
IfExpr.cpp IfExpr.cpp
Sequence.cpp Sequence.cpp
GlobalEnv.cpp GlobalSymtab.cpp
LocalEnv.cpp LocalSymtab.cpp
ConvertExpr.cpp ConvertExpr.cpp
Primitive.cpp Primitive.cpp
typeinf/type_ref.cpp typeinf/type_ref.cpp

View file

@ -4,15 +4,15 @@
*/ */
#include "xo/indentlog/print/ppdetail_atomic.hpp" #include "xo/indentlog/print/ppdetail_atomic.hpp"
#include "GlobalEnv.hpp" #include "GlobalSymtab.hpp"
#include "Expression.hpp" #include "Expression.hpp"
namespace xo { namespace xo {
namespace scm { namespace scm {
GlobalEnv::GlobalEnv() = default; GlobalSymtab::GlobalSymtab() = default;
bp<Expression> bp<Expression>
GlobalEnv::require_global(const std::string & vname, GlobalSymtab::require_global(const std::string & vname,
bp<Expression> expr) bp<Expression> expr)
{ {
this->global_map_[vname] = expr.get(); this->global_map_[vname] = expr.get();
@ -21,21 +21,21 @@ namespace xo {
} /*require_global*/ } /*require_global*/
void void
GlobalEnv::upsert_local(bp<Variable> target) { GlobalSymtab::upsert_local(bp<Variable> target) {
// in practice: paraphrase of .require_global() // in practice: paraphrase of .require_global()
this->global_map_[target->name()] = target.promote(); this->global_map_[target->name()] = target.promote();
} }
void void
GlobalEnv::print(std::ostream & os) const { GlobalSymtab::print(std::ostream & os) const {
os << "<GlobalEnv" os << "<GlobalEnv"
<< xtag("size", global_map_.size()) << xtag("size", global_map_.size())
<< ">"; << ">";
} }
std::uint32_t std::uint32_t
GlobalEnv::pretty_print(const xo::print::ppindentinfo & ppii) const GlobalSymtab::pretty_print(const xo::print::ppindentinfo & ppii) const
{ {
using xo::print::ppstate; using xo::print::ppstate;

View file

@ -87,7 +87,7 @@ namespace xo {
rp<Lambda> rp<Lambda>
Lambda::make(const std::string & name, Lambda::make(const std::string & name,
TypeDescr lambda_td, TypeDescr lambda_td,
const rp<LocalEnv> & env, const rp<LocalSymtab> & env,
const rp<Expression> & body) const rp<Expression> & body)
{ {
return new Lambda(name, lambda_td, env, body); return new Lambda(name, lambda_td, env, body);
@ -95,7 +95,7 @@ namespace xo {
rp<Lambda> rp<Lambda>
Lambda::make_from_env(const std::string & name, Lambda::make_from_env(const std::string & name,
const rp<LocalEnv> & env, const rp<LocalSymtab> & env,
TypeDescr explicit_return_td, TypeDescr explicit_return_td,
const rp<Expression> & body) const rp<Expression> & body)
{ {
@ -117,9 +117,9 @@ namespace xo {
Lambda::make(const std::string & name, Lambda::make(const std::string & name,
const std::vector<rp<Variable>> & argv, const std::vector<rp<Variable>> & argv,
const rp<Expression> & body, const rp<Expression> & body,
const rp<Environment> & parent_env) const rp<SymbolTable> & parent_env)
{ {
rp<LocalEnv> env = LocalEnv::make(argv, parent_env); rp<LocalSymtab> env = LocalSymtab::make(argv, parent_env);
TypeDescr explicit_return_td = nullptr; TypeDescr explicit_return_td = nullptr;
@ -257,7 +257,7 @@ namespace xo {
Lambda::Lambda(const std::string & name, Lambda::Lambda(const std::string & name,
TypeDescr lambda_td, TypeDescr lambda_td,
const rp<LocalEnv> & local_env, const rp<LocalSymtab> & local_env,
const rp<Expression> & body) const rp<Expression> & body)
: FunctionInterface(exprtype::lambda, lambda_td), : FunctionInterface(exprtype::lambda, lambda_td),
name_{name}, name_{name},
@ -334,7 +334,7 @@ namespace xo {
} /*ctor*/ } /*ctor*/
void void
Lambda::attach_envs(bp<Environment> p) { Lambda::attach_envs(bp<SymbolTable> p) {
local_env_->assign_parent(p); local_env_->assign_parent(p);
/** establish a binding path for each variable **/ /** establish a binding path for each variable **/
@ -364,11 +364,11 @@ namespace xo {
LambdaAccess::make(const std::string & name, LambdaAccess::make(const std::string & name,
const std::vector<rp<Variable>> & argv, const std::vector<rp<Variable>> & argv,
const rp<Expression> & body, const rp<Expression> & body,
const rp<Environment> & parent_env) const rp<SymbolTable> & parent_env)
{ {
TypeDescr explicit_return_td = nullptr; TypeDescr explicit_return_td = nullptr;
TypeDescr lambda_td = assemble_lambda_td(argv, explicit_return_td, body); TypeDescr lambda_td = assemble_lambda_td(argv, explicit_return_td, body);
rp<LocalEnv> env = LocalEnv::make(argv, parent_env); rp<LocalSymtab> env = LocalSymtab::make(argv, parent_env);
rp<LambdaAccess> retval rp<LambdaAccess> retval
= new LambdaAccess(name, = new LambdaAccess(name,
@ -393,7 +393,7 @@ namespace xo {
LambdaAccess::LambdaAccess(const std::string & name, LambdaAccess::LambdaAccess(const std::string & name,
TypeDescr lambda_td, TypeDescr lambda_td,
const rp<LocalEnv> & local_env, const rp<LocalSymtab> & local_env,
const rp<Expression> & body) const rp<Expression> & body)
: Lambda(name, lambda_td, local_env, body) : Lambda(name, lambda_td, local_env, body)
{} {}

View file

@ -1,9 +1,9 @@
/* file LocalEnv.cpp /* file LocalSymtab.cpp
* *
* author: Roland Conybeare * author: Roland Conybeare
*/ */
#include "LocalEnv.hpp" #include "LocalSymtab.hpp"
#include "pretty_variable.hpp" #include "pretty_variable.hpp"
#include "xo/indentlog/print/pretty_vector.hpp" #include "xo/indentlog/print/pretty_vector.hpp"
#include "xo/indentlog/print/vector.hpp" #include "xo/indentlog/print/vector.hpp"
@ -11,29 +11,29 @@
namespace xo { namespace xo {
namespace scm { namespace scm {
rp<LocalEnv> rp<LocalSymtab>
LocalEnv::make_empty() { LocalSymtab::make_empty() {
return new LocalEnv(std::vector<rp<Variable>>(), nullptr); return new LocalSymtab(std::vector<rp<Variable>>(), nullptr);
} }
rp<LocalEnv> rp<LocalSymtab>
LocalEnv::make(const std::vector<rp<Variable>> & argv, LocalSymtab::make(const std::vector<rp<Variable>> & argv,
const rp<Environment> & parent_env) const rp<SymbolTable> & parent_env)
{ {
return new LocalEnv(argv, parent_env); return new LocalSymtab(argv, parent_env);
} }
rp<LocalEnv> rp<LocalSymtab>
LocalEnv::make1(const rp<Variable> & arg1, LocalSymtab::make1(const rp<Variable> & arg1,
const rp<Environment> & parent_env) const rp<SymbolTable> & parent_env)
{ {
std::vector<rp<Variable>> argv = { arg1 }; std::vector<rp<Variable>> argv = { arg1 };
return make(argv, parent_env); return make(argv, parent_env);
} }
LocalEnv::LocalEnv(const std::vector<rp<Variable>> & argv, LocalSymtab::LocalSymtab(const std::vector<rp<Variable>> & argv,
const rp<Environment> & parent_env) const rp<SymbolTable> & parent_env)
: origin_{nullptr}, : origin_{nullptr},
argv_(argv), argv_(argv),
parent_env_{parent_env} parent_env_{parent_env}
@ -43,7 +43,7 @@ namespace xo {
} }
binding_path binding_path
LocalEnv::lookup_local_binding(const std::string & vname) const { LocalSymtab::lookup_local_binding(const std::string & vname) const {
int j_slot = 0; int j_slot = 0;
for (const auto & arg : argv_) { for (const auto & arg : argv_) {
if (arg->name() == vname) if (arg->name() == vname)
@ -55,7 +55,7 @@ namespace xo {
} /*lookup_local_binding*/ } /*lookup_local_binding*/
binding_path binding_path
LocalEnv::lookup_binding(const std::string & vname) const { LocalSymtab::lookup_binding(const std::string & vname) const {
{ {
auto local = this->lookup_local_binding(vname); auto local = this->lookup_local_binding(vname);
if (local.i_link_ == 0) if (local.i_link_ == 0)
@ -71,9 +71,9 @@ namespace xo {
} /*lookup_binding*/ } /*lookup_binding*/
void void
LocalEnv::assign_parent(bp<Environment> p) { LocalSymtab::assign_parent(bp<SymbolTable> p) {
if ((parent_env_.get() != nullptr) && (parent_env_.get() != p.get())) { if ((parent_env_.get() != nullptr) && (parent_env_.get() != p.get())) {
throw std::runtime_error(tostr("LocalEnv::assign_parent(P2): already have established parent P1", throw std::runtime_error(tostr("LocalSymtab::assign_parent(P2): already have established parent P1",
xtag("P1", parent_env_), xtag("P1", parent_env_),
xtag("P2", p))); xtag("P2", p)));
@ -84,7 +84,7 @@ namespace xo {
} }
void void
LocalEnv::upsert_local(bp<Variable> target) { LocalSymtab::upsert_local(bp<Variable> target) {
for (auto & var : this->argv_) { for (auto & var : this->argv_) {
if (var->name() == target->name()) { if (var->name() == target->name()) {
/* replace existing variable. This may change its type */ /* replace existing variable. This may change its type */
@ -99,20 +99,20 @@ namespace xo {
} }
void void
LocalEnv::print(std::ostream& os) const { LocalSymtab::print(std::ostream& os) const {
os << "<LocalEnv" os << "<LocalSymtab"
<< xtag("argv", argv_) << xtag("argv", argv_)
<< ">"; << ">";
} }
std::uint32_t std::uint32_t
LocalEnv::pretty_print(const xo::print::ppindentinfo & ppii) const { LocalSymtab::pretty_print(const xo::print::ppindentinfo & ppii) const {
using xo::print::ppstate; using xo::print::ppstate;
ppstate * pps = ppii.pps(); ppstate * pps = ppii.pps();
if (ppii.upto()) { if (ppii.upto()) {
if (!pps->print_upto("<LocalEnv")) if (!pps->print_upto("<LocalSymtab"))
return false; return false;
if (!pps->print_upto_tag("argv", argv_)) if (!pps->print_upto_tag("argv", argv_))
return false; return false;
@ -120,7 +120,7 @@ namespace xo {
return true; return true;
} else { } else {
pps->write("<LocalEnv"); pps->write("<LocalSymtab");
pps->newline_pretty_tag(ppii.ci1(), "this", (void*)this); pps->newline_pretty_tag(ppii.ci1(), "this", (void*)this);
pps->newline_pretty_tag(ppii.ci1(), "argv", argv_); pps->newline_pretty_tag(ppii.ci1(), "argv", argv_);
pps->write(">"); pps->write(">");
@ -132,5 +132,4 @@ namespace xo {
} /*namespace scm*/ } /*namespace scm*/
} /*namespace xo*/ } /*namespace xo*/
/* end LocalSymtab.cpp */
/* end LocalEnv.cpp */

View file

@ -55,7 +55,7 @@ namespace xo {
} }
void void
Sequence::attach_envs(bp<Environment> p) { Sequence::attach_envs(bp<SymbolTable> p) {
for (const auto & x : expr_v_) for (const auto & x : expr_v_)
x->attach_envs(p); x->attach_envs(p);
} }

View file

@ -1,7 +1,7 @@
/* @file Variable.cpp */ /* @file Variable.cpp */
#include "Variable.hpp" #include "Variable.hpp"
#include "Environment.hpp" #include "SymbolTable.hpp"
#include "pretty_expression.hpp" #include "pretty_expression.hpp"
namespace xo { namespace xo {
@ -19,7 +19,7 @@ namespace xo {
} }
void void
Variable::attach_envs(bp<Environment> e) { Variable::attach_envs(bp<SymbolTable> e) {
/** e makes accessible all enclosing lexical scopes **/ /** e makes accessible all enclosing lexical scopes **/
if (this->path_.i_link_ == -2 /*sentinel*/) { if (this->path_.i_link_ == -2 /*sentinel*/) {
this->path_ = e->lookup_binding(this->name_); this->path_ = e->lookup_binding(this->name_);

View file

@ -1,102 +0,0 @@
/** @file StackFrame.hpp **/
#include "xo/alloc/IAlloc.hpp"
#include "Env.hpp"
#include <cstddef>
#include <cstdint>
namespace xo {
namespace scm {
/** gc-only vector
**/
template <typename ElementType>
class CVector {
public:
using value_type = ElementType;
public:
CVector(gc::IAlloc * mm, std::size_t n)
: n_{n}, v_{nullptr}
{
if (n_ > 0) {
std::byte * mem = mm->alloc(n_ * sizeof(ElementType));
this->v_ = new (mem) ElementType[n];
}
}
std::size_t size() const { return n_; }
ElementType operator[](std::size_t i) const { return v_[i]; }
ElementType & operator[](std::size_t i) { return v_[i]; }
friend class StackFrame;
private:
/** number of elements in @ref v_ **/
std::size_t n_ = 0;
/** contiguous array of pointers **/
ElementType * v_ = nullptr;
};
/** @class StackFrame
* @brief Represent a single runtime stack frame for a Schematika function
*
* StackFrame intended to be used for interpreted functions.
* Compiled functions will still likely have stack frames, but need not use the
* @ref StackFrame class
*
* memory layout:
* ^
* +-----------------------+ |
* | vtable | |
* +-----------------------+ |
* | .parent +------/
* +------------+----------+
* | .slot_v_ | .n_ |
* | +----------+
* | | .v_ +------\
* +------------+----------+ <--/
* | .v_[0] +---------> Object(1)
* +-----------------------+
* . .. .
* +-----------------------+
* | .v_[.n_-1] +---------> Object(n)
* +-----------------------+
**/
class StackFrame : public Object {
public:
using TaggedPtr = xo::reflect::TaggedPtr;
public:
StackFrame(gc::IAlloc * mm, gp<StackFrame> p, std::size_t n) : parent_{p}, slot_v_{mm, n} {}
/** create frame using allocator @p mm,
* with parent @p p and exactly @p n_slot object pointers
**/
static gp<StackFrame> make(gc::IAlloc * mm, gp<StackFrame> p, std::size_t n_slot);
/** reflect StackFrame object representation **/
static void reflect_self();
gp<StackFrame> parent() const { return parent_; }
std::size_t size() const { return slot_v_.size(); }
gp<Object> operator[](std::size_t i) const { return slot_v_[i]; }
gp<Object> & operator[](std::size_t i) { return slot_v_[i]; }
// inherited from Object..
virtual TaggedPtr self_tp() const final override;
virtual void display(std::ostream & os) const final override;
virtual std::size_t _shallow_size() const final override;
virtual Object * _shallow_copy() const final override;
virtual std::size_t _forward_children() final override;
private:
/** parent stack frame **/
gp<StackFrame> parent_;
/** stack frame contents **/
CVector<gp<Object>> slot_v_;
};
} /*namespace scm*/
} /*namespace xo*/
/* end StackFrame.hpp */

View file

@ -1,131 +0,0 @@
/** @file StackFrame.cpp **/
#include "StackFrame.hpp"
#include "xo/reflect/Reflect.hpp"
#include "xo/reflect/StructReflector.hpp"
#include <cstring>
namespace xo {
using xo::reflect::Reflect;
using xo::reflect::StructReflector;
using xo::reflect::TypeDescrW;
using xo::reflect::TaggedPtr;
using xo::reflect::TypeDescrExtra;
using xo::reflect::EstablishTypeDescr;
using xo::reflect::StlVectorTdx;
using xo::print::quot;
namespace scm {
namespace {
std::size_t
slot_array_size(std::size_t n) {
return n * sizeof(gp<Object>);
}
}
gp<StackFrame>
StackFrame::make(gc::IAlloc * mm, gp<StackFrame> p, std::size_t n)
{
return new (MMPtr(mm)) StackFrame(mm, p, n);
}
TaggedPtr
StackFrame::self_tp() const
{
return Reflect::make_tp(const_cast<StackFrame *>(this));
}
void
StackFrame::display(std::ostream & os) const
{
os << "<stack-frame"
<< xtag("n", slot_v_.size());
#ifdef NOT_YET
for (std::size_t i = 0, n = n_slot(); i < n; ++i) {
char buf[24];
snprintf(buf, sizeof(buf), "v[%lu]", i);
os << xtag(buf, lookup(i));
}
#endif
os << ">";
}
std::size_t
StackFrame::_shallow_size() const
{
std::size_t retval = sizeof(StackFrame);
retval += gc::IAlloc::with_padding(slot_array_size(slot_v_.size()));
return retval;
}
Object *
StackFrame::_shallow_copy() const
{
Cpof cpof(Object::mm, this);
size_t z = size();
StackFrame * copy = new (cpof) StackFrame(cpof.mm_, parent_, z);
void * v_dest = copy->slot_v_.v_;
if (slot_v_.v_) {
::memcpy(v_dest, slot_v_.v_, slot_array_size(z));
}
#ifdef OBSOLETE
for (size_t i = 0, n = n_slot_; i < n; ++i) {
copy->v_[i] = v_[i];
}
#endif
return copy;
}
std::size_t
StackFrame::_forward_children()
{
Object::_forward_inplace(parent_);
for (std::size_t i = 0, n = slot_v_.size(); i < n; ++i) {
Object::_forward_inplace((*this)[i]);
}
return _shallow_size();
}
void
StackFrame::reflect_self()
{
StructReflector<StackFrame> sr;
if (sr.is_incomplete()) {
/* reflect CVector<gp<Object>>
*
* note: placement here works b/c CVector<T> not used anywhere else
*/
using VectorType = CVector<gp<Object>>;
/* custom reflection for array of Object pointers.
* Can use StlVectorTdx here, treating CVector<T> as a vector
* via .size() and .operator[] members
*/
std::unique_ptr<TypeDescrExtra> tdx1
= std::make_unique<StlVectorTdx<VectorType>>();
TypeDescrW td1
= EstablishTypeDescr::establish<VectorType>();
td1->assign_tdextra(Reflect::get_final_invoker<VectorType>(),
std::move(tdx1));
REFLECT_MEMBER(sr, parent);
REFLECT_MEMBER(sr, slot_v);
}
}
} /*namespace scm*/
} /*namespace xo*/
/* end StackFrame.cpp */

View file

@ -4,16 +4,16 @@
*/ */
#include "init_interpreter.hpp" #include "init_interpreter.hpp"
#include "StackFrame.hpp" #include "LocalEnv.hpp"
#include "xo/subsys/Subsystem.hpp" #include "xo/subsys/Subsystem.hpp"
namespace xo { namespace xo {
using xo::scm::StackFrame; using xo::scm::LocalEnv;
void void
InitSubsys<S_interpreter_tag>::init() InitSubsys<S_interpreter_tag>::init()
{ {
StackFrame::reflect_self(); LocalEnv::reflect_self();
} }
InitEvidence InitEvidence

View file

@ -3,7 +3,7 @@
set(UTEST_EXE utest.interpreter) set(UTEST_EXE utest.interpreter)
set(UTEST_SRCS set(UTEST_SRCS
interpreter_utest_main.cpp interpreter_utest_main.cpp
StackFrame.test.cpp LocalEnv.test.cpp
) )
xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS}) xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS})

View file

@ -1,134 +0,0 @@
/** @file StackFrame.test.cpp **/
#include "xo/interpreter/init_interpreter.hpp"
#include "xo/interpreter/StackFrame.hpp"
#include "xo/object/Integer.hpp"
#include "xo/alloc/GC.hpp"
#include <catch2/catch.hpp>
#include <vector>
#include <cstdint>
namespace xo {
using xo::scm::StackFrame;
using xo::obj::Integer;
using xo::gc::GC;
using xo::gc::ArenaAlloc;
using xo::gc::generation;
using xo::gc::generation_result;
using xo::reflect::TaggedPtr;
namespace ut {
static InitEvidence s_init = (InitSubsys<S_interpreter_tag>::require());
namespace {
struct Testcase_StackFrame {
Testcase_StackFrame(const std::vector<std::int32_t> & contents) : contents_{contents} {}
/* build xo::obj::Integer for each contents_[i], store in F[i] for new StackFrame F */
std::vector<std::int32_t> contents_;
};
std::vector<Testcase_StackFrame>
s_testcase_v = {
Testcase_StackFrame({}),
Testcase_StackFrame({}),
Testcase_StackFrame({111}),
Testcase_StackFrame({111, 222}),
};
}
TEST_CASE("StackFrame", "[StackFrame][interpreter]")
{
Subsystem::initialize_all();
constexpr bool c_debug_flag = false;
for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
scope log(XO_DEBUG(c_debug_flag), xtag("test", "StackFrame2"), xtag("i_tc", i_tc));
const Testcase_StackFrame & tc = s_testcase_v[i_tc];
up<ArenaAlloc> alloc = ArenaAlloc::make("utest", 16384, c_debug_flag);
REQUIRE(alloc.get());
Object::mm = alloc.get();
std::size_t n = tc.contents_.size();
gp<StackFrame> frame = StackFrame::make(alloc.get(), nullptr /*parent*/, n);
TaggedPtr tp = frame->self_tp();
REQUIRE(tp.is_struct());
}
}
TEST_CASE("StackFrame2", "[StackFrame][gc][interpreter]")
{
Subsystem::initialize_all();
constexpr bool c_debug_flag = false;
try {
for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
scope log(XO_DEBUG(c_debug_flag), xtag("test", "StackFrame2"), xtag("i_tc", i_tc));
const Testcase_StackFrame & tc = s_testcase_v[i_tc];
up<GC> gc = GC::make(
{.initial_nursery_z_ = 16384,
.initial_tenured_z_ = 32768,
.incr_gc_threshold_ = 4096,
.full_gc_threshold_ = 4096,
.object_stats_flag_ = true,
.debug_flag_ = c_debug_flag,
});
REQUIRE(gc.get());
/* use gc for all Object allocs */
GC * mm = gc.get();
Object::mm = mm;
std::size_t n = tc.contents_.size();
gp<Integer> x = Integer::make(gc.get(), 42);
gc->add_gc_root(reinterpret_cast<Object **>(&x));
REQUIRE(gc->tospace_generation_of(x.ptr()) == generation_result::nursery);
gp<StackFrame> frame = StackFrame::make(gc.get(), nullptr /*parent*/, n);
StackFrame ** frame_pp = frame.ptr_address();
gc->add_gc_root(reinterpret_cast<Object **>(frame_pp));
/* verifying allocated in N1 */
REQUIRE(gc->tospace_generation_of(frame.ptr()) == generation_result::nursery);
for (std::size_t i = 0; i < n; ++i)
(*frame)[i] = Integer::make(mm, tc.contents_.at(i));
std::size_t expected_alloc_z = frame->_shallow_size();
REQUIRE(expected_alloc_z >= sizeof(StackFrame) + n * sizeof(gp<Object>));
gc->request_gc(generation::nursery); // <<<<<<<<< GC here <<<<<<<<<
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1);
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 0);
/* verify Integer x preserved across gc */
REQUIRE(gc->tospace_generation_of(x.ptr()) == generation_result::nursery);
/* verify StackFrame preserved across gc */
REQUIRE(gc->tospace_generation_of(frame.ptr()) == generation_result::nursery);
REQUIRE(frame->size() == n);
for (std::size_t i = 0; i < n; ++i) {
//REQUIRE(Integer::from(frame->lookup(i)).ptr());
//REQUIRE(Integer::from(frame->lookup(i))->value() == tc.contents_.at(i));
}
}
} catch (std::exception & ex) {
std::cerr << "exception: " << ex.what() << std::endl;
REQUIRE(false);
}
}
}
}
/* end StackFrame.test.cpp */

View file

@ -20,7 +20,7 @@
#include "xo/expression/Lambda.hpp" #include "xo/expression/Lambda.hpp"
#include "xo/expression/Variable.hpp" #include "xo/expression/Variable.hpp"
#include "xo/expression/IfExpr.hpp" #include "xo/expression/IfExpr.hpp"
#include "xo/expression/GlobalEnv.hpp" #include "xo/expression/GlobalSymtab.hpp"
/* stuff from kaleidoscope.cpp */ /* stuff from kaleidoscope.cpp */
#include "llvm/ADT/APFloat.h" #include "llvm/ADT/APFloat.h"
@ -58,7 +58,7 @@ namespace xo {
public: public:
using Expression = xo::scm::Expression; using Expression = xo::scm::Expression;
using Lambda = xo::scm::Lambda; using Lambda = xo::scm::Lambda;
using GlobalEnv = xo::scm::GlobalEnv; using GlobalEnv = xo::scm::GlobalSymtab;
using TypeDescr = xo::reflect::TypeDescr; using TypeDescr = xo::reflect::TypeDescr;
using ExecutionSession = llvm::orc::ExecutionSession; using ExecutionSession = llvm::orc::ExecutionSession;
using DataLayout = llvm::DataLayout; using DataLayout = llvm::DataLayout;

View file

@ -16,7 +16,7 @@ namespace xo {
using xo::scm::Variable; using xo::scm::Variable;
using xo::scm::Apply; using xo::scm::Apply;
using xo::scm::IfExpr; using xo::scm::IfExpr;
using xo::scm::GlobalEnv; using xo::scm::GlobalSymtab;
using xo::scm::llvmintrinsic; using xo::scm::llvmintrinsic;
using xo::reflect::Reflect; using xo::reflect::Reflect;
using xo::reflect::StructMember; using xo::reflect::StructMember;

View file

@ -8,7 +8,7 @@
xxx; xxx;
#include "xo/expression/Variable.hpp" #include "xo/expression/Variable.hpp"
#include "xo/expression/LocalEnv.hpp" #include "xo/expression/LocalSymtab.hpp"
#include <vector> #include <vector>
namespace xo { namespace xo {

View file

@ -5,7 +5,7 @@
#pragma once #pragma once
#include "xo/expression/LocalEnv.hpp" #include "xo/expression/LocalSymtab.hpp"
namespace xo { namespace xo {
namespace scm { namespace scm {
@ -34,16 +34,16 @@ namespace xo {
**/ **/
void upsert(bp<Variable> target); void upsert(bp<Variable> target);
bp<Environment> top_envframe() const; bp<SymbolTable> top_envframe() const;
void push_envframe(const rp<Environment> & x); void push_envframe(const rp<SymbolTable> & x);
rp<Environment> pop_envframe(); rp<SymbolTable> pop_envframe();
void reset_to_toplevel() { stack_.resize(1); } void reset_to_toplevel() { stack_.resize(1); }
/** relative to top-of-stack. /** relative to top-of-stack.
* 0 -> top (last in), z-1 -> bottom (first in) * 0 -> top (last in), z-1 -> bottom (first in)
**/ **/
bp<Environment> operator[](std::size_t i) { bp<SymbolTable> operator[](std::size_t i) {
std::size_t z = stack_.size(); std::size_t z = stack_.size();
assert(i < z); assert(i < z);
@ -51,7 +51,7 @@ namespace xo {
return stack_[z - i - 1].get(); return stack_[z - i - 1].get();
} }
bp<Environment> operator[](std::size_t i) const { bp<SymbolTable> operator[](std::size_t i) const {
std::size_t z = stack_.size(); std::size_t z = stack_.size();
assert(i < z); assert(i < z);
@ -63,7 +63,7 @@ namespace xo {
bool pretty_print(const ppindentinfo & ppii) const; bool pretty_print(const ppindentinfo & ppii) const;
private: private:
std::vector<rp<Environment>> stack_; std::vector<rp<SymbolTable>> stack_;
}; };
inline std::ostream & inline std::ostream &

View file

@ -6,7 +6,7 @@
#pragma once #pragma once
#include "exprstate.hpp" #include "exprstate.hpp"
#include "xo/expression/LocalEnv.hpp" #include "xo/expression/LocalSymtab.hpp"
//#include <cstdint> //#include <cstdint>
namespace xo { namespace xo {
@ -55,8 +55,8 @@ namespace xo {
**/ **/
class lambda_xs : public exprstate { class lambda_xs : public exprstate {
public: public:
using Environment = xo::scm::Environment; using Environment = xo::scm::SymbolTable;
using LocalEnv = xo::scm::LocalEnv; using LocalEnv = xo::scm::LocalSymtab;
public: public:
lambda_xs(); lambda_xs();

View file

@ -6,13 +6,13 @@
#pragma once #pragma once
#include "exprstate.hpp" #include "exprstate.hpp"
#include "xo/expression/LocalEnv.hpp" #include "xo/expression/LocalSymtab.hpp"
namespace xo { namespace xo {
namespace scm { namespace scm {
class let1_xs : public exprstate { class let1_xs : public exprstate {
public: public:
using LocalEnv = xo::scm::LocalEnv; using LocalEnv = xo::scm::LocalSymtab;
public: public:
/** given local definition equivalent to /** given local definition equivalent to

View file

@ -24,7 +24,7 @@ namespace xo {
public: public:
using Expression = xo::scm::Expression; using Expression = xo::scm::Expression;
using Variable = xo::scm::Variable; using Variable = xo::scm::Variable;
using LocalEnv = xo::scm::LocalEnv; using LocalEnv = xo::scm::LocalSymtab;
using token_type = token<char>; using token_type = token<char>;
public: public:
@ -59,13 +59,13 @@ namespace xo {
void upsert_var(bp<Variable> x); void upsert_var(bp<Variable> x);
/** @return available variable bindings in current parsing state **/ /** @return available variable bindings in current parsing state **/
bp<Environment> top_envframe() const; bp<SymbolTable> top_envframe() const;
/** @return frame @p i levels from the top **/ /** @return frame @p i levels from the top **/
bp<Environment> lookup_envframe(std::size_t i) const; bp<SymbolTable> lookup_envframe(std::size_t i) const;
/** push frame @p x (with new variable bindings) onto environment stack **/ /** push frame @p x (with new variable bindings) onto environment stack **/
void push_envframe(const rp<LocalEnv> & x); void push_envframe(const rp<LocalEnv> & x);
/** @return pop innermost environment frame and return it **/ /** @return pop innermost environment frame and return it **/
rp<Environment> pop_envframe(); rp<SymbolTable> pop_envframe();
/** @return number of stacked environment frames **/ /** @return number of stacked environment frames **/
size_t env_stack_size() const { return env_stack_.size(); } size_t env_stack_size() const { return env_stack_.size(); }

View file

@ -8,11 +8,11 @@
#include "pretty_localenv.hpp" #include "pretty_localenv.hpp"
namespace xo { namespace xo {
using xo::scm::LocalEnv; using xo::scm::LocalSymtab;
using xo::scm::Variable; using xo::scm::Variable;
namespace scm { namespace scm {
bp<Environment> bp<SymbolTable>
envframestack::top_envframe() const { envframestack::top_envframe() const {
std::size_t z = stack_.size(); std::size_t z = stack_.size();
@ -25,7 +25,7 @@ namespace xo {
} }
void void
envframestack::push_envframe(const rp<Environment> & frame) envframestack::push_envframe(const rp<SymbolTable> & frame)
{ {
constexpr bool c_debug_flag = true; constexpr bool c_debug_flag = true;
scope log(XO_DEBUG(c_debug_flag), scope log(XO_DEBUG(c_debug_flag),
@ -38,7 +38,7 @@ namespace xo {
stack_[z] = frame; stack_[z] = frame;
} }
rp<Environment> rp<SymbolTable>
envframestack::pop_envframe() { envframestack::pop_envframe() {
constexpr bool c_debug_flag = true; constexpr bool c_debug_flag = true;
scope log(XO_DEBUG(c_debug_flag)); scope log(XO_DEBUG(c_debug_flag));
@ -48,7 +48,7 @@ namespace xo {
if (z > 0) { if (z > 0) {
//std::unique_ptr<exprstate> top = std::move(stack_[z-1]); //std::unique_ptr<exprstate> top = std::move(stack_[z-1]);
rp<Environment> retval = stack_.at(z-1); rp<SymbolTable> retval = stack_.at(z-1);
stack_.resize(z-1); stack_.resize(z-1);

View file

@ -13,7 +13,7 @@
namespace xo { namespace xo {
using xo::scm::Lambda; using xo::scm::Lambda;
using xo::scm::LocalEnv; using xo::scm::LocalSymtab;
namespace scm { namespace scm {
const char * const char *

View file

@ -17,8 +17,8 @@ namespace xo {
using Apply = xo::scm::Apply; using Apply = xo::scm::Apply;
using Lambda = xo::scm::Lambda; using Lambda = xo::scm::Lambda;
using LambdaAccess = xo::scm::LambdaAccess; using LambdaAccess = xo::scm::LambdaAccess;
using Environment = xo::scm::Environment; using Environment = xo::scm::SymbolTable;
using LocalEnv = xo::scm::LocalEnv; using LocalEnv = xo::scm::LocalSymtab;
using Variable = xo::scm::Variable; using Variable = xo::scm::Variable;
namespace scm { namespace scm {
@ -37,7 +37,7 @@ namespace xo {
const rp<Expression> & rhs, const rp<Expression> & rhs,
parserstatemachine * p_psm) parserstatemachine * p_psm)
{ {
rp<Environment> parent_env = p_psm->top_envframe().promote(); rp<SymbolTable> parent_env = p_psm->top_envframe().promote();
rp<Variable> var1 = Variable::make(lhs_name, rhs->valuetype()); rp<Variable> var1 = Variable::make(lhs_name, rhs->valuetype());
rp<LocalEnv> let_env = LocalEnv::make1(var1, parent_env); rp<LocalEnv> let_env = LocalEnv::make1(var1, parent_env);
@ -136,7 +136,7 @@ namespace xo {
std::string lambda_name = Variable::gensym("let1"); std::string lambda_name = Variable::gensym("let1");
rp<Environment> parent_env = p_psm->top_envframe().promote(); rp<SymbolTable> parent_env = p_psm->top_envframe().promote();
rp<Expression> lambda rp<Expression> lambda
= Lambda::make_from_env(lambda_name, = Lambda::make_from_env(lambda_name,

View file

@ -11,14 +11,14 @@
#include "xo/expression/DefineExpr.hpp" #include "xo/expression/DefineExpr.hpp"
#include "xo/expression/Constant.hpp" #include "xo/expression/Constant.hpp"
#include "xo/expression/ConvertExpr.hpp" #include "xo/expression/ConvertExpr.hpp"
#include "xo/expression/GlobalEnv.hpp" #include "xo/expression/GlobalSymtab.hpp"
//#include "xo/expression/LocalEnv.hpp" //#include "xo/expression/LocalSymtab.hpp"
//#include <regex> //#include <regex>
#include <stdexcept> #include <stdexcept>
namespace xo { namespace xo {
using xo::scm::Expression; using xo::scm::Expression;
using xo::scm::LocalEnv; using xo::scm::LocalSymtab;
using xo::reflect::TypeDescr; using xo::reflect::TypeDescr;
namespace scm { namespace scm {
@ -28,7 +28,7 @@ namespace xo {
: psm_{debug_flag} : psm_{debug_flag}
{ {
/* top-level environment. initially empty */ /* top-level environment. initially empty */
rp<Environment> toplevel_env = GlobalEnv::make_empty(); rp<SymbolTable> toplevel_env = GlobalSymtab::make_empty();
this->psm_.env_stack_.push_envframe(toplevel_env); this->psm_.env_stack_.push_envframe(toplevel_env);
} }

View file

@ -11,7 +11,7 @@
#include "xo/expression/pretty_expression.hpp" #include "xo/expression/pretty_expression.hpp"
namespace xo { namespace xo {
using xo::scm::LocalEnv; using xo::scm::LocalSymtab;
using xo::scm::Variable; using xo::scm::Variable;
namespace scm { namespace scm {
@ -45,12 +45,12 @@ namespace xo {
xs_stack_.push_exprstate(std::move(x)); xs_stack_.push_exprstate(std::move(x));
} }
bp<Environment> bp<SymbolTable>
parserstatemachine::top_envframe() const { parserstatemachine::top_envframe() const {
return env_stack_.top_envframe(); return env_stack_.top_envframe();
} }
bp<Environment> bp<SymbolTable>
parserstatemachine::lookup_envframe(std::size_t i) const { parserstatemachine::lookup_envframe(std::size_t i) const {
return env_stack_[i]; return env_stack_[i];
} }
@ -64,7 +64,7 @@ namespace xo {
env_stack_.push_envframe(x); env_stack_.push_envframe(x);
} }
rp<Environment> rp<SymbolTable>
parserstatemachine::pop_envframe() { parserstatemachine::pop_envframe() {
scope log(XO_DEBUG(debug_flag_)); scope log(XO_DEBUG(debug_flag_));