diff --git a/xo-interpreter2/include/xo/interpreter2/vsm/DVirtualSchematikaMachine.hpp b/xo-interpreter2/include/xo/interpreter2/vsm/DVirtualSchematikaMachine.hpp index 46de95f3..84070673 100644 --- a/xo-interpreter2/include/xo/interpreter2/vsm/DVirtualSchematikaMachine.hpp +++ b/xo-interpreter2/include/xo/interpreter2/vsm/DVirtualSchematikaMachine.hpp @@ -27,17 +27,15 @@ namespace xo { VsmResult() = default; explicit VsmResult(obj value) : result_{value} {} - explicit VsmResult(TokenizerError err) : result_{err} {} - bool is_value() const { return std::holds_alternative>(result_); } - bool is_tk_error() const { return std::holds_alternative(result_); } - bool is_eval_error() const; + bool is_value() const { return result_; } + bool is_error() const; - const obj * value() const { return std::get_if>(&result_); } - obj & value_ref() { return std::get>(result_); } + const obj * value() const { return &result_; } + obj & value_ref() { return result_; } /** result of evaluating first expression encountered in input **/ - std::variant, TokenizerError> result_; + obj result_; }; /** vsm result + reamining span **/ @@ -270,7 +268,9 @@ namespace xo { obj 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 mm_; diff --git a/xo-interpreter2/src/interpreter2/DVirtualSchematikaMachine.cpp b/xo-interpreter2/src/interpreter2/DVirtualSchematikaMachine.cpp index 8edc0538..9ceb8fac 100644 --- a/xo-interpreter2/src/interpreter2/DVirtualSchematikaMachine.cpp +++ b/xo-interpreter2/src/interpreter2/DVirtualSchematikaMachine.cpp @@ -60,15 +60,9 @@ namespace xo { namespace scm { bool - VsmResult::is_eval_error() const + VsmResult::is_error() const { - if (std::holds_alternative>(result_)) { - auto err = obj::from(*(this->value())); - - return err; - } else { - return false; - } + return (*this->value() && obj::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(DRuntimeError::_make(mm_.to_op(), src, msg)); + + { + obj error_pr + = FacetRegistry::instance().variant(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 * p_value = std::get_if>(&(evalresult.result_)); + obj value = evalresult.result_; - assert(p_value); + assert(value); - obj value_pr - = FacetRegistry::instance().variant(*p_value); + { + obj value_pr + = FacetRegistry::instance().variant(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 & diff --git a/xo-interpreter2/src/skrepl/skreplxx.cpp b/xo-interpreter2/src/skrepl/skreplxx.cpp index 51f9df06..a4f86857 100644 --- a/xo-interpreter2/src/skrepl/skreplxx.cpp +++ b/xo-interpreter2/src/skrepl/skreplxx.cpp @@ -230,7 +230,7 @@ namespace xo { *p_input = res.remaining_; - return !res.is_tk_error() && !res.is_eval_error(); + return !res.is_error(); } void diff --git a/xo-tokenizer2/cmake/xo_tokenizer2Config.cmake.in b/xo-tokenizer2/cmake/xo_tokenizer2Config.cmake.in index eccd2745..0c0dad0b 100644 --- a/xo-tokenizer2/cmake/xo_tokenizer2Config.cmake.in +++ b/xo-tokenizer2/cmake/xo_tokenizer2Config.cmake.in @@ -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) diff --git a/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp b/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp index bf7702b1..b08889bd 100644 --- a/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp +++ b/xo-tokenizer2/include/xo/tokenizer2/TokenizerError.hpp @@ -8,6 +8,8 @@ #include "TkInputState.hpp" #include "tokentype.hpp" #include "span.hpp" +#include +#include #include 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; @@ -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 mm) const; + ///@} private: diff --git a/xo-tokenizer2/src/tokenizer2/CMakeLists.txt b/xo-tokenizer2/src/tokenizer2/CMakeLists.txt index ccf1b551..3a748e70 100644 --- a/xo-tokenizer2/src/tokenizer2/CMakeLists.txt +++ b/xo-tokenizer2/src/tokenizer2/CMakeLists.txt @@ -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) diff --git a/xo-tokenizer2/src/tokenizer2/TokenizerError.cpp b/xo-tokenizer2/src/tokenizer2/TokenizerError.cpp index ffe3c8b4..c80996d9 100644 --- a/xo-tokenizer2/src/tokenizer2/TokenizerError.cpp +++ b/xo-tokenizer2/src/tokenizer2/TokenizerError.cpp @@ -54,6 +54,20 @@ namespace xo { } } + DString * + TokenizerError::report_to_string(obj 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*/