code.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. /*
  2. * 文件名: code.c
  3. * 目标: 管理Code结构体的函数
  4. */
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include "aFunCore.h"
  8. #include "tool.h"
  9. #include "__code.h"
  10. /* Code 创建函数 */
  11. static af_Code *makeCode(char prefix, FileLine line, FilePath path);
  12. static af_Code *freeCode(af_Code *bt);
  13. /* Code 相关操作 */
  14. static bool countElement(af_Code *element, CodeInt *elements, af_Code **next);
  15. /* Code IO函数 */
  16. static bool readCode(af_Code **bt, FILE *file);
  17. static bool writeCode(af_Code *bt, FILE *file);
  18. /* Code 转换STR函数 */
  19. struct af_BlockEnd {
  20. char ch;
  21. struct af_BlockEnd *next;
  22. };
  23. static bool checkElementData(char *data);
  24. static char *codeToStr_(af_Code *code, CodeInt *layer, struct af_BlockEnd **bn);
  25. static char *codeEndToStr(CodeInt code_end, CodeInt *layer, struct af_BlockEnd **bn);
  26. static af_Code *makeCode(char prefix, FileLine line, FilePath path) {
  27. af_Code *bt = calloc(1, sizeof(af_Code));
  28. bt->line = line;
  29. bt->prefix = prefix;
  30. if (path != NULL)
  31. bt->path = pathCopy(path);
  32. return bt;
  33. }
  34. af_Code *makeElementCode(char *var, char prefix, FileLine line, FilePath path) {
  35. if (prefix != NUL && strchr(E_PREFIX, prefix) == NULL)
  36. prefix = NUL;
  37. af_Code *bt = makeCode(prefix, line, path);
  38. bt->type = code_element;
  39. bt->element.data = strCopy(var);
  40. return bt;
  41. }
  42. /*
  43. * 函数名: countElement
  44. * 目标: 统计元素个数(不包括元素的子元素)
  45. */
  46. static bool countElement(af_Code *element, CodeInt *elements, af_Code **next) {
  47. CodeInt layer = 0;
  48. for (*elements = 0; element != NULL; *next = element, element = element->next) {
  49. if (layer == 0)
  50. (*elements)++;
  51. if (layer < 0)
  52. return false;
  53. if (element->type == code_block)
  54. layer++;
  55. if (element->code_end)
  56. layer = layer - element->code_end;
  57. }
  58. return true;
  59. }
  60. af_Code *makeBlockCode(enum af_BlockType type, af_Code *element, char prefix, FileLine line, FilePath path, af_Code **next) {
  61. af_Code *bt = NULL;
  62. af_Code *tmp = NULL; // 保存最后一个code的地址
  63. CodeInt elements = 0;
  64. if (next == NULL)
  65. next = &tmp;
  66. if (prefix != NUL && strchr(B_PREFIX, prefix) == NULL)
  67. prefix = NUL;
  68. if (!countElement(element, &elements, next))
  69. return NULL;
  70. bt = makeCode(prefix, line, path);
  71. bt->type = code_block;
  72. bt->block.type = type;
  73. bt->block.elements = elements;
  74. bt->next = element;
  75. if (*next != NULL)
  76. (*next)->code_end++;
  77. return bt;
  78. }
  79. af_Code *pushCode(af_Code **base, af_Code *next) {
  80. while ((*base) != NULL)
  81. base = &((*base)->next);
  82. *base = next;
  83. while (next != NULL && next->next != NULL)
  84. next = next->next;
  85. return next;
  86. }
  87. af_Code *copyCode(af_Code *base, FilePath *path) {
  88. af_Code *dest = NULL;
  89. af_Code **pdest = &dest;
  90. for (NULL; base != NULL; base = base->next) {
  91. *pdest = makeCode(base->prefix, base->line, base->path);
  92. (*pdest)->type = base->type;
  93. (*pdest)->code_end = base->code_end;
  94. switch (base->type) {
  95. case code_element:
  96. (*pdest)->element.data = strCopy(base->element.data);
  97. break;
  98. case code_block:
  99. (*pdest)->block.elements = base->block.elements;
  100. (*pdest)->block.type = base->block.type;
  101. break;
  102. default:
  103. break;
  104. }
  105. }
  106. if (dest != NULL && path != NULL) {
  107. free(dest->path);
  108. dest->path = pathCopy(path);
  109. }
  110. return dest;
  111. }
  112. static af_Code *freeCode(af_Code *bt) {
  113. af_Code *next = bt->next;
  114. free(bt->path);
  115. switch (bt->type) {
  116. case code_element:
  117. free(bt->element.data);
  118. break;
  119. default:
  120. break;
  121. }
  122. free(bt);
  123. return next;
  124. }
  125. void freeAllCode(af_Code *bt) {
  126. while (bt != NULL)
  127. bt = freeCode(bt);
  128. }
  129. af_Code *getCodeNext(af_Code *bt) {
  130. if (bt->type == code_element || bt->block.elements == 0) {
  131. return bt->next;
  132. }
  133. CodeInt layer = 1;
  134. bt = bt->next; // 跳过第一个code_block
  135. while (layer > 0) {
  136. if (bt->type == code_block && bt->block.elements != 0)
  137. layer++;
  138. layer = layer - bt->code_end;
  139. bt = bt->next;
  140. }
  141. if (layer == 0) // 当layer小于0时, 认为已经无next, 即连续跳出了多层
  142. return bt;
  143. return NULL;
  144. }
  145. af_Code *getCodeElement(af_Code *bt) {
  146. if (bt->type == code_element || bt->block.elements == 0)
  147. return NULL;
  148. return bt->next;
  149. }
  150. #define Done(write) do{if(!(write)){return false;}}while(0)
  151. static bool writeCode(af_Code *bt, FILE *file) {
  152. Done(byteWriteUint_8(file, bt->type));
  153. Done(byteWriteUint_8(file, bt->prefix));
  154. Done(byteWriteUint_32(file, bt->line));
  155. Done(byteWriteUint_32(file, bt->code_end));
  156. if (bt->path != NULL) {
  157. Done(byteWriteUint_8(file, true)); // 表示有path
  158. Done(byteWriteStr(file, bt->path));
  159. } else {
  160. Done(byteWriteUint_8(file, false)); // 表示无path
  161. }
  162. switch (bt->type) {
  163. case code_element:
  164. Done(byteWriteStr(file, bt->element.data));
  165. break;
  166. case code_block:
  167. Done(byteWriteUint_8(file, bt->block.type));
  168. Done(byteWriteUint_32(file, bt->block.elements));
  169. break;
  170. default:
  171. break;
  172. }
  173. return true;
  174. }
  175. /*
  176. * 函数名: writeAllCode
  177. * 目标: 将Code写入字节码文件中
  178. * 备注: 写入字节码时不做语义检查, 在读取时最语义检查即可
  179. */
  180. bool writeAllCode(af_Code *bt, FILE *file) {
  181. uint32_t count = 0;
  182. if (bt == NULL || bt->path == NULL)
  183. return false;
  184. for (af_Code *tmp = bt; tmp != NULL; tmp = tmp->next) // 统计个数
  185. count++;
  186. Done(byteWriteUint_32(file,count));
  187. for (NULL; bt != NULL; bt = bt->next) {
  188. if (!writeCode(bt, file))
  189. return false;
  190. }
  191. return true;
  192. }
  193. static bool readCode(af_Code **bt, FILE *file) {
  194. uint8_t type;
  195. uint8_t prefix;
  196. uint32_t line;
  197. uint8_t have_path;
  198. uint32_t code_end;
  199. char *path = NULL;
  200. Done(byteReadUint_8(file, &type));
  201. Done(byteReadUint_8(file, &prefix));
  202. Done(byteReadUint_32(file,&line));
  203. Done(byteReadUint_32(file, &code_end));
  204. Done(byteReadUint_8(file, &(have_path)));
  205. if (have_path)
  206. Done(byteReadStr(file, &path));
  207. *bt = makeCode((char)prefix, line, path);
  208. free(path);
  209. (*bt)->type = type;
  210. (*bt)->code_end = code_end;
  211. switch (type) {
  212. case code_element:
  213. Done(byteReadStr(file, &((*bt)->element.data)));
  214. break;
  215. case code_block: {
  216. uint8_t block_type;
  217. uint32_t elements;
  218. Done(byteReadUint_8(file, &block_type));
  219. Done(byteReadUint_32(file,&elements));
  220. (*bt)->block.type = block_type;
  221. (*bt)->block.elements = elements;
  222. break;
  223. }
  224. default:
  225. break;
  226. }
  227. return true;
  228. }
  229. bool readAllCode(af_Code **bt, FILE *file) {
  230. uint32_t count;
  231. Done(byteReadUint_32(file,&count));
  232. for (NULL; count != 0; count--, bt = &((*bt)->next)) {
  233. if(!readCode(bt, file))
  234. return false;
  235. }
  236. return true;
  237. }
  238. /*
  239. * 函数名: checkElementData
  240. * 目标: 检查element中data字符串是否有空白符
  241. */
  242. static bool checkElementData(char *data) {
  243. for (char *ch = data; *ch != NUL; ch++) {
  244. if (isspace(*ch) || *ch == '\n')
  245. return true;
  246. }
  247. return false;
  248. }
  249. /*
  250. * 函数名: codeEndToStr
  251. * 目标: 转换element或开括号为字符串
  252. */
  253. static char *codeToStr_(af_Code *code, CodeInt *layer, struct af_BlockEnd **bn) {
  254. char *re = charToStr(code->prefix);
  255. if (code->type == code_element) {
  256. if (checkElementData(code->element.data)) { // 需要|xx xx|语法
  257. re = strJoin(re, "|", true, false);
  258. re = strJoin(re, code->element.data, true, false);
  259. re = strJoin(re, "| ", true, false);
  260. } else
  261. re = strJoin(re, code->element.data, true, false);
  262. } else if (code->block.elements == 0) {
  263. switch(code->block.type) {
  264. case parentheses:
  265. re = strJoin(re, "()", true, false);
  266. break;
  267. case brackets:
  268. re = strJoin(re, "[]", true, false);
  269. break;
  270. case curly:
  271. re = strJoin(re, "{}", true, false);
  272. break;
  273. default:
  274. break;
  275. }
  276. } else {
  277. char ch = NUL;
  278. switch(code->block.type) {
  279. case parentheses:
  280. re = strJoin(re, "(", true, false);
  281. ch = ')';
  282. break;
  283. case brackets:
  284. re = strJoin(re, "[", true, false);
  285. ch = ']';
  286. break;
  287. case curly:
  288. re = strJoin(re, "{", true, false);
  289. ch = '}';
  290. break;
  291. default:
  292. break;
  293. }
  294. struct af_BlockEnd *new = calloc(1, sizeof(struct af_BlockEnd));
  295. new->ch = ch;
  296. new->next = *bn;
  297. *bn = new;
  298. (*layer)++;
  299. }
  300. return re;
  301. }
  302. /*
  303. * 函数名: codeEndToStr
  304. * 目标: 转换收尾括号为字符串
  305. */
  306. static char *codeEndToStr(CodeInt code_end, CodeInt *layer, struct af_BlockEnd **bn) {
  307. char *re = NEW_STR(code_end);
  308. for (size_t i = 0; code_end > 0; code_end--, i++) {
  309. if (*bn == NULL)
  310. break;
  311. (*layer)--;
  312. re[i] = (*bn)->ch;
  313. struct af_BlockEnd *tmp = (*bn)->next;
  314. free(*bn);
  315. *bn = tmp;
  316. }
  317. re = strJoin(re, " ", true, false);
  318. return re;
  319. }
  320. /*
  321. * 函数名: codeToStr
  322. * 目标: 转换n个元素(或n个函数调用)为code
  323. */
  324. char *codeToStr(af_Code *code, int n) {
  325. char *re = strCopy(NULL);
  326. struct af_BlockEnd *bn = NULL;
  327. CodeInt layer = 0;
  328. for (NULL; code != NULL && layer >= 0 && (n > 0 || n == -1); code = code->next) {
  329. if (strlen(re) >= CODE_STR_MAX_SIZE) {
  330. re = strJoin(re, " ...", true, false); // 限度
  331. break;
  332. }
  333. char *get = codeToStr_(code, &layer, &bn);
  334. re = strJoin(re, get, true, true);
  335. if (code->code_end != 0) {
  336. get = codeEndToStr(code->code_end, &layer, &bn);
  337. re = strJoin(re, get, true, true);
  338. }
  339. if (n != -1 && layer == 0) /* 完成一个元素的打印 */
  340. n--;
  341. }
  342. return re;
  343. }
  344. static void printLayerSpace(size_t layer) {
  345. for (size_t i = 0; i < layer; i++)
  346. printf(" ");
  347. }
  348. void printCode(af_Code *bt) {
  349. size_t layer = 0;
  350. for (NULL; bt != NULL || layer < 0; bt = bt->next) {
  351. printLayerSpace(layer);
  352. layer = layer - bt->code_end;
  353. switch (bt->type) {
  354. case code_element:
  355. printf("element: [prefix (%c)] [end %ld] [data '%s']\n", bt->prefix, bt->code_end, bt->element.data);
  356. break;
  357. case code_block:
  358. layer++;
  359. printf("code: [prefix (%c)] [end %ld] [type %c] [elements %ld]\n", bt->prefix, bt->code_end, bt->block.type, bt->block.elements);
  360. break;
  361. default:
  362. printf("Unknown: [prefix (%c)] [end %ld] [type %d]\n", bt->prefix, bt->code_end, bt->type);
  363. break;
  364. }
  365. }
  366. }
  367. enum af_CodeType getCodeType(af_Code *code) {
  368. return code->type;
  369. }
  370. enum af_BlockType getCodeBlockType(af_Code *code) {
  371. if (code->type != code_block)
  372. return '(';
  373. return code->block.type;
  374. }
  375. char getCodePrefix(af_Code *code) {
  376. return code->prefix;
  377. }
  378. CodeInt getCodeEndCount(af_Code *code) {
  379. return code->code_end;
  380. }
  381. char *getCodeElementData(af_Code *code) {
  382. if (code->type != code_element)
  383. return NULL;
  384. return code->element.data;
  385. }
  386. CodeInt getCodeElementCount(af_Code *code) {
  387. if (code->type != code_block)
  388. return -1;
  389. return code->block.elements;
  390. }