xo-expression2 stack: + mvp DGlobalSymtab impl
This commit is contained in:
parent
e7e9d226dd
commit
0ad4182325
6 changed files with 140 additions and 5 deletions
|
|
@ -12,6 +12,8 @@ namespace xo {
|
|||
namespace scm {
|
||||
class Binding {
|
||||
public:
|
||||
using slot_type = int32_t;
|
||||
|
||||
static constexpr int32_t c_link_sentinel = -2;
|
||||
static constexpr int32_t c_link_global = -1;
|
||||
|
||||
|
|
@ -22,7 +24,7 @@ namespace xo {
|
|||
|
||||
static Binding null() { return Binding(); }
|
||||
/** global bindings are located by symbol name **/
|
||||
static Binding global() { return Binding(c_link_global, 0); }
|
||||
static Binding global(int32_t j_slot) { return Binding(c_link_global, j_slot); }
|
||||
static Binding local(int32_t j_slot) { return Binding(0, j_slot); }
|
||||
static Binding relative(int32_t i_link, Binding def);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "Binding.hpp"
|
||||
#include "DVariable.hpp"
|
||||
#include <xo/object2/DArray.hpp>
|
||||
#include <xo/arena/DArenaHashMap.hpp>
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -23,7 +25,8 @@ namespace xo {
|
|||
public:
|
||||
using key_type = const DUniqueString *;
|
||||
using value_type = Binding;
|
||||
using repr_type = xo::map::DArenaHashMap<key_type, value_type>;
|
||||
using repr_type = xo::map::DArenaHashMap<key_type, Binding::slot_type>;
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||
|
||||
public:
|
||||
|
|
@ -31,6 +34,17 @@ namespace xo {
|
|||
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||
|
||||
public:
|
||||
/** lookup global symbol with name @p sym **/
|
||||
DVariable * lookup_variable(const DUniqueString * sym) const noexcept;
|
||||
|
||||
/** establish binding for @p sym, with type described by @p typeref,
|
||||
* replacing existing global (if present) with the same name.
|
||||
* Use memory from @p mm to create variable-expr
|
||||
**/
|
||||
DVariable * establish_variable(obj<AAllocator> mm,
|
||||
const DUniqueString * sym,
|
||||
TypeRef typeref);
|
||||
|
||||
/** @defgroup xo-expression2-symboltable-facet symboltable facet**/
|
||||
///@{
|
||||
|
||||
|
|
@ -49,6 +63,13 @@ namespace xo {
|
|||
/** map symbols -> bindings **/
|
||||
repr_type map_;
|
||||
|
||||
/** array of variables.
|
||||
* When S is a unique-string for a global symbol, then:
|
||||
* 1. map_[S] is unique global index i(S) for S.
|
||||
* 2. vars_[i(S)] is variable-expr var(S) for S
|
||||
* 3. var(S)->name == S
|
||||
**/
|
||||
DArray * vars_ = nullptr;
|
||||
};
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace xo {
|
|||
return slots_[ix.j_slot()].var_;
|
||||
}
|
||||
|
||||
/** increase slot size (provided beleow capacity) to append
|
||||
/** increase slot size (provided below capacity) to append
|
||||
* binding for one local variable. Local variable will be allocated
|
||||
* from @p mm, named @p name, with type described by @p typeref.
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -5,20 +5,108 @@
|
|||
|
||||
#include "DGlobalSymtab.hpp"
|
||||
#include "DUniqueString.hpp"
|
||||
#include <xo/expression2/Expression.hpp>
|
||||
#include <xo/expression2/Variable.hpp>
|
||||
#include <xo/gc/GCObject.hpp>
|
||||
#include <xo/facet/FacetRegistry.hpp>
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::mm::AGCObject;
|
||||
|
||||
namespace scm {
|
||||
|
||||
#ifdef NOT_YET
|
||||
DVariable *
|
||||
DGlobalSymtab::lookup_binding(Binding ix) noexcept
|
||||
{
|
||||
assert(ix.i_link() == -1);
|
||||
assert(ix.j_slot() >= 0);
|
||||
assert(vars_);
|
||||
assert(std::uint64_t(ix.j_slot()) < vars_->size());
|
||||
|
||||
auto var_gco = obj<AGCObject,DVariable>::from((*vars_)[ix.j_slot()]);;
|
||||
auto var = var_gco.to_facet<AExpression>();
|
||||
|
||||
assert(var.data());
|
||||
|
||||
return var.data();
|
||||
}
|
||||
#endif
|
||||
|
||||
DVariable *
|
||||
DGlobalSymtab::lookup_variable(const DUniqueString * sym) const noexcept
|
||||
{
|
||||
Binding existing = this->lookup_binding(sym);
|
||||
|
||||
if (existing.is_null())
|
||||
return nullptr;
|
||||
|
||||
auto var_gco = obj<AGCObject,DVariable>::from((*vars_)[existing.j_slot()]);
|
||||
auto var = var_gco.to_facet<AExpression>();
|
||||
|
||||
assert(var.data());
|
||||
|
||||
return var.data();
|
||||
}
|
||||
|
||||
DVariable *
|
||||
DGlobalSymtab::establish_variable(obj<AAllocator> mm,
|
||||
const DUniqueString * sym,
|
||||
TypeRef typeref)
|
||||
{
|
||||
DVariable * var = this->lookup_variable(sym);
|
||||
|
||||
if (!var) {
|
||||
assert(vars_);
|
||||
|
||||
DArray::size_type n = vars_->size();
|
||||
|
||||
/** make sure vars_ has room **/
|
||||
if (n == vars_->capacity()) {
|
||||
// reallocate with more capacity
|
||||
DArray * vars_2x = DArray::copy(mm, vars_, vars_->capacity() * 2);
|
||||
|
||||
assert(vars_2x);
|
||||
|
||||
this->vars_ = vars_2x;
|
||||
}
|
||||
|
||||
/** create new variable **/
|
||||
Binding binding = Binding::global(n);
|
||||
var = DVariable::make(mm, sym, typeref, binding);
|
||||
|
||||
if (!var) {
|
||||
// something terribly wrong
|
||||
assert(false);
|
||||
return var;
|
||||
}
|
||||
|
||||
map_[sym] = binding.j_slot();
|
||||
|
||||
bool ok = vars_->push_back(obj<AGCObject,DVariable>(var));
|
||||
|
||||
if (!ok)
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
Binding
|
||||
DGlobalSymtab::lookup_binding(const DUniqueString * sym) const noexcept
|
||||
{
|
||||
(void)sym;
|
||||
assert(sym);
|
||||
|
||||
scope log(XO_DEBUG(true), "stub");
|
||||
log && log(xtag("sym", std::string_view(*sym)));
|
||||
|
||||
return Binding();
|
||||
auto ix = map_.find(sym);
|
||||
|
||||
if (ix == map_.end())
|
||||
return Binding::null();
|
||||
|
||||
return Binding::global(ix->second);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
|
|
|
|||
|
|
@ -58,6 +58,13 @@ namespace xo {
|
|||
static DArray * empty(obj<AAllocator> mm,
|
||||
size_type cap);
|
||||
|
||||
/** create copy of @p src using memory from @p mm
|
||||
* with capacity for @p new_cap elements
|
||||
**/
|
||||
static DArray * copy(obj<AAllocator> mm,
|
||||
DArray * src,
|
||||
size_type new_cap);
|
||||
|
||||
/** create array containing elements @p args, using memory from @p mm.
|
||||
* Nullptr if space exhausted.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -37,6 +37,23 @@ namespace xo {
|
|||
return result;
|
||||
}
|
||||
|
||||
DArray *
|
||||
DArray::copy(obj<AAllocator> mm,
|
||||
DArray * src,
|
||||
size_type new_cap)
|
||||
{
|
||||
DArray * dest = empty(mm, new_cap);
|
||||
|
||||
/** could just memcpy here **/
|
||||
for (size_type i = 0, n = src->size(); i < n; ++i) {
|
||||
dest->elts_[i] = src->elts_[i];
|
||||
}
|
||||
|
||||
dest->size_ = src->size();
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
obj<AGCObject>
|
||||
DArray::at(size_type ix) const
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue