runoperation.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. #include "__run.h"
  2. static bool getLeftRightValue(Result *left, Result *right, FUNC);
  3. static ResultType operationCore(FUNC, wchar_t *name);
  4. ResultType operationCore2(FUNC, wchar_t *name);
  5. ResultType assOperation(FUNC);
  6. ResultType pointOperation(FUNC);
  7. ResultType blockOperation(FUNC);
  8. ResultType boolNotOperation(FUNC);
  9. ResultType boolOperation(FUNC);
  10. /**
  11. * operation的整体操作
  12. * @param st
  13. * @param inter
  14. * @param var_list
  15. * @return
  16. */
  17. #define OPT_CASE(TYPE) case OPT_##TYPE: operationCore(CNEXT, inter->data.mag_func[M_##TYPE]); break
  18. #define OPT_CASE2(TYPE) case OPT_##TYPE: operationCore2(CNEXT, inter->data.mag_func[M_##TYPE]); break
  19. ResultType operationStatement(FUNC) {
  20. setResultCore(result);
  21. switch (st->u.operation.OperationType) {
  22. OPT_CASE(ADD);
  23. OPT_CASE(SUB);
  24. OPT_CASE(MUL);
  25. OPT_CASE(DIV);
  26. OPT_CASE(INTDIV);
  27. OPT_CASE(MOD);
  28. OPT_CASE(POW);
  29. OPT_CASE(BAND);
  30. OPT_CASE(BOR);
  31. OPT_CASE(BXOR);
  32. OPT_CASE(BL);
  33. OPT_CASE(BR);
  34. OPT_CASE(EQ);
  35. OPT_CASE(MOREEQ);
  36. OPT_CASE(LESSEQ);
  37. OPT_CASE(MORE);
  38. OPT_CASE(LESS);
  39. OPT_CASE(NOTEQ);
  40. OPT_CASE2(BNOT);
  41. OPT_CASE2(NEGATE);
  42. case OPT_NOT:
  43. boolNotOperation(CNEXT);
  44. break;
  45. case OPT_OR:
  46. case OPT_AND:
  47. boolOperation(CNEXT);
  48. break;
  49. case OPT_ASS:
  50. assOperation(CNEXT);
  51. break;
  52. case OPT_OUTPOINT:
  53. case OPT_POINT:
  54. pointOperation(CNEXT);
  55. break;
  56. case OPT_BLOCK:
  57. blockOperation(CNEXT);
  58. break;
  59. default:
  60. setResult(result, inter);
  61. break;
  62. }
  63. return result->type;
  64. }
  65. #undef OPT_CASE
  66. static void updateBlockYield(Statement *block_st, Statement *node){
  67. block_st->info.node = node->type == yield_code ? node->next : node;
  68. block_st->info.have_info = true;
  69. }
  70. static void newBlockYield(Statement *block_st, Statement *node, VarList *new_var, Inter *inter){
  71. new_var->next = NULL;
  72. gc_freeze(inter, new_var, NULL, true);
  73. block_st->info.var_list = new_var;
  74. block_st->info.node = node->type == yield_code ? node->next : node;
  75. block_st->info.have_info = true;
  76. }
  77. static void setBlockResult(Statement *st, bool yield_run, Result *result, FUNC_CORE) {
  78. if (yield_run) {
  79. if (result->type == R_yield){
  80. updateBlockYield(st, result->node);
  81. result->type = R_opt;
  82. result->is_yield = true;
  83. }
  84. else
  85. freeRunInfo(st);
  86. }
  87. else {
  88. if (result->type == R_yield){
  89. newBlockYield(st, result->node, var_list, inter);
  90. result->type = R_opt;
  91. result->is_yield = true;
  92. }
  93. else
  94. popVarList(var_list);
  95. }
  96. }
  97. ResultType blockOperation(FUNC) {
  98. Statement *info_st = st->u.operation.left;
  99. bool yield_run;
  100. if ((yield_run = popYieldVarList(st, &var_list, var_list, inter)))
  101. info_st = st->info.node;
  102. blockSafeInterStatement(CFUNC(info_st, var_list, result, belong));
  103. if (result->type == R_error)
  104. return result->type;
  105. else
  106. setBlockResult(st, yield_run, result, CFUNC_CORE(var_list));
  107. if (CHECK_RESULT(result) && st->aut != auto_aut)
  108. result->value->aut = st->aut; // 权限覆盖
  109. return result->type;
  110. }
  111. ResultType boolNotOperation(FUNC) {
  112. bool new;
  113. LinkValue *left;
  114. setResultCore(result);
  115. if (operationSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)))
  116. return result->type;
  117. GET_RESULT(left, result);
  118. new = !checkBool(left, st->line, st->code_file, CNEXT_NT);
  119. gc_freeTmpLink(&left->gc_status);
  120. if (CHECK_RESULT(result)) {
  121. freeResult(result);
  122. makeBoolValue(new, st->line, st->code_file, CNEXT_NT);
  123. }
  124. return result->type;
  125. }
  126. ResultType boolOperation(FUNC) {
  127. bool left_bool;
  128. LinkValue *left;
  129. setResultCore(result);
  130. if (operationSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)))
  131. return result->type;
  132. GET_RESULT(left, result);
  133. left_bool = checkBool(left, st->line, st->code_file, CNEXT_NT);
  134. gc_freeTmpLink(&left->gc_status);
  135. if (!CHECK_RESULT(result))
  136. return result->type;
  137. freeResult(result);
  138. if (st->u.operation.OperationType == OPT_AND) { // 与运算
  139. if (left_bool)
  140. operationSafeInterStatement(CFUNC(st->u.operation.right, var_list, result, belong));
  141. else
  142. setResultOperation(result, left);
  143. } else { // 或运算
  144. if (left_bool)
  145. setResultOperation(result, left);
  146. else
  147. operationSafeInterStatement(CFUNC(st->u.operation.right, var_list, result, belong));
  148. }
  149. return result->type;
  150. }
  151. ResultType pointOperation(FUNC) {
  152. LinkValue *left;
  153. VarList *object = NULL;
  154. bool pri_auto;
  155. setResultCore(result);
  156. if (operationSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)) || result->value->value->type == V_none)
  157. return result->type;
  158. GET_RESULT(left, result);
  159. if (st->aut != auto_aut)
  160. left->aut = st->aut; // 权限覆盖
  161. if (st->u.operation.OperationType == OPT_POINT)
  162. object = left->value->object.var;
  163. else if (st->u.operation.OperationType == OPT_OUTPOINT)
  164. object = left->value->object.out_var;
  165. if (object == NULL) {
  166. setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), st->line, st->code_file, true, CNEXT_NT);
  167. goto return_;
  168. }
  169. gc_freeze(inter, var_list, object, true);
  170. operationSafeInterStatement(CFUNC(st->u.operation.right, object, result, left)); // 点运算运算时需要调整belong为点的左值
  171. pri_auto = result->value->belong == NULL || result->value->belong->value == belong->value || checkAttribution(belong->value, result->value->belong->value);
  172. if (!CHECK_RESULT(result) || !checkAut(left->aut, result->value->aut, st->line, st->code_file, NULL, pri_auto, CNEXT_NT))
  173. PASS;
  174. else if (result->value->belong == NULL || result->value->belong->value == left->value || checkAttribution(left->value, result->value->belong->value)) // 检查result所属于的对象是否位左值的父亲
  175. result->value->belong = left;
  176. gc_freeze(inter, var_list, object, false);
  177. return_:
  178. gc_freeTmpLink(&left->gc_status);
  179. return result->type;
  180. }
  181. ResultType delOperation(FUNC) {
  182. Statement *var;
  183. setResultCore(result);
  184. var = st->u.del_.var;
  185. delCore(var, false, CNEXT_NT);
  186. return result->type;
  187. }
  188. ResultType delCore(Statement *name, bool check_aut, FUNC_NT) {
  189. setResultCore(result);
  190. if (name->type == base_list && name->u.base_list.type == L_tuple)
  191. listDel(name, CNEXT_NT);
  192. else if (name->type == slice_)
  193. downDel(name, CNEXT_NT);
  194. else if (name->type == operation && (name->u.operation.OperationType == OPT_POINT || name->u.operation.OperationType == OPT_OUTPOINT))
  195. pointDel(name, CNEXT_NT);
  196. else
  197. varDel(name, check_aut, CNEXT_NT);
  198. return result->type;
  199. }
  200. ResultType listDel(Statement *name, FUNC_NT) {
  201. setResultCore(result);
  202. for (Parameter *pt = name->u.base_list.list; pt != NULL; pt = pt->next){
  203. delCore(pt->data.value, false, CNEXT_NT);
  204. freeResult(result);
  205. }
  206. setResultBase(result, inter);
  207. return result->type;
  208. }
  209. ResultType varDel(Statement *name, bool check_aut, FUNC_NT) {
  210. wchar_t *str_name = NULL;
  211. int int_times = 0;
  212. setResultCore(result);
  213. getVarInfo(&str_name, &int_times, CFUNC(name, var_list, result, belong));
  214. if (!CHECK_RESULT(result)) {
  215. memFree(str_name);
  216. return result->type;
  217. }
  218. if (check_aut) {
  219. LinkValue *tmp = findFromVarList(str_name, int_times, read_var, CFUNC_CORE(var_list));
  220. freeResult(result);
  221. if (tmp != NULL && !checkAut(name->aut, tmp->aut, name->line, name->code_file, NULL, false, CNEXT_NT))
  222. goto return_;
  223. }
  224. findFromVarList(str_name, int_times, del_var, CFUNC_CORE(var_list));
  225. setResult(result, inter);
  226. return_:
  227. memFree(str_name);
  228. return result->type;
  229. }
  230. ResultType pointDel(Statement *name, FUNC_NT) {
  231. LinkValue *left;
  232. VarList *object = NULL;
  233. Statement *right = name->u.operation.right;
  234. setResultCore(result);
  235. if (operationSafeInterStatement(CFUNC(name->u.operation.left, var_list, result, belong)))
  236. return result->type;
  237. GET_RESULT(left, result); // 不关心左值和整体(st)权限
  238. object = name->u.operation.OperationType == OPT_POINT ? left->value->object.var : left->value->object.out_var;
  239. if (object == NULL) {
  240. setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), name->line, name->code_file, true, CNEXT_NT);
  241. goto return_;
  242. }
  243. gc_freeze(inter, var_list, object, true);
  244. if (right->type == T_OPERATION && (right->u.operation.OperationType == OPT_POINT || right->u.operation.OperationType == OPT_OUTPOINT))
  245. pointDel(name->u.operation.right, CFUNC_NT(object, result, belong));
  246. else
  247. delCore(name->u.operation.right, true, CFUNC_NT(object, result, belong));
  248. gc_freeze(inter, var_list, object, false);
  249. return_:
  250. gc_freeTmpLink(&left->gc_status);
  251. return result->type;
  252. }
  253. ResultType downDel(Statement *name, FUNC_NT) {
  254. LinkValue *iter = NULL;
  255. LinkValue *_func_ = NULL;
  256. Parameter *pt = name->u.slice_.index;
  257. setResultCore(result);
  258. if (operationSafeInterStatement(CFUNC(name->u.slice_.element, var_list, result, belong)))
  259. return result->type;
  260. GET_RESULT(iter, result);
  261. if (name->u.slice_.type == SliceType_down_)
  262. _func_ = findAttributes(inter->data.mag_func[M_DOWN_DEL], false, LINEFILE, true, CFUNC_NT(var_list, result, iter));
  263. else
  264. _func_ = findAttributes(inter->data.mag_func[M_DOWN_DEL], false, LINEFILE, true, CFUNC_NT(var_list, result, iter));
  265. if (!CHECK_RESULT(result))
  266. goto return_;
  267. freeResult(result);
  268. if (_func_ != NULL){
  269. Argument *arg = NULL;
  270. gc_addTmpLink(&_func_->gc_status);
  271. arg = getArgument(pt, false, CNEXT_NT);
  272. if (!CHECK_RESULT(result))
  273. goto dderror_;
  274. freeResult(result);
  275. callBackCore(_func_, arg, name->line, name->code_file, 0, CNEXT_NT);
  276. dderror_:
  277. gc_freeTmpLink(&_func_->gc_status);
  278. freeArgument(arg, true);
  279. }
  280. else
  281. setResultErrorSt(E_TypeException, OBJ_NOTSUPPORT(del(__down_del__/__slice_del__)), true, name, CNEXT_NT);
  282. return_:
  283. gc_freeTmpLink(&iter->gc_status);
  284. return result->type;
  285. }
  286. ResultType assOperation(FUNC) {
  287. LinkValue *value = NULL;
  288. setResultCore(result);
  289. if (st->u.operation.left->type == call_function){
  290. Statement *return_st = makeReturnStatement(st->u.operation.right, st->line, st->code_file);
  291. LinkValue *func = NULL;
  292. makeVMFunctionValue(return_st, st->u.operation.left->u.call_function.parameter, CNEXT_NT);
  293. return_st->u.return_code.value = NULL;
  294. freeStatement(return_st);
  295. GET_RESULT(func, result);
  296. assCore(st->u.operation.left->u.call_function.function, func, false, true, CNEXT_NT);
  297. gc_freeTmpLink(&func->gc_status);
  298. }
  299. else{
  300. if (operationSafeInterStatement(CFUNC(st->u.operation.right, var_list, result, belong)))
  301. return result->type;
  302. value = result->value;
  303. freeResult(result);
  304. assCore(st->u.operation.left, value, false, false, CNEXT_NT);
  305. }
  306. return result->type;
  307. }
  308. ResultType assCore(Statement *name, LinkValue *value, bool check_aut, bool setting, FUNC_NT) {
  309. setResultCore(result);
  310. gc_addTmpLink(&value->gc_status);
  311. if (name->type == base_list && name->u.base_list.type == L_tuple)
  312. listAss(name, value, CNEXT_NT);
  313. else if (name->type == slice_)
  314. downAss(name, value, CNEXT_NT);
  315. else if (name->type == operation && (name->u.operation.OperationType == OPT_POINT || name->u.operation.OperationType == OPT_OUTPOINT))
  316. pointAss(name, value, CNEXT_NT);
  317. else
  318. varAss(name, value, check_aut, setting, CNEXT_NT);
  319. gc_freeTmpLink(&value->gc_status);
  320. return result->type;
  321. }
  322. ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool setting, FUNC_NT) {
  323. wchar_t *str_name = NULL;
  324. int int_times = 0;
  325. LinkValue *name_ = NULL;
  326. LinkValue *tmp;
  327. bool run = name->type == base_var ? name->u.base_var.run : name->type == base_svar ? name->u.base_svar.run : false;
  328. setResultCore(result);
  329. getVarInfo(&str_name, &int_times, CFUNC(name, var_list, result, belong));
  330. if (!CHECK_RESULT(result)) {
  331. memFree(str_name);
  332. return result->type;
  333. }
  334. GET_RESULT(name_, result);
  335. if (name->aut != auto_aut) // 当左值设定访问权限的时候, 覆盖右值的权限
  336. value->aut = name->aut;
  337. tmp = findFromVarList(str_name, int_times, read_var, CFUNC_CORE(var_list));
  338. if (check_aut) {
  339. if (tmp != NULL && !checkAut(value->aut, tmp->aut, name->line, name->code_file, NULL, false, CNEXT_NT))
  340. goto error_;
  341. }
  342. if (tmp == NULL || !run || !setVarFunc(tmp, value, name->line, name->code_file, CNEXT_NT))
  343. addFromVarList(str_name, name_, int_times, value, CFUNC_CORE(var_list));
  344. if (!CHECK_RESULT(result))
  345. goto error_;
  346. if (setting) {
  347. freeResult(result);
  348. newObjectSetting(name_, name->line, name->code_file, value, result, inter, var_list);
  349. if (!CHECK_RESULT(result))
  350. goto error_;
  351. }
  352. freeResult(result);
  353. result->type = R_opt;
  354. result->value = value;
  355. gc_addTmpLink(&result->value->gc_status);
  356. error_:
  357. gc_freeTmpLink(&name_->gc_status);
  358. memFree(str_name);
  359. return result->type;
  360. }
  361. ResultType listAss(Statement *name, LinkValue *value, FUNC_NT) {
  362. Parameter *pt = NULL;
  363. Argument *call = NULL;
  364. Statement *tmp_st = makeBaseLinkValueStatement(value, name->line, name->code_file);
  365. setResultCore(result);
  366. pt = makeArgsParameter(tmp_st);
  367. call = getArgument(pt, false, CNEXT_NT);
  368. if (!CHECK_RESULT(result))
  369. goto return_;
  370. freeResult(result);
  371. setParameterCore(name->line, name->code_file, call, name->u.base_list.list, var_list, CNEXT_NT);
  372. if (CHECK_RESULT(result)){
  373. freeResult(result);
  374. makeListValue(call, name->line, name->code_file, L_tuple, CNEXT_NT);
  375. }
  376. return_:
  377. freeArgument(call, false);
  378. freeParameter(pt, true);
  379. return result->type;
  380. }
  381. ResultType downAss(Statement *name, LinkValue *value, FUNC_NT) {
  382. LinkValue *iter = NULL;
  383. LinkValue *_func_ = NULL;
  384. Parameter *pt = name->u.slice_.index;
  385. setResultCore(result);
  386. if (operationSafeInterStatement(CFUNC(name->u.slice_.element, var_list, result, belong)))
  387. return result->type;
  388. GET_RESULT(iter, result);
  389. if (name->u.slice_.type == SliceType_down_)
  390. _func_ = findAttributes(inter->data.mag_func[M_DOWN_ASSIGMENT], false, LINEFILE, true, CFUNC_NT(var_list, result, iter));
  391. else
  392. _func_ = findAttributes(inter->data.mag_func[M_SLICE_ASSIGMENT], false, LINEFILE, true, CFUNC_NT(var_list, result, iter));
  393. if (!CHECK_RESULT(result))
  394. goto return_;
  395. freeResult(result);
  396. if (_func_ != NULL){
  397. Argument *arg = makeValueArgument(value);
  398. gc_addTmpLink(&_func_->gc_status);
  399. arg->next = getArgument(pt, false, CNEXT_NT);
  400. if (!CHECK_RESULT(result))
  401. goto daerror_;
  402. freeResult(result);
  403. callBackCore(_func_, arg, name->line, name->code_file, 0, CNEXT_NT);
  404. daerror_:
  405. freeArgument(arg, true);
  406. gc_freeTmpLink(&_func_->gc_status);
  407. }
  408. else
  409. setResultErrorSt(E_TypeException, OBJ_NOTSUPPORT(assignment(__down_assignment__/__slice_assignment__)), true, name, CNEXT_NT);
  410. return_:
  411. gc_freeTmpLink(&iter->gc_status);
  412. return result->type;
  413. }
  414. ResultType pointAss(Statement *name, LinkValue *value, FUNC_NT) {
  415. LinkValue *left;
  416. Statement *right = name->u.operation.right;
  417. VarList *object = NULL;
  418. setResultCore(result);
  419. if (operationSafeInterStatement(CFUNC(name->u.operation.left, var_list, result, belong)))
  420. return result->type;
  421. GET_RESULT(left, result); // 不关心左值和整体(st)权限
  422. object = name->u.operation.OperationType == OPT_POINT ? left->value->object.var : left->value->object.out_var;
  423. if (object == NULL) {
  424. setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), name->line, name->code_file, true, CNEXT_NT);
  425. goto return_;
  426. }
  427. gc_freeze(inter, var_list, object, true);
  428. if (right->type == T_OPERATION && (right->u.operation.OperationType == OPT_POINT || right->u.operation.OperationType == OPT_OUTPOINT))
  429. pointAss(name->u.operation.right, value, CFUNC_NT(object, result, belong));
  430. else
  431. assCore(name->u.operation.right, value, true, false, CFUNC_NT(object, result, belong));
  432. gc_freeze(inter, var_list, object, false);
  433. return_:
  434. gc_freeTmpLink(&left->gc_status);
  435. return result->type;
  436. }
  437. static ResultType setNameException(LinkValue *val, wchar_t *name, fline line, char *file, FUNC_NT) {
  438. Result tmp;
  439. LinkValue *_attr_;
  440. wchar_t *message = memWidecat(L"Variable not found: ", name, false, false);
  441. setResultCore(&tmp);
  442. gc_addTmpLink(&val->gc_status);
  443. setResultError(E_NameExceptiom, message, line, file, true, CNEXT_NT);
  444. addAttributes(inter->data.mag_func[M_VAL], false, val, line, file, true, CFUNC_NT(var_list, &tmp, result->value)); // 将错误设置为__val__
  445. if (!RUN_TYPE(tmp.type)) {
  446. freeResult(result);
  447. *result = tmp;
  448. goto return_;
  449. }
  450. freeResult(&tmp);
  451. _attr_ = findAttributes(inter->data.mag_func[M_ATTR], false, LINEFILE, true, CFUNC_NT(var_list, &tmp, belong));
  452. if (!RUN_TYPE(tmp.type)) { // 回调__attr__并把错误作为参数
  453. freeResult(result);
  454. *result = tmp;
  455. goto return_;
  456. }
  457. freeResult(&tmp);
  458. if (_attr_ != NULL) {
  459. Argument *arg = makeValueArgument(result->value);
  460. freeResult(result);
  461. gc_addTmpLink(&_attr_->gc_status);
  462. callBackCore(_attr_, arg, line, file, 0, CFUNC_NT(var_list, result, belong));
  463. gc_freeTmpLink(&_attr_->gc_status);
  464. freeArgument(arg, true);
  465. }
  466. return_:
  467. gc_freeTmpLink(&val->gc_status);
  468. memFree(message);
  469. return result->type;
  470. }
  471. ResultType getVar(FUNC, VarInfo var_info) {
  472. int int_times = 0;
  473. wchar_t *name = NULL;
  474. LinkValue *var;
  475. LinkValue *val;
  476. setResultCore(result);
  477. var_info(&name, &int_times, CNEXT);
  478. if (!CHECK_RESULT(result)) {
  479. memFree(name);
  480. return result->type;
  481. }
  482. GET_RESULT(val, result);
  483. var = findFromVarList(name, int_times, get_var, CFUNC_CORE(var_list));
  484. if (var == NULL) {
  485. if (st->type == base_svar && !st->u.base_svar.is_var) {
  486. setResultOperationBase(result, val);
  487. } else
  488. setNameException(val, name, st->line, st->code_file, CNEXT_NT);
  489. } else if (checkAut(st->aut, var->aut, st->line, st->code_file, name, true, CNEXT_NT)) { // 默认访问权限为pri
  490. bool run = st->type == base_var ? st->u.base_var.run : st->type == base_svar ? st->u.base_svar.run : false;
  491. if (!run || !runVarFunc(var, st->line, st->code_file, CNEXT_NT))
  492. setResultOperationBase(result, var);
  493. }
  494. gc_freeTmpLink(&val->gc_status);
  495. memFree(name);
  496. return result->type;
  497. }
  498. ResultType getBaseValue(FUNC) {
  499. setResultCore(result);
  500. if (st->u.base_value.type == link_value) {
  501. result->value = st->u.base_value.value;
  502. result->type = R_opt;
  503. gc_addTmpLink(&result->value->gc_status);
  504. }
  505. else {
  506. switch (st->u.base_value.type) {
  507. case number_str: {
  508. if (wcschr(st->u.base_value.str, '.') == NULL)
  509. makeIntValue(wcstoll(st->u.base_value.str, NULL, 10), st->line, st->code_file, CNEXT_NT);
  510. else
  511. makeDouValue(wcstold(st->u.base_value.str, NULL), st->line, st->code_file, CNEXT_NT);
  512. break;
  513. }
  514. case bool_true:
  515. makeBoolValue(true, st->line, st->code_file, CNEXT_NT);
  516. break;
  517. case bool_false:
  518. makeBoolValue(false, st->line, st->code_file, CNEXT_NT);
  519. break;
  520. case pass_value:
  521. makePassValue(st->line, st->code_file, CNEXT_NT);
  522. break;
  523. case null_value:
  524. useNoneValue(inter, result);
  525. break;
  526. default:
  527. makeStringValue(st->u.base_value.str, st->line, st->code_file, CNEXT_NT);
  528. break;
  529. }
  530. result->value->belong = belong;
  531. }
  532. return result->type;
  533. }
  534. ResultType getList(FUNC) {
  535. Argument *at = NULL;
  536. Argument *at_tmp = NULL;
  537. setResultCore(result);
  538. at = getArgument(st->u.base_list.list, false, CNEXT_NT);
  539. at_tmp = at;
  540. if (!CHECK_RESULT(result)){
  541. freeArgument(at_tmp, false);
  542. return result->type;
  543. }
  544. freeResult(result);
  545. makeListValue(at, st->line, st->code_file, st->u.base_list.type, CNEXT_NT);
  546. freeArgument(at_tmp, false);
  547. return result->type;
  548. }
  549. ResultType getDict(FUNC) {
  550. Argument *at = NULL;
  551. setResultCore(result);
  552. at = getArgument(st->u.base_dict.dict, true, CNEXT_NT);
  553. if (!CHECK_RESULT(result)) {
  554. freeArgument(at, false);
  555. return result->type;
  556. }
  557. freeResult(result);
  558. Value *tmp_value = makeDictValue(at, true, st->line, st->code_file, CNEXT_NT);
  559. if (!CHECK_RESULT(result)) {
  560. freeArgument(at, false);
  561. return result->type;
  562. }
  563. freeResult(result);
  564. LinkValue *value = makeLinkValue(tmp_value, belong, inter);
  565. setResultOperation(result, value);
  566. freeArgument(at, false);
  567. return result->type;
  568. }
  569. ResultType setDefault(FUNC){
  570. enum DefaultType type = st->u.default_var.default_type;
  571. int base = 0; // 用于nonlocal和global
  572. setResultCore(result);
  573. if (type == global_)
  574. for (VarList *tmp = var_list; tmp->next != NULL; tmp = tmp->next)
  575. base++;
  576. else if (type == nonlocal_)
  577. base = 1;
  578. for (Parameter *pt = st->u.default_var.var; pt != NULL; pt = pt->next){
  579. wchar_t *name = NULL;
  580. int times = 0;
  581. freeResult(result);
  582. getVarInfo(&name, &times, CFUNC(pt->data.value, var_list, result, belong));
  583. if (!CHECK_RESULT(result))
  584. break;
  585. if (type != default_)
  586. times = base;
  587. var_list->default_var = connectDefaultVar(var_list->default_var, name, times);
  588. memFree(name);
  589. }
  590. return result->type;
  591. }
  592. bool getLeftRightValue(Result *left, Result *right, FUNC){
  593. if (operationSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)))
  594. return true;
  595. *left = *result;
  596. setResultCore(result);
  597. if (operationSafeInterStatement(CFUNC(st->u.operation.right, var_list, result, belong)))
  598. return true;
  599. *right = *result;
  600. setResultCore(result);
  601. return false;
  602. }
  603. ResultType operationCore(FUNC, wchar_t *name) {
  604. Result left;
  605. Result right;
  606. setResultCore(&left);
  607. setResultCore(&right);
  608. setResultCore(result);
  609. if (getLeftRightValue(&left, &right, CNEXT)) // 不需要释放result
  610. return result->type;
  611. runOperationFromValue(left.value, right.value, name, st->line, st->code_file, CNEXT_NT);
  612. freeResult(&left);
  613. freeResult(&right);
  614. return result->type;
  615. }
  616. ResultType operationCore2(FUNC, wchar_t *name) {
  617. LinkValue *left;
  618. setResultCore(result);
  619. if (operationSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)))
  620. return result->type;
  621. GET_RESULTONLY(left, result); // 不使用freeResult, 不需要多余的把result.value设置为none
  622. runOperationFromValue(left, NULL, name, st->line, st->code_file, CNEXT_NT);
  623. gc_freeTmpLink(&left->gc_status);
  624. return result->type;
  625. }
  626. ResultType runOperationFromValue(LinkValue *self, LinkValue *arg, wchar_t *name, fline line, char *file, FUNC_NT) {
  627. LinkValue *_func_;
  628. gc_addTmpLink(&self->gc_status);
  629. if (arg != NULL)
  630. gc_addTmpLink(&arg->gc_status);
  631. setResultCore(result);
  632. _func_ = findAttributes(name, false, LINEFILE, true, CFUNC_NT(var_list, result, self));
  633. if (!CHECK_RESULT(result))
  634. goto return_;
  635. freeResult(result);
  636. if (_func_ != NULL){
  637. Argument *f_arg = NULL;
  638. if (arg != NULL)
  639. f_arg = makeValueArgument(arg);
  640. gc_addTmpLink(&_func_->gc_status);
  641. callBackCore(_func_, f_arg, line, file, 0, CNEXT_NT);
  642. gc_freeTmpLink(&_func_->gc_status);
  643. freeArgument(f_arg, true);
  644. }
  645. else {
  646. wchar_t *message = memWidecat(L"Object not support ", name, false, false);
  647. setResultError(E_TypeException, message, line, file, true, CNEXT_NT);
  648. memFree(message);
  649. }
  650. return_:
  651. gc_freeTmpLink(&self->gc_status);
  652. if (arg != NULL)
  653. gc_freeTmpLink(&arg->gc_status);
  654. return result->type;
  655. }