|
@@ -3,11 +3,10 @@
|
|
|
#include "libraries/Math.h"
|
|
|
#include "libraries/Time.h"
|
|
|
#include "tokenizer/Tokenizer.h"
|
|
|
+#include "utils/HashMap.h"
|
|
|
#include "utils/StringBuffer.h"
|
|
|
#include "vm/Script.h"
|
|
|
|
|
|
-static Function function;
|
|
|
-
|
|
|
static const char* unicode(int32 c) {
|
|
|
static char buffer[5];
|
|
|
int index = 0;
|
|
@@ -47,39 +46,65 @@ static void printString(Script* sc) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void printInt32(Script* sc) {
|
|
|
+ int32 i;
|
|
|
+ if(sPopInt32(sc, &i)) {
|
|
|
+ printf("%d", i);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void wait(Script* sc) {
|
|
|
+ sError(sc, "w");
|
|
|
+}
|
|
|
+
|
|
|
+static Snuvi::Event event = Snuvi::Event::NONE;
|
|
|
+
|
|
|
+static void getEvent(Script* sc) {
|
|
|
+ sPushInt32(sc, event);
|
|
|
+}
|
|
|
+
|
|
|
static void initPrinter() {
|
|
|
- Snuvi::initFunction("print", printString);
|
|
|
- Snuvi::addStringArgument();
|
|
|
+ Snuvi::initFunction("print", dtVoid(), printString);
|
|
|
+ Snuvi::addArgument(dtConst(dtText()));
|
|
|
+ Snuvi::addFunction();
|
|
|
+ Snuvi::initFunction("print", dtVoid(), printInt32);
|
|
|
+ Snuvi::addArgument(dtInt32());
|
|
|
Snuvi::addFunction();
|
|
|
}
|
|
|
|
|
|
-struct Init {
|
|
|
- Init() {
|
|
|
+struct Scripts {
|
|
|
+ int scriptId = 0;
|
|
|
+ HashMap<int, Script*> scripts;
|
|
|
+
|
|
|
+ Scripts() {
|
|
|
gfsInit();
|
|
|
gstsInit();
|
|
|
lTimeRegister();
|
|
|
lMathRegister();
|
|
|
initPrinter();
|
|
|
+ Snuvi::initFunction("wait", dtVoid(), wait);
|
|
|
+ Snuvi::addFunction();
|
|
|
+ Snuvi::initFunction("getEvent", dtInt32(), getEvent);
|
|
|
+ Snuvi::addFunction();
|
|
|
}
|
|
|
|
|
|
- ~Init() {
|
|
|
+ ~Scripts() {
|
|
|
gfsDelete();
|
|
|
gstsDelete();
|
|
|
+ Snuvi::termAll();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-void Snuvi::init() {
|
|
|
- static Init init;
|
|
|
-}
|
|
|
+static Scripts scripts;
|
|
|
+static Function function;
|
|
|
|
|
|
-void Snuvi::initFunction(const char* name, ScriptFunction sf) {
|
|
|
- gfInit(&function, name, dtVoid(), sf);
|
|
|
+void Snuvi::initFunction(const char* name, DataType returnType,
|
|
|
+ ScriptFunction sf) {
|
|
|
+ gfInit(&function, name, returnType, sf);
|
|
|
}
|
|
|
|
|
|
-void Snuvi::addStringArgument() {
|
|
|
- DataType string = dtConst(dtInt32());
|
|
|
- dtDereference(&string);
|
|
|
- gfAddArgument(&function, string);
|
|
|
+void Snuvi::addArgument(DataType type) {
|
|
|
+ gfAddArgument(&function, type);
|
|
|
}
|
|
|
|
|
|
void Snuvi::addFunction() {
|
|
@@ -91,22 +116,92 @@ static void logError(const char* msg, int line) {
|
|
|
printf("line: %d\n", line);
|
|
|
}
|
|
|
|
|
|
-void Snuvi::start(const char* path) {
|
|
|
+static bool runScript(Script* script) {
|
|
|
+ sRun(script);
|
|
|
+ if(script->error[0] == 'w' && script->error[1] == '\0') {
|
|
|
+ script->error[0] = '\0';
|
|
|
+ return false;
|
|
|
+ } else if(script->error[0] != '\0') {
|
|
|
+ logError(script->error, script->line);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return script->readIndex >= script->code->length;
|
|
|
+}
|
|
|
+
|
|
|
+int Snuvi::start(const char* path) {
|
|
|
StringBuffer<256> s("resources/scripts/");
|
|
|
s.append(path).append(".snuvi");
|
|
|
if(tTokenize(s)) {
|
|
|
logError(tGetError(), tGetLine());
|
|
|
- return;
|
|
|
+ return -1;
|
|
|
}
|
|
|
ByteCode* code = cCompile();
|
|
|
if(code == nullptr) {
|
|
|
logError(cGetError(), cGetLine());
|
|
|
- return;
|
|
|
+ return -1;
|
|
|
}
|
|
|
Script* script = sInit(code);
|
|
|
- sRun(script);
|
|
|
- if(script->error[0] != '\0') {
|
|
|
- logError(script->error, script->line);
|
|
|
+ if(runScript(script)) {
|
|
|
+ sDelete(script);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ int id = scripts.scriptId++;
|
|
|
+ scripts.scripts.tryEmplace(id, script);
|
|
|
+ return id;
|
|
|
+}
|
|
|
+
|
|
|
+void Snuvi::termAll() {
|
|
|
+ for(auto& entry : scripts.scripts) {
|
|
|
+ sDelete(entry.value);
|
|
|
+ }
|
|
|
+ scripts.scripts.clear();
|
|
|
+}
|
|
|
+
|
|
|
+void Snuvi::callEvent(Event e) {
|
|
|
+ event = e;
|
|
|
+ for(auto& entry : scripts.scripts) {
|
|
|
+ if(runScript(entry.value)) {
|
|
|
+ sDelete(entry.value);
|
|
|
+ scripts.scripts.remove(entry.getKey());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static int32 readChar(int& index, const char* s) {
|
|
|
+ if(s[index] == '\0') {
|
|
|
+ return '\0';
|
|
|
+ }
|
|
|
+ return s[index++];
|
|
|
+}
|
|
|
+
|
|
|
+Pointer Snuvi::toString(Script* sc, const char* s) {
|
|
|
+ List<int> data;
|
|
|
+ int index = 0;
|
|
|
+ while(s[index] != '\0') {
|
|
|
+ int32 c = readChar(index, s);
|
|
|
+ if((c & 0xE0) == 0xC0) {
|
|
|
+ c = ((c & 0x1F) << 6) | (readChar(index, s) & 0x3F);
|
|
|
+ } else if((c & 0xF0) == 0xE0) {
|
|
|
+ c = ((c & 0xF) << 12) | ((readChar(index, s) & 0x3F) << 6);
|
|
|
+ c |= readChar(index, s) & 0x3F;
|
|
|
+ } else if((c & 0xF8) == 0xF0) {
|
|
|
+ c = ((c & 0x7) << 18) | ((readChar(index, s) & 0x3F) << 12);
|
|
|
+ c |= (readChar(index, s) & 0x3F) << 6;
|
|
|
+ c |= readChar(index, s) & 0x3F;
|
|
|
+ }
|
|
|
+ data.add(c);
|
|
|
+ }
|
|
|
+ Pointer p;
|
|
|
+ p.offset = 0;
|
|
|
+ p.array = asAllocate(&sc->arrays, sizeof(int32), data.getLength());
|
|
|
+ printf("%d wsdfdg\n", data.getLength());
|
|
|
+ SnuviArray* array = asGet(&sc->arrays, p.array);
|
|
|
+ if(array == nullptr) {
|
|
|
+ sError(sc, "cannot allocate string memory");
|
|
|
+ p.offset = -1;
|
|
|
+ p.array = -1;
|
|
|
+ } else {
|
|
|
+ memcpy(array->data, data.begin(), sizeof(int32) * data.getLength());
|
|
|
}
|
|
|
- sDelete(script);
|
|
|
+ return p;
|
|
|
}
|