Variables #8
@@ -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
|
size_t Stack::size() const
|
||||||
{
|
{
|
||||||
return stack_.size() - fps_.top();
|
return stack_.size() - fps_.top();
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ public:
|
|||||||
[[nodiscard]] Value at(int pos) const;
|
[[nodiscard]] Value at(int pos) const;
|
||||||
[[nodiscard]] size_t size() const;
|
[[nodiscard]] size_t size() const;
|
||||||
|
|
||||||
|
void set(int pos, Value const& val);
|
||||||
|
|
||||||
void push_fp();
|
void push_fp();
|
||||||
void pop_fp();
|
void pop_fp();
|
||||||
|
|
||||||
|
|||||||
@@ -270,15 +270,19 @@ TEST(VM, StringString)
|
|||||||
|
|
||||||
TEST(VM, LocalVariables)
|
TEST(VM, LocalVariables)
|
||||||
{
|
{
|
||||||
/*
|
VM vm = run(R"(
|
||||||
ASSERT_EQ(run(R"(
|
|
||||||
.func 0
|
.func 0
|
||||||
pushv 2
|
pushv 2 ; local a, b
|
||||||
pushi 3
|
pushi 3 ; a = 3
|
||||||
setv 0
|
set 0
|
||||||
pushi
|
pushi 4 ; b = 4
|
||||||
)").to_integer(-1), 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)
|
int main(int argc, char** argv)
|
||||||
|
|||||||
27
src/vm/vm.cc
27
src/vm/vm.cc
@@ -131,6 +131,33 @@ void VM::step()
|
|||||||
stack_.push(stack_.peek());
|
stack_.push(stack_.peek());
|
||||||
break;
|
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
|
// logical/arithmetic
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public:
|
|||||||
[[nodiscard]] float to_float(int index) const;
|
[[nodiscard]] float to_float(int index) const;
|
||||||
[[nodiscard]] std::string to_string(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:
|
private:
|
||||||
void run_until_return();
|
void run_until_return();
|
||||||
|
|||||||
Reference in New Issue
Block a user