This repository has been archived on 2023-09-09. You can view files and clone it, but cannot push or open issues/pull-requests.
skemla/lib/VM.cpp

87 lines
1.6 KiB
C++
Raw Permalink Normal View History

2023-09-08 11:13:47 +00:00
#include "VM.hpp"
#include "Value.hpp"
#include "lib/opcodes.hpp"
namespace sk
{
/*explicit*/ VM::VM()
{
}
/*virtual*/ VM::~VM()
{
}
std::string VM::string() const
{
std::stringstream ss;
ss << "--- constants ---" << "\n";
for (size_t i=0; i<m_frames.back().program->value_size(); i++)
{
ss << i << "\t" << m_frames.back().program->value(i)->string()
<< "\n";
}
ss << "--- stack ---" << "\n";
for (size_t i=0; i<m_stack.size(); i++)
{
ss << i << "\t" << m_stack[i] << "\n";
}
return ss.str();
}
void VM::exec(std::shared_ptr<Program> program)
{
Frame frame;
frame.program = program;
m_frames.push_back(frame);
m_pc = 0;
exec();
}
void VM::exec()
{
while (m_pc < program()->size())
{
Instr instr = program()->instr(m_pc);
switch (instr.opcode)
{
case OPCODE_PUSH_CONST: {
push(*instr.param);
m_pc++;
} break;
default:
throw std::runtime_error {std::string()
+ "vm cannot execute unknown opcode '"
+ OpcodeTypeStr[instr.opcode]
+ "'"};
}
}
}
std::shared_ptr<Program> VM::program() const
{
return m_frames.back().program;
}
void VM::push(param_t param)
{
m_stack.push_back(param);
}
param_t VM::pop()
{
assert(m_stack.empty() == false);
auto param = m_stack.back();
m_stack.pop_back();
return param;
}
}