Snuvi.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "server/snuviscript/Snuvi.h"
  2. #include "Compiler.h"
  3. #include "libraries/Math.h"
  4. #include "libraries/Time.h"
  5. #include "tokenizer/Tokenizer.h"
  6. #include "utils/StringBuffer.h"
  7. #include "vm/Script.h"
  8. static Function function;
  9. static const char* unicode(int32 c) {
  10. static char buffer[5];
  11. int index = 0;
  12. if(c > 0xFFFF) {
  13. buffer[index++] = 0xF0 | ((c >> 18) & 0x07);
  14. buffer[index++] = 0x80 | ((c >> 12) & 0x3F);
  15. buffer[index++] = 0x80 | ((c >> 6) & 0x3F);
  16. buffer[index++] = 0x80 | (c & 0x3F);
  17. } else if(c > 0x7FF) {
  18. buffer[index++] = 0xE0 | ((c >> 12) & 0x0F);
  19. buffer[index++] = 0x80 | ((c >> 6) & 0x3F);
  20. buffer[index++] = 0x80 | (c & 0x3F);
  21. } else if(c > 0x7F) {
  22. buffer[index++] = 0xC0 | ((c >> 6) & 0x1F);
  23. buffer[index++] = 0x80 | (c & 0x3F);
  24. } else {
  25. buffer[index++] = c;
  26. }
  27. buffer[index++] = '\0';
  28. return buffer;
  29. }
  30. static void printString(Script* sc) {
  31. int length;
  32. Pointer p;
  33. if(!sPopPointer(sc, &p) || sGetPointerLength(sc, &p, &length)) {
  34. return;
  35. }
  36. for(int i = 0; i < length; i++) {
  37. const void* data = sCheckAddress(sc, &p, sizeof(int));
  38. if(data != nullptr) {
  39. int c;
  40. memcpy(&c, data, sizeof(int));
  41. printf(unicode(c));
  42. }
  43. p.offset += sizeof(int);
  44. }
  45. }
  46. static void initPrinter() {
  47. Snuvi::initFunction("print", printString);
  48. Snuvi::addStringArgument();
  49. Snuvi::addFunction();
  50. }
  51. struct Init {
  52. Init() {
  53. gfsInit();
  54. gstsInit();
  55. lTimeRegister();
  56. lMathRegister();
  57. initPrinter();
  58. }
  59. ~Init() {
  60. gfsDelete();
  61. gstsDelete();
  62. }
  63. };
  64. void Snuvi::init() {
  65. static Init init;
  66. }
  67. void Snuvi::initFunction(const char* name, ScriptFunction sf) {
  68. gfInit(&function, name, dtVoid(), sf);
  69. }
  70. void Snuvi::addStringArgument() {
  71. DataType string = dtConst(dtInt32());
  72. dtDereference(&string);
  73. gfAddArgument(&function, string);
  74. }
  75. void Snuvi::addFunction() {
  76. gfsAdd(&function);
  77. }
  78. static void logError(const char* msg, int line) {
  79. puts(msg);
  80. printf("line: %d\n", line);
  81. }
  82. void Snuvi::start(const char* path) {
  83. StringBuffer<256> s("resources/scripts/");
  84. s.append(path).append(".snuvi");
  85. if(tTokenize(s)) {
  86. logError(tGetError(), tGetLine());
  87. return;
  88. }
  89. ByteCode* code = cCompile();
  90. if(code == nullptr) {
  91. logError(cGetError(), cGetLine());
  92. return;
  93. }
  94. Script* script = sInit(code);
  95. sRun(script);
  96. if(script->error[0] != '\0') {
  97. logError(script->error, script->line);
  98. }
  99. sDelete(script);
  100. }