added interpreter framework

actorid
Marc Zinnschlag 15 years ago
parent fdcd34941b
commit 487a70388f

@ -76,10 +76,12 @@ set(COMPILER components/compiler/errorhandler.cpp
file(GLOB COMPILER_HEADER components/compiler/*.hpp)
source_group(compiler FILES ${COMPILER} ${COMPILER_HEADER})
set(INTERPRETER components/interpreter/runtime.cpp components/interpreter/interpreter.cpp)
file(GLOB INTERPRETER_HEADER components/interpreter/*.hpp)
source_group(interpreter FILES ${INTERPRETER_HEADER})
source_group(interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER})
set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${OGRE} ${INPUT} ${MISC} ${COMPILER})
set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${OGRE} ${INPUT} ${MISC} ${COMPILER}
${INTERPRETER})
set(COMPONENTS_HEADER ${BSA_HEADER} ${NIF_HEADER} ${NIFOGRE_HEADER} ${ESM_STORE_HEADER}
${ESM_HEADER} ${OGRE_HEADER} ${INPUT_HEADER} ${MISC_HEADER} ${COMPILER_HEADER}
${INTERPRETER_HEADER})
@ -183,3 +185,10 @@ set(TOOLS_MWCOMPILER ${COMPILER} apps/mwcompiler/main.cpp apps/mwcompiler/contex
add_executable(mwcompiler ${TOOLS_MWCOMPILER})
endif()
option(BUILD_MWINTERPRETER "build standalone Morrowind script code interpreter" ON)
if (BUILD_MWINTERPRETER)
set(TOOLS_MWINTERPRETER ${INTERPRETER} apps/mwinterpreter/main.cpp)
add_executable(mwinterpreter ${TOOLS_MWINTERPRETER})
endif()

@ -0,0 +1,49 @@
// Stand-alone MW-script code interpreter
#include <exception>
#include <fstream>
#include <iostream>
#include <vector>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/context.hpp>
#include <components/interpreter/types.hpp>
int main (int argc, char **argv)
{
try
{
Interpreter::Context context;
Interpreter::Interpreter interpreter (context);
std::string filename = argc>1 ? argv[1] : "test.mwscript";
std::string codefilename = filename + ".code";
std::ifstream codefile (codefilename.c_str());
if (!codefile.is_open())
{
std::cout << "can't open code file: " << codefilename << std::endl;
return 1;
}
std::vector<Interpreter::Type_Code> code (4);
codefile.read (reinterpret_cast<char *> (&code[0]), 4 * sizeof (Interpreter::Type_Code));
unsigned int size = code[0] + code[1] + code[2] + code[3];
code.resize (4+size);
codefile.read (reinterpret_cast<char *> (&code[4]), size * sizeof (Interpreter::Type_Code));
interpreter.run (&code[0], size+4);
}
catch (const std::exception &e)
{
std::cout << "\nERROR: " << e.what() << std::endl;
return 1;
}
}

@ -0,0 +1,14 @@
#ifndef INTERPRETER_CONTEXT_H_INCLUDED
#define INTERPRETER_CONTEXT_H_INCLUDED
namespace Interpreter
{
class Context
{
};
}
#endif

@ -0,0 +1,22 @@
#include "interpreter.hpp"
namespace Interpreter
{
Interpreter::Interpreter (Context& context)
: mRuntime (context)
{}
Interpreter::~Interpreter()
{
}
void Interpreter::run (const Type_Code *code, int codeSize)
{
mRuntime.configure (code, codeSize);
mRuntime.clear();
}
}

@ -0,0 +1,28 @@
#ifndef INTERPRETER_INTERPRETER_H_INCLUDED
#define INTERPRETER_INTERPRETER_H_INCLUDED
#include "runtime.hpp"
#include "types.hpp"
namespace Interpreter
{
class Interpreter
{
Runtime mRuntime;
// not implemented
Interpreter (const Interpreter&);
Interpreter& operator= (const Interpreter&);
public:
Interpreter (Context& context);
~Interpreter();
void run (const Type_Code *code, int codeSize);
};
}
#endif

@ -0,0 +1,40 @@
#ifndef INTERPRETER_OPCODES_H_INCLUDED
#define INTERPRETER_OPCODES_H_INCLUDED
namespace Interpreter
{
class Runtime;
/// opcode for 0 arguments
class Opcode0
{
public:
virtual void execute (Runtime& runtime) = 0;
virtual ~Opcode0() {}
};
/// opcode for 1 argument
class Opcode1
{
public:
virtual void execute (Runtime& runtime, unsigned int arg0) = 0;
virtual ~Opcode0() {}
};
/// opcode for 2 arguments
class Opcode2
{
public:
virtual void execute (Runtime& runtime, unsigned int arg1, unsigned int arg2) = 0;
virtual ~Opcode0() {}
};
}
#endif

@ -0,0 +1,22 @@
#include "runtime.hpp"
namespace Interpreter
{
Runtime::Runtime (Context& context) : mContext (context), mCode (0) {}
void Runtime::configure (const Interpreter::Type_Code *code, int codeSize)
{
clear();
mCode = code;
mCodeSize = codeSize;
}
void Runtime::clear()
{
mCode = 0;
mCodeSize = 0;
}
}

@ -0,0 +1,31 @@
#ifndef INTERPRETER_RUNTIME_H_INCLUDED
#define INTERPRETER_RUNTIME_H_INCLUDED
#include "types.hpp"
namespace Interpreter
{
class Context;
/// Runtime data and engine interface
class Runtime
{
Context& mContext;
const Interpreter::Type_Code *mCode;
int mCodeSize;
public:
Runtime (Context& context);
void configure (const Interpreter::Type_Code *code, int codeSize);
///< \a context and \a code must exist as least until either configure, clear or
/// the destructor is called. \a codeSize is given in 32-bit words.
void clear();
};
}
#endif
Loading…
Cancel
Save