79 lines
1.2 KiB
C++
79 lines
1.2 KiB
C++
|
#include "VM.hpp"
|
||
|
#include "src/Program.hpp"
|
||
|
|
||
|
namespace zn
|
||
|
{
|
||
|
/*explicit*/ VM::VM()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/*virtual*/ VM::~VM()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void VM::execute(Program& program)
|
||
|
{
|
||
|
m_pc = 0;
|
||
|
m_frames.push_back(Frame {program});
|
||
|
|
||
|
while (m_pc < program.size())
|
||
|
{
|
||
|
auto instr = program.instr(m_pc);
|
||
|
execute(instr.opcode, instr.param);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void VM::execute(Opcode opcode, int param)
|
||
|
{
|
||
|
switch (opcode)
|
||
|
{
|
||
|
case OPCODE_LOAD_CONST: {
|
||
|
push(param);
|
||
|
m_pc++;
|
||
|
} break;
|
||
|
|
||
|
case OPCODE_POP: {
|
||
|
pop();
|
||
|
m_pc++;
|
||
|
} break;
|
||
|
|
||
|
default: {
|
||
|
std::cerr << "cannot execute opcode '"
|
||
|
<< OpcodeStr[opcode]
|
||
|
<< "'" << std::endl;
|
||
|
abort();
|
||
|
} break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
std::string VM::string() const
|
||
|
{
|
||
|
std::stringstream ss;
|
||
|
|
||
|
ss << "======== VM Stack ========\n";
|
||
|
|
||
|
size_t addr = 0;
|
||
|
|
||
|
for (int val: m_stack)
|
||
|
{
|
||
|
ss << addr << " " << val << "\n";
|
||
|
addr++;
|
||
|
}
|
||
|
|
||
|
return ss.str();
|
||
|
}
|
||
|
|
||
|
void VM::push(int value)
|
||
|
{
|
||
|
m_stack.push_back(value);
|
||
|
}
|
||
|
|
||
|
int VM::pop()
|
||
|
{
|
||
|
assert(m_stack.size() > 0);
|
||
|
int value = m_stack.back();
|
||
|
m_stack.pop_back();
|
||
|
return value;
|
||
|
}
|
||
|
}
|