runbranch.c 37 KB

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