run.c 11 KB

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