code.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * 文件名: code.c
  3. * 目标: 管理Code结构体的函数
  4. */
  5. #include <stdio.h>
  6. #include "aFun.h"
  7. #include "tool.h"
  8. #include "__code.h"
  9. /* Code 创建函数 */
  10. static af_Code *makeCode(char prefix, FileLine line, FilePath path);
  11. static af_Code *freeCode(af_Code *bt);
  12. /* Code 操作函数 */
  13. static void countElement(af_Code *element, CodeUint *elements, af_Code **next);
  14. /* Code IO函数 */
  15. static bool readCode(af_Code **bt, FILE *file);
  16. static bool writeCode(af_Code *bt, FILE *file);
  17. static af_Code *makeCode(char prefix, FileLine line, FilePath path) {
  18. af_Code *bt = calloc(1, sizeof(af_Code));
  19. bt->line = line;
  20. bt->prefix = prefix;
  21. if (path != NULL)
  22. bt->path = pathCopy(path);
  23. return bt;
  24. }
  25. af_Code *makeElementCode(char *var, char prefix, FileLine line, FilePath path) {
  26. if (prefix != NUL && strchr(LV_PREFIX, prefix) == NULL)
  27. prefix = NUL;
  28. af_Code *bt = makeCode(prefix, line, path);
  29. bt->type = code_element;
  30. bt->element.data = strCopy(var);
  31. return bt;
  32. }
  33. /*
  34. * 函数名: countElement
  35. * 目标: 统计元素个数(不包括元素的子元素)
  36. */
  37. static void countElement(af_Code *element, CodeUint *elements, af_Code **next) {
  38. CodeUint layer = 0;
  39. for (*elements = 0; element != NULL; *next = element, element = element->next) {
  40. if (layer == 0)
  41. (*elements)++;
  42. if (element->type == code_block)
  43. layer++;
  44. if (element->code_end)
  45. layer = layer - element->code_end;
  46. }
  47. }
  48. af_Code *makeBlockCode(enum af_BlockType type, af_Code *element, char prefix, FileLine line, FilePath path, af_Code **next) {
  49. af_Code *bt = NULL;
  50. af_Code *tmp = NULL; // 保存最后一个code的地址
  51. CodeUint elements = 0;
  52. if (next == NULL)
  53. next = &tmp;
  54. if (prefix != NUL && strchr(B_PREFIX, prefix) == NULL)
  55. prefix = NUL;
  56. countElement(element, &elements, next);
  57. bt = makeCode(prefix, line, path);
  58. bt->type = code_block;
  59. bt->block.type = type;
  60. bt->block.elements = elements;
  61. bt->next = element;
  62. if (*next != NULL)
  63. (*next)->code_end++;
  64. return bt;
  65. }
  66. af_Code *connectCode(af_Code **base, af_Code *next) {
  67. while ((*base) != NULL)
  68. base = &((*base)->next);
  69. *base = next;
  70. while (next != NULL && next->next != NULL)
  71. next = next->next;
  72. return next;
  73. }
  74. af_Code *copyCode(af_Code *base, FilePath *path) {
  75. af_Code *dest = NULL;
  76. af_Code **pdest = &dest;
  77. for (NULL; base != NULL; base = base->next) {
  78. *pdest = makeCode(base->prefix, base->line, base->path);
  79. (*pdest)->type = base->type;
  80. (*pdest)->code_end = base->code_end;
  81. switch (base->type) {
  82. case code_element:
  83. (*pdest)->element.data = strCopy(base->element.data);
  84. break;
  85. case code_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. static af_Code *freeCode(af_Code *bt) {
  100. af_Code *next = bt->next;
  101. free(bt->path);
  102. switch (bt->type) {
  103. case code_element:
  104. free(bt->element.data);
  105. break;
  106. default:
  107. break;
  108. }
  109. free(bt);
  110. return next;
  111. }
  112. void freeAllCode(af_Code *bt) {
  113. while (bt != NULL)
  114. bt = freeCode(bt);
  115. }
  116. bool getCodeBlockNext(af_Code *bt, af_Code **next) {
  117. if (bt->block.elements == 0) {
  118. *next = bt->next;
  119. return true;
  120. }
  121. CodeUint count = 1;
  122. bt = bt->next;
  123. for (NULL; count != 0; bt = bt->next) {
  124. if (bt == NULL)
  125. return false;
  126. if (bt->type == code_block)
  127. count++;
  128. count = count - bt->code_end;
  129. }
  130. *next = bt;
  131. return true;
  132. }
  133. #define Done(write) do{if(!(write)){return false;}}while(0)
  134. static bool writeCode(af_Code *bt, FILE *file) {
  135. Done(byteWriteUint_8(file, bt->type));
  136. Done(byteWriteUint_8(file, bt->prefix));
  137. Done(byteWriteUint_32(file, bt->line));
  138. Done(byteWriteUint_32(file, bt->code_end));
  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 code_element:
  147. Done(byteWriteStr(file, bt->element.data));
  148. break;
  149. case code_block:
  150. Done(byteWriteUint_8(file, bt->block.type));
  151. Done(byteWriteUint_32(file, bt->block.elements));
  152. break;
  153. default:
  154. break;
  155. }
  156. return true;
  157. }
  158. /*
  159. * 函数名: writeAllCode
  160. * 目标: 将Code写入字节码文件中
  161. * 备注: 写入字节码时不做语义检查, 在读取时最语义检查即可
  162. */
  163. bool writeAllCode(af_Code *bt, FILE *file) {
  164. uint32_t count = 0;
  165. if (bt == NULL || bt->path == NULL)
  166. return false;
  167. for (af_Code *tmp = bt; tmp != NULL; tmp = tmp->next) // 统计个数
  168. count++;
  169. Done(byteWriteUint_32(file,count));
  170. for (NULL; bt != NULL; bt = bt->next) {
  171. if (!writeCode(bt, file))
  172. return false;
  173. }
  174. return true;
  175. }
  176. static bool readCode(af_Code **bt, FILE *file) {
  177. uint8_t type;
  178. uint8_t prefix;
  179. uint32_t line;
  180. uint8_t have_path;
  181. uint32_t code_end;
  182. char *path = NULL;
  183. Done(byteReadUint_8(file, &type));
  184. Done(byteReadUint_8(file, &prefix));
  185. Done(byteReadUint_32(file,&line));
  186. Done(byteReadUint_8(file, &(have_path)));
  187. if (have_path)
  188. Done(byteReadStr(file, &path));
  189. Done(byteReadUint_32(file, &code_end));
  190. *bt = makeCode((char)prefix, line, path);
  191. free(path);
  192. (*bt)->type = type;
  193. (*bt)->code_end = code_end;
  194. switch (type) {
  195. case code_element:
  196. Done(byteReadStr(file, &((*bt)->element.data)));
  197. break;
  198. case code_block: {
  199. uint8_t block_type;
  200. uint32_t elements;
  201. Done(byteReadUint_8(file, &block_type));
  202. Done(byteReadUint_32(file,&elements));
  203. (*bt)->block.type = block_type;
  204. (*bt)->block.elements = elements;
  205. break;
  206. }
  207. default:
  208. break;
  209. }
  210. return true;
  211. }
  212. bool readAllCode(af_Code **bt, FILE *file) {
  213. uint32_t count;
  214. Done(byteReadUint_32(file,&count));
  215. for (NULL; count != 0; count--, bt = &((*bt)->next)) {
  216. if(!readCode(bt, file))
  217. return false;
  218. }
  219. return true;
  220. }
  221. void printCode(af_Code *bt) {
  222. for (NULL; bt != NULL; bt = bt->next) {
  223. switch (bt->type) {
  224. case code_element:
  225. printf("code_element: %s prefix: %d\n", bt->element.data, bt->prefix);
  226. break;
  227. case code_block:
  228. printf("code_block: %d %d prefix: %d\n", bt->block.elements, bt->block.type, bt->prefix);
  229. break;
  230. default:
  231. printf("Unknow: %d prefix: %d\n", bt->type, bt->prefix);
  232. break;
  233. }
  234. }
  235. }