xo-inteerpreter2: rework VsmResult to use pointer

Preefer to maintain ref to VSM.result_, since gc will
preserve it.
This commit is contained in:
Roland Conybeare 2026-03-27 12:13:09 -04:00
commit 338d063edf
3 changed files with 27 additions and 8 deletions

View file

@ -32,18 +32,33 @@ namespace xo {
bool is_error() const;
const obj<AGCObject> * value() const { return &result_; }
obj<AGCObject> & value_ref() { return result_; }
const obj<AGCObject> & value_ref() const { return result_; }
/** result of evaluating first expression encountered in input **/
obj<AGCObject> result_;
};
/** vsm result + reamining span **/
struct VsmResultExt : public VsmResult {
/** vsm result + reamining span
*
* Preserves address of wrapped VsmResult
* (so it can continue to be owned by DVirtualSchematikaMachine,
* and to be known to gc without add'l effort)
**/
struct VsmResultExt {
using AGCObject = xo::mm::AGCObject;
using span_type = VsmResult::span_type;
VsmResultExt() = default;
VsmResultExt(const VsmResult & result, span_type rem) : VsmResult{result}, remaining_{rem} {}
VsmResultExt(const VsmResult & result, span_type rem) : p_result_{&result}, remaining_{rem} {}
bool is_empty() const { return !p_result_; }
bool is_value() const { return p_result_ ? p_result_->is_value() : false; }
bool is_error() const { return p_result_ ? p_result_->is_error() : false; }
const obj<AGCObject> * value() const { return p_result_ ? p_result_->value() : nullptr; }
//const obj<AGCObject> & value_ref() { return result_.value_ref(); }
const VsmResult * p_result_ = nullptr;
/** unconsumed portion of input **/
VsmResult::span_type remaining_;

View file

@ -197,6 +197,8 @@ namespace xo {
auto error = obj<AGCObject,DRuntimeError>(DRuntimeError::_make(mm_.to_op(), src, msg));
this->value_ = VsmResult(error);
{
obj<APrintable> error_pr
= FacetRegistry::instance().variant<APrintable,AGCObject>(error);
@ -206,7 +208,7 @@ namespace xo {
pps.prettyn(error_pr);
}
return VsmResultExt(VsmResult(error), remaining);
return VsmResultExt(value_, remaining);
} else {
// incomplete input
return VsmResultExt(VsmResult(), remaining);
@ -215,7 +217,7 @@ namespace xo {
// here: have obtained complete input expression
VsmResult evalresult = this->start_eval(expr);
const VsmResult & evalresult = this->start_eval(expr);
if (evalresult.is_error()) {
// TODO: print error here
@ -239,7 +241,7 @@ namespace xo {
pps.prettyn(value_pr);
}
return VsmResultExt(VsmResult(value), remaining);
return VsmResultExt(evalresult, remaining);
}
const VsmResult &
@ -975,7 +977,7 @@ namespace xo {
gc.forward_inplace(&fn_);
gc.forward_inplace(&args_);
if (value_.is_value()) {
gc.forward_inplace(&value_.value_ref());
gc.forward_inplace(const_cast<obj<AGCObject> *>(&value_.value_ref()));
}
return this->shallow_size();

View file

@ -103,6 +103,8 @@ namespace xo {
{
scope log(XO_DEBUG(debug_flag));
// WARNING: res.value() is unstable - gc may move it
VsmResultExt res = vsm_->read_eval_print(input_span, eof_flag);
REQUIRE(res.is_value());