This commit is contained in:
Andre Wagner
2026-05-02 15:36:36 -05:00
parent 1d24570f1b
commit d63f495fcf
5 changed files with 57 additions and 9 deletions

View File

@@ -47,6 +47,21 @@ Value Stack::at(int pos) const
}
}
void Stack::set(int pos, Value const& val)
{
try {
if (pos >= 0) {
stack_.at(fps_.top() + pos) = val;
} else {
if ((int) fps_.top() + (int) stack_.size() + pos < 0)
throw VMStackOutOfRange();
stack_.at(stack_.size() + pos) = val;
}
} catch (std::out_of_range&) {
throw VMStackOutOfRange();
}
}
size_t Stack::size() const
{
return stack_.size() - fps_.top();

View File

@@ -19,6 +19,8 @@ public:
[[nodiscard]] Value at(int pos) const;
[[nodiscard]] size_t size() const;
void set(int pos, Value const& val);
void push_fp();
void pop_fp();

View File

@@ -270,15 +270,19 @@ TEST(VM, StringString)
TEST(VM, LocalVariables)
{
/*
ASSERT_EQ(run(R"(
VM vm = run(R"(
.func 0
pushv 2
pushi 3
setv 0
pushi
)").to_integer(-1), 4);
*/
pushv 2 ; local a, b
pushi 3 ; a = 3
set 0
pushi 4 ; b = 4
set 1
dupv 0 ; return a
ret
)");
ASSERT_EQ(vm.stack_sz(), 1);
ASSERT_EQ(vm.to_integer(-1), 3);
}
int main(int argc, char** argv)

View File

@@ -131,6 +131,33 @@ void VM::step()
stack_.push(stack_.peek());
break;
//
// variables
//
case Instruction::PushValues8:
case Instruction::PushValues16:
case Instruction::PushValues32:
for (int i = 0; i < op.operator_; ++i)
push_nil();
break;
case Instruction::SetValue8:
case Instruction::SetValue16:
case Instruction::SetValue32: {
Value a = stack_.pop();
stack_.set(op.operator_, a);
break;
}
case Instruction::DuplicateValue8:
case Instruction::DuplicateValue16:
case Instruction::DuplicateValue32: {
Value a = stack_.at(op.operator_);
stack_.push(a);
break;
}
//
// logical/arithmetic
//

View File

@@ -33,7 +33,7 @@ public:
[[nodiscard]] float to_float(int index) const;
[[nodiscard]] std::string to_string(int index) const;
[[nodiscard]] std::string debug_stack() const { return stack_.debug(); }
[[nodiscard]] std::string debug_stack() const { return stack_.debug(); }
private:
void run_until_return();