VM basics #5
@@ -16,7 +16,7 @@ void Stack::push(Value const& value)
|
|||||||
|
|
||||||
Value Stack::pop()
|
Value Stack::pop()
|
||||||
{
|
{
|
||||||
if (stack_.size() <= fps_.size())
|
if (stack_.size() <= fps_.top())
|
||||||
throw VMStackUnderflow();
|
throw VMStackUnderflow();
|
||||||
|
|
||||||
Value v = stack_.back();
|
Value v = stack_.back();
|
||||||
@@ -58,4 +58,15 @@ void Stack::pop_fp()
|
|||||||
fps_.pop();
|
fps_.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Stack::debug() const
|
||||||
|
{
|
||||||
|
if (stack_.empty())
|
||||||
|
return "empty";
|
||||||
|
|
||||||
|
std::string out;
|
||||||
|
for (size_t i = 0; i < stack_.size(); ++i)
|
||||||
|
out += "[" + stack_.at(i).to_string() + "] ";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
} // tyche
|
} // tyche
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] size_t fp_level() const { return fps_.size(); }
|
[[nodiscard]] size_t fp_level() const { return fps_.size(); }
|
||||||
|
|
||||||
|
[[nodiscard]] std::string debug() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Value> stack_;
|
std::vector<Value> stack_;
|
||||||
std::stack<size_t> fps_;
|
std::stack<size_t> fps_;
|
||||||
|
|||||||
@@ -84,7 +84,9 @@ TEST(VM, BasicCode)
|
|||||||
|
|
||||||
VM vm;
|
VM vm;
|
||||||
vm.load_bytecode(std::move(ba));
|
vm.load_bytecode(std::move(ba));
|
||||||
|
printf("%s\n", vm.debug_stack().c_str());
|
||||||
vm.call(0);
|
vm.call(0);
|
||||||
|
printf("%s\n", vm.debug_stack().c_str());
|
||||||
|
|
||||||
int32_t result = vm.to_integer(-1);
|
int32_t result = vm.to_integer(-1);
|
||||||
ASSERT_EQ(result, 5);
|
ASSERT_EQ(result, 5);
|
||||||
|
|||||||
@@ -15,4 +15,15 @@ Type Value::type() const
|
|||||||
}, value_);
|
}, value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Value::to_string() const
|
||||||
|
{
|
||||||
|
return std::visit(overloaded {
|
||||||
|
[](std::monostate) { return std::string("nil"); },
|
||||||
|
[](int32_t i) { return std::to_string(i); },
|
||||||
|
[](float f) { return std::to_string(f); },
|
||||||
|
[](std::string const& s) { return s; },
|
||||||
|
[](Function const& f) { return "@" + std::to_string(f.f_id); }
|
||||||
|
}, value_);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public:
|
|||||||
[[nodiscard]] std::string as_string() const { return std::get<std::string>(value_); }
|
[[nodiscard]] std::string as_string() const { return std::get<std::string>(value_); }
|
||||||
[[nodiscard]] FunctionId as_function_id() const { return std::get<Function>(value_).f_id; }
|
[[nodiscard]] FunctionId as_function_id() const { return std::get<Function>(value_).f_id; }
|
||||||
|
|
||||||
|
[[nodiscard]] std::string to_string() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Internal = std::variant<std::monostate, int32_t, float, std::string, Function>;
|
using Internal = std::variant<std::monostate, int32_t, float, std::string, Function>;
|
||||||
Internal value_;
|
Internal value_;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ public:
|
|||||||
|
|
||||||
void push_integer(int32_t value);
|
void push_integer(int32_t value);
|
||||||
|
|
||||||
|
[[nodiscard]] std::string debug_stack() const { return stack_.debug(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run_until_return();
|
void run_until_return();
|
||||||
void step();
|
void step();
|
||||||
|
|||||||
Reference in New Issue
Block a user