bytecode.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * 文件名: bytecode.c
  3. * 目标: 管理ByteCode结构体的函数
  4. */
  5. #include <stdio.h>
  6. #include "aFun.h"
  7. #include "__bytecode.h"
  8. #include "tool.h"
  9. static af_ByteCode *makeByteCode(char prefix, FileLine line, FilePath path) {
  10. af_ByteCode *bt = calloc(1, sizeof(af_ByteCode));
  11. bt->line = line;
  12. bt->prefix = prefix;
  13. if (path != NULL)
  14. bt->path = pathCopy(path);
  15. return bt;
  16. }
  17. af_ByteCode *makeLiteralByteCode(char *literal_data, char *func, char prefix, FileLine line, FilePath path) {
  18. af_ByteCode *bt = makeByteCode(prefix, line, path);
  19. bt->type = literal;
  20. bt->literal.literal_data = strCopy(literal_data);
  21. bt->literal.func = strCopy(func);
  22. return bt;
  23. }
  24. af_ByteCode *makeVariableByteCode(char *var, char prefix, FileLine line, FilePath path) {
  25. af_ByteCode *bt = makeByteCode(prefix, line, path);
  26. bt->type = variable;
  27. bt->variable.name = strCopy(var);
  28. return bt;
  29. }
  30. /*
  31. * 函数名: countElement
  32. * 目标: 统计元素个数(不包括元素的子元素)
  33. */
  34. static bool countElement(af_ByteCode *element, ByteCodeUint *count, af_ByteCode **next) {
  35. ByteCodeUint to_next = 0; // 表示紧接着的元素都不纳入统计(指block的子元素)
  36. for (*count = 0; element != NULL; *next = element, element = element->next) {
  37. if (to_next == 0)
  38. (*count)++;
  39. else
  40. to_next--;
  41. if (element->type == block)
  42. to_next += element->block.elements;
  43. }
  44. if (to_next != 0)
  45. return false;
  46. return true;
  47. }
  48. af_ByteCode *makeBlockByteCode(enum af_BlockType type, af_ByteCode *element, char prefix, FileLine line, FilePath path, af_ByteCode **next) {
  49. af_ByteCode *bt = NULL;
  50. af_ByteCode *tmp = NULL;
  51. ByteCodeUint count = 0;
  52. if (next == NULL)
  53. next = &tmp;
  54. if (!countElement(element, &count, next))
  55. return NULL;
  56. bt = makeByteCode(prefix, line, path);
  57. bt->type = block;
  58. bt->block.type = type;
  59. bt->block.elements = count;
  60. bt->next = element;
  61. return bt;
  62. }
  63. af_ByteCode *connectByteCode(af_ByteCode **base, af_ByteCode *next) {
  64. while ((*base) != NULL)
  65. base = &((*base)->next);
  66. *base = next;
  67. while (next != NULL && next->next != NULL)
  68. next = next->next;
  69. return next;
  70. }
  71. af_ByteCode *copyByteCode(af_ByteCode *base, FilePath *path) {
  72. af_ByteCode *dest = NULL;
  73. af_ByteCode **pdest = &dest;
  74. for (NULL; base != NULL; base = base->next) {
  75. *pdest = makeByteCode(base->prefix, base->line, base->path);
  76. (*pdest)->type = base->type;
  77. switch (base->type) {
  78. case literal:
  79. (*pdest)->literal.literal_data = strCopy(base->literal.literal_data);
  80. (*pdest)->literal.func = strCopy(base->literal.func);
  81. break;
  82. case variable:
  83. (*pdest)->variable.name = strCopy(base->variable.name);
  84. break;
  85. case block:
  86. (*pdest)->block.elements = base->block.elements;
  87. (*pdest)->block.type = base->block.type;
  88. break;
  89. default:
  90. break;
  91. }
  92. }
  93. if (dest != NULL && path != NULL) {
  94. free(dest->path);
  95. dest->path = pathCopy(path);
  96. }
  97. return dest;
  98. }
  99. af_ByteCode *freeByteCode(af_ByteCode *bt) {
  100. if (bt == NULL)
  101. return NULL;
  102. af_ByteCode *next = bt->next;
  103. free(bt->path);
  104. switch (bt->type) {
  105. case literal:
  106. free(bt->literal.literal_data);
  107. free(bt->literal.func);
  108. break;
  109. case variable:
  110. free(bt->variable.name);
  111. break;
  112. default:
  113. break;
  114. }
  115. free(bt);
  116. return next;
  117. }
  118. bool freeByteCodeWithElement(af_ByteCode *bt, af_ByteCode **next) {
  119. ByteCodeUint count = 1; // 要释放的元素个数
  120. for (NULL; count != 0; count--) {
  121. if (bt == NULL)
  122. return false;
  123. if (bt->type == block)
  124. count += bt->block.elements;
  125. bt = freeByteCode(bt);
  126. }
  127. *next = bt;
  128. return true;
  129. }
  130. void freeAllByteCode(af_ByteCode *bt) {
  131. while (bt != NULL)
  132. bt = freeByteCode(bt);
  133. }
  134. #define Done(write) do{if(!(write)){return false;}}while(0)
  135. static bool writeByteCode(af_ByteCode *bt, FILE *file) {
  136. Done(byteWriteUint_8(file, bt->type));
  137. Done(byteWriteUint_8(file, bt->prefix));
  138. Done(byteWriteUint_32(file, bt->line));
  139. if (bt->path != NULL) {
  140. Done(byteWriteUint_8(file, true)); // 表示有path
  141. Done(byteWriteStr(file, bt->path));
  142. } else {
  143. Done(byteWriteUint_8(file, false)); // 表示无path
  144. }
  145. switch (bt->type) {
  146. case literal:
  147. Done(byteWriteStr(file, bt->literal.literal_data));
  148. Done(byteWriteStr(file, bt->literal.func));
  149. break;
  150. case variable:
  151. Done(byteWriteStr(file, bt->variable.name));
  152. break;
  153. case block:
  154. Done(byteWriteUint_8(file, bt->block.type));
  155. Done(byteWriteUint_32(file, bt->block.elements));
  156. break;
  157. default:
  158. break;
  159. }
  160. return true;
  161. }
  162. /*
  163. * 函数名: writeAllByteCode
  164. * 目标: 将ByteCode写入字节码文件中
  165. * 备注: 写入字节码时不做语义检查, 在读取时最语义检查即可
  166. */
  167. bool writeAllByteCode(af_ByteCode *bt, FILE *file) {
  168. uint32_t count = 0;
  169. if (bt == NULL || bt->path == NULL)
  170. return false;
  171. for (af_ByteCode *tmp = bt; tmp != NULL; tmp = tmp->next) // 统计个数
  172. count++;
  173. Done(byteWriteUint_32(file,count));
  174. for (NULL; bt != NULL; bt = bt->next) {
  175. if (!writeByteCode(bt, file))
  176. return false;
  177. }
  178. return true;
  179. }
  180. static bool readByteCode(af_ByteCode **bt, FILE *file) {
  181. uint8_t type;
  182. uint8_t prefix;
  183. uint32_t line;
  184. uint8_t have_path;
  185. char *path = NULL;
  186. Done(byteReadUint_8(file, &type));
  187. Done(byteReadUint_8(file, &prefix));
  188. Done(byteReadUint_32(file,&line));
  189. Done(byteReadUint_8(file, &(have_path)));
  190. if (have_path)
  191. Done(byteReadStr(file, &path));
  192. *bt = makeByteCode((char)prefix, line, path);
  193. free(path);
  194. (*bt)->type = type;
  195. switch (type) {
  196. case literal:
  197. Done(byteReadStr(file, &((*bt)->literal.literal_data)));
  198. Done(byteReadStr(file, &((*bt)->literal.func)));
  199. break;
  200. case variable:
  201. Done(byteReadStr(file, &((*bt)->variable.name)));
  202. break;
  203. case block: {
  204. uint8_t block_type;
  205. uint32_t elements;
  206. Done(byteReadUint_8(file, &block_type));
  207. Done(byteReadUint_32(file,&elements));
  208. (*bt)->block.type = block_type;
  209. (*bt)->block.elements = elements;
  210. break;
  211. }
  212. default:
  213. break;
  214. }
  215. return true;
  216. }
  217. /*
  218. * 函数名: writeAllByteCode
  219. * 目标: 将ByteCode写入字节码文件中
  220. * 备注: 写入字节码时不做语义检查, 在读取时最语义检查即可 【语义检查还未实现】
  221. */
  222. bool readAllByteCode(af_ByteCode **bt, FILE *file) {
  223. uint32_t count;
  224. Done(byteReadUint_32(file,&count));
  225. for (NULL; count != 0; count--, bt = &((*bt)->next)) {
  226. if(!readByteCode(bt, file))
  227. return false;
  228. }
  229. return true;
  230. }
  231. void printByteCode(af_ByteCode *bt) {
  232. for (NULL; bt != NULL; bt = bt->next) {
  233. switch (bt->type) {
  234. case literal:
  235. printf("literal: %s %s prefix: %d\n", bt->literal.literal_data, bt->literal.func, bt->prefix);
  236. break;
  237. case variable:
  238. printf("variable: %s prefix: %d\n", bt->variable.name, bt->prefix);
  239. break;
  240. case block:
  241. printf("variable: %d %d prefix: %d\n", bt->block.elements, bt->block.type, bt->prefix);
  242. break;
  243. default:
  244. printf("Unknow: %d prefix: %d\n", bt->type, bt->prefix);
  245. break;
  246. }
  247. }
  248. }