xo-interpreter2 stack: wrap TokenizerError as DRuntimeError
Also fix _read_eval_print() to report them!
This commit is contained in:
parent
c704e59f02
commit
6189e631f3
7 changed files with 69 additions and 30 deletions
|
|
@ -27,17 +27,15 @@ namespace xo {
|
|||
|
||||
VsmResult() = default;
|
||||
explicit VsmResult(obj<AGCObject> value) : result_{value} {}
|
||||
explicit VsmResult(TokenizerError err) : result_{err} {}
|
||||
|
||||
bool is_value() const { return std::holds_alternative<obj<AGCObject>>(result_); }
|
||||
bool is_tk_error() const { return std::holds_alternative<TokenizerError>(result_); }
|
||||
bool is_eval_error() const;
|
||||
bool is_value() const { return result_; }
|
||||
bool is_error() const;
|
||||
|
||||
const obj<AGCObject> * value() const { return std::get_if<obj<AGCObject>>(&result_); }
|
||||
obj<AGCObject> & value_ref() { return std::get<obj<AGCObject>>(result_); }
|
||||
const obj<AGCObject> * value() const { return &result_; }
|
||||
obj<AGCObject> & value_ref() { return result_; }
|
||||
|
||||
/** result of evaluating first expression encountered in input **/
|
||||
std::variant<obj<AGCObject>, TokenizerError> result_;
|
||||
obj<AGCObject> result_;
|
||||
};
|
||||
|
||||
/** vsm result + reamining span **/
|
||||
|
|
@ -270,7 +268,9 @@ namespace xo {
|
|||
obj<AAllocator> aux_mm_;
|
||||
|
||||
/** allocator (likely DX1Collector or similar) for
|
||||
* expressions and values. Schemaatika reader will use this also
|
||||
* expressions and values. Schemaatika reader will use this also.
|
||||
*
|
||||
* Allocations must represent a type that supports GCObject.
|
||||
**/
|
||||
abox<AAllocator> mm_;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,15 +60,9 @@ namespace xo {
|
|||
namespace scm {
|
||||
|
||||
bool
|
||||
VsmResult::is_eval_error() const
|
||||
VsmResult::is_error() const
|
||||
{
|
||||
if (std::holds_alternative<obj<AGCObject>>(result_)) {
|
||||
auto err = obj<AGCObject,DRuntimeError>::from(*(this->value()));
|
||||
|
||||
return err;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return (*this->value() && obj<AGCObject,DRuntimeError>::from(*(this->value())));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
@ -191,18 +185,39 @@ namespace xo {
|
|||
|
||||
reader_.reset_result();
|
||||
|
||||
auto [expr, remaining, error1]
|
||||
auto [expr, remaining, tk_error]
|
||||
= reader_.read_expr(input, eof);
|
||||
|
||||
if (!expr) {
|
||||
/* tokenizer error */
|
||||
if (tk_error.is_error()) {
|
||||
// tokenizer error -> convert to runtime error
|
||||
|
||||
return VsmResultExt(VsmResult(error1), remaining);
|
||||
DString * src = DString::from_view(mm_.to_op(), tk_error.src_function());
|
||||
DString * msg = tk_error.report_to_string(mm_.to_op());
|
||||
|
||||
auto error = obj<AGCObject,DRuntimeError>(DRuntimeError::_make(mm_.to_op(), src, msg));
|
||||
|
||||
{
|
||||
obj<APrintable> error_pr
|
||||
= FacetRegistry::instance().variant<APrintable,AGCObject>(error);
|
||||
|
||||
ppconfig ppc;
|
||||
ppstate_standalone pps(&cout, 0, &ppc);
|
||||
pps.prettyn(error_pr);
|
||||
}
|
||||
|
||||
return VsmResultExt(VsmResult(error), remaining);
|
||||
} else {
|
||||
// incomplete input
|
||||
return VsmResultExt(VsmResult(), remaining);
|
||||
}
|
||||
}
|
||||
|
||||
// here: have obtained complete input expression
|
||||
|
||||
VsmResult evalresult = this->start_eval(expr);
|
||||
|
||||
if (evalresult.is_tk_error()) {
|
||||
if (evalresult.is_error()) {
|
||||
// TODO: print error here
|
||||
|
||||
return VsmResultExt(evalresult, remaining);
|
||||
|
|
@ -210,19 +225,21 @@ namespace xo {
|
|||
|
||||
assert(evalresult.is_value());
|
||||
|
||||
obj<AGCObject> * p_value = std::get_if<obj<AGCObject>>(&(evalresult.result_));
|
||||
obj<AGCObject> value = evalresult.result_;
|
||||
|
||||
assert(p_value);
|
||||
assert(value);
|
||||
|
||||
obj<APrintable> value_pr
|
||||
= FacetRegistry::instance().variant<APrintable,AGCObject>(*p_value);
|
||||
{
|
||||
obj<APrintable> value_pr
|
||||
= FacetRegistry::instance().variant<APrintable,AGCObject>(value);
|
||||
|
||||
// pretty_toplevel(value_pr, &cout, ppconfig());
|
||||
ppconfig ppc;
|
||||
ppstate_standalone pps(&cout, 0, &ppc);
|
||||
pps.prettyn(value_pr);
|
||||
// pretty_toplevel(value_pr, &cout, ppconfig());
|
||||
ppconfig ppc;
|
||||
ppstate_standalone pps(&cout, 0, &ppc);
|
||||
pps.prettyn(value_pr);
|
||||
}
|
||||
|
||||
return VsmResultExt(VsmResult(*p_value), remaining);
|
||||
return VsmResultExt(VsmResult(value), remaining);
|
||||
}
|
||||
|
||||
const VsmResult &
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ namespace xo {
|
|||
|
||||
*p_input = res.remaining_;
|
||||
|
||||
return !res.is_tk_error() && !res.is_eval_error();
|
||||
return !res.is_error();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ include(CMakeFindDependencyMacro)
|
|||
# must coordinate with xo_dependency() calls
|
||||
# in src/tokenizer2/CMakeLists.txt
|
||||
#
|
||||
find_dependency(xo_stringtable2)
|
||||
find_dependency(xo_arena)
|
||||
find_dependency(indentlog)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include "TkInputState.hpp"
|
||||
#include "tokentype.hpp"
|
||||
#include "span.hpp"
|
||||
#include <xo/stringtable2/String.hpp>
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include <iomanip>
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -19,6 +21,7 @@ namespace xo {
|
|||
**/
|
||||
class TokenizerError {
|
||||
public:
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
using CharT = char;
|
||||
using span_type = xo::mm::span<const CharT>;
|
||||
|
||||
|
|
@ -89,6 +92,9 @@ namespace xo {
|
|||
/** Print human-oriented error report on @p os. **/
|
||||
void report(std::ostream & os) const;
|
||||
|
||||
/** Similar to report, but capture as string, allocated from @p mm **/
|
||||
DString * report_to_string(obj<AAllocator> mm) const;
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ set(SELF_SRCS
|
|||
|
||||
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})
|
||||
# deps must coordinate with xo-tokenizer/cmake/xo_tokenizer2Config.cmake.in
|
||||
xo_dependency(${SELF_LIB} xo_stringtable2)
|
||||
xo_dependency(${SELF_LIB} xo_arena)
|
||||
xo_dependency(${SELF_LIB} indentlog)
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,20 @@ namespace xo {
|
|||
}
|
||||
}
|
||||
|
||||
DString *
|
||||
TokenizerError::report_to_string(obj<AAllocator> dest_mm) const
|
||||
{
|
||||
// FIXME:
|
||||
// using heap here for scratch space.
|
||||
// Would prefer to checkpoint + realloc.
|
||||
|
||||
std::stringstream ss;
|
||||
|
||||
this->report(ss);
|
||||
|
||||
return DString::from_str(dest_mm, ss.str());
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue