xo-interpreter2: scaffold repl + alloc measurement frameowkr
This commit is contained in:
parent
a71060bb75
commit
6db1ddc802
7 changed files with 152 additions and 45 deletions
|
|
@ -14,21 +14,42 @@
|
|||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
struct EvaluationError {
|
||||
/** source location (in vsm implementation) at which error identified **/
|
||||
std::string_view src_function_;
|
||||
/** error description (allocated from ErrorArena) **/
|
||||
std::string_view error_description_;
|
||||
// TODO: info about location in schematika source
|
||||
};
|
||||
|
||||
/** similar to @ref xo::scm::ReaderResult **/
|
||||
struct VsmResult {
|
||||
using AGCObject = xo::mm::AGCObject;
|
||||
using span_type = xo::mm::span<const char>;
|
||||
|
||||
bool is_tk_error() const { return tk_error_.is_error(); }
|
||||
VsmResult() = default;
|
||||
VsmResult(obj<AGCObject> value) : result_{value} {}
|
||||
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 { return std::holds_alternative<EvaluationError>(result_); }
|
||||
|
||||
const obj<AGCObject> * value() const { return std::get_if<obj<AGCObject>>(&result_); }
|
||||
|
||||
/** result of evaluating first expression encountered in input **/
|
||||
obj<AGCObject> value_;
|
||||
std::variant<obj<AGCObject>, TokenizerError, EvaluationError> result_;
|
||||
};
|
||||
|
||||
/** unconsumed portion of input span **/
|
||||
span_type remaining_input_;
|
||||
/** vsm result + reamining span **/
|
||||
struct VsmResultExt : public VsmResult {
|
||||
using span_type = VsmResult::span_type;
|
||||
|
||||
/** {src_function, error_description, input_state, error_pos} **/
|
||||
TokenizerError tk_error_;
|
||||
VsmResultExt() = default;
|
||||
VsmResultExt(const VsmResult & result, span_type rem) : VsmResult{result}, remaining_{rem} {}
|
||||
|
||||
/** unconsumed portion of input **/
|
||||
VsmResult::span_type remaining_;
|
||||
};
|
||||
|
||||
/** @class VirtualSchematikaMachine
|
||||
|
|
@ -40,16 +61,29 @@ namespace xo {
|
|||
using Stack = void *;
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
using AGCObject = xo::mm::AGCObject;
|
||||
using MemorySizeInfo = xo::mm::MemorySizeInfo;
|
||||
using span_type = xo::mm::span<const char>;
|
||||
|
||||
public:
|
||||
VirtualSchematikaMachine(const VsmConfig & config);
|
||||
|
||||
/** consume input @p input_cstr **/
|
||||
VsmResult read_eval_print(span_type input_span, bool eof);
|
||||
size_t _n_store() const noexcept;
|
||||
MemorySizeInfo _store_info(std::size_t i) const noexcept;
|
||||
|
||||
/** evaluate expression @p expr **/
|
||||
std::pair<obj<AGCObject>, TokenizerError> eval(obj<AExpression> expr);
|
||||
/** begin interactive session. **/
|
||||
void begin_interactive_session();
|
||||
/** begin batch session **/
|
||||
void begin_batch_session();
|
||||
|
||||
/** consume input @p input_cstr.
|
||||
* Require: must first start interactive/batch session
|
||||
**/
|
||||
VsmResultExt read_eval_print(span_type input_span, bool eof);
|
||||
|
||||
/** evaluate expression @p expr
|
||||
* Require: must first start interactive/batch session
|
||||
**/
|
||||
VsmResult start_eval(obj<AExpression> expr);
|
||||
|
||||
/** borrow calling thread to run indefinitely,
|
||||
* until halt instruction
|
||||
|
|
@ -124,13 +158,16 @@ namespace xo {
|
|||
/** configuration **/
|
||||
VsmConfig config_;
|
||||
|
||||
/** allocator (likely collector) for
|
||||
* expressions and values
|
||||
**/
|
||||
box<AAllocator> mm_;
|
||||
|
||||
/** reader: text -> expression **/
|
||||
SchematikaReader reader_;
|
||||
|
||||
/** program counter **/
|
||||
VsmInstr pc_ = VsmInstr::halt();
|
||||
VsmInstr pc_ = VsmInstr::c_halt;
|
||||
|
||||
#ifdef NOT_YET
|
||||
/** stack pointer **/
|
||||
|
|
@ -141,10 +178,10 @@ namespace xo {
|
|||
obj<AExpression> expr_;
|
||||
|
||||
/** result register **/
|
||||
obj<AGCObject> value_;
|
||||
VsmResult value_;
|
||||
|
||||
/** continuation register **/
|
||||
VsmInstr cont_ = VsmInstr::halt();
|
||||
VsmInstr cont_ = VsmInstr::c_halt;
|
||||
};
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ namespace xo {
|
|||
|
||||
VsmConfig() = default;
|
||||
|
||||
/** true for interactive parser session; false for batch session **/
|
||||
bool interactive_flag_ = true;
|
||||
|
||||
/** reader configuration **/
|
||||
ReaderConfig rdr_config_;
|
||||
/** Configuration for allocator/collector.
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ namespace xo {
|
|||
public:
|
||||
explicit VsmInstr(vsm_opcode oc) : opcode_{oc} {}
|
||||
|
||||
static VsmInstr halt() { return VsmInstr{vsm_opcode::halt}; }
|
||||
static VsmInstr eval() { return VsmInstr{vsm_opcode::eval}; }
|
||||
static VsmInstr c_halt;
|
||||
static VsmInstr c_eval;
|
||||
|
||||
vsm_opcode opcode() const noexcept { return opcode_; }
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ set(SELF_LIB xo_interpreter2)
|
|||
set(SELF_SRCS
|
||||
init_interpreter2.cpp
|
||||
VirtualSchematikaMachine.cpp
|
||||
VsmInstr.cpp
|
||||
#IExpression_Any.cpp
|
||||
#interpreter2_register_facets.cpp
|
||||
)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace xo {
|
|||
using xo::print::ppconfig;
|
||||
using xo::print::ppstate_standalone;
|
||||
using xo::mm::AGCObject;
|
||||
using xo::mm::MemorySizeInfo;
|
||||
using xo::mm::DX1Collector;
|
||||
using xo::facet::FacetRegistry;
|
||||
using std::cout;
|
||||
|
|
@ -29,50 +30,84 @@ namespace xo {
|
|||
reader_{config.rdr_config_, mm_.to_op()}
|
||||
{}
|
||||
|
||||
VsmResult
|
||||
std::size_t
|
||||
VirtualSchematikaMachine::_n_store() const noexcept
|
||||
{
|
||||
// oops. need something that goes through AAllocator api
|
||||
|
||||
return reader_._n_store();
|
||||
}
|
||||
|
||||
MemorySizeInfo
|
||||
VirtualSchematikaMachine::_store_info(std::size_t i) const noexcept
|
||||
{
|
||||
// oops. need something poly that goes through AAllocator api
|
||||
|
||||
return reader_._store_info(i);
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::begin_interactive_session()
|
||||
{
|
||||
reader_.begin_interactive_session();
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::begin_batch_session()
|
||||
{
|
||||
reader_.begin_batch_session();
|
||||
}
|
||||
|
||||
VsmResultExt
|
||||
VirtualSchematikaMachine::read_eval_print(span_type input, bool eof)
|
||||
{
|
||||
if (input.empty()) {
|
||||
return VsmResult();
|
||||
return VsmResultExt();
|
||||
}
|
||||
|
||||
auto [expr, remaining, error1]
|
||||
= reader_.read_expr(input, eof);
|
||||
|
||||
if (!expr) {
|
||||
return {
|
||||
.remaining_input_ = remaining,
|
||||
.tk_error_ = error1
|
||||
};
|
||||
/* tokenizer error */
|
||||
|
||||
return VsmResultExt(VsmResult(error1), remaining);
|
||||
}
|
||||
|
||||
auto [value, error2] = this->eval(expr);
|
||||
VsmResult evalresult = this->start_eval(expr);
|
||||
|
||||
if (!value) {
|
||||
return {
|
||||
.remaining_input_ = remaining,
|
||||
.tk_error_ = error2
|
||||
};
|
||||
if (evalresult.is_eval_error() || evalresult.is_tk_error()) {
|
||||
return VsmResultExt(evalresult, remaining);
|
||||
}
|
||||
|
||||
assert(evalresult.is_value());
|
||||
|
||||
obj<AGCObject> * p_value = std::get_if<obj<AGCObject>>(&(evalresult.result_));
|
||||
|
||||
assert(p_value);
|
||||
|
||||
obj<APrintable> value_pr
|
||||
= FacetRegistry::instance().variant<APrintable,AGCObject>(value);
|
||||
= FacetRegistry::instance().variant<APrintable,AGCObject>(*p_value);
|
||||
|
||||
// pretty_toplevel(value_pr, &cout, ppconfig());
|
||||
ppconfig ppc;
|
||||
ppstate_standalone pps(&cout, 0, &ppc);
|
||||
pps.prettyn(value_pr);
|
||||
|
||||
return { .remaining_input_ = remaining };
|
||||
return VsmResultExt(VsmResult(*p_value), remaining);
|
||||
}
|
||||
|
||||
std::pair<obj<AGCObject>, TokenizerError>
|
||||
VirtualSchematikaMachine::eval(obj<AExpression> expr)
|
||||
VsmResult
|
||||
VirtualSchematikaMachine::start_eval(obj<AExpression> expr)
|
||||
{
|
||||
(void)expr;
|
||||
this->pc_ = VsmInstr::c_eval;
|
||||
this->expr_ = expr;
|
||||
this->value_ = obj<AGCObject>();
|
||||
this->cont_ = VsmInstr::c_halt;
|
||||
|
||||
assert(false);
|
||||
return std::make_pair(obj<AGCObject>(), TokenizerError());
|
||||
this->run();
|
||||
|
||||
return value_;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
18
src/interpreter2/VsmInstr.cpp
Normal file
18
src/interpreter2/VsmInstr.cpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/** @file VsmInstr.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Feb 2026
|
||||
**/
|
||||
|
||||
#include "VsmInstr.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
VsmInstr
|
||||
VsmInstr::c_halt = VsmInstr(vsm_opcode::halt);
|
||||
|
||||
VsmInstr
|
||||
VsmInstr::c_eval = VsmInstr(vsm_opcode::eval);
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end VsmInstr.cpp */
|
||||
|
|
@ -4,6 +4,8 @@
|
|||
**/
|
||||
|
||||
#include <xo/interpreter2/VirtualSchematikaMachine.hpp>
|
||||
#include <xo/object2/DFloat.hpp>
|
||||
#include <xo/object2/number/IGCObject_DFloat.hpp>
|
||||
|
||||
#ifdef NOT_YET
|
||||
#include <xo/reader2/SchematikaParser.hpp>
|
||||
|
|
@ -16,12 +18,18 @@
|
|||
#ifdef NOT_YET
|
||||
#include <xo/alloc2/arena/IAllocator_DArena.hpp>
|
||||
#endif
|
||||
#include <xo/indentlog/print/hex.hpp>
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::scm::VirtualSchematikaMachine;
|
||||
using xo::scm::VsmConfig;
|
||||
using xo::scm::VsmResultExt;
|
||||
using xo::scm::DFloat;
|
||||
using xo::mm::AGCObject;
|
||||
using span_type = xo::scm::VirtualSchematikaMachine::span_type;
|
||||
using Catch::Matchers::WithinAbs;
|
||||
|
||||
#ifdef NOT_YET
|
||||
using xo::scm::SchematikaParser;
|
||||
|
|
@ -39,27 +47,32 @@ namespace xo {
|
|||
using xo::mm::DArena;
|
||||
using xo::facet::with_facet;
|
||||
#endif
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
static InitEvidence s_init = (InitSubsys<S_interpreter2_tag>::require());
|
||||
|
||||
namespace ut {
|
||||
TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]")
|
||||
{
|
||||
VirtualSchematikaMachine vsm(VsmConfig);
|
||||
VsmConfig cfg;
|
||||
VirtualSchematikaMachine vsm(cfg);
|
||||
|
||||
#ifdef NOT_YET
|
||||
ArenaConfig config;
|
||||
config.name_ = "test-arena";
|
||||
config.size_ = 16 * 1024;
|
||||
bool eof_flag = false;
|
||||
|
||||
DArena expr_arena = DArena::map(config);
|
||||
obj<AAllocator> expr_alloc = with_facet<AAllocator>::mkobj(&expr_arena);
|
||||
vsm.begin_interactive_session();
|
||||
VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("3.141592635;"), eof_flag);
|
||||
|
||||
SchematikaParser parser(config, 4096, expr_alloc, false /*debug_flag*/);
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
||||
REQUIRE(parser.debug_flag() == false);
|
||||
REQUIRE(parser.is_at_toplevel() == true);
|
||||
#endif
|
||||
auto x = obj<AGCObject,DFloat>::from(*res.value());
|
||||
|
||||
REQUIRE(x);
|
||||
REQUIRE_THAT(x.data()->value(), WithinAbs(3.141592635, 1e-6));
|
||||
|
||||
REQUIRE(res.remaining_.size() == 1);
|
||||
REQUIRE(*res.remaining_.lo() == '\n');
|
||||
}
|
||||
|
||||
} /*namespace ut*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue