#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); }