This commit is contained in:
Andre Wagner
2026-04-29 15:50:27 -05:00
parent 03b61f4339
commit feb272e545
3 changed files with 55 additions and 5 deletions

View File

@@ -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

View File

@@ -1,6 +1,7 @@
#ifndef TYCHE_STACK_HH
#define TYCHE_STACK_HH
#include <stack>
#include <vector>
#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<Value> stack_;
std::stack<size_t> fps_;
};
} // tyche

View File

@@ -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);