185 lines
5.2 KiB
C++
185 lines
5.2 KiB
C++
/** @file LocalEnv.cpp **/
|
|
|
|
#include "LocalEnv.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<LocalEnv>
|
|
LocalEnv::make(gc::IAlloc * mm,
|
|
gp<LocalEnv> p,
|
|
const rp<LocalSymtab> & s,
|
|
std::size_t n)
|
|
{
|
|
if (s) {
|
|
assert(static_cast<int>(n) == s->n_arg());
|
|
}
|
|
|
|
return new (MMPtr(mm)) LocalEnv(mm, p, s, n);
|
|
}
|
|
|
|
LocalEnv::LocalEnv(gc::IAlloc * mm,
|
|
gp<LocalEnv> p,
|
|
const rp<LocalSymtab> & s,
|
|
std::size_t n) : parent_{p},
|
|
symtab_{s},
|
|
slot_v_{mm, n}
|
|
{}
|
|
|
|
bool
|
|
LocalEnv::local_contains_var(const std::string & vname) const
|
|
{
|
|
assert(symtab_.get());
|
|
|
|
return symtab_->lookup_local(vname);
|
|
}
|
|
|
|
gp<Object> *
|
|
LocalEnv::lookup_slot(const std::string & vname)
|
|
{
|
|
binding_path b = symtab_->lookup_local_binding(vname);
|
|
|
|
if (b.i_link_ == 0) {
|
|
assert((b.j_slot_ >= 0) && (static_cast<size_t>(b.j_slot_) < slot_v_.size()));
|
|
|
|
return &(slot_v_[b.j_slot_]);
|
|
}
|
|
|
|
if (parent_.get()) {
|
|
return parent_->lookup_slot(vname);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
gp<Object> *
|
|
LocalEnv::establish_var(bp<Variable> v)
|
|
{
|
|
assert(v);
|
|
|
|
throw std::runtime_error(tostr("LocalEnv::establish_var:"
|
|
" inserting new variables not supported for LocalEnv",
|
|
xtag("v.name", v->name())));
|
|
}
|
|
|
|
TaggedPtr
|
|
LocalEnv::self_tp() const
|
|
{
|
|
return Reflect::make_tp(const_cast<LocalEnv *>(this));
|
|
}
|
|
|
|
void
|
|
LocalEnv::display(std::ostream & os) const
|
|
{
|
|
os << "<local-env"
|
|
<< 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
|
|
LocalEnv::_shallow_size() const
|
|
{
|
|
std::size_t retval = sizeof(LocalEnv);
|
|
|
|
retval += gc::IAlloc::with_padding(slot_array_size(slot_v_.size()));
|
|
|
|
return retval;
|
|
}
|
|
|
|
Object *
|
|
LocalEnv::_shallow_copy(gc::IAlloc * mm) const
|
|
{
|
|
Cpof cpof(mm, this);
|
|
|
|
size_t z = this->size();
|
|
|
|
LocalEnv * copy = new (cpof) LocalEnv(cpof.mm_, parent_, symtab_, 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
|
|
LocalEnv::_forward_children(gc::IAlloc * gc)
|
|
{
|
|
static_assert(decltype(symtab_)::is_gc_ptr == false);
|
|
|
|
Object::_forward_inplace(parent_, gc);
|
|
// Object::_forward_inplace(symtab_); // not a gp yet
|
|
for (std::size_t i = 0, n = slot_v_.size(); i < n; ++i) {
|
|
Object::_forward_inplace((*this)[i], gc);
|
|
}
|
|
|
|
return _shallow_size();
|
|
}
|
|
|
|
void
|
|
LocalEnv::reflect_self()
|
|
{
|
|
StructReflector<LocalEnv> sr;
|
|
|
|
if (sr.is_incomplete()) {
|
|
/* reflect CVector<gp<Object>>
|
|
*
|
|
* note: placement here works b/c CVector<T> not used anywhere else
|
|
*/
|
|
using VectorType = obj::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 LocalEnv.cpp */
|