ByteCodePrinter.c 6.8 KB

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