xo-expression2: upsert global vars works in DDefineSsm
This commit is contained in:
parent
06521e5e79
commit
03847102be
3 changed files with 57 additions and 29 deletions
|
|
@ -65,13 +65,12 @@ namespace xo {
|
|||
/** @defgroup scm-globalsymtab-general-methods general methods **/
|
||||
///@{
|
||||
|
||||
/** 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
|
||||
/** update this symtab to associate @p var with @c var->name().
|
||||
* If there was a previous variable with the same name,
|
||||
* replace it with @p var.
|
||||
**/
|
||||
DVariable * establish_variable(obj<AAllocator> mm,
|
||||
const DUniqueString * sym,
|
||||
TypeRef typeref);
|
||||
void upsert_variable(obj<AAllocator> mm,
|
||||
DVariable * var);
|
||||
|
||||
///@}
|
||||
/** @defgroup scm-globalsymtab-symboltable-facet symboltable facet **/
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ namespace xo {
|
|||
Binding path() const { return path_; }
|
||||
|
||||
void assign_name(const DUniqueString * name) { this->name_ = name; }
|
||||
void assign_path(Binding b) { this->path_ = b; }
|
||||
|
||||
/** @defgroup scm-variable-expression-facet **/
|
||||
///@{
|
||||
|
|
|
|||
|
|
@ -65,6 +65,65 @@ namespace xo {
|
|||
return var.data();
|
||||
}
|
||||
|
||||
void
|
||||
DGlobalSymtab::upsert_variable(obj<AAllocator> mm,
|
||||
DVariable * var)
|
||||
{
|
||||
// It's possible there's already a global variable
|
||||
// with the same name.
|
||||
//
|
||||
// For example redefining a variable in an interactive session.
|
||||
// In this case use the established binding.
|
||||
//
|
||||
DVariable * existing = this->lookup_variable(var->name());
|
||||
|
||||
if (existing) {
|
||||
if (existing == var) {
|
||||
// impossible, but.. noop, right?
|
||||
return;
|
||||
}
|
||||
|
||||
// adopt the existing binding
|
||||
var->assign_path(existing->path());
|
||||
|
||||
// stash new definition (possibly has different type),
|
||||
// replacing previous one
|
||||
//
|
||||
(*vars_)[existing->path().j_slot()] = obj<AGCObject,DVariable>(var);
|
||||
} else {
|
||||
DArray::size_type n = vars_->size();
|
||||
|
||||
// NOTE: expansion of var_ array here is moot at present (Feb 2026),
|
||||
// since the feature isn't yet implemented in ArenaHashMap
|
||||
|
||||
/** make sure vars_ has room **/
|
||||
if (n == vars_->capacity()) {
|
||||
// DArray is out of room. Reallocate with more capacity
|
||||
DArray * vars_2x = DArray::copy(mm, vars_, vars_->capacity() * 2);
|
||||
|
||||
if (!vars_2x) {
|
||||
assert(false);
|
||||
|
||||
// in any case, we can't make progress
|
||||
return;
|
||||
}
|
||||
|
||||
this->vars_ = vars_2x;
|
||||
}
|
||||
|
||||
/** now we know binding for var **/
|
||||
Binding binding = Binding::global(n);
|
||||
|
||||
var->assign_path(binding);
|
||||
|
||||
// need slot# in .map_ for this unique symbol
|
||||
(*map_)[var->name()] = binding.j_slot();
|
||||
|
||||
vars_->push_back(obj<AGCObject,DVariable>(var));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NOT_USING // don't know if we need this path
|
||||
DVariable *
|
||||
DGlobalSymtab::establish_variable(obj<AAllocator> mm,
|
||||
const DUniqueString * sym,
|
||||
|
|
@ -75,43 +134,12 @@ namespace xo {
|
|||
if (!var) {
|
||||
assert(vars_);
|
||||
|
||||
DArray::size_type n = vars_->size();
|
||||
|
||||
// NOTE: expansion here is moot at present (Feb 2026).
|
||||
// Not implemented in ArenaHashMap
|
||||
|
||||
/** 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;
|
||||
}
|
||||
|
||||
assert(map_->size() < map_->capacity());
|
||||
|
||||
(*map_)[sym] = binding.j_slot();
|
||||
|
||||
bool ok = vars_->push_back(obj<AGCObject,DVariable>(var));
|
||||
|
||||
if (!ok)
|
||||
assert(false);
|
||||
xxx;
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
#endif
|
||||
|
||||
Binding
|
||||
DGlobalSymtab::lookup_binding(const DUniqueString * sym) const noexcept
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue