ByteCodePrinter.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include <stdarg.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "utils/ByteCodePrinter.h"
  5. #define LINE_LENGTH 80
  6. static ByteCode* code;
  7. static int readIndex;
  8. static int line;
  9. static char buffer[LINE_LENGTH];
  10. static int bIndex;
  11. static void btPrintHeading() {
  12. puts("| Index | Line | Operation | Argument 1 | Argument 2 |");
  13. puts("|--------|-------|----------------------|------------|------------|");
  14. }
  15. static void btAdd(const char* format, ...) {
  16. va_list args;
  17. va_start(args, format);
  18. bIndex += vsnprintf(buffer + bIndex, LINE_LENGTH - bIndex, format, args);
  19. va_end(args);
  20. }
  21. static void btFillBase() {
  22. buffer[0] = '\0';
  23. bIndex = 0;
  24. btAdd("| %6d | %5d |", readIndex - 1, line);
  25. }
  26. static void btRead(void* buffer, int length) {
  27. if(readIndex + length > code->length) {
  28. return;
  29. }
  30. memcpy(buffer, code->code + readIndex, length);
  31. readIndex += length;
  32. }
  33. static void btAddOperation(const char* s) {
  34. if(s[0] != '\0' && s[1] != '\0' && s[2] != '\0' && s[3] != '\0') {
  35. s += 3;
  36. }
  37. btAdd(" %20s |", s);
  38. }
  39. static void btAddInt() {
  40. int value = 0;
  41. btRead(&value, sizeof(int));
  42. btAdd(" %10d |", value);
  43. }
  44. static void btAddLong() {
  45. long value = 0;
  46. btRead(&value, sizeof(long));
  47. btAdd(" %10d |", value);
  48. }
  49. static void btAddByte() {
  50. char value = 0;
  51. btRead(&value, sizeof(char));
  52. btAdd(" %10d |", (int)value);
  53. }
  54. static void btAddFloat() {
  55. float value = 0;
  56. btRead(&value, sizeof(float));
  57. btAdd(" %10.2f |", value);
  58. }
  59. static void btAddFiller() {
  60. btAdd(" |");
  61. }
  62. static void sPrintLine() {
  63. btRead(&line, 2);
  64. printf("| %6d |-------|----------------------|------------|------------|\n",
  65. readIndex - 3);
  66. }
  67. static void btPrintOp(const char* op) {
  68. btFillBase();
  69. btAddOperation(op);
  70. btAddFiller();
  71. btAddFiller();
  72. puts(buffer);
  73. }
  74. static void btPrintInt(const char* op) {
  75. btFillBase();
  76. btAddOperation(op);
  77. btAddInt();
  78. btAddFiller();
  79. puts(buffer);
  80. }
  81. static void btPrintLong(const char* op) {
  82. btFillBase();
  83. btAddOperation(op);
  84. btAddLong();
  85. btAddFiller();
  86. puts(buffer);
  87. }
  88. static void btPrintByte(const char* op) {
  89. btFillBase();
  90. btAddOperation(op);
  91. btAddByte();
  92. btAddFiller();
  93. puts(buffer);
  94. }
  95. static void btPrintInt2(const char* op) {
  96. btFillBase();
  97. btAddOperation(op);
  98. btAddInt();
  99. btAddInt();
  100. puts(buffer);
  101. }
  102. static void btPrintFloat(const char* op) {
  103. btFillBase();
  104. btAddOperation(op);
  105. btAddFloat();
  106. btAddFiller();
  107. puts(buffer);
  108. }
  109. #define PRINT_OP_BASE(op, name) \
  110. case op: \
  111. btPrint##name(#op); \
  112. break;
  113. #define PRINT_OP(op) PRINT_OP_BASE(op, Op)
  114. #define PRINT_OP_BYTE(op) PRINT_OP_BASE(op, Byte)
  115. #define PRINT_OP_INT(op) PRINT_OP_BASE(op, Int)
  116. #define PRINT_OP_INT2(op) PRINT_OP_BASE(op, Int2)
  117. #define PRINT_OP_LONG(op) PRINT_OP_BASE(op, Long)
  118. #define PRINT_INTEGRAL_OP(op) PRINT_OP(OP_##op##_INT) PRINT_OP(OP_##op##_LONG)
  119. #define PRINT_NUMBER_OP(op) PRINT_INTEGRAL_OP(op) PRINT_OP(OP_##op##_FLOAT)
  120. #define PRINT_TYPES(TYPE) \
  121. PRINT_OP(OP_STORE_##TYPE); \
  122. PRINT_OP(OP_LOAD_##TYPE); \
  123. PRINT_OP_INT(OP_RETURN_##TYPE); \
  124. PRINT_OP(OP_EQUAL_##TYPE);
  125. static void btConsumeOperation() {
  126. Operation op = code->code[readIndex++];
  127. switch(op) {
  128. PRINT_TYPES(INT);
  129. PRINT_TYPES(LONG);
  130. PRINT_TYPES(BOOL);
  131. PRINT_TYPES(FLOAT);
  132. PRINT_OP(OP_NOTHING);
  133. PRINT_OP_LONG(OP_PUSH_LONG);
  134. PRINT_OP_INT(OP_PUSH_INT);
  135. PRINT_OP_BASE(OP_PUSH_FLOAT, Float);
  136. PRINT_OP(OP_PUSH_TRUE);
  137. PRINT_OP(OP_PUSH_FALSE);
  138. PRINT_OP(OP_PUSH_NULLPTR);
  139. PRINT_NUMBER_OP(ADD);
  140. PRINT_NUMBER_OP(SUB);
  141. PRINT_NUMBER_OP(MUL);
  142. PRINT_NUMBER_OP(DIV);
  143. PRINT_OP(OP_MOD_INT);
  144. PRINT_OP(OP_MOD_LONG);
  145. PRINT_NUMBER_OP(INVERT_SIGN);
  146. PRINT_NUMBER_OP(LESS);
  147. PRINT_NUMBER_OP(GREATER);
  148. PRINT_OP(OP_NOT);
  149. PRINT_OP(OP_AND);
  150. PRINT_OP(OP_OR);
  151. PRINT_INTEGRAL_OP(BIT_NOT);
  152. PRINT_INTEGRAL_OP(BIT_AND);
  153. PRINT_INTEGRAL_OP(BIT_OR);
  154. PRINT_INTEGRAL_OP(BIT_XOR);
  155. PRINT_INTEGRAL_OP(LEFT_SHIFT);
  156. PRINT_INTEGRAL_OP(RIGHT_SHIFT);
  157. PRINT_OP_INT(OP_GOTO);
  158. PRINT_OP_INT(OP_IF_GOTO);
  159. PRINT_OP_INT(OP_PEEK_FALSE_GOTO);
  160. PRINT_OP_INT(OP_PEEK_TRUE_GOTO);
  161. PRINT_OP_INT2(OP_GOSUB);
  162. PRINT_OP_INT(OP_RETURN);
  163. PRINT_OP_INT(OP_RETURN_POINTER);
  164. PRINT_OP_INT2(OP_RESERVE);
  165. PRINT_OP_INT(OP_DEREFERENCE_VAR);
  166. PRINT_OP(OP_REFERENCE);
  167. PRINT_OP(OP_DUPLICATE_REFERENCE);
  168. PRINT_OP_INT(OP_ADD_REFERENCE);
  169. PRINT_OP_INT(OP_NEW);
  170. PRINT_OP(OP_DELETE);
  171. PRINT_OP(OP_LENGTH);
  172. PRINT_OP_INT(OP_LOAD);
  173. PRINT_OP(OP_STORE_POINTER);
  174. PRINT_OP(OP_EQUAL_POINTER);
  175. PRINT_OP_BYTE(OP_PUSH_PRE_CHANGE_INT);
  176. PRINT_OP_BYTE(OP_PUSH_POST_CHANGE_INT);
  177. PRINT_OP_BYTE(OP_CHANGE_INT);
  178. PRINT_OP_BYTE(OP_PUSH_PRE_CHANGE_LONG);
  179. PRINT_OP_BYTE(OP_PUSH_POST_CHANGE_LONG);
  180. PRINT_OP_BYTE(OP_CHANGE_LONG);
  181. PRINT_OP(OP_INT_TO_FLOAT);
  182. PRINT_OP(OP_FLOAT_TO_INT);
  183. PRINT_OP(OP_INT_TO_LONG);
  184. PRINT_OP(OP_LONG_TO_INT);
  185. PRINT_OP(OP_FLOAT_TO_LONG);
  186. PRINT_OP(OP_LONG_TO_FLOAT);
  187. PRINT_OP_INT(OP_CALL);
  188. case OP_LINE: sPrintLine(); break;
  189. }
  190. }
  191. void btPrint(ByteCode* bt) {
  192. code = bt;
  193. readIndex = 0;
  194. line = 0;
  195. btPrintHeading();
  196. while(readIndex < code->length) {
  197. btConsumeOperation();
  198. }
  199. }