.
This commit is contained in:
@@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
namespace tyche {
|
namespace tyche {
|
||||||
|
|
||||||
|
Stack::Stack()
|
||||||
|
{
|
||||||
|
fps_.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
void Stack::push(Value const& value)
|
void Stack::push(Value const& value)
|
||||||
{
|
{
|
||||||
stack_.push_back(value);
|
stack_.push_back(value);
|
||||||
@@ -11,7 +16,7 @@ void Stack::push(Value const& value)
|
|||||||
|
|
||||||
Value Stack::pop()
|
Value Stack::pop()
|
||||||
{
|
{
|
||||||
if (stack_.empty())
|
if (stack_.size() <= fps_.size())
|
||||||
throw VMStackUnderflow();
|
throw VMStackUnderflow();
|
||||||
|
|
||||||
Value v = stack_.back();
|
Value v = stack_.back();
|
||||||
@@ -22,10 +27,13 @@ Value Stack::pop()
|
|||||||
Value Stack::at(int pos) const
|
Value Stack::at(int pos) const
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (pos >= 0)
|
if (pos >= 0) {
|
||||||
return stack_.at(pos);
|
return stack_.at(fps_.top() + pos);
|
||||||
else
|
} else {
|
||||||
|
if ((int) fps_.top() + (int) stack_.size() + pos < 0)
|
||||||
|
throw VMStackOutOfRange();
|
||||||
return stack_.at(stack_.size() + pos);
|
return stack_.at(stack_.size() + pos);
|
||||||
|
}
|
||||||
} catch (std::out_of_range&) {
|
} catch (std::out_of_range&) {
|
||||||
throw VMStackOutOfRange();
|
throw VMStackOutOfRange();
|
||||||
}
|
}
|
||||||
@@ -33,7 +41,17 @@ Value Stack::at(int pos) const
|
|||||||
|
|
||||||
size_t Stack::size() 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
|
} // tyche
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef TYCHE_STACK_HH
|
#ifndef TYCHE_STACK_HH
|
||||||
#define TYCHE_STACK_HH
|
#define TYCHE_STACK_HH
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "value.hh"
|
#include "value.hh"
|
||||||
@@ -9,14 +10,20 @@ namespace tyche {
|
|||||||
|
|
||||||
class Stack {
|
class Stack {
|
||||||
public:
|
public:
|
||||||
|
Stack();
|
||||||
|
|
||||||
void push(Value const& value);
|
void push(Value const& value);
|
||||||
Value pop();
|
Value pop();
|
||||||
|
|
||||||
[[nodiscard]] Value at(int pos) const;
|
[[nodiscard]] Value at(int pos) const;
|
||||||
[[nodiscard]] size_t size() const;
|
[[nodiscard]] size_t size() const;
|
||||||
|
|
||||||
|
void push_fp();
|
||||||
|
void pop_fp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Value> stack_;
|
std::vector<Value> stack_;
|
||||||
|
std::stack<size_t> fps_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // tyche
|
} // tyche
|
||||||
|
|||||||
@@ -43,6 +43,31 @@ TEST(Stack, PushPullGet)
|
|||||||
ASSERT_EQ(stack.at(-2).as_integer(), 20);
|
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)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
|||||||
Reference in New Issue
Block a user