ByteCodePrinter.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include <stdarg.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "Types.h"
  5. #include "utils/ByteCodePrinter.h"
  6. #define LINE_LENGTH 80
  7. static ByteCode* code;
  8. static int readIndex;
  9. static int line;
  10. static char buffer[LINE_LENGTH];
  11. static int bIndex;
  12. static void btPrintHeading() {
  13. puts("| Index | Line | Operation | Argument 1 | Argument 2 |");
  14. puts("|--------|-------|----------------------|------------|------------|");
  15. }
  16. static void btAdd(const char* format, ...) {
  17. va_list args;
  18. va_start(args, format);
  19. bIndex += vsnprintf(buffer + bIndex, LINE_LENGTH - bIndex, format, args);
  20. va_end(args);
  21. }
  22. static void btFillBase() {
  23. buffer[0] = '\0';
  24. bIndex = 0;
  25. btAdd("| %6d | %5d |", readIndex - 1, line);
  26. }
  27. static void btRead(void* buffer, int length) {
  28. if(readIndex + length > code->length) {
  29. return;
  30. }
  31. memcpy(buffer, code->code + readIndex, length);
  32. readIndex += length;
  33. }
  34. static void btAddOperation(const char* s) {
  35. if(s[0] != '\0' && s[1] != '\0' && s[2] != '\0' && s[3] != '\0') {
  36. s += 3;
  37. }
  38. btAdd(" %20s |", s);
  39. }
  40. static void btAddInt32() {
  41. int32 value = 0;
  42. btRead(&value, sizeof(int32));
  43. btAdd(" %10d |", value);
  44. }
  45. static void btAddInt64() {
  46. int64 value = 0;
  47. btRead(&value, sizeof(int64));
  48. btAdd(" %10ld |", value);
  49. }
  50. static void btAddInt8() {
  51. int8 value = 0;
  52. btRead(&value, sizeof(int8));
  53. btAdd(" %10d |", (int32)value);
  54. }
  55. static void btAddFloat() {
  56. float value = 0;
  57. btRead(&value, sizeof(float));
  58. btAdd(" %10.2f |", value);
  59. }
  60. static void btAddText() {
  61. int32 length = 0;
  62. btRead(&length, sizeof(int32));
  63. for(int i = 0; i < length; i++) {
  64. int32 c;
  65. btRead(&c, sizeof(int32));
  66. }
  67. btAdd(" %10s |", "Text");
  68. }
  69. static void btAddFiller() {
  70. btAdd(" |");
  71. }
  72. static void sPrintLine() {
  73. btRead(&line, 2);
  74. printf("| %6d |-------|----------------------|------------|------------|\n",
  75. readIndex - 3);
  76. }
  77. static void btPrintOp(const char* op) {
  78. btFillBase();
  79. btAddOperation(op);
  80. btAddFiller();
  81. btAddFiller();
  82. puts(buffer);
  83. }
  84. static void btPrintInt32(const char* op) {
  85. btFillBase();
  86. btAddOperation(op);
  87. btAddInt32();
  88. btAddFiller();
  89. puts(buffer);
  90. }
  91. static void btPrintInt64(const char* op) {
  92. btFillBase();
  93. btAddOperation(op);
  94. btAddInt64();
  95. btAddFiller();
  96. puts(buffer);
  97. }
  98. static void btPrintInt8(const char* op) {
  99. btFillBase();
  100. btAddOperation(op);
  101. btAddInt8();
  102. btAddFiller();
  103. puts(buffer);
  104. }
  105. static void btPrint2Int32(const char* op) {
  106. btFillBase();
  107. btAddOperation(op);
  108. btAddInt32();
  109. btAddInt32();
  110. puts(buffer);
  111. }
  112. static void btPrintFloat(const char* op) {
  113. btFillBase();
  114. btAddOperation(op);
  115. btAddFloat();
  116. btAddFiller();
  117. puts(buffer);
  118. }
  119. static void btPrintText(const char* op) {
  120. btFillBase();
  121. btAddOperation(op);
  122. btAddText();
  123. btAddFiller();
  124. puts(buffer);
  125. }
  126. #define PRINT_OP_BASE(op, name) \
  127. case op: \
  128. btPrint##name(#op); \
  129. break;
  130. #define PRINT_OP(op) PRINT_OP_BASE(op, Op)
  131. #define PRINT_OP_INT8(op) PRINT_OP_BASE(op, Int8)
  132. #define PRINT_OP_INT32(op) PRINT_OP_BASE(op, Int32)
  133. #define PRINT_OP_2INT32(op) PRINT_OP_BASE(op, 2Int32)
  134. #define PRINT_OP_INT64(op) PRINT_OP_BASE(op, Int64)
  135. #define PRINT_INTEGRAL_OP(op) \
  136. PRINT_OP(OP_##op##_INT32) PRINT_OP(OP_##op##_INT64)
  137. #define PRINT_NUMBER_OP(op) PRINT_INTEGRAL_OP(op) PRINT_OP(OP_##op##_FLOAT)
  138. #define PRINT_TYPES(TYPE) \
  139. PRINT_OP(OP_STORE_##TYPE); \
  140. PRINT_OP(OP_LOAD_##TYPE); \
  141. PRINT_OP_INT32(OP_RETURN_##TYPE); \
  142. PRINT_OP(OP_EQUAL_##TYPE); \
  143. PRINT_OP(OP_NOT_EQUAL_##TYPE);
  144. static void btConsumeOperation() {
  145. Operation op = code->code[readIndex++];
  146. switch(op) {
  147. PRINT_TYPES(INT32);
  148. PRINT_TYPES(INT64);
  149. PRINT_TYPES(BOOL);
  150. PRINT_TYPES(FLOAT);
  151. PRINT_OP(OP_NOTHING);
  152. PRINT_OP_INT32(OP_PUSH_INT32);
  153. PRINT_OP_INT64(OP_PUSH_INT64);
  154. PRINT_OP_BASE(OP_PUSH_FLOAT, Float);
  155. PRINT_OP(OP_PUSH_TRUE);
  156. PRINT_OP(OP_PUSH_FALSE);
  157. PRINT_OP(OP_PUSH_NULLPTR);
  158. PRINT_OP_BASE(OP_PUSH_TEXT, Text);
  159. PRINT_NUMBER_OP(ADD);
  160. PRINT_NUMBER_OP(SUB);
  161. PRINT_NUMBER_OP(MUL);
  162. PRINT_NUMBER_OP(DIV);
  163. PRINT_INTEGRAL_OP(MOD);
  164. PRINT_NUMBER_OP(INVERT_SIGN);
  165. PRINT_NUMBER_OP(LESS);
  166. PRINT_NUMBER_OP(LESS_EQUAL);
  167. PRINT_NUMBER_OP(GREATER);
  168. PRINT_NUMBER_OP(GREATER_EQUAL);
  169. PRINT_OP(OP_NOT);
  170. PRINT_OP(OP_AND);
  171. PRINT_OP(OP_OR);
  172. PRINT_INTEGRAL_OP(BIT_NOT);
  173. PRINT_INTEGRAL_OP(BIT_AND);
  174. PRINT_INTEGRAL_OP(BIT_OR);
  175. PRINT_INTEGRAL_OP(BIT_XOR);
  176. PRINT_INTEGRAL_OP(LEFT_SHIFT);
  177. PRINT_INTEGRAL_OP(RIGHT_SHIFT);
  178. PRINT_OP_INT32(OP_GOTO);
  179. PRINT_OP_INT32(OP_IF_GOTO);
  180. PRINT_OP_INT32(OP_PEEK_FALSE_GOTO);
  181. PRINT_OP_INT32(OP_PEEK_TRUE_GOTO);
  182. PRINT_OP_2INT32(OP_GOSUB);
  183. PRINT_OP_INT32(OP_RETURN);
  184. PRINT_OP_INT32(OP_RETURN_POINTER);
  185. PRINT_OP_2INT32(OP_RESERVE);
  186. PRINT_OP_INT32(OP_DEREFERENCE_VAR);
  187. PRINT_OP(OP_REFERENCE);
  188. PRINT_OP(OP_DUPLICATE_REFERENCE);
  189. PRINT_OP_INT32(OP_ADD_REFERENCE);
  190. PRINT_OP_INT32(OP_NEW);
  191. PRINT_OP(OP_DELETE);
  192. PRINT_OP(OP_LENGTH);
  193. PRINT_OP_INT32(OP_LOAD);
  194. PRINT_OP(OP_STORE_POINTER);
  195. PRINT_OP(OP_EQUAL_POINTER);
  196. PRINT_OP(OP_NOT_EQUAL_POINTER);
  197. PRINT_OP_INT8(OP_PUSH_PRE_CHANGE_INT32);
  198. PRINT_OP_INT8(OP_PUSH_POST_CHANGE_INT32);
  199. PRINT_OP_INT8(OP_CHANGE_INT32);
  200. PRINT_OP_INT8(OP_PUSH_PRE_CHANGE_INT64);
  201. PRINT_OP_INT8(OP_PUSH_POST_CHANGE_INT64);
  202. PRINT_OP_INT8(OP_CHANGE_INT64);
  203. PRINT_OP(OP_INT32_TO_FLOAT);
  204. PRINT_OP(OP_FLOAT_TO_INT32);
  205. PRINT_OP(OP_INT32_TO_INT64);
  206. PRINT_OP(OP_INT64_TO_INT32);
  207. PRINT_OP(OP_FLOAT_TO_INT64);
  208. PRINT_OP(OP_INT64_TO_FLOAT);
  209. PRINT_OP_INT32(OP_CALL);
  210. case OP_LINE: sPrintLine(); break;
  211. }
  212. }
  213. void btPrint(ByteCode* bt) {
  214. code = bt;
  215. readIndex = 0;
  216. line = 0;
  217. btPrintHeading();
  218. while(readIndex < code->length) {
  219. btConsumeOperation();
  220. }
  221. }