diff --git a/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/include/xo/interpreter2/VirtualSchematikaMachine.hpp index 6e1595da..c9dc0749 100644 --- a/include/xo/interpreter2/VirtualSchematikaMachine.hpp +++ b/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -14,6 +14,23 @@ namespace xo { namespace scm { + /** similar to @ref xo::scm::ReaderResult **/ + struct VsmResult { + using AGCObject = xo::mm::AGCObject; + using span_type = xo::mm::span; + + bool is_tk_error() const { return tk_error_.is_error(); } + + /** result of evaluating first expression encountered in input **/ + obj value_; + + /** unconsumed portion of input span **/ + span_type remaining_input_; + + /** {src_function, error_description, input_state, error_pos} **/ + TokenizerError tk_error_; + }; + /** @class VirtualSchematikaMachine * @brief virtual machine for schematika **/ @@ -23,10 +40,17 @@ namespace xo { using Stack = void *; using AAllocator = xo::mm::AAllocator; using AGCObject = xo::mm::AGCObject; + using span_type = xo::mm::span; public: VirtualSchematikaMachine(const VsmConfig & config); + /** consume input @p input_cstr **/ + VsmResult read_eval_print(span_type input_span, bool eof); + + /** evaluate expression @p expr **/ + std::pair, TokenizerError> eval(obj expr); + /** borrow calling thread to run indefinitely, * until halt instruction **/ diff --git a/include/xo/interpreter2/VsmConfig.hpp b/include/xo/interpreter2/VsmConfig.hpp index 5071c020..2957b297 100644 --- a/include/xo/interpreter2/VsmConfig.hpp +++ b/include/xo/interpreter2/VsmConfig.hpp @@ -10,11 +10,13 @@ namespace xo { namespace scm { - /** Configuration for virtual schematika machine + /** Configuration for virtual schematika machine **/ struct VsmConfig { using X1CollectorConfig = xo::mm::X1CollectorConfig; + VsmConfig() = default; + /** reader configuration **/ ReaderConfig rdr_config_; /** Configuration for allocator/collector. diff --git a/src/interpreter2/VirtualSchematikaMachine.cpp b/src/interpreter2/VirtualSchematikaMachine.cpp index f7e8259e..fabc5441 100644 --- a/src/interpreter2/VirtualSchematikaMachine.cpp +++ b/src/interpreter2/VirtualSchematikaMachine.cpp @@ -8,10 +8,18 @@ #include #include #include +#include +#include #include namespace xo { + using xo::print::APrintable; + using xo::print::ppconfig; + using xo::print::ppstate_standalone; + using xo::mm::AGCObject; using xo::mm::DX1Collector; + using xo::facet::FacetRegistry; + using std::cout; namespace scm { @@ -21,6 +29,52 @@ namespace xo { reader_{config.rdr_config_, mm_.to_op()} {} + VsmResult + VirtualSchematikaMachine::read_eval_print(span_type input, bool eof) + { + if (input.empty()) { + return VsmResult(); + } + + auto [expr, remaining, error1] + = reader_.read_expr(input, eof); + + if (!expr) { + return { + .remaining_input_ = remaining, + .tk_error_ = error1 + }; + } + + auto [value, error2] = this->eval(expr); + + if (!value) { + return { + .remaining_input_ = remaining, + .tk_error_ = error2 + }; + } + + 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); + + return { .remaining_input_ = remaining }; + } + + std::pair, TokenizerError> + VirtualSchematikaMachine::eval(obj expr) + { + (void)expr; + + assert(false); + return std::make_pair(obj(), TokenizerError()); + } + void VirtualSchematikaMachine::run() { diff --git a/utest/VirtualSchematikaMachine.test.cpp b/utest/VirtualSchematikaMachine.test.cpp index 29301b1f..8dacb437 100644 --- a/utest/VirtualSchematikaMachine.test.cpp +++ b/utest/VirtualSchematikaMachine.test.cpp @@ -20,6 +20,9 @@ #include namespace xo { + using xo::scm::VirtualSchematikaMachine; + using xo::scm::VsmConfig; + #ifdef NOT_YET using xo::scm::SchematikaParser; using xo::scm::ASyntaxStateMachine; @@ -42,6 +45,8 @@ namespace xo { namespace ut { TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]") { + VirtualSchematikaMachine vsm(VsmConfig); + #ifdef NOT_YET ArenaConfig config; config.name_ = "test-arena";