code.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  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. switch (bt->type) {
  157. case code_element:
  158. Done(byteWriteStr(file, bt->element.data));
  159. break;
  160. case code_block:
  161. Done(byteWriteUint_8(file, bt->block.type));
  162. Done(byteWriteUint_32(file, bt->block.elements));
  163. break;
  164. default:
  165. break;
  166. }
  167. return true;
  168. }
  169. /*
  170. * 函数名: writeAllCode
  171. * 目标: 将Code写入字节码文件中
  172. * 备注: 写入字节码时不做语义检查, 在读取时最语义检查即可
  173. */
  174. bool writeAllCode(af_Code *bt, FILE *file) {
  175. if (bt == NULL || bt->path == NULL)
  176. return false;
  177. for (NULL; bt != NULL; bt = bt->next) {
  178. if (!writeCode(bt, file))
  179. return false;
  180. Done(byteWriteUint_8(file, (bt->next == NULL))); // 记录是否为最后一位
  181. }
  182. return true;
  183. }
  184. static bool readCode(af_Code **bt, FILE *file) {
  185. uint8_t type;
  186. uint8_t prefix;
  187. uint32_t line;
  188. uint32_t code_end;
  189. Done(byteReadUint_8(file, &type));
  190. Done(byteReadUint_8(file, &prefix));
  191. Done(byteReadUint_32(file,&line));
  192. Done(byteReadUint_32(file, &code_end));
  193. *bt = makeCode((char)prefix, line, NULL);
  194. (*bt)->type = type;
  195. (*bt)->code_end = (CodeInt)code_end;
  196. switch (type) {
  197. case code_element:
  198. Done(byteReadStr(file, &((*bt)->element.data)));
  199. break;
  200. case code_block: {
  201. uint8_t block_type;
  202. uint32_t elements;
  203. Done(byteReadUint_8(file, &block_type));
  204. Done(byteReadUint_32(file,&elements));
  205. (*bt)->block.type = block_type;
  206. (*bt)->block.elements = (CodeInt)elements;
  207. break;
  208. }
  209. default:
  210. break;
  211. }
  212. return true;
  213. }
  214. bool readAllCode(af_Code **bt, FilePath path, FILE *file) {
  215. af_Code **base = bt;
  216. *bt = NULL;
  217. for (NULL; true;bt = &((*bt)->next)) {
  218. if(!readCode(bt, file))
  219. return false;
  220. if (ferror(stdin))
  221. return false;
  222. uint8_t last;
  223. Done(byteReadUint_8(file, &last));
  224. if (last)
  225. break;
  226. }
  227. if (*base != NULL)
  228. (*base)->path = strCopy(path);
  229. return true;
  230. }
  231. /*
  232. * 函数名: checkElementData
  233. * 目标: 检查element中data字符串是否有空白符
  234. */
  235. static bool checkElementData(char *data) {
  236. for (char *ch = data; *ch != NUL; ch++) {
  237. if (isspace(*ch) || *ch == '\n')
  238. return true;
  239. }
  240. return false;
  241. }
  242. /*
  243. * 函数名: codeEndToStr
  244. * 目标: 转换element或开括号为字符串
  245. */
  246. static char *codeToStr_(af_Code *code, CodeInt *layer, struct af_BlockEnd **bn) {
  247. char *re = charToStr(code->prefix);
  248. if (code->type == code_element) {
  249. if (checkElementData(code->element.data)) { // 需要|xx xx|语法
  250. re = strJoin(re, "|", true, false);
  251. re = strJoin(re, code->element.data, true, false);
  252. re = strJoin(re, "| ", true, false);
  253. } else
  254. re = strJoin(re, code->element.data, true, false);
  255. } else if (code->block.elements == 0) {
  256. switch(code->block.type) {
  257. case parentheses:
  258. re = strJoin(re, "()", true, false);
  259. break;
  260. case brackets:
  261. re = strJoin(re, "[]", true, false);
  262. break;
  263. case curly:
  264. re = strJoin(re, "{}", true, false);
  265. break;
  266. default:
  267. break;
  268. }
  269. } else {
  270. char ch = NUL;
  271. switch(code->block.type) {
  272. case parentheses:
  273. re = strJoin(re, "(", true, false);
  274. ch = ')';
  275. break;
  276. case brackets:
  277. re = strJoin(re, "[", true, false);
  278. ch = ']';
  279. break;
  280. case curly:
  281. re = strJoin(re, "{", true, false);
  282. ch = '}';
  283. break;
  284. default:
  285. break;
  286. }
  287. struct af_BlockEnd *new = calloc(1, sizeof(struct af_BlockEnd));
  288. new->ch = ch;
  289. new->next = *bn;
  290. *bn = new;
  291. (*layer)++;
  292. }
  293. return re;
  294. }
  295. /*
  296. * 函数名: codeEndToStr
  297. * 目标: 转换收尾括号为字符串
  298. */
  299. static char *codeEndToStr(CodeInt code_end, CodeInt *layer, struct af_BlockEnd **bn) {
  300. char *re = NEW_STR(code_end);
  301. for (size_t i = 0; code_end > 0; code_end--, i++) {
  302. if (*bn == NULL)
  303. break;
  304. (*layer)--;
  305. re[i] = (*bn)->ch;
  306. struct af_BlockEnd *tmp = (*bn)->next;
  307. free(*bn);
  308. *bn = tmp;
  309. }
  310. re = strJoin(re, " ", true, false);
  311. return re;
  312. }
  313. /*
  314. * 函数名: codeToStr
  315. * 目标: 转换n个元素(或n个函数调用)为code
  316. */
  317. char *codeToStr(af_Code *code, int n) {
  318. char *re = strCopy(NULL);
  319. struct af_BlockEnd *bn = NULL;
  320. CodeInt layer = 0;
  321. for (NULL; code != NULL && layer >= 0 && (n > 0 || n == -1); code = code->next) {
  322. if (strlen(re) >= CODE_STR_MAX_SIZE) {
  323. re = strJoin(re, " ...", true, false); // 限度
  324. break;
  325. }
  326. char *get = codeToStr_(code, &layer, &bn);
  327. re = strJoin(re, get, true, true);
  328. if (code->code_end != 0) {
  329. get = codeEndToStr(code->code_end, &layer, &bn);
  330. re = strJoin(re, get, true, true);
  331. }
  332. if (n != -1 && layer == 0) /* 完成一个元素的打印 */
  333. n--;
  334. }
  335. return re;
  336. }
  337. static void printLayerSpace(size_t layer) {
  338. for (size_t i = 0; i < layer; i++)
  339. printf(" ");
  340. }
  341. void printCode(af_Code *bt) {
  342. size_t layer = 0;
  343. for (NULL; bt != NULL || layer < 0; bt = bt->next) {
  344. printLayerSpace(layer);
  345. layer = layer - bt->code_end;
  346. switch (bt->type) {
  347. case code_element:
  348. printf("element: [prefix (%c)] [end %ld] [data '%s']\n", bt->prefix, bt->code_end, bt->element.data);
  349. break;
  350. case code_block:
  351. layer++;
  352. printf("code: [prefix (%c)] [end %ld] [type %c] [elements %ld]\n", bt->prefix, bt->code_end, bt->block.type, bt->block.elements);
  353. break;
  354. default:
  355. printf("Unknown: [prefix (%c)] [end %ld] [type %d]\n", bt->prefix, bt->code_end, bt->type);
  356. break;
  357. }
  358. }
  359. }
  360. enum af_CodeType getCodeType(af_Code *code) {
  361. return code->type;
  362. }
  363. enum af_BlockType getCodeBlockType(af_Code *code) {
  364. if (code->type != code_block)
  365. return '(';
  366. return code->block.type;
  367. }
  368. char getCodePrefix(af_Code *code) {
  369. return code->prefix;
  370. }
  371. CodeInt getCodeEndCount(af_Code *code) {
  372. return code->code_end;
  373. }
  374. char *getCodeElementData(af_Code *code) {
  375. if (code->type != code_element)
  376. return NULL;
  377. return code->element.data;
  378. }
  379. CodeInt getCodeElementCount(af_Code *code) {
  380. if (code->type != code_block)
  381. return -1;
  382. return code->block.elements;
  383. }