From feb272e545d928499f696096852411f324fafcda Mon Sep 17 00:00:00 2001 From: Andre Wagner Date: Wed, 29 Apr 2026 15:50:27 -0500 Subject: [PATCH] . --- src/vm/stack.cc | 28 +++++++++++++++++++++++----- src/vm/stack.hh | 7 +++++++ src/vm/tests.cc | 25 +++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/vm/stack.cc b/src/vm/stack.cc index 82a91e0..eee209a 100644 --- a/src/vm/stack.cc +++ b/src/vm/stack.cc @@ -4,6 +4,11 @@ namespace tyche { +Stack::Stack() +{ + fps_.push(0); +} + void Stack::push(Value const& value) { stack_.push_back(value); @@ -11,7 +16,7 @@ void Stack::push(Value const& value) Value Stack::pop() { - if (stack_.empty()) + if (stack_.size() <= fps_.size()) throw VMStackUnderflow(); Value v = stack_.back(); @@ -22,10 +27,13 @@ Value Stack::pop() Value Stack::at(int pos) const { try { - if (pos >= 0) - return stack_.at(pos); - else + if (pos >= 0) { + return stack_.at(fps_.top() + pos); + } else { + if ((int) fps_.top() + (int) stack_.size() + pos < 0) + throw VMStackOutOfRange(); return stack_.at(stack_.size() + pos); + } } catch (std::out_of_range&) { throw VMStackOutOfRange(); } @@ -33,7 +41,17 @@ Value Stack::at(int pos) const size_t Stack::size() const { - return stack_.size(); + return stack_.size() - fps_.top(); +} + +void Stack::push_fp() +{ + fps_.push(stack_.size()); +} + +void Stack::pop_fp() +{ + } } // tyche diff --git a/src/vm/stack.hh b/src/vm/stack.hh index 8c3ec8d..c6b59ac 100644 --- a/src/vm/stack.hh +++ b/src/vm/stack.hh @@ -1,6 +1,7 @@ #ifndef TYCHE_STACK_HH #define TYCHE_STACK_HH +#include #include #include "value.hh" @@ -9,14 +10,20 @@ namespace tyche { class Stack { public: + Stack(); + void push(Value const& value); Value pop(); [[nodiscard]] Value at(int pos) const; [[nodiscard]] size_t size() const; + void push_fp(); + void pop_fp(); + private: std::vector stack_; + std::stack fps_; }; } // tyche diff --git a/src/vm/tests.cc b/src/vm/tests.cc index dab978d..0f92135 100644 --- a/src/vm/tests.cc +++ b/src/vm/tests.cc @@ -43,6 +43,31 @@ TEST(Stack, PushPullGet) ASSERT_EQ(stack.at(-2).as_integer(), 20); } +TEST(Stack, FramePointer) +{ + Stack stack; + stack.push(Value::CreateInteger(10)); + stack.push(Value::CreateInteger(20)); + stack.push_fp(); + stack.push(Value::CreateInteger(30)); + stack.push(Value::CreateInteger(40)); + stack.push(Value::CreateInteger(50)); + + ASSERT_EQ(stack.size(), 3); + ASSERT_EQ(stack.at(0).as_integer(), 30); + ASSERT_EQ(stack.at(1).as_integer(), 40); + ASSERT_EQ(stack.at(-1).as_integer(), 50); + ASSERT_EQ(stack.at(-2).as_integer(), 40); + + stack.pop_fp(); + + ASSERT_EQ(stack.size(), 2); + ASSERT_EQ(stack.at(0).as_integer(), 10); + ASSERT_EQ(stack.at(1).as_integer(), 20); + ASSERT_EQ(stack.at(-1).as_integer(), 20); + ASSERT_EQ(stack.at(-2).as_integer(), 10); +} + int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv);