runbranch.c 36 KB

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