|
@@ -0,0 +1,112 @@
|
|
|
+#include "server/snuviscript/Snuvi.h"
|
|
|
+#include "Compiler.h"
|
|
|
+#include "libraries/Math.h"
|
|
|
+#include "libraries/Time.h"
|
|
|
+#include "tokenizer/Tokenizer.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;
|
|
|
+ if(c > 0xFFFF) {
|
|
|
+ buffer[index++] = 0xF0 | ((c >> 18) & 0x07);
|
|
|
+ buffer[index++] = 0x80 | ((c >> 12) & 0x3F);
|
|
|
+ buffer[index++] = 0x80 | ((c >> 6) & 0x3F);
|
|
|
+ buffer[index++] = 0x80 | (c & 0x3F);
|
|
|
+ } else if(c > 0x7FF) {
|
|
|
+ buffer[index++] = 0xE0 | ((c >> 12) & 0x0F);
|
|
|
+ buffer[index++] = 0x80 | ((c >> 6) & 0x3F);
|
|
|
+ buffer[index++] = 0x80 | (c & 0x3F);
|
|
|
+ } else if(c > 0x7F) {
|
|
|
+ buffer[index++] = 0xC0 | ((c >> 6) & 0x1F);
|
|
|
+ buffer[index++] = 0x80 | (c & 0x3F);
|
|
|
+ } else {
|
|
|
+ buffer[index++] = c;
|
|
|
+ }
|
|
|
+ buffer[index++] = '\0';
|
|
|
+ return buffer;
|
|
|
+}
|
|
|
+
|
|
|
+static void printString(Script* sc) {
|
|
|
+ int length;
|
|
|
+ Pointer p;
|
|
|
+ if(!sPopPointer(sc, &p) || sGetPointerLength(sc, &p, &length)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for(int i = 0; i < length; i++) {
|
|
|
+ const void* data = sCheckAddress(sc, &p, sizeof(int));
|
|
|
+ if(data != nullptr) {
|
|
|
+ int c;
|
|
|
+ memcpy(&c, data, sizeof(int));
|
|
|
+ printf(unicode(c));
|
|
|
+ }
|
|
|
+ p.offset += sizeof(int);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void initPrinter() {
|
|
|
+ Snuvi::initFunction("print", printString);
|
|
|
+ Snuvi::addStringArgument();
|
|
|
+ Snuvi::addFunction();
|
|
|
+}
|
|
|
+
|
|
|
+struct Init {
|
|
|
+ Init() {
|
|
|
+ gfsInit();
|
|
|
+ gstsInit();
|
|
|
+ lTimeRegister();
|
|
|
+ lMathRegister();
|
|
|
+ initPrinter();
|
|
|
+ }
|
|
|
+
|
|
|
+ ~Init() {
|
|
|
+ gfsDelete();
|
|
|
+ gstsDelete();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+void Snuvi::init() {
|
|
|
+ static Init init;
|
|
|
+}
|
|
|
+
|
|
|
+void Snuvi::initFunction(const char* name, ScriptFunction sf) {
|
|
|
+ gfInit(&function, name, dtVoid(), sf);
|
|
|
+}
|
|
|
+
|
|
|
+void Snuvi::addStringArgument() {
|
|
|
+ DataType string = dtConst(dtInt32());
|
|
|
+ dtDereference(&string);
|
|
|
+ gfAddArgument(&function, string);
|
|
|
+}
|
|
|
+
|
|
|
+void Snuvi::addFunction() {
|
|
|
+ gfsAdd(&function);
|
|
|
+}
|
|
|
+
|
|
|
+static void logError(const char* msg, int line) {
|
|
|
+ puts(msg);
|
|
|
+ printf("line: %d\n", line);
|
|
|
+}
|
|
|
+
|
|
|
+void Snuvi::start(const char* path) {
|
|
|
+ StringBuffer<256> s("resources/scripts/");
|
|
|
+ s.append(path).append(".snuvi");
|
|
|
+ if(tTokenize(s)) {
|
|
|
+ logError(tGetError(), tGetLine());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ ByteCode* code = cCompile();
|
|
|
+ if(code == nullptr) {
|
|
|
+ logError(cGetError(), cGetLine());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Script* script = sInit(code);
|
|
|
+ sRun(script);
|
|
|
+ if(script->error[0] != '\0') {
|
|
|
+ logError(script->error, script->line);
|
|
|
+ }
|
|
|
+ sDelete(script);
|
|
|
+}
|