4 * Created on: Oct 13, 2012
8 #include "ScriptRunner.h"
11 #include "ScriptHost.h"
15 using geometry::Vector;
19 ScriptRunner::ScriptRunner()
27 ScriptRunner::~ScriptRunner() {
32 bool ScriptRunner::Running() const {
33 return script && cursor < script->textlen;
36 void ScriptRunner::Run(ScriptHost &h, const Script &s) {
40 while (cursor < script->textlen) {
47 void ScriptRunner::Reset() {
49 for (int i(0); i < numRegisters; ++i) {
52 vector[i] = Vector<int>(0, 0);
56 void ScriptRunner::Exec(Script::Code code) {
57 switch (code.command) {
58 case Script::COMMAND_NOOP:
61 case Script::COMMAND_MOVE:
62 if (code.reg1 >= numRegisters) {
66 case Script::TYPE_ADDRESS: {
67 void *value(code.reg2 < numRegisters ? address[code.reg2] : PopAddress());
68 address[code.reg1] = value;
71 case Script::TYPE_INTEGER: {
72 int value(code.reg2 < numRegisters ? integer[code.reg2] : PopInt());
73 integer[code.reg1] = value;
76 case Script::TYPE_VECTOR: {
77 Vector<int> value(code.reg2 < numRegisters ? vector[code.reg2] : PopVector());
78 vector[code.reg1] = value;
84 case Script::COMMAND_ADD:
85 if (code.reg1 >= numRegisters) {
89 case Script::TYPE_INTEGER: {
90 int value(code.reg2 < numRegisters ? integer[code.reg2] : PopInt());
91 integer[code.reg1] += value;
94 case Script::TYPE_VECTOR: {
95 Vector<int> value(code.reg2 < numRegisters ? vector[code.reg2] : PopVector());
96 vector[code.reg1] += value;
102 case Script::COMMAND_MOD: {
103 if (code.reg1 >= numRegisters) {
106 int value(code.reg2 < numRegisters ? integer[code.reg2] : PopInt());
107 integer[code.reg1] %= value;
111 case Script::COMMAND_RAND:
112 if (code.reg1 >= numRegisters) {
115 integer[code.reg1] = std::rand();
118 case Script::COMMAND_CMP: {
119 int lhs(code.reg1 < numRegisters ? integer[code.reg1] : PopInt());
120 int rhs(code.reg2 < numRegisters ? integer[code.reg2] : PopInt());
125 case Script::COMMAND_JMP:
128 case Script::COMMAND_JEQ: {
130 if (compare == COMPARE_EQUAL) {
135 case Script::COMMAND_JNE: {
137 if (compare != COMPARE_EQUAL) {
142 case Script::COMMAND_JL: {
144 if (compare == COMPARE_LESS) {
149 case Script::COMMAND_JLE: {
151 if (compare != COMPARE_GREATER) {
156 case Script::COMMAND_JG: {
158 if (compare == COMPARE_GREATER) {
163 case Script::COMMAND_JGE: {
165 if (compare != COMPARE_LESS) {
170 case Script::COMMAND_SYSC:
171 host->HandleSyscall(*this);
176 Script::Code ScriptRunner::PopCode() {
177 const Script::Code *i(reinterpret_cast<const Script::Code *>(script->text + cursor));
178 cursor += sizeof(Script::Code);
182 void *ScriptRunner::PopAddress() {
183 void *const *addr(reinterpret_cast<void *const *>(script->text + cursor));
184 cursor += sizeof(void *);
188 int ScriptRunner::PopInt() {
189 const int *i(reinterpret_cast<const int *>(script->text + cursor));
190 cursor += sizeof(int);
194 const Vector<int> &ScriptRunner::PopVector() {
195 const Vector<int> *vec(reinterpret_cast<const Vector<int> *>(script->text + cursor));
196 cursor += sizeof(Vector<int>);
200 void ScriptRunner::Compare(int lhs, int rhs) {
202 compare = COMPARE_LESS;
203 } else if (lhs > rhs) {
204 compare = COMPARE_GREATER;
206 compare = COMPARE_EQUAL;