xo-interpreter2 stack: VSM as AGCObject for virtual root
This commit is contained in:
parent
364f34cc8a
commit
92bea14aa0
15 changed files with 679 additions and 412 deletions
|
|
@ -26,11 +26,19 @@ add_subdirectory(utest)
|
|||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# only supporting forward_children(), for virtual root.
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-interpreter2-facetimpl-gcobject-virtualschematikamachine
|
||||
FACET_PKG xo_alloc2
|
||||
INPUT idl/IGCObject_DVirtualSchematikaMachine.json5
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
# note: manual target; generated code committed to git
|
||||
xo_add_genfacetimpl(
|
||||
TARGET xo-interpreter2-facetimpl-gcobject-vsmdefcontframe
|
||||
FACET_PKG xo_alloc2
|
||||
# REPR VsmDefContFrame
|
||||
INPUT idl/IGCObject_DVsmDefContFrame.json5
|
||||
)
|
||||
|
||||
|
|
@ -38,7 +46,6 @@ xo_add_genfacetimpl(
|
|||
xo_add_genfacetimpl(
|
||||
TARGET xo-interpreter2-facetimpl-printable-vsmdefcontframe
|
||||
FACET_PKG xo_printable2
|
||||
# REPR VsmDefContFrame
|
||||
INPUT idl/IPrintable_DVsmDefContFrame.json5
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
mode: "implementation",
|
||||
output_cpp_dir: "src/interpreter2",
|
||||
output_cpp_dir: "src/interpreter2/facet",
|
||||
output_hpp_dir: "include/xo/interpreter2",
|
||||
output_impl_subdir: "env",
|
||||
includes: [
|
||||
|
|
|
|||
18
idl/IGCObject_DVirtualSchematikaMachine.json5
Normal file
18
idl/IGCObject_DVirtualSchematikaMachine.json5
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
mode: "implementation",
|
||||
output_cpp_dir: "src/interpreter2/facet",
|
||||
output_hpp_dir: "include/xo/interpreter2",
|
||||
output_impl_subdir: "vsm",
|
||||
includes: [
|
||||
"<xo/alloc2/GCObject.hpp>",
|
||||
"<xo/alloc2/Allocator.hpp>"
|
||||
],
|
||||
local_types: [ ],
|
||||
namespace1: "xo",
|
||||
namespace2: "scm",
|
||||
facet_idl: "idl/GCObject.json5",
|
||||
brief: "provide AGCObject interface for DVirtualSchematikaMachine",
|
||||
using_doxygen: true,
|
||||
repr: "DVirtualSchematikaMachine",
|
||||
doc: [ "implement AGCObject for DVirtualSchematikaMachine" ],
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
namespace xo {
|
||||
namespace scm {
|
||||
// see xo-interpreter/ VirtualSchematikaMachine.hpp
|
||||
class VirtualSchematikaMachine;
|
||||
class DVirtualSchematikaMachine;
|
||||
|
||||
/** @brief Runtime context for schematika interpreter
|
||||
*
|
||||
|
|
@ -26,7 +26,7 @@ namespace xo {
|
|||
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||
|
||||
public:
|
||||
DVsmRcx(VirtualSchematikaMachine * vsm);
|
||||
DVsmRcx(DVirtualSchematikaMachine * vsm);
|
||||
|
||||
obj<AAllocator> allocator() const noexcept;
|
||||
obj<ACollector> collector() const noexcept;
|
||||
|
|
@ -36,7 +36,7 @@ namespace xo {
|
|||
|
||||
private:
|
||||
/** schematika interpreter **/
|
||||
VirtualSchematikaMachine * vsm_ = nullptr;;
|
||||
DVirtualSchematikaMachine * vsm_ = nullptr;;
|
||||
};
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -1,321 +1,11 @@
|
|||
/** @file VirtualSchematikaMachine.hpp
|
||||
*
|
||||
* @author Roland Conybare, Jan 2026
|
||||
* @author Roland Conybeare, Mar 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "VsmConfig.hpp"
|
||||
#include "VsmInstr.hpp"
|
||||
#include "VsmFrame.hpp"
|
||||
#include "LocalEnv.hpp"
|
||||
#include "GlobalEnv.hpp"
|
||||
#include <xo/object2/RuntimeError.hpp>
|
||||
#include <xo/object2/Array.hpp>
|
||||
#include <xo/reader2/SchematikaReader.hpp>
|
||||
#include <xo/expression2/Expression.hpp>
|
||||
#include <xo/alloc2/GCObject.hpp>
|
||||
#include <xo/alloc2/abox.hpp>
|
||||
#include <variant>
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
#ifdef OBSOLETE // see DVsmError
|
||||
// TODO: move error to collected space?
|
||||
// or special arena?
|
||||
//
|
||||
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
|
||||
};
|
||||
#endif
|
||||
|
||||
/** similar to @ref xo::scm::ReaderResult **/
|
||||
struct VsmResult {
|
||||
using AGCObject = xo::mm::AGCObject;
|
||||
using span_type = xo::mm::span<const char>;
|
||||
|
||||
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;
|
||||
|
||||
const obj<AGCObject> * value() const { return std::get_if<obj<AGCObject>>(&result_); }
|
||||
obj<AGCObject> & value_ref() { return std::get<obj<AGCObject>>(result_); }
|
||||
|
||||
/** result of evaluating first expression encountered in input **/
|
||||
std::variant<obj<AGCObject>, TokenizerError> result_;
|
||||
};
|
||||
|
||||
/** vsm result + reamining span **/
|
||||
struct VsmResultExt : public VsmResult {
|
||||
using span_type = VsmResult::span_type;
|
||||
|
||||
VsmResultExt() = default;
|
||||
VsmResultExt(const VsmResult & result, span_type rem) : VsmResult{result}, remaining_{rem} {}
|
||||
|
||||
/** unconsumed portion of input **/
|
||||
VsmResult::span_type remaining_;
|
||||
};
|
||||
|
||||
/** @class VirtualSchematikaMachine
|
||||
* @brief virtual machine for schematika
|
||||
**/
|
||||
class VirtualSchematikaMachine {
|
||||
public:
|
||||
// will be DArenaVector<obj<StackFrame>> probably
|
||||
using Stack = void *;
|
||||
using ACollector = xo::mm::ACollector;
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
using AGCObject = xo::mm::AGCObject;
|
||||
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||
using span_type = xo::mm::span<const char>;
|
||||
|
||||
public:
|
||||
/** @p config. configuration
|
||||
* @p aux_mm. Allocator for miscellaneous dataN
|
||||
* owned by this VSM.
|
||||
**/
|
||||
VirtualSchematikaMachine(const VsmConfig & config,
|
||||
obj<AAllocator> aux_mm);
|
||||
|
||||
/** non-trivial dtor because of @ref reader_
|
||||
* indirect dependency on DGlobalSymtab
|
||||
**/
|
||||
~VirtualSchematikaMachine() = default;
|
||||
|
||||
/** allocator for schematika data **/
|
||||
obj<AAllocator> allocator() const noexcept;
|
||||
/** allocator for runtime errors **/
|
||||
obj<AAllocator> error_allocator() const noexcept;
|
||||
/** global unique-string table **/
|
||||
StringTable * stringtable() noexcept;
|
||||
|
||||
/** true iff parser is at top-level -> does not contain
|
||||
* state for a incomplete/partial expression
|
||||
**/
|
||||
bool is_at_toplevel() const noexcept;
|
||||
|
||||
/** visit vsm-owned memory pools; call visitor(info) for each **/
|
||||
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||
|
||||
/** 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
|
||||
**/
|
||||
void run();
|
||||
|
||||
/** execute vsm instruction in @ref pc_.
|
||||
* @retval instruction count. 1 unless pc_ is halt.
|
||||
**/
|
||||
bool execute_one();
|
||||
|
||||
/** @defgroup scm-virtualschematikamachine-gcobject-facet gcobject facet **/
|
||||
///@{
|
||||
|
||||
/** object size **/
|
||||
std::size_t shallow_size() const noexcept;
|
||||
|
||||
/** forward gc-aware child pointers
|
||||
**/
|
||||
std::size_t forward_children(obj<ACollector> gc) noexcept;
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
/** Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_op();
|
||||
|
||||
/** evaluate a constant expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_constant_op();
|
||||
|
||||
/** evaluate a define-expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_define_op();
|
||||
|
||||
/** evaluate a lambda expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_lambda_op();
|
||||
|
||||
/** evaluate variable expression (definition)
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_variable_op();
|
||||
|
||||
/** evaluate a variable reference (use after definition)
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_varref_op();
|
||||
|
||||
/** evaluate an apply expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_apply_op();
|
||||
|
||||
/** evaluate an if-else expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_if_else_op();
|
||||
|
||||
/** evaluate a sequence expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_sequence_op();
|
||||
|
||||
/** apply a function to evaluated arguments **/
|
||||
void _do_apply_op();
|
||||
|
||||
/** evaluate arguments on behalf of a function call
|
||||
* Require:
|
||||
* - expression value in @ref value_
|
||||
* - stack:
|
||||
* [0] VsmEvalArgsFrame
|
||||
* [1] VsmApplyFrame
|
||||
* ...
|
||||
**/
|
||||
void _do_evalargs_op();
|
||||
|
||||
/** call closure @ref fn_ with arguments @ref args_ **/
|
||||
void _do_call_closure_op();
|
||||
/** call primitive @ref fn_ with arguments @ref args_ **/
|
||||
void _do_call_primitive_op();
|
||||
|
||||
/** perform assignment after evaluating
|
||||
* the rhs of a define-expr
|
||||
**/
|
||||
void _do_def_cont_op();
|
||||
|
||||
/** restore registers from stack frame
|
||||
* (specifically: local_env_, stack_, cont_)
|
||||
* after invoking a schematika closure
|
||||
**/
|
||||
void _do_apply_cont_op();
|
||||
|
||||
/** proceed with if- or else- branch of an if-else expression
|
||||
* after evaluating test condition
|
||||
**/
|
||||
void _do_ifelse_cont_op();
|
||||
|
||||
/** loop continuation after evaluating element of a SequenceExpr **/
|
||||
void _do_seq_cont_op();
|
||||
|
||||
private:
|
||||
/*
|
||||
* Some registers are preserved by evaluation:
|
||||
* stack_
|
||||
* cont_
|
||||
* local_env_
|
||||
*
|
||||
* Other registers not preserved
|
||||
* pc_
|
||||
* expr_
|
||||
* fn_
|
||||
* args_
|
||||
* value_
|
||||
*/
|
||||
|
||||
/** configuration **/
|
||||
VsmConfig config_;
|
||||
|
||||
/** allocator (likely DArena) for globals.
|
||||
* For example DArenaHashMap in global symta.
|
||||
**/
|
||||
obj<AAllocator> aux_mm_;
|
||||
|
||||
/** allocator (likely DX1Collector or similar) for
|
||||
* expressions and values. Schemaatika reader will use this also
|
||||
**/
|
||||
abox<AAllocator> mm_;
|
||||
|
||||
/** Sidecar allocator for error reporting.
|
||||
* Separate to mitigate interference with @ref mm_
|
||||
* (separate memory so we can for example report
|
||||
* an out-of-memory error).
|
||||
* Likely DArena or similar
|
||||
**/
|
||||
abox<AAllocator> error_mm_;
|
||||
|
||||
/** runtime context for this vsm.
|
||||
* For example, provides allocator to primitives
|
||||
**/
|
||||
abox<ARuntimeContext> rcx_;
|
||||
|
||||
// consider separate allocator (which _may_ turn out to be the same)
|
||||
// for VM stack. Only works for code that doesn't rely on fancy
|
||||
// lexical scoping
|
||||
|
||||
// consider separate allocator for reader (i.e. program code)
|
||||
// and data (program execution)
|
||||
|
||||
/** reader: text -> expression **/
|
||||
SchematikaReader reader_;
|
||||
|
||||
/** program counter **/
|
||||
VsmInstr pc_ = VsmInstr::c_halt;
|
||||
|
||||
/** stack pointer **/
|
||||
obj<AGCObject> stack_;
|
||||
|
||||
/** expression register **/
|
||||
obj<AExpression> expr_;
|
||||
|
||||
/** environment pointer. Maintains bindings
|
||||
* for global variables. Obtained from reader
|
||||
**/
|
||||
obj<AGCObject,DGlobalEnv> global_env_;
|
||||
|
||||
/** environment pointer. Provides bindings
|
||||
* for surrounding lexical scope at this point
|
||||
* in execution
|
||||
**/
|
||||
obj<AGCObject,DLocalEnv> local_env_;
|
||||
|
||||
/** evaluated function to call **/
|
||||
obj<AGCObject> fn_;
|
||||
/** evaluated argument list **/
|
||||
obj<AGCObject,DArray> args_;
|
||||
|
||||
/** result register **/
|
||||
VsmResult value_;
|
||||
|
||||
/** continuation register **/
|
||||
VsmInstr cont_ = VsmInstr::c_halt;
|
||||
};
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
#include "vsm/DVirtualSchematikaMachine.hpp"
|
||||
#include "vsm/IGCObject_DVirtualSchematikaMachine.hpp"
|
||||
|
||||
/* end VirtualSchematikaMachine.hpp */
|
||||
|
|
|
|||
340
include/xo/interpreter2/vsm/DVirtualSchematikaMachine.hpp
Normal file
340
include/xo/interpreter2/vsm/DVirtualSchematikaMachine.hpp
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/** @file VirtualSchematikaMachine.hpp
|
||||
*
|
||||
* @author Roland Conybare, Jan 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "VsmConfig.hpp"
|
||||
#include "VsmInstr.hpp"
|
||||
#include "VsmFrame.hpp"
|
||||
#include "LocalEnv.hpp"
|
||||
#include "GlobalEnv.hpp"
|
||||
#include <xo/object2/RuntimeError.hpp>
|
||||
#include <xo/object2/Array.hpp>
|
||||
#include <xo/reader2/SchematikaReader.hpp>
|
||||
#include <xo/expression2/Expression.hpp>
|
||||
#include <xo/alloc2/GCObject.hpp>
|
||||
#include <xo/alloc2/abox.hpp>
|
||||
#include <variant>
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
#ifdef OBSOLETE // see DVsmError
|
||||
// TODO: move error to collected space?
|
||||
// or special arena?
|
||||
//
|
||||
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
|
||||
};
|
||||
#endif
|
||||
|
||||
/** similar to @ref xo::scm::ReaderResult **/
|
||||
struct VsmResult {
|
||||
using AGCObject = xo::mm::AGCObject;
|
||||
using span_type = xo::mm::span<const char>;
|
||||
|
||||
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;
|
||||
|
||||
const obj<AGCObject> * value() const { return std::get_if<obj<AGCObject>>(&result_); }
|
||||
obj<AGCObject> & value_ref() { return std::get<obj<AGCObject>>(result_); }
|
||||
|
||||
/** result of evaluating first expression encountered in input **/
|
||||
std::variant<obj<AGCObject>, TokenizerError> result_;
|
||||
};
|
||||
|
||||
/** vsm result + reamining span **/
|
||||
struct VsmResultExt : public VsmResult {
|
||||
using span_type = VsmResult::span_type;
|
||||
|
||||
VsmResultExt() = default;
|
||||
VsmResultExt(const VsmResult & result, span_type rem) : VsmResult{result}, remaining_{rem} {}
|
||||
|
||||
/** unconsumed portion of input **/
|
||||
VsmResult::span_type remaining_;
|
||||
};
|
||||
|
||||
/** @class VirtualSchematikaMachine
|
||||
* @brief virtual machine for schematika
|
||||
**/
|
||||
class DVirtualSchematikaMachine {
|
||||
public:
|
||||
// will be DArenaVector<obj<StackFrame>> probably
|
||||
using Stack = void *;
|
||||
using ACollector = xo::mm::ACollector;
|
||||
using AAllocator = xo::mm::AAllocator;
|
||||
using AGCObject = xo::mm::AGCObject;
|
||||
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||
using span_type = xo::mm::span<const char>;
|
||||
|
||||
public:
|
||||
/** @p config. configuration
|
||||
* @p aux_mm. Allocator for miscellaneous dataN
|
||||
* owned by this VSM.
|
||||
**/
|
||||
DVirtualSchematikaMachine(const VsmConfig & config,
|
||||
obj<AAllocator> aux_mm);
|
||||
|
||||
/** non-trivial dtor because of @ref reader_
|
||||
* indirect dependency on DGlobalSymtab
|
||||
**/
|
||||
~DVirtualSchematikaMachine() = default;
|
||||
|
||||
/** create instance using memory from @p mm.
|
||||
* with configuration @p config.
|
||||
* Machine will use @p aux_mm for auxiliary (non-GC, non-arena)
|
||||
* memory.
|
||||
**/
|
||||
static DVirtualSchematikaMachine * _make(obj<AAllocator> mm,
|
||||
const VsmConfig & config,
|
||||
obj<AAllocator> aux_mm);
|
||||
|
||||
/** like _make(), but create fop **/
|
||||
static obj<AGCObject,DVirtualSchematikaMachine> make(obj<AAllocator> mm,
|
||||
const VsmConfig & config,
|
||||
obj<AAllocator> aux_mm);
|
||||
|
||||
/** allocator for schematika data **/
|
||||
obj<AAllocator> allocator() const noexcept;
|
||||
/** allocator for runtime errors **/
|
||||
obj<AAllocator> error_allocator() const noexcept;
|
||||
/** global unique-string table **/
|
||||
StringTable * stringtable() noexcept;
|
||||
|
||||
/** true iff parser is at top-level -> does not contain
|
||||
* state for a incomplete/partial expression
|
||||
**/
|
||||
bool is_at_toplevel() const noexcept;
|
||||
|
||||
/** visit vsm-owned memory pools; call visitor(info) for each **/
|
||||
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||
|
||||
/** 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
|
||||
**/
|
||||
void run();
|
||||
|
||||
/** execute vsm instruction in @ref pc_.
|
||||
* @retval instruction count. 1 unless pc_ is halt.
|
||||
**/
|
||||
bool execute_one();
|
||||
|
||||
/** @defgroup scm-virtualschematikamachine-gcobject-facet gcobject facet **/
|
||||
///@{
|
||||
|
||||
/** object size. Not implemented. Only intending to support VSM as virtual root **/
|
||||
std::size_t shallow_size() const noexcept;
|
||||
|
||||
/** shallow copy during gc cycle. Not implemented! Only intending to support
|
||||
* VSM as virtual root
|
||||
**/
|
||||
DVirtualSchematikaMachine * shallow_copy(obj<AAllocator> mm) const noexcept;
|
||||
|
||||
/** forward gc-aware child pointers
|
||||
**/
|
||||
std::size_t forward_children(obj<ACollector> gc) noexcept;
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
/** Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_op();
|
||||
|
||||
/** evaluate a constant expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_constant_op();
|
||||
|
||||
/** evaluate a define-expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_define_op();
|
||||
|
||||
/** evaluate a lambda expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_lambda_op();
|
||||
|
||||
/** evaluate variable expression (definition)
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_variable_op();
|
||||
|
||||
/** evaluate a variable reference (use after definition)
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_varref_op();
|
||||
|
||||
/** evaluate an apply expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_apply_op();
|
||||
|
||||
/** evaluate an if-else expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_if_else_op();
|
||||
|
||||
/** evaluate a sequence expression
|
||||
* Require:
|
||||
* - expression in @ref expr_
|
||||
**/
|
||||
void _do_eval_sequence_op();
|
||||
|
||||
/** apply a function to evaluated arguments **/
|
||||
void _do_apply_op();
|
||||
|
||||
/** evaluate arguments on behalf of a function call
|
||||
* Require:
|
||||
* - expression value in @ref value_
|
||||
* - stack:
|
||||
* [0] VsmEvalArgsFrame
|
||||
* [1] VsmApplyFrame
|
||||
* ...
|
||||
**/
|
||||
void _do_evalargs_op();
|
||||
|
||||
/** call closure @ref fn_ with arguments @ref args_ **/
|
||||
void _do_call_closure_op();
|
||||
/** call primitive @ref fn_ with arguments @ref args_ **/
|
||||
void _do_call_primitive_op();
|
||||
|
||||
/** perform assignment after evaluating
|
||||
* the rhs of a define-expr
|
||||
**/
|
||||
void _do_def_cont_op();
|
||||
|
||||
/** restore registers from stack frame
|
||||
* (specifically: local_env_, stack_, cont_)
|
||||
* after invoking a schematika closure
|
||||
**/
|
||||
void _do_apply_cont_op();
|
||||
|
||||
/** proceed with if- or else- branch of an if-else expression
|
||||
* after evaluating test condition
|
||||
**/
|
||||
void _do_ifelse_cont_op();
|
||||
|
||||
/** loop continuation after evaluating element of a SequenceExpr **/
|
||||
void _do_seq_cont_op();
|
||||
|
||||
private:
|
||||
/*
|
||||
* Some registers are preserved by evaluation:
|
||||
* stack_
|
||||
* cont_
|
||||
* local_env_
|
||||
*
|
||||
* Other registers not preserved
|
||||
* pc_
|
||||
* expr_
|
||||
* fn_
|
||||
* args_
|
||||
* value_
|
||||
*/
|
||||
|
||||
/** configuration **/
|
||||
VsmConfig config_;
|
||||
|
||||
/** allocator (likely DArena) for globals.
|
||||
* For example DArenaHashMap in global symta.
|
||||
**/
|
||||
obj<AAllocator> aux_mm_;
|
||||
|
||||
/** allocator (likely DX1Collector or similar) for
|
||||
* expressions and values. Schemaatika reader will use this also
|
||||
**/
|
||||
abox<AAllocator> mm_;
|
||||
|
||||
/** Sidecar allocator for error reporting.
|
||||
* Separate to mitigate interference with @ref mm_
|
||||
* (separate memory so we can for example report
|
||||
* an out-of-memory error).
|
||||
* Likely DArena or similar
|
||||
**/
|
||||
abox<AAllocator> error_mm_;
|
||||
|
||||
/** runtime context for this vsm.
|
||||
* For example, provides allocator to primitives
|
||||
**/
|
||||
abox<ARuntimeContext> rcx_;
|
||||
|
||||
// consider separate allocator (which _may_ turn out to be the same)
|
||||
// for VM stack. Only works for code that doesn't rely on fancy
|
||||
// lexical scoping
|
||||
|
||||
// consider separate allocator for reader (i.e. program code)
|
||||
// and data (program execution)
|
||||
|
||||
/** reader: text -> expression **/
|
||||
SchematikaReader reader_;
|
||||
|
||||
/** program counter **/
|
||||
VsmInstr pc_ = VsmInstr::c_halt;
|
||||
|
||||
/** stack pointer **/
|
||||
obj<AGCObject> stack_;
|
||||
|
||||
/** expression register **/
|
||||
obj<AExpression> expr_;
|
||||
|
||||
/** environment pointer. Maintains bindings
|
||||
* for global variables. Obtained from reader
|
||||
**/
|
||||
obj<AGCObject,DGlobalEnv> global_env_;
|
||||
|
||||
/** environment pointer. Provides bindings
|
||||
* for surrounding lexical scope at this point
|
||||
* in execution
|
||||
**/
|
||||
obj<AGCObject,DLocalEnv> local_env_;
|
||||
|
||||
/** evaluated function to call **/
|
||||
obj<AGCObject> fn_;
|
||||
/** evaluated argument list **/
|
||||
obj<AGCObject,DArray> args_;
|
||||
|
||||
/** result register **/
|
||||
VsmResult value_;
|
||||
|
||||
/** continuation register **/
|
||||
VsmInstr cont_ = VsmInstr::c_halt;
|
||||
};
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DVirtualSchematikaMachine.hpp */
|
||||
67
include/xo/interpreter2/vsm/IGCObject_DLocalEnv.hpp
Normal file
67
include/xo/interpreter2/vsm/IGCObject_DLocalEnv.hpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/** @file IGCObject_DLocalEnv.hpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IGCObject_DVirtualSchematikaMachine.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_repr.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IGCObject_DVirtualSchematikaMachine.json5]
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GCObject.hpp"
|
||||
#include <xo/alloc2/GCObject.hpp>
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include "DLocalEnv.hpp"
|
||||
|
||||
namespace xo { namespace scm { class IGCObject_DLocalEnv; } }
|
||||
|
||||
namespace xo {
|
||||
namespace facet {
|
||||
template <>
|
||||
struct FacetImplementation<xo::mm::AGCObject,
|
||||
xo::scm::DLocalEnv>
|
||||
{
|
||||
using ImplType = xo::mm::IGCObject_Xfer
|
||||
<xo::scm::DLocalEnv,
|
||||
xo::scm::IGCObject_DLocalEnv>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** @class IGCObject_DLocalEnv
|
||||
**/
|
||||
class IGCObject_DLocalEnv {
|
||||
public:
|
||||
/** @defgroup scm-gcobject-dlocalenv-type-traits **/
|
||||
///@{
|
||||
using size_type = xo::mm::AGCObject::size_type;
|
||||
using AAllocator = xo::mm::AGCObject::AAllocator;
|
||||
using ACollector = xo::mm::AGCObject::ACollector;
|
||||
using Copaque = xo::mm::AGCObject::Copaque;
|
||||
using Opaque = xo::mm::AGCObject::Opaque;
|
||||
///@}
|
||||
/** @defgroup scm-gcobject-dlocalenv-methods **/
|
||||
///@{
|
||||
// const methods
|
||||
/** memory consumption for this instance **/
|
||||
static size_type shallow_size(const DLocalEnv & self) noexcept;
|
||||
/** copy instance using allocator **/
|
||||
static Opaque shallow_copy(const DLocalEnv & self, obj<AAllocator> mm) noexcept;
|
||||
|
||||
// non-const methods
|
||||
/** during GC: forward immdiate children **/
|
||||
static size_type forward_children(DLocalEnv & self, obj<ACollector> gc) noexcept;
|
||||
///@}
|
||||
};
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end */
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/** @file IGCObject_DVirtualSchematikaMachine.hpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IGCObject_DVirtualSchematikaMachine.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_repr.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IGCObject_DVirtualSchematikaMachine.json5]
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GCObject.hpp"
|
||||
#include <xo/alloc2/GCObject.hpp>
|
||||
#include <xo/alloc2/Allocator.hpp>
|
||||
#include "DVirtualSchematikaMachine.hpp"
|
||||
|
||||
namespace xo { namespace scm { class IGCObject_DVirtualSchematikaMachine; } }
|
||||
|
||||
namespace xo {
|
||||
namespace facet {
|
||||
template <>
|
||||
struct FacetImplementation<xo::mm::AGCObject,
|
||||
xo::scm::DVirtualSchematikaMachine>
|
||||
{
|
||||
using ImplType = xo::mm::IGCObject_Xfer
|
||||
<xo::scm::DVirtualSchematikaMachine,
|
||||
xo::scm::IGCObject_DVirtualSchematikaMachine>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
/** @class IGCObject_DVirtualSchematikaMachine
|
||||
**/
|
||||
class IGCObject_DVirtualSchematikaMachine {
|
||||
public:
|
||||
/** @defgroup scm-gcobject-dvirtualschematikamachine-type-traits **/
|
||||
///@{
|
||||
using size_type = xo::mm::AGCObject::size_type;
|
||||
using AAllocator = xo::mm::AGCObject::AAllocator;
|
||||
using ACollector = xo::mm::AGCObject::ACollector;
|
||||
using Copaque = xo::mm::AGCObject::Copaque;
|
||||
using Opaque = xo::mm::AGCObject::Opaque;
|
||||
///@}
|
||||
/** @defgroup scm-gcobject-dvirtualschematikamachine-methods **/
|
||||
///@{
|
||||
// const methods
|
||||
/** memory consumption for this instance **/
|
||||
static size_type shallow_size(const DVirtualSchematikaMachine & self) noexcept;
|
||||
/** copy instance using allocator **/
|
||||
static Opaque shallow_copy(const DVirtualSchematikaMachine & self, obj<AAllocator> mm) noexcept;
|
||||
|
||||
// non-const methods
|
||||
/** during GC: forward immdiate children **/
|
||||
static size_type forward_children(DVirtualSchematikaMachine & self, obj<ACollector> gc) noexcept;
|
||||
///@}
|
||||
};
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end */
|
||||
|
|
@ -5,9 +5,11 @@ set(SELF_SRCS
|
|||
init_interpreter2.cpp
|
||||
SetupInterpreter2.cpp
|
||||
|
||||
VirtualSchematikaMachine.cpp
|
||||
VsmPrimitives.cpp
|
||||
|
||||
DVirtualSchematikaMachine.cpp
|
||||
facet/IGCObject_DVirtualSchematikaMachine.cpp
|
||||
|
||||
DVsmDefContFrame.cpp
|
||||
IGCObject_DVsmDefContFrame.cpp
|
||||
IPrintable_DVsmDefContFrame.cpp
|
||||
|
|
@ -37,7 +39,7 @@ set(SELF_SRCS
|
|||
IPrintable_DClosure.cpp
|
||||
|
||||
DLocalEnv.cpp
|
||||
IGCObject_DLocalEnv.cpp
|
||||
facet/IGCObject_DLocalEnv.cpp
|
||||
IPrintable_DLocalEnv.cpp
|
||||
|
||||
DVsmRcx.cpp
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ namespace xo {
|
|||
// NOTE: using heap here for {DX1Collector, DArena, DVsmRcx} instances
|
||||
// (though DX1Collector allocations will be from explictly mmap'd memory)
|
||||
//
|
||||
VirtualSchematikaMachine::VirtualSchematikaMachine(const VsmConfig & config,
|
||||
DVirtualSchematikaMachine::DVirtualSchematikaMachine(const VsmConfig & config,
|
||||
obj<AAllocator> aux_mm)
|
||||
: config_{config},
|
||||
aux_mm_{aux_mm},
|
||||
|
|
@ -91,40 +91,51 @@ namespace xo {
|
|||
//this->_add_gc_roots();
|
||||
}
|
||||
|
||||
VirtualSchematikaMachine *
|
||||
VirtualSchematikaMachine::_make(obj<AAllocator> mm,
|
||||
DVirtualSchematikaMachine *
|
||||
DVirtualSchematikaMachine::_make(obj<AAllocator> mm,
|
||||
const VsmConfig & config,
|
||||
obj<AAllocator> aux_mm)
|
||||
{
|
||||
xxx;
|
||||
void * mem = mm.alloc_for<DVirtualSchematikaMachine>();
|
||||
|
||||
return new (mem) DVirtualSchematikaMachine(config, aux_mm);
|
||||
}
|
||||
|
||||
obj<AGCObject,DVirtualSchematikaMachine>
|
||||
DVirtualSchematikaMachine::make(obj<AAllocator> mm,
|
||||
const VsmConfig & config,
|
||||
obj<AAllocator> aux_mm)
|
||||
{
|
||||
return obj<AGCObject,DVirtualSchematikaMachine>(
|
||||
_make(mm, config, aux_mm));
|
||||
}
|
||||
|
||||
obj<AAllocator>
|
||||
VirtualSchematikaMachine::allocator() const noexcept
|
||||
DVirtualSchematikaMachine::allocator() const noexcept
|
||||
{
|
||||
return mm_.to_op();
|
||||
}
|
||||
|
||||
obj<AAllocator>
|
||||
VirtualSchematikaMachine::error_allocator() const noexcept
|
||||
DVirtualSchematikaMachine::error_allocator() const noexcept
|
||||
{
|
||||
return error_mm_.to_op();
|
||||
}
|
||||
|
||||
StringTable *
|
||||
VirtualSchematikaMachine::stringtable() noexcept
|
||||
DVirtualSchematikaMachine::stringtable() noexcept
|
||||
{
|
||||
return reader_.stringtable();
|
||||
}
|
||||
|
||||
bool
|
||||
VirtualSchematikaMachine::is_at_toplevel() const noexcept
|
||||
DVirtualSchematikaMachine::is_at_toplevel() const noexcept
|
||||
{
|
||||
return reader_.is_at_toplevel();
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const
|
||||
DVirtualSchematikaMachine::visit_pools(const MemorySizeVisitor & visitor) const
|
||||
{
|
||||
aux_mm_.visit_pools(visitor);
|
||||
mm_.visit_pools(visitor);
|
||||
|
|
@ -133,19 +144,19 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::begin_interactive_session()
|
||||
DVirtualSchematikaMachine::begin_interactive_session()
|
||||
{
|
||||
reader_.begin_interactive_session();
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::begin_batch_session()
|
||||
DVirtualSchematikaMachine::begin_batch_session()
|
||||
{
|
||||
reader_.begin_batch_session();
|
||||
}
|
||||
|
||||
VsmResultExt
|
||||
VirtualSchematikaMachine::read_eval_print(span_type input, bool eof)
|
||||
DVirtualSchematikaMachine::read_eval_print(span_type input, bool eof)
|
||||
{
|
||||
if (input.empty()) {
|
||||
return VsmResultExt();
|
||||
|
|
@ -188,7 +199,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
VsmResult
|
||||
VirtualSchematikaMachine::start_eval(obj<AExpression> expr)
|
||||
DVirtualSchematikaMachine::start_eval(obj<AExpression> expr)
|
||||
{
|
||||
this->pc_ = VsmInstr::c_eval;
|
||||
this->expr_ = expr;
|
||||
|
|
@ -201,14 +212,14 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::run()
|
||||
DVirtualSchematikaMachine::run()
|
||||
{
|
||||
while (this->execute_one())
|
||||
;
|
||||
}
|
||||
|
||||
bool
|
||||
VirtualSchematikaMachine::execute_one()
|
||||
DVirtualSchematikaMachine::execute_one()
|
||||
{
|
||||
scope log(XO_DEBUG(config_.debug_flag_));
|
||||
|
||||
|
|
@ -264,7 +275,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_op()
|
||||
DVirtualSchematikaMachine::_do_eval_op()
|
||||
{
|
||||
switch(expr_.extype()) {
|
||||
case exprtype::invalid:
|
||||
|
|
@ -298,7 +309,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_constant_op()
|
||||
DVirtualSchematikaMachine::_do_eval_constant_op()
|
||||
{
|
||||
auto expr
|
||||
= obj<AExpression,DConstant>::from(expr_);
|
||||
|
|
@ -310,7 +321,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_define_op()
|
||||
DVirtualSchematikaMachine::_do_eval_define_op()
|
||||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
|
|
@ -318,6 +329,11 @@ namespace xo {
|
|||
= obj<AExpression,DDefineExpr>::from(expr_);
|
||||
|
||||
if (local_env_) {
|
||||
// nested defines implemented by rewriting,
|
||||
// so this branch should be unreachable
|
||||
|
||||
assert(false);
|
||||
} else {
|
||||
// top-level define
|
||||
|
||||
// .stack_ --+
|
||||
|
|
@ -349,16 +365,11 @@ namespace xo {
|
|||
this->expr_ = def_expr->rhs();
|
||||
this->pc_ = VsmInstr::c_eval;
|
||||
this->cont_ = VsmInstr::c_def_cont;
|
||||
} else {
|
||||
// nested defines implemented by rewriting,
|
||||
// so this branch should be unreachable
|
||||
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_def_cont_op()
|
||||
DVirtualSchematikaMachine::_do_def_cont_op()
|
||||
{
|
||||
// see DVsmDefContFrame
|
||||
|
||||
|
|
@ -385,7 +396,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_lambda_op()
|
||||
DVirtualSchematikaMachine::_do_eval_lambda_op()
|
||||
{
|
||||
// assuming bump allocator
|
||||
//
|
||||
|
|
@ -430,14 +441,14 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_variable_op()
|
||||
DVirtualSchematikaMachine::_do_eval_variable_op()
|
||||
{
|
||||
// not implemented
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_varref_op()
|
||||
DVirtualSchematikaMachine::_do_eval_varref_op()
|
||||
{
|
||||
auto var = obj<AExpression,DVarRef>::from(expr_);
|
||||
|
||||
|
|
@ -477,7 +488,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_apply_op()
|
||||
DVirtualSchematikaMachine::_do_eval_apply_op()
|
||||
{
|
||||
// ApplyExpr in expr_ register
|
||||
|
||||
|
|
@ -527,7 +538,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_if_else_op()
|
||||
DVirtualSchematikaMachine::_do_eval_if_else_op()
|
||||
{
|
||||
// control:
|
||||
// self -> eval(test) -> ifelse_cont -> eval(when_true)
|
||||
|
|
@ -546,7 +557,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_eval_sequence_op()
|
||||
DVirtualSchematikaMachine::_do_eval_sequence_op()
|
||||
{
|
||||
// stack:
|
||||
//
|
||||
|
|
@ -587,7 +598,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_apply_op()
|
||||
DVirtualSchematikaMachine::_do_apply_op()
|
||||
{
|
||||
// rcx_ : runtime context
|
||||
// fn_ : function to call
|
||||
|
|
@ -607,7 +618,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_call_closure_op()
|
||||
DVirtualSchematikaMachine::_do_call_closure_op()
|
||||
{
|
||||
// We need to preserve registers while evaluating
|
||||
// lambda body
|
||||
|
|
@ -654,7 +665,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_call_primitive_op()
|
||||
DVirtualSchematikaMachine::_do_call_primitive_op()
|
||||
{
|
||||
auto fn = fn_.to_facet<AProcedure>();
|
||||
|
||||
|
|
@ -664,7 +675,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_evalargs_op()
|
||||
DVirtualSchematikaMachine::_do_evalargs_op()
|
||||
{
|
||||
scope log(XO_DEBUG(false));
|
||||
|
||||
|
|
@ -796,7 +807,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_apply_cont_op()
|
||||
DVirtualSchematikaMachine::_do_apply_cont_op()
|
||||
{
|
||||
// see DVsmApplyClosureFrame
|
||||
|
||||
|
|
@ -811,7 +822,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_ifelse_cont_op()
|
||||
DVirtualSchematikaMachine::_do_ifelse_cont_op()
|
||||
{
|
||||
// pre: result of evaluating test condition in value_ register
|
||||
|
||||
|
|
@ -856,7 +867,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
VirtualSchematikaMachine::_do_seq_cont_op()
|
||||
DVirtualSchematikaMachine::_do_seq_cont_op()
|
||||
{
|
||||
auto frame = obj<AGCObject,DVsmSeqContFrame>::from(stack_);
|
||||
|
||||
|
|
@ -891,13 +902,25 @@ namespace xo {
|
|||
}
|
||||
|
||||
std::size_t
|
||||
VirtualSchematikaMachine::shallow_size() const noexcept
|
||||
DVirtualSchematikaMachine::shallow_size() const noexcept
|
||||
{
|
||||
return sizeof(VirtualSchematikaMachine);
|
||||
return sizeof(DVirtualSchematikaMachine);
|
||||
}
|
||||
|
||||
DVirtualSchematikaMachine *
|
||||
DVirtualSchematikaMachine::shallow_copy(obj<AAllocator> mm) const noexcept
|
||||
{
|
||||
(void)mm;
|
||||
|
||||
/** not copyable (because SchematikaReader isn't) **/
|
||||
|
||||
assert(false);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
VirtualSchematikaMachine::forward_children(obj<ACollector> gc) noexcept
|
||||
DVirtualSchematikaMachine::forward_children(obj<ACollector> gc) noexcept
|
||||
{
|
||||
reader_.forward_children(gc);
|
||||
|
||||
|
|
@ -917,4 +940,4 @@ namespace xo {
|
|||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end VirtualSchematikaMachine.cpp */
|
||||
/* end DVirtualSchematikaMachine.cpp */
|
||||
|
|
@ -13,7 +13,7 @@ namespace xo {
|
|||
|
||||
namespace scm {
|
||||
|
||||
DVsmRcx::DVsmRcx(VirtualSchematikaMachine * vsm) : vsm_{vsm} {}
|
||||
DVsmRcx::DVsmRcx(DVirtualSchematikaMachine * vsm) : vsm_{vsm} {}
|
||||
|
||||
obj<AAllocator>
|
||||
DVsmRcx::allocator() const noexcept
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
/** @file IGCObject_DVirtualSchematikaMachine.cpp
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
* [xo-facet/codegen/genfacet]
|
||||
* arguments:
|
||||
* --input [idl/IGCObject_DVirtualSchematikaMachine.json5]
|
||||
* 2. jinja2 template for abstract facet .hpp file:
|
||||
* [iface_facet_any.hpp.j2]
|
||||
* 3. idl for facet methods
|
||||
* [idl/IGCObject_DVirtualSchematikaMachine.json5]
|
||||
**/
|
||||
|
||||
#include "vsm/IGCObject_DVirtualSchematikaMachine.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace scm {
|
||||
auto
|
||||
IGCObject_DVirtualSchematikaMachine::shallow_size(const DVirtualSchematikaMachine & self) noexcept -> size_type
|
||||
{
|
||||
return self.shallow_size();
|
||||
}
|
||||
|
||||
auto
|
||||
IGCObject_DVirtualSchematikaMachine::shallow_copy(const DVirtualSchematikaMachine & self, obj<AAllocator> mm) noexcept -> Opaque
|
||||
{
|
||||
return self.shallow_copy(mm);
|
||||
}
|
||||
|
||||
auto
|
||||
IGCObject_DVirtualSchematikaMachine::forward_children(DVirtualSchematikaMachine & self, obj<ACollector> gc) noexcept -> size_type
|
||||
{
|
||||
return self.forward_children(gc);
|
||||
}
|
||||
|
||||
} /*namespace scm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IGCObject_DVirtualSchematikaMachine.cpp */
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
#endif
|
||||
|
||||
namespace xo {
|
||||
using xo::scm::VirtualSchematikaMachine;
|
||||
using xo::scm::DVirtualSchematikaMachine;
|
||||
using xo::scm::VsmResultExt;
|
||||
using xo::mm::AAllocator;
|
||||
using xo::mm::ArenaConfig;
|
||||
|
|
@ -108,17 +108,17 @@ namespace xo {
|
|||
//using AAllocator = xo::mm::AAllocator;
|
||||
//using DX1Collector = xo::mm::DX1Collector;
|
||||
//using X1CollectorConfig = xo::mm::X1CollectorConfig;
|
||||
using AGCObject = xo::mm::AGCObject;
|
||||
//using DArena = xo::mm::DArena;
|
||||
//using ArenaConfig = xo::mm::ArenaConfig;
|
||||
using VsmConfig = xo::scm::VsmConfig;
|
||||
using Replxx = replxx::Replxx;
|
||||
using span_type = VirtualSchematikaMachine::span_type;
|
||||
using span_type = DVirtualSchematikaMachine::span_type;
|
||||
|
||||
App(const AppConfig & cfg = AppConfig())
|
||||
: repl_config_{cfg.repl_config_},
|
||||
app_arena_{cfg.app_arena_config_},
|
||||
vsm_config_{cfg.vsm_config_}
|
||||
//vsm_{cfg.vsm_config_, obj<AAllocator,DArena>(&app_arena_)}
|
||||
{
|
||||
this->interactive_ = isatty(STDIN_FILENO);
|
||||
|
||||
|
|
@ -136,6 +136,7 @@ namespace xo {
|
|||
void _start();
|
||||
void _repl();
|
||||
bool _read_eval_print(span_type * p_input, bool eof);
|
||||
void _stop();
|
||||
|
||||
private:
|
||||
InitEvidence init_evidence_ = 0;
|
||||
|
|
@ -151,7 +152,7 @@ namespace xo {
|
|||
DArena app_arena_;
|
||||
/** schematika virtual machine **/
|
||||
VsmConfig vsm_config_;
|
||||
std::unique_ptr<VirtualSchematikaMachine> vsm_;
|
||||
abox<AGCObject,DVirtualSchematikaMachine> vsm_;
|
||||
};
|
||||
|
||||
void
|
||||
|
|
@ -173,8 +174,9 @@ namespace xo {
|
|||
|
||||
Subsystem::initialize_all();
|
||||
|
||||
vsm_.reset(new VirtualSchematikaMachine(vsm_config_,
|
||||
obj<AAllocator,DArena>(&app_arena_)));
|
||||
vsm_.adopt(DVirtualSchematikaMachine::make(obj<AAllocator,DArena>(&app_arena_),
|
||||
vsm_config_,
|
||||
obj<AAllocator,DArena>(&app_arena_)));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -231,6 +233,12 @@ namespace xo {
|
|||
return !res.is_tk_error() && !res.is_eval_error();
|
||||
}
|
||||
|
||||
void
|
||||
App::_stop()
|
||||
{
|
||||
vsm_._drop();
|
||||
}
|
||||
|
||||
} /*namespace xo*/
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -14,13 +14,14 @@
|
|||
#include <xo/object2/RuntimeError.hpp>
|
||||
#include <xo/stringtable2/UniqueString.hpp>
|
||||
#include <xo/alloc2/Arena.hpp>
|
||||
#include <xo/alloc2/abox.hpp>
|
||||
#include <xo/facet/TypeRegistry.hpp>
|
||||
#include <xo/indentlog/print/hex.hpp>
|
||||
|
||||
#include <catch2/catch.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::scm::VirtualSchematikaMachine;
|
||||
using xo::scm::DVirtualSchematikaMachine;
|
||||
using xo::scm::VsmConfig;
|
||||
using xo::scm::VsmResultExt;
|
||||
using xo::scm::DClosure;
|
||||
|
|
@ -39,7 +40,7 @@ namespace xo {
|
|||
using xo::mm::ArenaConfig;
|
||||
using xo::facet::FacetRegistry;
|
||||
using xo::facet::TypeRegistry;
|
||||
using span_type = xo::scm::VirtualSchematikaMachine::span_type;
|
||||
using span_type = xo::scm::DVirtualSchematikaMachine::span_type;
|
||||
using Catch::Matchers::WithinAbs;
|
||||
|
||||
using std::cout;
|
||||
|
|
@ -63,9 +64,14 @@ namespace xo {
|
|||
explicit VsmFixture(const std::string & testname,
|
||||
bool debug_flag,
|
||||
const VsmConfig & cfg = VsmConfig())
|
||||
: aux_mm_{testname},
|
||||
vsm_{cfg.with_debug_flag(debug_flag), aux_mm_.to_op()}
|
||||
{}
|
||||
: aux_mm_{testname}
|
||||
{
|
||||
vsm_.adopt(DVirtualSchematikaMachine::make(aux_mm_.to_op(),
|
||||
cfg.with_debug_flag(debug_flag),
|
||||
aux_mm_.to_op()));
|
||||
}
|
||||
|
||||
~VsmFixture() {}
|
||||
|
||||
bool log_memory_layout(scope * p_log) {
|
||||
auto visitor = [p_log](const MemorySizeInfo & info) {
|
||||
|
|
@ -79,13 +85,13 @@ namespace xo {
|
|||
aux_mm_.arena_.visit_pools(visitor);
|
||||
TypeRegistry::instance().visit_pools(visitor);
|
||||
FacetRegistry::instance().visit_pools(visitor);
|
||||
vsm_.visit_pools(visitor);
|
||||
vsm_->visit_pools(visitor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ArenaShim aux_mm_;
|
||||
VirtualSchematikaMachine vsm_;
|
||||
abox<AGCObject,DVirtualSchematikaMachine> vsm_;
|
||||
};
|
||||
|
||||
TEST_CASE("VirtualSchematikaMachine-ctor", "[interpreter2][VSM]")
|
||||
|
|
@ -113,8 +119,8 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("3.141592635;"), eof_flag);
|
||||
vsm->begin_interactive_session();
|
||||
VsmResultExt res = vsm->read_eval_print(span_type::from_cstr("3.141592635;"), eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -143,8 +149,8 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("1011;"), eof_flag);
|
||||
vsm->begin_interactive_session();
|
||||
VsmResultExt res = vsm->read_eval_print(span_type::from_cstr("1011;"), eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -174,8 +180,8 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("3.14159265 * 0.5;"), eof_flag);
|
||||
vsm->begin_interactive_session();
|
||||
VsmResultExt res = vsm->read_eval_print(span_type::from_cstr("3.14159265 * 0.5;"), eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -205,8 +211,8 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
VsmResultExt res = vsm.read_eval_print(span_type::from_cstr("3.14159265 / 0.5;"), eof_flag);
|
||||
vsm->begin_interactive_session();
|
||||
VsmResultExt res = vsm->read_eval_print(span_type::from_cstr("3.14159265 / 0.5;"), eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -236,10 +242,10 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(span_type::from_cstr("123 == 123;"),
|
||||
eof_flag);
|
||||
= vsm->read_eval_print(span_type::from_cstr("123 == 123;"),
|
||||
eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -269,10 +275,10 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(span_type::from_cstr("if 123 == 123 then \"equal\" else \"notequal\";"),
|
||||
eof_flag);
|
||||
= vsm->read_eval_print(span_type::from_cstr("if 123 == 123 then \"equal\" else \"notequal\";"),
|
||||
eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -302,9 +308,9 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(span_type::from_cstr("lambda (x : i64) -> i64 { x * x; }"),
|
||||
= vsm->read_eval_print(span_type::from_cstr("lambda (x : i64) -> i64 { x * x; }"),
|
||||
eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
|
|
@ -335,9 +341,9 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(span_type::from_cstr
|
||||
= vsm->read_eval_print(span_type::from_cstr
|
||||
("(lambda (x : i64, y : i64) { x * y; })(13, 15);"),
|
||||
eof_flag);
|
||||
|
||||
|
|
@ -374,9 +380,9 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(span_type::from_cstr("def foo = 3.14159;"),
|
||||
= vsm->read_eval_print(span_type::from_cstr("def foo = 3.14159;"),
|
||||
eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
|
|
@ -413,7 +419,7 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("def foo = 3.14159; foo;");
|
||||
|
||||
|
|
@ -421,7 +427,7 @@ namespace xo {
|
|||
log && log(xtag("input", input));
|
||||
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(input, eof_flag);
|
||||
= vsm->read_eval_print(input, eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -464,7 +470,7 @@ namespace xo {
|
|||
|
||||
bool eof_flag = true;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("def fact = lambda (n) { if (n == 0) then 1 else n * fact(n - 1) };");
|
||||
|
||||
|
|
@ -472,7 +478,7 @@ namespace xo {
|
|||
log && log(xtag("input", input));
|
||||
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(input, eof_flag);
|
||||
= vsm->read_eval_print(input, eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -506,7 +512,7 @@ namespace xo {
|
|||
|
||||
bool eof_flag = true;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("def n = 4; if (n == 4) then n * 3 else n * 5;");
|
||||
|
||||
|
|
@ -514,7 +520,7 @@ namespace xo {
|
|||
log && log(xtag("input", input));
|
||||
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(input, eof_flag);
|
||||
= vsm->read_eval_print(input, eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -553,7 +559,7 @@ namespace xo {
|
|||
|
||||
bool eof_flag = true;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("def fact = lambda (n) { if (n == 0) then 1 else n * fact(n - 1) }; fact(4);");
|
||||
|
||||
|
|
@ -561,7 +567,7 @@ namespace xo {
|
|||
log && log(xtag("input", input));
|
||||
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(input, eof_flag);
|
||||
= vsm->read_eval_print(input, eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -601,14 +607,14 @@ namespace xo {
|
|||
|
||||
bool eof_flag = false;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("#q{ 4.5 };");
|
||||
|
||||
log && log(xtag("input", input));
|
||||
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(input, eof_flag);
|
||||
= vsm->read_eval_print(input, eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -639,14 +645,14 @@ namespace xo {
|
|||
|
||||
bool eof_flag = true;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("#q{ (4.5 7.2) };");
|
||||
|
||||
log && log(xtag("input", input));
|
||||
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(input, eof_flag);
|
||||
= vsm->read_eval_print(input, eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -683,14 +689,14 @@ namespace xo {
|
|||
|
||||
bool eof_flag = true;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("#q{ [4.5 7.2] };");
|
||||
|
||||
log && log(xtag("input", input));
|
||||
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(input, eof_flag);
|
||||
= vsm->read_eval_print(input, eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
@ -727,14 +733,14 @@ namespace xo {
|
|||
|
||||
bool eof_flag = true;
|
||||
|
||||
vsm.begin_interactive_session();
|
||||
vsm->begin_interactive_session();
|
||||
|
||||
span_type input = span_type::from_cstr("report-memory-use();");
|
||||
|
||||
log && log(xtag("input", input));
|
||||
|
||||
VsmResultExt res
|
||||
= vsm.read_eval_print(input, eof_flag);
|
||||
= vsm->read_eval_print(input, eof_flag);
|
||||
|
||||
REQUIRE(res.is_value());
|
||||
REQUIRE(res.value());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue