run.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  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) { // TODO-list 优化: 只有指定的st需要执行gc
  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. break;
  47. case if_branch:
  48. type = ifBranch(CNEXT);
  49. break;
  50. case while_branch:
  51. type = whileBranch(CNEXT);
  52. break;
  53. case for_branch:
  54. type = forBranch(CNEXT);
  55. break;
  56. case with_branch:
  57. type = withBranch(CNEXT);
  58. break;
  59. case try_branch:
  60. type = tryBranch(CNEXT);
  61. break;
  62. case break_cycle:
  63. type = breakCycle(CNEXT);
  64. break;
  65. case continue_cycle:
  66. type = continueCycle(CNEXT);
  67. break;
  68. case rego_if:
  69. type = regoIf(CNEXT);
  70. break;
  71. case restart:
  72. type = restartCode(CNEXT);
  73. break;
  74. case return_code:
  75. type = returnCode(CNEXT);
  76. break;
  77. case yield_code:
  78. type = yieldCode(CNEXT);
  79. break;
  80. case raise_code:
  81. type = raiseCode(CNEXT);
  82. break;
  83. case include_file:
  84. type = includeFile(CNEXT);
  85. break;
  86. case import_file:
  87. type = importFile(CNEXT);
  88. break;
  89. case from_import_file:
  90. type = fromImportFile(CNEXT);
  91. break;
  92. case default_var:
  93. type = setDefault(CNEXT);
  94. break;
  95. case assert_:
  96. type = assertCode(CNEXT);
  97. break;
  98. case goto_:
  99. type = gotoLabel(CNEXT);
  100. break;
  101. case del_:
  102. type = delOperation(CNEXT);
  103. break;
  104. default:
  105. setResult(result, inter);
  106. break;
  107. }
  108. if (RUN_TYPE(type) && st->aut != auto_aut)
  109. result->value->aut = st->aut; // 权限覆盖
  110. result->node = st;
  111. gc_freeTmpLink(&belong->gc_status);
  112. #if START_GC
  113. gc_run(inter, var_list, 1, 2, 0, var_list, belong, result->value);
  114. #endif
  115. return type;
  116. }
  117. ResultType runStatementOpt(FUNC) { // 不运行gc机制
  118. ResultType type = R_not;
  119. setResultCore(result);
  120. gc_addTmpLink(&belong->gc_status);
  121. switch (st->type) {
  122. case base_value:
  123. type = getBaseValue(CNEXT);
  124. break;
  125. case base_var:
  126. type = getVar(CNEXT, getBaseVarInfo);
  127. break;
  128. case base_svar:
  129. type = getVar(CNEXT, getBaseSVarInfo);
  130. break;
  131. case base_list:
  132. type = getList(CNEXT);
  133. break;
  134. case base_dict:
  135. type = getDict(CNEXT);
  136. break;
  137. case base_lambda:
  138. type = setLambda(CNEXT);
  139. break;
  140. case operation:
  141. type = operationStatement(CNEXT);
  142. break;
  143. case slice_:
  144. type = elementSlice(CNEXT);
  145. break;
  146. case call_function:
  147. type = callBack(CNEXT);
  148. break;
  149. default:
  150. setResult(result, inter);
  151. errasert(runStatementOpt default);
  152. break;
  153. }
  154. if (RUN_TYPE(type) && st->aut != auto_aut)
  155. result->value->aut = st->aut; // 权限覆盖
  156. result->node = st;
  157. gc_freeTmpLink(&belong->gc_status);
  158. return type;
  159. }
  160. static bool checkSignal(fline line, char *file, FUNC_NT) {
  161. if (is_KeyInterrupt == signal_appear){
  162. is_KeyInterrupt = signal_reset;
  163. setResultError(E_KeyInterrupt, KEY_INTERRUPT, line, file, true, CNEXT_NT);
  164. return true;
  165. }
  166. return false;
  167. }
  168. static bool gotoStatement(Statement **next, FUNC) {
  169. Statement *label_st = checkLabel(st, result->label);
  170. if (label_st == NULL){
  171. setResultErrorSt(E_GotoException, L"Don't find label", true, st, CNEXT_NT);
  172. return false;
  173. }
  174. runLabel(CFUNC(label_st, var_list, result, belong));
  175. if (!CHECK_RESULT(result))
  176. return false;
  177. *next = label_st->next;
  178. return true;
  179. }
  180. /**
  181. * 局部程序运行statement
  182. * @param st
  183. * @param inter
  184. * @param var_list
  185. * @return
  186. */
  187. ResultType iterStatement(FUNC) {
  188. Statement *base;
  189. ResultType type;
  190. void *bak = NULL;
  191. setResultCore(result);
  192. if (st == NULL){
  193. setResult(result, inter);
  194. return result->type;
  195. }
  196. is_KeyInterrupt = signal_reset;
  197. bak = signal(SIGINT, signalStopInter);
  198. gc_addTmpLink(&belong->gc_status);
  199. do {
  200. base = st;
  201. if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
  202. type = result->type;
  203. break;
  204. }
  205. while (base != NULL) {
  206. freeResult(result);
  207. type = runStatement(CFUNC(base, var_list, result, belong));
  208. if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
  209. type = result->type;
  210. break;
  211. }
  212. if (type == R_goto && result->times == 0){
  213. if (!gotoStatement(&base, CNEXT)) {
  214. type = result->type;
  215. break;
  216. }
  217. }
  218. else if (!RUN_TYPE(type))
  219. break;
  220. else
  221. base = base->next;
  222. }
  223. } while (type == R_restart && result->times == 0);
  224. if (type == R_not || type == R_restart)
  225. setResultOperationNone(result, inter, belong);
  226. result->node = base;
  227. gc_freeTmpLink(&belong->gc_status);
  228. signal(SIGINT, bak);
  229. return result->type;
  230. }
  231. /**
  232. * 全局程序运行statement
  233. * @param inter
  234. * @return
  235. */
  236. ResultType globalIterStatement(Result *result, Inter *inter, Statement *st, bool p_clock) {
  237. ResultType type;
  238. VarList *var_list = NULL;
  239. Statement *base;
  240. LinkValue *belong = inter->base_belong;
  241. void *bak = NULL;
  242. clock_t start, stop;
  243. if (st == NULL){
  244. setResult(result, inter);
  245. return result->type;
  246. }
  247. is_KeyInterrupt = signal_reset;
  248. bak = signal(SIGINT, signalStopInter);
  249. gc_addTmpLink(&belong->gc_status);
  250. start = clock();
  251. do {
  252. base = st;
  253. var_list = inter->var_list;
  254. if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
  255. type = result->type;
  256. break;
  257. }
  258. while (base != NULL) {
  259. freeResult(result);
  260. type = runStatement(CFUNC(base, var_list, result, belong));
  261. if (checkSignal(base->line, base->code_file, CNEXT_NT)) {
  262. type = result->type;
  263. break;
  264. }
  265. if (type == R_goto){
  266. if (!gotoStatement(&base, CNEXT)) {
  267. type = result->type;
  268. break;
  269. }
  270. }
  271. else if (!RUN_TYPE(type))
  272. break;
  273. else
  274. base = base->next;
  275. }
  276. } while (type == R_restart && result->times == 0);
  277. stop = clock();
  278. if (type != R_error && type != R_func)
  279. setResultOperationNone(result, inter, belong);
  280. result->node = base;
  281. if (p_clock)
  282. printf("run times = %Lf sec\n", (double long)(stop - start) / CLOCKS_PER_SEC);
  283. gc_freeTmpLink(&belong->gc_status);
  284. signal(SIGINT, bak);
  285. return result->type;
  286. }
  287. // 若需要中断执行, 则返回true
  288. bool operationSafeInterStatement(FUNC){
  289. ResultType type;
  290. assert(st->next == NULL); // opt 以单句形式存在
  291. type = runStatementOpt(CNEXT);
  292. if (RUN_TYPE(type))
  293. return false;
  294. assert(type == return_code || type == R_error);
  295. return true;
  296. }
  297. bool ifBranchSafeInterStatement(FUNC){
  298. ResultType type;
  299. type = iterStatement(CNEXT);
  300. if (RUN_TYPE(type))
  301. return false;
  302. if (type == R_rego){
  303. result->times--;
  304. if (result->times < 0)
  305. return false;
  306. }
  307. if (type == R_restart || type == R_goto)
  308. result->times--;
  309. return true;
  310. }
  311. bool cycleBranchSafeInterStatement(FUNC){
  312. ResultType type;
  313. type = iterStatement(CNEXT);
  314. if (RUN_TYPE(type))
  315. return false;
  316. if (type == R_break || type == R_continue){
  317. result->times--;
  318. if (result->times < 0)
  319. return false;
  320. }
  321. if (type == R_restart || type == R_goto)
  322. result->times--;
  323. return true;
  324. }
  325. bool withBranchSafeInterStatement(FUNC){
  326. ResultType type;
  327. type = iterStatement(CNEXT);
  328. if (RUN_TYPE(type))
  329. return false;
  330. if (type == R_restart || type == R_goto)
  331. result->times--;
  332. return true;
  333. }
  334. bool tryBranchSafeInterStatement(FUNC){
  335. ResultType type;
  336. type = iterStatement(CNEXT);
  337. if (RUN_TYPE(type))
  338. return false;
  339. if (type == R_restart || type == R_goto)
  340. result->times--;
  341. return true;
  342. }
  343. bool functionSafeInterStatement(FUNC){
  344. ResultType type;
  345. type = iterStatement(CNEXT);
  346. if (type == R_error || result->type == R_yield)
  347. return true;
  348. else if (type == R_func)
  349. result->type = R_opt;
  350. else
  351. result->type = R_not;
  352. return false;
  353. }
  354. bool includeSafeInterStatement(FUNC){
  355. iterStatement(CNEXT);
  356. return !CHECK_RESULT(result);
  357. }
  358. bool blockSafeInterStatement(FUNC){
  359. ResultType type;
  360. type = iterStatement(CNEXT);
  361. if (type == R_error || type == R_yield)
  362. return true;
  363. result->type = R_opt;
  364. return false;
  365. }
  366. Statement *checkLabel(Statement *base, wchar_t *label){
  367. for (PASS; base != NULL; base = base->next)
  368. if (base->type == label_ && eqWide(base->u.label_.label, label))
  369. return base;
  370. return NULL;
  371. }
  372. bool is_quitExc(LinkValue *value, Inter *inter) {
  373. return value->value == inter->data.base_exc[E_QuitException]->value || checkAttribution(value->value, inter->data.base_exc[E_QuitException]->value);
  374. }