|
|
|
@ -1,14 +1,16 @@
|
|
|
|
|
#ifndef INTERPRETER_INTERPRETER_H_INCLUDED
|
|
|
|
|
#define INTERPRETER_INTERPRETER_H_INCLUDED
|
|
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <stack>
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
|
|
#include "components/interpreter/program.hpp"
|
|
|
|
|
#include <components/misc/strings/format.hpp>
|
|
|
|
|
|
|
|
|
|
#include "opcodes.hpp"
|
|
|
|
|
#include "program.hpp"
|
|
|
|
|
#include "runtime.hpp"
|
|
|
|
|
#include "types.hpp"
|
|
|
|
|
|
|
|
|
@ -32,11 +34,13 @@ namespace Interpreter
|
|
|
|
|
|
|
|
|
|
void end();
|
|
|
|
|
|
|
|
|
|
template <typename TSeg, typename TOp>
|
|
|
|
|
void installSegment(TSeg& seg, int code, TOp&& op)
|
|
|
|
|
template <typename T, typename... Args>
|
|
|
|
|
void installSegment(auto& segment, std::string_view name, int code, Args&&... args)
|
|
|
|
|
{
|
|
|
|
|
assert(seg.find(code) == seg.end());
|
|
|
|
|
seg.emplace(code, std::move(op));
|
|
|
|
|
if (segment.find(code) != segment.end())
|
|
|
|
|
throw std::invalid_argument(Misc::StringUtils::format(
|
|
|
|
|
"Duplicated interpreter instruction code in segment %s: 0x%x", name, code));
|
|
|
|
|
segment.emplace(code, std::make_unique<T>(std::forward<Args>(args)...));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
@ -48,25 +52,25 @@ namespace Interpreter
|
|
|
|
|
template <typename T, typename... TArgs>
|
|
|
|
|
void installSegment0(int code, TArgs&&... args)
|
|
|
|
|
{
|
|
|
|
|
installSegment(mSegment0, code, std::make_unique<T>(std::forward<TArgs>(args)...));
|
|
|
|
|
installSegment<T>(mSegment0, "0", code, std::forward<TArgs>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T, typename... TArgs>
|
|
|
|
|
void installSegment2(int code, TArgs&&... args)
|
|
|
|
|
{
|
|
|
|
|
installSegment(mSegment2, code, std::make_unique<T>(std::forward<TArgs>(args)...));
|
|
|
|
|
installSegment<T>(mSegment2, "2", code, std::forward<TArgs>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T, typename... TArgs>
|
|
|
|
|
void installSegment3(int code, TArgs&&... args)
|
|
|
|
|
{
|
|
|
|
|
installSegment(mSegment3, code, std::make_unique<T>(std::forward<TArgs>(args)...));
|
|
|
|
|
installSegment<T>(mSegment3, "3", code, std::forward<TArgs>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T, typename... TArgs>
|
|
|
|
|
void installSegment5(int code, TArgs&&... args)
|
|
|
|
|
{
|
|
|
|
|
installSegment(mSegment5, code, std::make_unique<T>(std::forward<TArgs>(args)...));
|
|
|
|
|
installSegment<T>(mSegment5, "5", code, std::forward<TArgs>(args)...);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void run(const Program& program, Context& context);
|
|
|
|
|