xo-inteerpreter2: rework VsmResult to use pointer
Preefer to maintain ref to VSM.result_, since gc will preserve it.
This commit is contained in:
parent
6189e631f3
commit
338d063edf
3 changed files with 27 additions and 8 deletions
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue