From 03b61f43392fd463f2533535143c8f11f05bb351 Mon Sep 17 00:00:00 2001 From: Andre Wagner Date: Wed, 29 Apr 2026 15:36:22 -0500 Subject: [PATCH] . --- CMakeLists.txt | 3 +++ src/vm/stack.cc | 39 +++++++++++++++++++++++++++++++++++++++ src/vm/stack.hh | 24 ++++++++++++++++++++++++ src/vm/tests.cc | 15 +++++++++++++++ src/vm/vm_exceptions.hh | 29 +++++++++++++++++++++++++++++ 5 files changed, 110 insertions(+) create mode 100644 src/vm/stack.cc create mode 100644 src/vm/stack.hh create mode 100644 src/vm/vm_exceptions.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index 27e1f49..ca26996 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,9 @@ add_library(lib${PROJECT_NAME} SHARED src/vm/instruction.cc src/vm/value.cc src/vm/value.hh + src/vm/stack.cc + src/vm/stack.hh + src/vm/vm_exceptions.hh ) target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings}) diff --git a/src/vm/stack.cc b/src/vm/stack.cc new file mode 100644 index 0000000..82a91e0 --- /dev/null +++ b/src/vm/stack.cc @@ -0,0 +1,39 @@ +#include "stack.hh" + +#include "vm_exceptions.hh" + +namespace tyche { + +void Stack::push(Value const& value) +{ + stack_.push_back(value); +} + +Value Stack::pop() +{ + if (stack_.empty()) + throw VMStackUnderflow(); + + Value v = stack_.back(); + stack_.pop_back(); + return v; +} + +Value Stack::at(int pos) const +{ + try { + if (pos >= 0) + return stack_.at(pos); + else + return stack_.at(stack_.size() + pos); + } catch (std::out_of_range&) { + throw VMStackOutOfRange(); + } +} + +size_t Stack::size() const +{ + return stack_.size(); +} + +} // tyche diff --git a/src/vm/stack.hh b/src/vm/stack.hh new file mode 100644 index 0000000..8c3ec8d --- /dev/null +++ b/src/vm/stack.hh @@ -0,0 +1,24 @@ +#ifndef TYCHE_STACK_HH +#define TYCHE_STACK_HH + +#include + +#include "value.hh" + +namespace tyche { + +class Stack { +public: + void push(Value const& value); + Value pop(); + + [[nodiscard]] Value at(int pos) const; + [[nodiscard]] size_t size() const; + +private: + std::vector stack_; +}; + +} // tyche + +#endif //TYCHE_STACK_HH diff --git a/src/vm/tests.cc b/src/vm/tests.cc index 40b0bb0..dab978d 100644 --- a/src/vm/tests.cc +++ b/src/vm/tests.cc @@ -4,6 +4,7 @@ #include "../bytecode/bytearray.hh" #include "../bytecode/bytecode.hh" #include "code.hh" +#include "stack.hh" using namespace tyche; @@ -28,6 +29,20 @@ TEST(Code, ImportSingleAndDebug) printf("%s\n", code.disassemble().c_str()); } +TEST(Stack, PushPullGet) +{ + Stack stack; + stack.push(Value::CreateInteger(10)); + stack.push(Value::CreateInteger(20)); + stack.push(Value::CreateInteger(30)); + + ASSERT_EQ(stack.size(), 3); + ASSERT_EQ(stack.at(0).as_integer(), 10); + ASSERT_EQ(stack.at(1).as_integer(), 20); + ASSERT_EQ(stack.at(-1).as_integer(), 30); + ASSERT_EQ(stack.at(-2).as_integer(), 20); +} + int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); diff --git a/src/vm/vm_exceptions.hh b/src/vm/vm_exceptions.hh new file mode 100644 index 0000000..dc4160f --- /dev/null +++ b/src/vm/vm_exceptions.hh @@ -0,0 +1,29 @@ +#ifndef TYCHE_VM_EXCEPTIONS_HH +#define TYCHE_VM_EXCEPTIONS_HH + +#include +#include + +namespace tyche { + +class VMRuntimeError : public std::runtime_error +{ +public: + explicit VMRuntimeError(std::string const& str) : std::runtime_error(str.c_str()) {} +}; + +class VMStackUnderflow : public VMRuntimeError +{ +public: + explicit VMStackUnderflow() : VMRuntimeError("Stack underflow") {} +}; + +class VMStackOutOfRange : public VMRuntimeError +{ +public: + explicit VMStackOutOfRange() : VMRuntimeError("Item does not exist in stack") {} +}; + +} + +#endif //TYCHE_VM_EXCEPTIONS_HH