runbranch.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  1. #include "__run.h"
  2. #define SET_FOLDING_BRANCH(folding_bak, set_folding, inter)bool folding_bak[] = {(inter)->data.value_folding /*[0]*/, \
  3. (inter)->data.var_folding /*[1]*/, (inter)->data.opt_folding /*[2]*/}; \
  4. bool set_folding = (inter)->data.func_folding; \
  5. if (set_folding) { (inter)->data.value_folding = (inter)->data.var_folding = (inter)->data.opt_folding = true;}
  6. #define SET_FOLDING_END(folding_bak, set_folding, inter) if (set_folding) {(inter)->data.value_folding = (folding_bak)[0];(inter)->data.var_folding = (folding_bak)[1];(inter)->data.opt_folding = (folding_bak)[2];}
  7. static bool checkNumber(FUNC){
  8. if (!isType(result->value->value, V_int)) {
  9. setResultErrorSt(E_TypeException, L"Don't get a int of layers", true, st, CNEXT_NT);
  10. return false;
  11. }
  12. return true;
  13. }
  14. static void newBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status, Inter *inter){
  15. if (new_var != NULL)
  16. new_var->next = NULL;
  17. branch_st->info.var_list = new_var;
  18. branch_st->info.node = node->type == yield_code ? node->next : node;
  19. branch_st->info.branch.sl_node = sl_node;
  20. branch_st->info.branch.status = status;
  21. branch_st->info.have_info = true;
  22. }
  23. static void newWithBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status,
  24. Inter *inter, LinkValue *value, LinkValue *_exit_, LinkValue *_enter_, LinkValue *with){
  25. newBranchYield(branch_st, node, sl_node, new_var, status, inter);
  26. branch_st->info.branch.with_.value = value;
  27. branch_st->info.branch.with_._exit_ = _exit_;
  28. branch_st->info.branch.with_._enter_ = _enter_;
  29. branch_st->info.branch.with_.with_belong = with;
  30. }
  31. static void newForBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status,
  32. Inter *inter, LinkValue *iter){
  33. newBranchYield(branch_st, node, sl_node, new_var, status, inter);
  34. branch_st->info.branch.for_.iter = iter;
  35. gc_addTmpLink(&iter->gc_status);
  36. }
  37. static void updateBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, enum StatementInfoStatus status){
  38. branch_st->info.node = node->type == yield_code ? node->next : node;
  39. branch_st->info.branch.sl_node = sl_node;
  40. branch_st->info.branch.status = status;
  41. branch_st->info.have_info = true;
  42. }
  43. static void setBranchResult(bool yield_run, StatementList *sl, Statement *st, Result *result, enum StatementInfoStatus status, FUNC_CORE) {
  44. if (yield_run) {
  45. if (result->type == R_yield)
  46. updateBranchYield(st, result->node, sl, status);
  47. else
  48. freeRunInfo(st);
  49. } else {
  50. if (result->type == R_yield)
  51. newBranchYield(st, result->node, sl, var_list, status, inter);
  52. else
  53. var_list = popVarList(var_list);
  54. }
  55. }
  56. static bool runBranchHeard(Statement *condition, Statement *var, LinkValue **condition_value, FUNC_NT) {
  57. setResultCore(result);
  58. if (operationSafeInterStatement(CFUNC(condition, var_list, result, belong)))
  59. return false;
  60. *condition_value = result->value;
  61. if (var != NULL) {
  62. result->value = NULL;
  63. freeResult(result);
  64. assCore(var, *condition_value, false, false, CNEXT_NT);
  65. gc_freeTmpLink(&(*condition_value)->gc_status);
  66. if (!CHECK_RESULT(result))
  67. return false;
  68. }
  69. return true;
  70. }
  71. static int checkCondition(bool is_rego, LinkValue *condition_value, fline line, char *file, FUNC_NT) {
  72. bool return_;
  73. if (is_rego)
  74. return 1;
  75. return_ = checkBool(condition_value, line, file, CNEXT_NT);
  76. if (!CHECK_RESULT(result))
  77. return -1;
  78. return return_;
  79. }
  80. static bool runFinally(bool set_result, bool (*run)(FUNC), FUNC) {
  81. Result finally_tmp;
  82. setResultCore(&finally_tmp);
  83. if (run(CFUNC(st, var_list, &finally_tmp, belong))) {
  84. if (!set_result)
  85. freeResult(result);
  86. *result = finally_tmp;
  87. return false;
  88. }
  89. freeResult(&finally_tmp);
  90. return true;
  91. }
  92. static int runIfList(StatementList *if_list, Statement *info_vl, fline line, char *file, FUNC_NT) {
  93. bool is_rego = false;
  94. setResultCore(result);
  95. for (PASS; if_list != NULL; if_list = if_list->next){
  96. bool condition;
  97. if (info_vl != NULL){
  98. if (ifBranchSafeInterStatement(CFUNC(info_vl, var_list, result, belong)))
  99. return -1;
  100. if (result->type == R_rego)
  101. is_rego = true;
  102. info_vl = NULL;
  103. } else if (if_list->type == if_b){
  104. LinkValue *condition_value = NULL;
  105. if (!runBranchHeard(if_list->condition, if_list->var, &condition_value, CNEXT_NT))
  106. return -1;
  107. freeResult(result);
  108. condition = checkCondition(is_rego, condition_value, line, file, CNEXT_NT);
  109. if (condition == -1)
  110. return -1;
  111. else if (condition == 1){
  112. is_rego = false;
  113. freeResult(result);
  114. if (ifBranchSafeInterStatement(CFUNC(if_list->code, var_list, result, belong)))
  115. return -1;
  116. if (result->type == R_rego)
  117. is_rego = true;
  118. else {
  119. freeResult(result);
  120. return 0;
  121. }
  122. }
  123. } else{
  124. if (ifBranchSafeInterStatement(CFUNC(if_list->code, var_list, result, belong)))
  125. return -1;
  126. if (result->type == R_rego)
  127. is_rego = true;
  128. }
  129. freeResult(result);
  130. }
  131. return 1;
  132. }
  133. ResultType ifBranch(FUNC) {
  134. StatementList *if_list = NULL;
  135. Statement *else_st = NULL;
  136. Statement *finally = NULL;
  137. Statement *info_vl = NULL;
  138. bool set_result = true;
  139. bool yield_run = false;
  140. enum StatementInfoStatus result_from = info_vl_branch;
  141. setResultCore(result);
  142. yield_run = popYieldVarList(st, &var_list, var_list, inter);
  143. if (yield_run) {
  144. if (st->info.branch.status == info_vl_branch){
  145. if_list = st->info.branch.sl_node;
  146. info_vl = st->info.node;
  147. else_st = st->u.if_branch.else_list;
  148. finally = st->u.if_branch.finally;
  149. if (info_vl == NULL)
  150. if_list = NULL; // 证明if分支的yield已经到头了
  151. } else if (st->info.branch.status == info_else_branch) {
  152. else_st = st->info.node;
  153. finally = st->u.if_branch.finally;
  154. } else if (st->info.branch.status == info_finally_branch)
  155. finally = st->info.node;
  156. else {
  157. var_list = popVarList(var_list);
  158. setResultError(E_SystemException, L"yield info error", st->line, st->code_file, true, CNEXT_NT);
  159. return R_error;
  160. }
  161. } else {
  162. if_list = st->u.if_branch.if_list;
  163. else_st = st->u.if_branch.else_list;
  164. finally = st->u.if_branch.finally;
  165. }
  166. if (if_list != NULL) {
  167. int status = runIfList(if_list, info_vl, st->line, st->code_file, CNEXT_NT);
  168. if (status == -1 || status == 0)
  169. else_st = NULL;
  170. if (status == -1)
  171. set_result = false;
  172. }
  173. if (else_st != NULL) {
  174. if (ifBranchSafeInterStatement(CFUNC(else_st, var_list, result, belong))) {
  175. set_result = false;
  176. result_from = info_else_branch;
  177. } else
  178. freeResult(result);
  179. }
  180. if (finally != NULL && !runFinally(set_result, ifBranchSafeInterStatement, finally, CNEXT_NT)) {
  181. set_result = false;
  182. result_from = info_finally_branch;
  183. }
  184. setBranchResult(yield_run, if_list, st, result, result_from, CFUNC_CORE(var_list));
  185. if (set_result)
  186. setResult(result, inter);
  187. return result->type;
  188. }
  189. static int runWhileList(StatementList *while_list, Statement *after, Statement *info_vl, Statement *after_vl, bool do_while, fline line, char *file, enum StatementInfoStatus *from, FUNC_NT) {
  190. bool is_break = false;
  191. setResultCore(result);
  192. while (!is_break){
  193. LinkValue *condition_value = NULL;
  194. Statement *after_st = after;
  195. Statement *while_st = while_list->code;
  196. bool condition;
  197. *from = info_vl_branch;
  198. if (info_vl != NULL) {
  199. condition = 1;
  200. while_st = info_vl;
  201. info_vl = NULL;
  202. } else if (after_vl != NULL) {
  203. condition = -2;
  204. after_st = after_vl;
  205. after_vl = NULL;
  206. } else{
  207. if (!runBranchHeard(while_list->condition, while_list->var, &condition_value, CNEXT_NT))
  208. return -1;
  209. freeResult(result);
  210. condition = checkCondition(do_while, condition_value, line, file, CNEXT_NT);
  211. }
  212. do_while = false;
  213. if (condition == -1)
  214. return -1;
  215. else if (condition == 1){
  216. freeResult(result);
  217. if (cycleBranchSafeInterStatement(CFUNC(while_st, var_list, result, belong)))
  218. return -1;
  219. else if (result->type == R_break)
  220. is_break = true;
  221. } else if (condition != -2){
  222. freeResult(result);
  223. break;
  224. }
  225. if (after_st != NULL) {
  226. *from = info_after_do;
  227. freeResult(result);
  228. if (cycleBranchSafeInterStatement(CFUNC(after_st, var_list, result, belong)))
  229. return -1;
  230. else if (result->type == R_break) {
  231. freeResult(result);
  232. return 0;
  233. }
  234. }
  235. freeResult(result);
  236. }
  237. return is_break ? 0 : 1;
  238. }
  239. ResultType whileBranch(FUNC) {
  240. StatementList *while_list = st->u.while_branch.while_list;
  241. Statement *first = st->u.while_branch.first;
  242. Statement *after = st->u.while_branch.after;
  243. Statement *else_st = st->u.while_branch.else_list;
  244. Statement *finally = st->u.while_branch.finally;
  245. Statement *info_vl = NULL;
  246. Statement *after_vl = NULL;
  247. bool set_result = true;
  248. bool yield_run = false;
  249. bool do_while = st->u.while_branch.type == do_while_;
  250. enum StatementInfoStatus result_from = info_first_do;
  251. SET_FOLDING_BRANCH(folding_bak, set_folding, inter) // 不需要分号
  252. setResultCore(result);
  253. yield_run = popYieldVarList(st, &var_list, var_list, inter);
  254. if (yield_run) {
  255. if (st->info.branch.status == info_first_do)
  256. first = st->info.node;
  257. else if (st->info.branch.status == info_vl_branch){
  258. first = NULL;
  259. info_vl = st->info.node;
  260. }
  261. else if (st->info.branch.status == info_after_do){
  262. first = NULL;
  263. after_vl = st->info.node;
  264. }
  265. else if (st->info.branch.status == info_else_branch){
  266. first = NULL;
  267. while_list = NULL;
  268. else_st = st->info.node;
  269. }
  270. else if (st->info.branch.status == info_finally_branch){
  271. first = NULL;
  272. while_list = NULL;
  273. else_st = NULL;
  274. finally = st->info.node;
  275. } else {
  276. var_list = popVarList(var_list);
  277. setResultError(E_SystemException, L"yield info error", st->line, st->code_file, true, CNEXT_NT);
  278. return R_error;
  279. }
  280. }
  281. if (first != NULL) {
  282. if (cycleBranchSafeInterStatement(CFUNC(first, var_list, result, belong))) {
  283. set_result = false;
  284. while_list = NULL;
  285. else_st = NULL;
  286. } else
  287. freeResult(result);
  288. }
  289. if (while_list != NULL){
  290. int status = runWhileList(while_list, after, info_vl, after_vl, do_while, st->line, st->code_file, &result_from, CNEXT_NT);
  291. if (status == -1 || status == 0)
  292. else_st = NULL;
  293. if (status == -1)
  294. set_result = false;
  295. }
  296. if (else_st != NULL) {
  297. if (cycleBranchSafeInterStatement(CFUNC(else_st, var_list, result, belong))) {
  298. result_from = info_else_branch;
  299. set_result = false;
  300. } else
  301. freeResult(result);
  302. }
  303. if (finally != NULL && !runFinally(set_result, cycleBranchSafeInterStatement, finally, CNEXT_NT)) {
  304. set_result = false;
  305. result_from = info_finally_branch;
  306. }
  307. setBranchResult(yield_run, while_list, st, result, result_from, CFUNC_CORE(var_list));
  308. if (set_result)
  309. setResult(result, inter);
  310. SET_FOLDING_END(folding_bak, set_folding, inter) // 不需要分号
  311. return result->type;
  312. }
  313. static int getForHeard(LinkValue **iter, LinkValue **first_yield, StatementList *for_list, fline line, char *file, FUNC_NT) {
  314. LinkValue *tmp = NULL;
  315. setResultCore(result);
  316. if (operationSafeInterStatement(CFUNC(for_list->condition, var_list, result, belong)))
  317. return -1;
  318. if (result->is_yield){
  319. iter = NULL;
  320. GET_RESULTONLY(*first_yield, result);
  321. return 1;
  322. }
  323. GET_RESULT(tmp, result);
  324. getIter(tmp, 1, line, file, CNEXT_NT);
  325. gc_freeTmpLink(&tmp->gc_status);
  326. if (!CHECK_RESULT(result))
  327. return -1;
  328. GET_RESULTONLY(*iter, result);
  329. return 0;
  330. }
  331. static int runForHeard(LinkValue *iter, LinkValue *first_yield, StatementList *for_list, fline line, char *file, FUNC_NT) {
  332. LinkValue *element = NULL;
  333. if (iter != NULL) {
  334. getIter(iter, 0, line, file, CNEXT_NT);
  335. if (!CHECK_RESULT(result)) {
  336. if (is_iterStop(result->value, inter)) {
  337. freeResult(result);
  338. return 1;
  339. } else
  340. return -1;
  341. }
  342. GET_RESULT(element, result);
  343. } else if (first_yield != NULL)
  344. element = first_yield;
  345. else {
  346. if (operationSafeInterStatement(CFUNC(for_list->condition, var_list, result, belong)))
  347. return -1;
  348. GET_RESULT(element, result);
  349. if (!result->is_yield)
  350. return 1;
  351. }
  352. assCore(for_list->var, element, false, false, CNEXT_NT);
  353. gc_freeTmpLink(&element->gc_status);
  354. if (!CHECK_RESULT(result))
  355. return -1;
  356. freeResult(result);
  357. return 0;
  358. }
  359. static int runForList(StatementList *for_list, Statement *after, Statement *info_vl, Statement *after_vl, LinkValue *iter, LinkValue *first_yield, fline line, char *file, enum StatementInfoStatus *from, FUNC_NT) {
  360. bool is_break = false;
  361. while (!is_break){ // 循环执行的本体
  362. Statement *for_st = for_list->code;
  363. Statement *after_st = after;
  364. *from = info_vl_branch;
  365. if (info_vl != NULL){
  366. for_st = info_vl;
  367. info_vl = NULL;
  368. }
  369. else if (after_vl != NULL){
  370. after_st = after_vl;
  371. after_vl = NULL;
  372. for_st = NULL;
  373. } else {
  374. int status = runForHeard(iter, first_yield, for_list, line, file, CNEXT_NT);
  375. first_yield = NULL;
  376. if (status == -1)
  377. return -1;
  378. else if (status == 1)
  379. break;
  380. }
  381. if (for_st != NULL) {
  382. if (cycleBranchSafeInterStatement(CFUNC(for_st, var_list, result, belong)))
  383. return -1;
  384. else if (result->type == R_break)
  385. is_break = true;
  386. }
  387. *from = info_after_do;
  388. if (after_st != NULL) {
  389. freeResult(result);
  390. if (cycleBranchSafeInterStatement(CFUNC(after_st, var_list, result, belong)))
  391. return -1;
  392. else if (result->type == R_break)
  393. is_break = true;
  394. }
  395. freeResult(result);
  396. }
  397. return is_break ? 0 : 1;
  398. }
  399. static void setForResult(bool yield_run, StatementList *sl, Statement *st, Result *result, LinkValue *iter, enum StatementInfoStatus status, FUNC_CORE) {
  400. if (yield_run) {
  401. if (result->type == R_yield)
  402. updateBranchYield(st, result->node, sl, status);
  403. else
  404. freeRunInfo(st);
  405. } else {
  406. if (result->type == R_yield)
  407. newForBranchYield(st, result->node, sl, var_list, status, inter, iter);
  408. else
  409. popVarList(var_list);
  410. }
  411. }
  412. ResultType forBranch(FUNC) {
  413. StatementList *for_list = st->u.for_branch.for_list;
  414. Statement *first = st->u.for_branch.first_do;
  415. Statement *after = st->u.for_branch.after_do;
  416. Statement *else_st = st->u.for_branch.else_list;
  417. Statement *finally = st->u.for_branch.finally;
  418. Statement *info_vl = NULL;
  419. Statement *after_vl = NULL;
  420. bool set_result = true;
  421. bool yield_run = false;
  422. bool heard = true;
  423. LinkValue *first_yield = NULL;
  424. LinkValue *iter = NULL;
  425. enum StatementInfoStatus result_from = info_first_do;
  426. SET_FOLDING_BRANCH(folding_bak, set_folding, inter) // 不需要分号
  427. setResultCore(result);
  428. yield_run = popYieldVarList(st, &var_list, var_list, inter);
  429. if (yield_run) {
  430. if (st->info.branch.status == info_first_do)
  431. first = st->info.node;
  432. else if (st->info.branch.status == info_vl_branch) {
  433. first = NULL;
  434. info_vl = st->info.node;
  435. iter = st->info.branch.for_.iter;
  436. heard = false;
  437. } else if (st->info.branch.status == info_after_do) {
  438. first = NULL;
  439. after_vl = st->info.node;
  440. iter = st->info.branch.for_.iter;
  441. heard = false;
  442. } else if (st->info.branch.status == info_else_branch) {
  443. first = NULL;
  444. heard = false;
  445. for_list = false;
  446. else_st = st->info.node;
  447. } else if (st->info.branch.status == info_finally_branch) {
  448. first = NULL;
  449. heard = false;
  450. for_list = false;
  451. else_st = NULL;
  452. finally = st->info.node;
  453. } else {
  454. var_list = popVarList(var_list);
  455. setResultError(E_SystemException, L"yield info error", st->line, st->code_file, true, CNEXT_NT);
  456. return R_error;
  457. }
  458. }
  459. if (first != NULL) {
  460. if (cycleBranchSafeInterStatement(CFUNC(first, var_list, result, belong))) {
  461. set_result = false;
  462. heard = false;
  463. for_list = NULL;
  464. else_st = NULL;
  465. } else
  466. freeResult(result);
  467. }
  468. if (heard){
  469. int status = getForHeard(&iter, &first_yield, for_list, st->line, st->code_file, CNEXT_NT);
  470. if (status == -1) {
  471. set_result = false;
  472. for_list = NULL;
  473. else_st = NULL;
  474. } else
  475. freeResult(result);
  476. }
  477. if (for_list != NULL){
  478. int status = runForList(for_list, after, info_vl, after_vl, iter, first_yield, st->line, st->code_file, &result_from, CNEXT_NT);
  479. if (status == -1 || status == 0)
  480. else_st = NULL;
  481. if (status == -1)
  482. set_result = false;
  483. }
  484. if (else_st != NULL) {
  485. if (cycleBranchSafeInterStatement(CFUNC(else_st, var_list, result, belong))) {
  486. result_from = info_else_branch;
  487. set_result = false;
  488. }
  489. else
  490. freeResult(result);
  491. }
  492. if (finally != NULL && !runFinally(set_result, cycleBranchSafeInterStatement, finally, CNEXT_NT)) {
  493. set_result = false;
  494. result_from = info_finally_branch;
  495. }
  496. setForResult(yield_run, for_list, st, result, iter, result_from, CFUNC_CORE(var_list));
  497. if (!yield_run && iter != NULL)
  498. gc_freeTmpLink(&iter->gc_status);
  499. if (set_result)
  500. setResult(result, inter);
  501. SET_FOLDING_END(folding_bak, set_folding, inter)
  502. return result->type;
  503. }
  504. static bool getEnterExit(LinkValue *value, LinkValue **_enter_, LinkValue **_exit_, fline line, char *file, FUNC_NT) {
  505. setResultCore(result);
  506. *_enter_ = findAttributes(inter->data.mag_func[M_ENTER], false, LINEFILE, true, CFUNC_NT(var_list, result, value));
  507. if (!CHECK_RESULT(result))
  508. return false;
  509. freeResult(result);
  510. *_exit_ = findAttributes(inter->data.mag_func[M_EXIT], false, LINEFILE, true, CFUNC_NT(var_list, result, value));
  511. if (!CHECK_RESULT(result))
  512. return false;
  513. freeResult(result);
  514. if (*_enter_ == NULL || *_exit_ == NULL) {
  515. *_enter_ = NULL;
  516. *_exit_ = NULL;
  517. setResultError(E_TypeException, OBJ_NOTSUPPORT(__enter__/__exit__), line, file, true, CNEXT_NT);
  518. return false;
  519. }
  520. gc_addTmpLink(&(*_enter_)->gc_status);
  521. gc_addTmpLink(&(*_exit_)->gc_status);
  522. return true;
  523. }
  524. static int runWithList(StatementList *with_list, LinkValue **with_belong, LinkValue **value, VarList **new, LinkValue **_enter_, LinkValue **_exit_, fline line, char *file, FUNC_NT) {
  525. if (operationSafeInterStatement(CFUNC(with_list->condition, var_list, result, belong)))
  526. return -1;
  527. GET_RESULT(*value, result);
  528. if (with_list->var == NULL) {
  529. *with_belong = *value;
  530. gc_addTmpLink(&(*with_belong)->gc_status);
  531. *new = copyVarListCore((*value)->value->object.var, inter);
  532. (*new)->next = var_list;
  533. *_enter_ = NULL;
  534. *_exit_ = NULL;
  535. } else {
  536. LinkValue *enter_value = NULL;
  537. *with_belong = belong;
  538. gc_addTmpLink(&(*with_belong)->gc_status);
  539. *_enter_ = findAttributes(inter->data.mag_func[M_ENTER], false, LINEFILE, true, CFUNC_NT(var_list, result, *value));
  540. if (!CHECK_RESULT(result))
  541. goto error_;
  542. freeResult(result);
  543. *_exit_ = findAttributes(inter->data.mag_func[M_EXIT], false, LINEFILE, true, CFUNC_NT(var_list, result, *value));
  544. if (!CHECK_RESULT(result))
  545. goto error_;
  546. freeResult(result);
  547. if (!getEnterExit(*value, _enter_, _exit_, line, file, CNEXT_NT)) {
  548. error_:
  549. gc_freeTmpLink(&(*value)->gc_status);
  550. gc_freeTmpLink(&(*with_belong)->gc_status);
  551. *value = NULL;
  552. return -1;
  553. }
  554. callBackCore(*_enter_, NULL, line, file, 0, CNEXT_NT);
  555. if (!CHECK_RESULT(result))
  556. return 0;
  557. *new = pushVarList(var_list, inter);
  558. enter_value = result->value;
  559. freeResult(result);
  560. assCore(with_list->var, enter_value, false, false, CFUNC_NT(*new, result, belong));
  561. if (!CHECK_RESULT(result)) {
  562. *new = popVarList(*new);
  563. return 0;
  564. }
  565. freeResult(result);
  566. }
  567. return 1;
  568. }
  569. static void setWithResult(bool yield_run, StatementList *sl, Statement *st, Result *result, LinkValue *value, LinkValue *_enter_, LinkValue *_exit_, LinkValue *with, enum StatementInfoStatus status, FUNC_CORE) {
  570. if (yield_run) {
  571. if (result->type == R_yield)
  572. if (status == info_finally_branch) {
  573. freeRunInfo(st);
  574. newBranchYield(st, result->node, sl, NULL, status, inter);
  575. } else
  576. updateBranchYield(st, result->node, sl, status);
  577. else
  578. freeRunInfo(st);
  579. } else {
  580. if (result->type == R_yield)
  581. if (status == info_finally_branch) {
  582. newBranchYield(st, result->node, sl, NULL, status, inter);
  583. popVarList(var_list);
  584. }
  585. else
  586. newWithBranchYield(st, result->node, sl, var_list, status, inter, value, _exit_, _enter_, with);
  587. else {
  588. if (var_list != NULL)
  589. popVarList(var_list);
  590. }
  591. }
  592. }
  593. ResultType withBranch(FUNC) {
  594. StatementList *with_list = st->u.with_branch.with_list;
  595. Statement *else_st = st->u.with_branch.else_list;
  596. Statement *finally = st->u.with_branch.finally;
  597. Statement *vl_info = NULL;
  598. VarList *new = NULL;
  599. LinkValue *_enter_ = NULL;
  600. LinkValue *_exit_ = NULL;
  601. LinkValue *value = NULL;
  602. LinkValue *with_belong = NULL; // with在运行的时候调整belong, 就类似于定义class的时候调整belong
  603. bool set_result = true;
  604. bool run_block = true;
  605. bool run_exit = true;
  606. bool yield_run;
  607. enum StatementInfoStatus result_from = info_vl_branch;
  608. setResultCore(result);
  609. if ((yield_run = st->info.have_info)){
  610. value = st->info.branch.with_.value;
  611. _enter_ = st->info.branch.with_._enter_;
  612. _exit_ = st->info.branch.with_._exit_;
  613. with_belong = st->info.branch.with_.with_belong;
  614. if (st->info.var_list != NULL) {
  615. new = st->info.var_list;
  616. new->next = var_list;
  617. }
  618. if (st->info.branch.status == info_vl_branch) {
  619. vl_info = st->info.node;
  620. if (vl_info == NULL)
  621. run_block = false;
  622. }
  623. else if (st->info.branch.status == info_else_branch) {
  624. run_block = false;
  625. else_st = st->info.node;
  626. }
  627. else if (st->info.branch.status == info_finally_branch){
  628. run_block = false;
  629. else_st = NULL;
  630. finally = st->info.node;
  631. }
  632. } else {
  633. int status = runWithList(with_list, &with_belong, &value, &new, &_enter_, &_exit_, st->line, st->code_file, CNEXT_NT);
  634. if (status == -1) {
  635. set_result = false;
  636. run_block = false;
  637. else_st = NULL;
  638. } else if (status == 0) {
  639. set_result = false;
  640. gc_freeTmpLink(&value->gc_status);
  641. gc_freeTmpLink(&_enter_->gc_status);
  642. gc_freeTmpLink(&_exit_->gc_status);
  643. gc_freeTmpLink(&with_belong->gc_status);
  644. run_block = false;
  645. else_st = NULL;
  646. }
  647. }
  648. if (run_block) {
  649. if (vl_info == NULL)
  650. vl_info = with_list->code;
  651. if (withBranchSafeInterStatement(CFUNC(vl_info, new, result, with_belong))) {
  652. set_result = false;
  653. if (result->type == R_yield) {
  654. run_exit = false;
  655. else_st = NULL;
  656. }
  657. } else
  658. freeResult(result);
  659. }
  660. if (else_st != NULL){
  661. Result else_tmp;
  662. setResultCore(&else_tmp);
  663. if (withBranchSafeInterStatement(CFUNC(else_st, new, &else_tmp, with_belong))) {
  664. if (!set_result)
  665. freeResult(result);
  666. set_result = false;
  667. *result = else_tmp;
  668. result_from = info_else_branch;
  669. if (result->type == R_yield)
  670. run_exit = false;
  671. } else
  672. freeResult(&else_tmp);
  673. }
  674. if (run_exit){ // 若运行中的某处返回了R_yield则不执行exit
  675. if (_exit_ != NULL){
  676. Result exit_tmp;
  677. setResultCore(&exit_tmp);
  678. callBackCore(_exit_, NULL, st->line, st->code_file, 0, CFUNC_NT(var_list, &exit_tmp, belong));
  679. if (!RUN_TYPE(exit_tmp.type)) {
  680. if (!set_result)
  681. freeResult(result);
  682. set_result = false;
  683. *result = exit_tmp;
  684. } else
  685. freeResult(&exit_tmp);
  686. if (!yield_run) {
  687. gc_freeTmpLink(&_enter_->gc_status);
  688. gc_freeTmpLink(&_exit_->gc_status);
  689. _enter_ = NULL;
  690. _exit_ = NULL;
  691. }
  692. }
  693. if (!yield_run) {
  694. if (with_belong != NULL){
  695. gc_freeTmpLink(&with_belong->gc_status);
  696. with_belong = NULL;
  697. }
  698. if (value != NULL){
  699. gc_freeTmpLink(&value->gc_status);
  700. value = NULL;
  701. }
  702. }
  703. }
  704. if (finally != NULL && !runFinally(set_result, withBranchSafeInterStatement, finally, CNEXT_NT)) {
  705. set_result = false;
  706. result_from = info_finally_branch;
  707. }
  708. setWithResult(yield_run, with_list, st, result, value, _enter_, _exit_, with_belong, result_from, CFUNC_CORE(new));
  709. if (set_result)
  710. setResult(result, inter);
  711. return result->type;
  712. }
  713. static int checkError(StatementList **except_list, LinkValue *error_value, FUNC_NT) {
  714. setResultCore(result);
  715. if (*except_list == NULL)
  716. return -1;
  717. for (PASS; *except_list != NULL; except_list = &(*except_list)->next) {
  718. freeResult(result);
  719. if ((*except_list)->condition == NULL)
  720. break;
  721. if (operationSafeInterStatement(CFUNC((*except_list)->condition, var_list, result, belong)))
  722. return 0;
  723. if (result->value->value == error_value->value || checkAttribution(error_value->value, result->value->value))
  724. break;
  725. }
  726. return *except_list == NULL ? -1 : 1;
  727. }
  728. ResultType tryBranch(FUNC) {
  729. StatementList *except_list = NULL;
  730. Statement *try = st->u.try_branch.try;
  731. Statement *else_st = st->u.try_branch.else_list;
  732. Statement *finally = st->u.try_branch.finally;
  733. Statement *info_vl = NULL;
  734. LinkValue *error_value = NULL;
  735. bool set_result = true;
  736. bool yield_run;
  737. enum StatementInfoStatus result_from = info_first_do;
  738. setResultCore(result);
  739. yield_run = popYieldVarList(st, &var_list, var_list, inter);
  740. if (yield_run && st->info.branch.status == info_first_do)
  741. try = st->info.node;
  742. else if (yield_run && st->info.branch.status == info_vl_branch){
  743. try = NULL;
  744. info_vl = st->info.node;
  745. }
  746. else if (yield_run && st->info.branch.status == info_else_branch){
  747. try = NULL;
  748. else_st = st->info.node;
  749. }
  750. else if (yield_run && st->info.branch.status == info_finally_branch){
  751. try = NULL;
  752. else_st = NULL;
  753. finally = st->info.node;
  754. }
  755. if (try != NULL){
  756. if (tryBranchSafeInterStatement(CFUNC(try, var_list, result, belong))) {
  757. if (result->type == R_yield) {
  758. result_from = info_first_do;
  759. set_result = false;
  760. else_st = NULL;
  761. } else {
  762. int status;
  763. GET_RESULT(error_value, result);
  764. except_list = st->u.try_branch.except_list;
  765. status = checkError(&except_list, error_value, CNEXT_NT);
  766. if (status == -1 || status == 0) {
  767. set_result = false;
  768. result_from = info_vl_branch;
  769. except_list = NULL;
  770. else_st = NULL;
  771. } else
  772. freeResult(result);
  773. gc_freeTmpLink(&error_value->gc_status);
  774. }
  775. } else
  776. freeResult(result);
  777. }
  778. if (except_list != NULL) {
  779. if (except_list->var != NULL) {
  780. gc_addTmpLink(&error_value->gc_status);
  781. assCore(except_list->var, error_value, false, false, CNEXT_NT);
  782. gc_freeTmpLink(&error_value->gc_status);
  783. if (!CHECK_RESULT(result)) {
  784. set_result = false;
  785. else_st = NULL;
  786. } else
  787. freeResult(result);
  788. }
  789. info_vl = except_list->code;
  790. }
  791. if (info_vl != NULL) {
  792. freeResult(result);
  793. if (tryBranchSafeInterStatement(CFUNC(info_vl, var_list, result, belong))) {
  794. result_from = info_vl_branch;
  795. set_result = false;
  796. } else
  797. freeResult(result);
  798. }
  799. if (else_st != NULL) {
  800. if (tryBranchSafeInterStatement(CFUNC(else_st, var_list, result, belong))) {
  801. set_result = false;
  802. result_from = info_else_branch;
  803. }
  804. else
  805. freeResult(result);
  806. }
  807. if (finally != NULL && !runFinally(set_result, ifBranchSafeInterStatement, finally, CNEXT_NT)) {
  808. set_result = false;
  809. result_from = info_finally_branch;
  810. }
  811. setBranchResult(yield_run, except_list, st, result, result_from, CFUNC_CORE(var_list));
  812. if (set_result)
  813. setResult(result, inter);
  814. return result->type;
  815. }
  816. ResultType breakCycle(FUNC){
  817. int times_int = 0;
  818. setResultCore(result);
  819. if (st->u.break_cycle.times == NULL)
  820. goto not_times;
  821. if (operationSafeInterStatement(CFUNC(st->u.break_cycle.times, var_list, result, belong)))
  822. return result->type;
  823. if (!checkNumber(CNEXT))
  824. return result->type;
  825. times_int = (int)result->value->value->data.int_.num;
  826. freeResult(result);
  827. not_times:
  828. setResult(result, inter);
  829. if (times_int >= 0) {
  830. result->type = R_break;
  831. result->times = times_int;
  832. }
  833. return result->type;
  834. }
  835. ResultType continueCycle(FUNC){
  836. int times_int = 0;
  837. setResultCore(result);
  838. if (st->u.continue_cycle.times == NULL)
  839. goto not_times;
  840. if (operationSafeInterStatement(CFUNC(st->u.continue_cycle.times, var_list, result, belong)))
  841. return result->type;
  842. if (!checkNumber(CNEXT))
  843. return result->type;
  844. times_int = (int)result->value->value->data.int_.num;
  845. freeResult(result);
  846. not_times:
  847. setResult(result, inter);
  848. if (times_int >= 0) {
  849. result->type = R_continue;
  850. result->times = times_int;
  851. }
  852. return result->type;
  853. }
  854. ResultType regoIf(FUNC){
  855. int times_int = 0;
  856. setResultCore(result);
  857. if (st->u.rego_if.times == NULL)
  858. goto not_times;
  859. if (operationSafeInterStatement(CFUNC(st->u.rego_if.times, var_list, result, belong)))
  860. return result->type;
  861. if (!checkNumber(CNEXT))
  862. return result->type;
  863. times_int = (int)result->value->value->data.int_.num;
  864. freeResult(result);
  865. not_times:
  866. setResult(result, inter);
  867. if (times_int >= 0) {
  868. result->type = R_rego;
  869. result->times = times_int;
  870. }
  871. return result->type;
  872. }
  873. ResultType restartCode(FUNC){
  874. int times_int = 0;
  875. setResultCore(result);
  876. if (st->u.restart.times == NULL)
  877. goto not_times;
  878. if (operationSafeInterStatement(CFUNC(st->u.restart.times, var_list, result, belong)))
  879. return result->type;
  880. if (!checkNumber(CNEXT))
  881. return result->type;
  882. times_int = (int)result->value->value->data.int_.num;
  883. freeResult(result);
  884. not_times:
  885. setResult(result, inter);
  886. if (times_int >= 0) {
  887. result->type = R_restart;
  888. result->times = times_int;
  889. }
  890. return result->type;
  891. }
  892. ResultType returnCode(FUNC){
  893. setResultCore(result);
  894. if (st->u.return_code.value == NULL) {
  895. setResult(result, inter);
  896. goto set_result;
  897. }
  898. if (operationSafeInterStatement(CFUNC(st->u.return_code.value, var_list, result, belong)))
  899. return result->type;
  900. set_result:
  901. result->type = R_func;
  902. return result->type;
  903. }
  904. ResultType yieldCode(FUNC){
  905. setResultCore(result);
  906. if (st->u.yield_code.value == NULL) {
  907. setResult(result, inter);
  908. goto set_result;
  909. }
  910. if (operationSafeInterStatement(CFUNC(st->u.yield_code.value, var_list, result, belong)))
  911. return result->type;
  912. set_result:
  913. result->type = R_yield;
  914. return result->type;
  915. }
  916. ResultType raiseCode(FUNC){
  917. setResultCore(result);
  918. if (st->u.raise_code.value == NULL) {
  919. setResult(result, inter);
  920. goto set_result;
  921. }
  922. if (operationSafeInterStatement(CFUNC(st->u.raise_code.value, var_list, result, belong)))
  923. return result->type;
  924. set_result:
  925. result->type = R_error;
  926. result->error = connectError(makeError(L"RaiseException", L"Exception was raise by user", st->line, st->code_file), result->error);
  927. return result->type;
  928. }
  929. ResultType assertCode(FUNC){
  930. bool result_;
  931. LinkValue *opt;
  932. setResultCore(result);
  933. if (inter->data.assert_run == assert_ignore) { // 不执行断言
  934. setResult(result, inter);
  935. return result->type;
  936. }
  937. if (operationSafeInterStatement(CFUNC(st->u.raise_code.value, var_list, result, belong)) || inter->data.assert_run == assert_run)
  938. return result->type;
  939. GET_RESULT(opt, result);
  940. result_ = checkBool(opt, st->line, st->code_file, CNEXT_NT);
  941. gc_freeTmpLink(&opt->gc_status);
  942. if (!CHECK_RESULT(result))
  943. return result->type;
  944. else if (result_)
  945. setResult(result, inter);
  946. else
  947. setResultErrorSt(E_AssertException, L"Assertion check error", true, st, CNEXT_NT);
  948. return result->type;
  949. }
  950. ResultType gotoLabel(FUNC){
  951. int times_int = 0;
  952. wchar_t *label = NULL;
  953. setResultCore(result);
  954. if (operationSafeInterStatement(CFUNC(st->u.goto_.label, var_list, result, belong)))
  955. return result->type;
  956. if (!isType(result->value->value, V_str)) {
  957. setResultErrorSt(E_TypeException, ONLY_ACC(label name, V_str), true, st, CNEXT_NT);
  958. return result->type;
  959. }
  960. label = memWidecpy(result->value->value->data.str.str);
  961. freeResult(result);
  962. if (st->u.goto_.times == NULL)
  963. goto not_times;
  964. if (operationSafeInterStatement(CFUNC(st->u.goto_.times, var_list, result, belong))) {
  965. memFree(label);
  966. return result->type;
  967. }
  968. if (!checkNumber(CNEXT)) {
  969. memFree(label);
  970. return result->type;
  971. }
  972. times_int = (int)result->value->value->data.int_.num;
  973. freeResult(result);
  974. not_times:
  975. if (st->u.goto_.return_ == NULL)
  976. setResult(result, inter);
  977. else if (operationSafeInterStatement(CFUNC(st->u.goto_.return_, var_list, result, belong))) {
  978. memFree(label);
  979. return result->type;
  980. }
  981. result->times = times_int;
  982. result->type = R_goto;
  983. result->label = label;
  984. return result->type;
  985. }
  986. ResultType runLabel(FUNC) {
  987. LinkValue *goto_value;
  988. GET_RESULT(goto_value, result); // goto的值通过result传入, 因此不能进行setResultCore
  989. if (st->u.label_.as != NULL)
  990. assCore(st->u.label_.as, goto_value, false, false, CNEXT_NT);
  991. gc_freeTmpLink(&goto_value->gc_status);
  992. if (st->u.label_.as != NULL && !CHECK_RESULT(result))
  993. return result->type;
  994. freeResult(result);
  995. if (st->u.label_.command != NULL)
  996. operationSafeInterStatement(CFUNC(st->u.label_.command, var_list, result, belong));
  997. else
  998. setResult(result, inter);
  999. return result->type;
  1000. }