run.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. #include "__run.h"
  2. /**
  3. * 运行单个statement
  4. * @param st
  5. * @param inter
  6. * @param var_list
  7. * @return
  8. */
  9. ResultType runStatement(FUNC) {
  10. ResultType type = R_not;
  11. setResultCore(result);
  12. gc_addTmpLink(&belong->gc_status);
  13. switch (st->type) {
  14. case base_value:
  15. type = getBaseValue(CNEXT);
  16. break;
  17. case base_var:
  18. type = getVar(CNEXT, getBaseVarInfo);
  19. break;
  20. case base_svar:
  21. type = getVar(CNEXT, getBaseSVarInfo);
  22. break;
  23. case base_list:
  24. type = getList(CNEXT);
  25. break;
  26. case base_dict:
  27. type = getDict(CNEXT);
  28. break;
  29. case base_lambda:
  30. type = setLambda(CNEXT);
  31. break;
  32. case operation:
  33. type = operationStatement(CNEXT);
  34. break;
  35. case set_class:
  36. type = setClass(CNEXT);
  37. break;
  38. case set_function:
  39. type = setFunction(CNEXT);
  40. break;
  41. case slice_:
  42. type = elementSlice(CNEXT);
  43. break;
  44. case call_function:
  45. type = callBack(CNEXT);
  46. printf("TAG A\n");
  47. break;
  48. case if_branch:
  49. type = ifBranch(CNEXT);
  50. break;
  51. case while_branch:
  52. type = whileBranch(CNEXT);
  53. break;
  54. case for_branch:
  55. type = forBranch(CNEXT);
  56. break;
  57. case with_branch:
  58. type = withBranch(CNEXT);
  59. break;
  60. case try_branch:
  61. type = tryBranch(CNEXT);
  62. break;
  63. case break_cycle:
  64. type = breakCycle(CNEXT);
  65. break;
  66. case continue_cycle:
  67. type = continueCycle(CNEXT);
  68. break;
  69. case rego_if:
  70. type = regoIf(CNEXT);
  71. break;
  72. case restart:
  73. type = restartCode(CNEXT);
  74. break;
  75. case return_code:
  76. type = returnCode(CNEXT);
  77. break;
  78. case yield_code:
  79. type = yieldCode(CNEXT);
  80. break;
  81. case raise_code:
  82. type = raiseCode(CNEXT);
  83. break;
  84. case include_file:
  85. type = includeFile(CNEXT);
  86. break;
  87. case import_file:
  88. type = importFile(CNEXT);
  89. break;
  90. case from_import_file:
  91. type = fromImportFile(CNEXT);
  92. break;
  93. case default_var:
  94. type = setDefault(CNEXT);
  95. break;
  96. case assert:
  97. type = assertCode(CNEXT);
  98. break;
  99. case goto_:
  100. type = gotoLabel(CNEXT);
  101. break;
  102. case del_:
  103. type = delOperation(CNEXT);
  104. break;
  105. default:
  106. setResult(result, inter);
  107. break;
  108. }
  109. if (RUN_TYPE(type) && result->value->aut == auto_aut)
  110. result->value->aut = st->aut;
  111. result->node = st;
  112. #if START_GC
  113. gc_freeTmpLink(&belong->gc_status);
  114. gc_run(inter, var_list, 1, 2, 0, var_list, belong, result->value);
  115. #endif
  116. return type;
  117. }
  118. static bool checkSignal(fline line, char *file, FUNC_NT) {
  119. if (is_KeyInterrupt == signal_appear){
  120. is_KeyInterrupt = signal_reset;
  121. setResultError(E_KeyInterrupt, KEY_INTERRUPT, line, file, true, CNEXT_NT);
  122. return true;
  123. }
  124. return false;
  125. }
  126. static bool gotoStatement(Statement **next, FUNC) {
  127. Statement *label_st = checkLabel(st, result->label);
  128. if (label_st == NULL){
  129. setResultErrorSt(E_GotoException, L"Don't find label", true, st, CNEXT_NT);
  130. return false;
  131. }
  132. runLabel(CFUNC(label_st, var_list, result, belong));
  133. if (!CHECK_RESULT(result))
  134. return false;
  135. *next = label_st->next;
  136. return true;
  137. }
  138. /**
  139. * 局部程序运行statement
  140. * @param st
  141. * @param inter
  142. * @param var_list
  143. * @return
  144. */
  145. ResultType iterStatement(FUNC) {
  146. Statement *base;
  147. ResultType type;
  148. void *bak = NULL;
  149. setResultCore(result);
  150. if (st == NULL){
  151. setResult(result, inter);
  152. return result->type;
  153. }
  154. is_KeyInterrupt = signal_reset;
  155. bak = signal(SIGINT, signalStopInter);
  156. gc_addTmpLink(&belong->gc_status);
  157. do {
  158. base = st;
  159. if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
  160. type = result->type;
  161. break;
  162. }
  163. while (base != NULL) {
  164. freeResult(result);
  165. type = runStatement(CFUNC(base, var_list, result, belong));
  166. if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
  167. type = result->type;
  168. break;
  169. }
  170. if (type == R_goto && result->times == 0){
  171. if (!gotoStatement(&base, CNEXT)) {
  172. type = result->type;
  173. break;
  174. }
  175. }
  176. else if (!RUN_TYPE(type))
  177. break;
  178. else
  179. base = base->next;
  180. }
  181. } while (type == R_restart && result->times == 0);
  182. if (type == R_not || type == R_restart)
  183. setResultOperationNone(result, inter, belong);
  184. result->node = base;
  185. #if START_GC
  186. gc_freeTmpLink(&belong->gc_status);
  187. gc_run(inter, var_list, 1, 2, 0, var_list, belong, result->value);
  188. #endif
  189. signal(SIGINT, bak);
  190. return result->type;
  191. }
  192. /**
  193. * 全局程序运行statement
  194. * @param inter
  195. * @return
  196. */
  197. ResultType globalIterStatement(Result *result, Inter *inter, Statement *st) {
  198. ResultType type;
  199. VarList *var_list = NULL;
  200. Statement *base;
  201. LinkValue *belong = inter->base_belong;
  202. void *bak = NULL;
  203. if (st == NULL){
  204. setResult(result, inter);
  205. return result->type;
  206. }
  207. is_KeyInterrupt = signal_reset;
  208. bak = signal(SIGINT, signalStopInter);
  209. gc_addTmpLink(&belong->gc_status);
  210. do {
  211. base = st;
  212. var_list = inter->var_list;
  213. if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
  214. type = result->type;
  215. break;
  216. }
  217. while (base != NULL) {
  218. freeResult(result);
  219. type = runStatement(CFUNC(base, var_list, result, belong));
  220. if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
  221. type = result->type;
  222. break;
  223. }
  224. if (type == R_goto){
  225. if (!gotoStatement(&base, CNEXT)) {
  226. type = result->type;
  227. break;
  228. }
  229. }
  230. else if (!RUN_TYPE(type))
  231. break;
  232. else
  233. base = base->next;
  234. }
  235. } while (type == R_restart && result->times == 0);
  236. if (type != R_error && type != R_func)
  237. setResultOperationNone(result, inter, belong);
  238. result->node = base;
  239. #if START_GC
  240. gc_freeTmpLink(&belong->gc_status);
  241. gc_run(inter, var_list, 1, 2, 0, var_list, belong, result->value);
  242. #endif
  243. signal(SIGINT, bak);
  244. return result->type;
  245. }
  246. // 若需要中断执行, 则返回true
  247. bool operationSafeInterStatement(FUNC){
  248. ResultType type;
  249. type = iterStatement(CNEXT);
  250. if (RUN_TYPE(type))
  251. return false;
  252. else if (type != return_code && type != R_error)
  253. setResultErrorSt(E_ResultException, L"Operation get not support result type", true, st, CNEXT_NT);
  254. return true;
  255. }
  256. bool ifBranchSafeInterStatement(FUNC){
  257. ResultType type;
  258. type = iterStatement(CNEXT);
  259. if (RUN_TYPE(type))
  260. return false;
  261. if (type == R_rego){
  262. result->times--;
  263. if (result->times < 0)
  264. return false;
  265. }
  266. if (type == R_restart || type == R_goto)
  267. result->times--;
  268. return true;
  269. }
  270. bool cycleBranchSafeInterStatement(FUNC){
  271. ResultType type;
  272. type = iterStatement(CNEXT);
  273. if (RUN_TYPE(type))
  274. return false;
  275. if (type == R_break || type == R_continue){
  276. result->times--;
  277. if (result->times < 0)
  278. return false;
  279. }
  280. if (type == R_restart || type == R_goto)
  281. result->times--;
  282. return true;
  283. }
  284. bool withBranchSafeInterStatement(FUNC){
  285. ResultType type;
  286. type = iterStatement(CNEXT);
  287. if (RUN_TYPE(type))
  288. return false;
  289. if (type == R_restart || type == R_goto)
  290. result->times--;
  291. return true;
  292. }
  293. bool tryBranchSafeInterStatement(FUNC){
  294. ResultType type;
  295. type = iterStatement(CNEXT);
  296. if (RUN_TYPE(type))
  297. return false;
  298. if (type == R_restart || type == R_goto)
  299. result->times--;
  300. return true;
  301. }
  302. bool functionSafeInterStatement(FUNC){
  303. ResultType type;
  304. type = iterStatement(CNEXT);
  305. if (type == R_error || result->type == R_yield)
  306. return true;
  307. else if (type == R_func)
  308. result->type = R_opt;
  309. else
  310. result->type = R_not;
  311. return false;
  312. }
  313. bool includeSafeInterStatement(FUNC){
  314. iterStatement(CNEXT);
  315. return !CHECK_RESULT(result);
  316. }
  317. bool blockSafeInterStatement(FUNC){
  318. ResultType type;
  319. type = iterStatement(CNEXT);
  320. if (type == R_error || type == R_yield)
  321. return true;
  322. result->type = R_opt;
  323. return false;
  324. }
  325. Statement *checkLabel(Statement *base, wchar_t *label){
  326. for (PASS; base != NULL; base = base->next)
  327. if (base->type == label_ && eqWide(base->u.label_.label, label))
  328. return base;
  329. return NULL;
  330. }
  331. bool is_quitExc(LinkValue *value, Inter *inter) {
  332. return value->value == inter->data.quit_exc->value || checkAttribution(value->value, inter->data.quit_exc->value);
  333. }