diff --git a/CMakeLists.txt b/CMakeLists.txt index aa9c09e6..ac944a36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,14 +20,9 @@ add_definitions(${PROJECT_CXX_FLAGS}) # ---------------------------------------------------------------- # output targets +add_subdirectory(src/interpreter2) #add_subdirectory(utest) -# ---------------------------------------------------------------- -# header-only library - -set(SELF_LIB xo_interpreter2) -xo_add_headeronly_library(${SELF_LIB}) -xo_install_library4(${SELF_LIB} ${PROJECT_NAME}Targets) xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) # ---------------------------------------------------------------- diff --git a/cmake/xo_interpreter2Config.cmake.in b/cmake/xo_interpreter2Config.cmake.in index b5c3cd5c..bea8e9cc 100644 --- a/cmake/xo_interpreter2Config.cmake.in +++ b/cmake/xo_interpreter2Config.cmake.in @@ -6,7 +6,8 @@ include(CMakeFindDependencyMacro) # must coordinate with xo_dependency() calls # in CMakeLists.txt # -#find_dependency(xo_flatstring) +find_dependency(xo_expression2) +find_dependency(xo_gc) include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") check_required_components("@PROJECT_NAME@") diff --git a/include/xo/interpreter2/VirtualSchematikaMachine.hpp b/include/xo/interpreter2/VirtualSchematikaMachine.hpp new file mode 100644 index 00000000..6facb3fb --- /dev/null +++ b/include/xo/interpreter2/VirtualSchematikaMachine.hpp @@ -0,0 +1,78 @@ +/** @file VirtualSchematikaMachine.hpp + * + * @author Roland Conybare, Jan 2026 + **/ + +#pragma once + +#include "VsmInstr.hpp" +#include +#include + +namespace xo { + namespace scm { + /** @class VirtualSchematikaMachine + * @brief virtual machine for schematika + **/ + class VirtualSchematikaMachine { + public: + // will be DArenaVector> probably + using Stack = void *; + using AGCObject = xo::mm::AGCObject; + + public: + VirtualSchematikaMachine(); + + /** 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(); + + private: + /** Require: + * - expression in @ref expr_ + **/ + void _do_eval_op(); + + /** evaluate a constant expression + * Require: + * - expression in @ref expr_ + **/ + void _do_eval_constant_op(); + + private: + /* + * Some registers are preserved by evaluation: + * stack_ + * cont_ + * + * Other registers are not preserved + * pc_ + * expr_ + * value_ + */ + + /** program counter **/ + VsmInstr pc_ = VsmInstr::halt(); + + /** stack pointer **/ + Stack stack_; + + /** expression register **/ + obj expr_; + + /** result register **/ + obj value_; + + /** continuation register **/ + VsmInstr cont_ = VsmInstr::halt(); + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end VirtualSchematikaMachine.hpp */ diff --git a/include/xo/interpreter2/VsmInstr.hpp b/include/xo/interpreter2/VsmInstr.hpp new file mode 100644 index 00000000..ca74bc4c --- /dev/null +++ b/include/xo/interpreter2/VsmInstr.hpp @@ -0,0 +1,27 @@ +/** @file VsmInstr.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "VsmOpcode.hpp" + +namespace xo { + namespace scm { + class VsmInstr { + public: + explicit VsmInstr(vsm_opcode oc) : opcode_{oc} {} + + static VsmInstr halt() { return VsmInstr{vsm_opcode::halt}; } + static VsmInstr eval() { return VsmInstr{vsm_opcode::eval}; } + + vsm_opcode opcode() const noexcept { return opcode_; } + + private: + vsm_opcode opcode_; + }; + } /*namespace scm*/ +} /*namespace xo*/ + +/* end VsmInstr.hpp */ diff --git a/include/xo/interpreter2/VsmOpcode.hpp b/include/xo/interpreter2/VsmOpcode.hpp new file mode 100644 index 00000000..3638fa29 --- /dev/null +++ b/include/xo/interpreter2/VsmOpcode.hpp @@ -0,0 +1,29 @@ +/** @file VsmOpcode.hpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include + +namespace xo { + namespace scm { + /** Opcode for a virtual schematika expression; + * exeucted by VirtualSchematikaMachine + **/ + enum class vsm_opcode { + /** Immediately halt virtual schematika machine. **/ + halt, + /** Evaluate expression in expr register **/ + eval, + + /** sentinel, counts number of opcodes **/ + N, + }; + + static constexpr uint32_t n_opcode = static_cast(vsm_opcode::N); + } /*namespace scm*/ +} /*namespace xo*/ + +/* end VsmOpcode.hpp */ diff --git a/src/interpreter2/CMakeLists.txt b/src/interpreter2/CMakeLists.txt new file mode 100644 index 00000000..15d06fdf --- /dev/null +++ b/src/interpreter2/CMakeLists.txt @@ -0,0 +1,17 @@ +# interpreter2/CMakeLists.txt + +set(SELF_LIB xo_interpreter2) +set(SELF_SRCS + VirtualSchematikaMachine.cpp + #IExpression_Any.cpp + #interpreter2_register_facets.cpp + ) + +xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) +# note: deps here must also appear in cmake/xo_interpreter2Config.cmake.in +xo_dependency(${SELF_LIB} xo_expression2) +xo_dependency(${SELF_LIB} xo_gc) +#xo_dependency(${SELF_LIB} reflect) +#xo_dependency(${SELF_LIB} xo_printable2) +#xo_dependency(${SELF_LIB} xo_flatstring) +#xo_dependency(${SELF_LIB} indentlog) diff --git a/src/interpreter2/VirtualSchematikaMachine.cpp b/src/interpreter2/VirtualSchematikaMachine.cpp new file mode 100644 index 00000000..5882dc89 --- /dev/null +++ b/src/interpreter2/VirtualSchematikaMachine.cpp @@ -0,0 +1,63 @@ +/** @file VirtualSchematikaMachine.cpp + * + * @author Roland Conybeare, Jan 2026 + **/ + +#include "VirtualSchematikaMachine.hpp" +#include +#include + +namespace xo { + namespace scm { + + VirtualSchematikaMachine::VirtualSchematikaMachine() + {} + + void + VirtualSchematikaMachine::run() + { + while (this->execute_one()) + ; + } + + bool + VirtualSchematikaMachine::execute_one() + { + switch (pc_.opcode()) { + case vsm_opcode::halt: + case vsm_opcode::N: + return false; + case vsm_opcode::eval: + _do_eval_op(); + } + + return true; + } + + void + VirtualSchematikaMachine::_do_eval_op() + { + switch(expr_.extype()) { + case exprtype::invalid: + case exprtype::N: + break; + case exprtype::constant: + _do_eval_constant_op(); + break; + } + } + + void + VirtualSchematikaMachine::_do_eval_constant_op() + { + auto expr + = obj::from(expr_); + + this->value_ = expr.data()->value(); + this->pc_ = this->cont_; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end VirtualSchematikaMachine.hpp */