runbranch.c 34 KB

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