vobject.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. #include "__ofunc.h"
  2. typedef void (*base_opt)(FUNC_VOBJ);
  3. #define OPERATION_DEFAULT(M_NAME_, ERR_NAME) do{ if (is_left) {runOperationFromValue(right, left, right, inter->data.mag_func[M_##M_NAME_], LINEFILE, CNEXT_NT);} else {setResultError(E_TypeException, CUL_ERROR(ERR_NAME), LINEFILE, true, CNEXT_NT);} }while(0)
  4. void vobject_add_base(FUNC_VOBJ) {
  5. setResultCore(result);
  6. if (left->value->type == V_int && right->value->type == V_int)
  7. makeIntValue(left->value->data.int_.num + right->value->data.int_.num, LINEFILE, CNEXT_NT);
  8. else if (left->value->type == V_int && right->value->type == V_dou)
  9. makeDouValue(left->value->data.int_.num + right->value->data.dou.num, LINEFILE, CNEXT_NT);
  10. else if (left->value->type == V_dou && right->value->type == V_int)
  11. makeDouValue(left->value->data.dou.num + right->value->data.int_.num, LINEFILE, CNEXT_NT);
  12. else if (left->value->type == V_dou && right->value->type == V_dou)
  13. makeDouValue(left->value->data.dou.num + right->value->data.dou.num, LINEFILE, CNEXT_NT);
  14. else if (left->value->type == V_str && right->value->type == V_str) {
  15. wchar_t *new_string = memWidecat(left->value->data.str.str, right->value->data.str.str, false, false);
  16. makeStringValue(new_string, LINEFILE, CNEXT_NT);
  17. memFree(new_string);
  18. } else
  19. OPERATION_DEFAULT(ADD, Add);
  20. }
  21. void vobject_sub_base(FUNC_VOBJ) {
  22. setResultCore(result);
  23. if (left->value->type == V_int && right->value->type == V_int)
  24. makeIntValue(left->value->data.int_.num - right->value->data.int_.num, LINEFILE, CNEXT_NT);
  25. else if (left->value->type == V_int && right->value->type == V_dou)
  26. makeDouValue(left->value->data.int_.num - right->value->data.dou.num, LINEFILE, CNEXT_NT);
  27. else if (left->value->type == V_dou && right->value->type == V_int)
  28. makeDouValue(left->value->data.dou.num - right->value->data.int_.num, LINEFILE, CNEXT_NT);
  29. else if (left->value->type == V_dou && right->value->type == V_dou)
  30. makeDouValue(left->value->data.dou.num - right->value->data.dou.num, LINEFILE, CNEXT_NT);
  31. else if (left->value->type == V_pointer && right->value->type == V_pointer)
  32. makeIntValue((char *) left->value->data.pointer.pointer - (char *) right->value->data.pointer.pointer, LINEFILE,
  33. CNEXT_NT);
  34. else
  35. OPERATION_DEFAULT(SUB, Sub);
  36. }
  37. void vobject_mul_base(FUNC_VOBJ) {
  38. setResultCore(result);
  39. if (left->value->type == V_int && right->value->type == V_int)
  40. makeIntValue(left->value->data.int_.num * right->value->data.int_.num, LINEFILE, CNEXT_NT);
  41. else if (left->value->type == V_int && right->value->type == V_dou)
  42. makeDouValue(left->value->data.int_.num * right->value->data.dou.num, LINEFILE, CNEXT_NT);
  43. else if (left->value->type == V_dou && right->value->type == V_int)
  44. makeDouValue(left->value->data.dou.num * right->value->data.int_.num, LINEFILE, CNEXT_NT);
  45. else if (left->value->type == V_dou && right->value->type == V_dou)
  46. makeDouValue(left->value->data.dou.num * right->value->data.dou.num, LINEFILE, CNEXT_NT);
  47. else if (left->value->type == V_int && right->value->type == V_str) {
  48. Value *tmp = left->value;
  49. left->value = right->value;
  50. right->value = tmp;
  51. goto mul_str;
  52. } else if (left->value->type == V_str && right->value->type == V_int)
  53. mul_str:
  54. {
  55. wchar_t *new_string = memWidecpySelf(left->value->data.str.str, right->value->data.int_.num);
  56. makeStringValue(new_string, LINEFILE, CNEXT_NT);
  57. memFree(new_string);
  58. }
  59. else
  60. OPERATION_DEFAULT(MUL, Mul);
  61. }
  62. void vobject_div_base(FUNC_VOBJ) {
  63. setResultCore(result);
  64. if (right->value->type == V_int && right->value->data.int_.num == 0 || right->value->type == V_dou &&
  65. !(right->value->data.dou.num !=
  66. 0)) // !(right->value->data.dou.num != 0) 因为long double检查是否位0时容易出错
  67. setResultError(E_ValueException, L"divisor mustn't be 0", LINEFILE, true, CNEXT_NT);
  68. else if (left->value->type == V_int && right->value->type == V_int) {
  69. lldiv_t div_result = lldiv(left->value->data.int_.num, right->value->data.int_.num);
  70. makeIntValue(div_result.quot, LINEFILE, CNEXT_NT);
  71. } else if (left->value->type == V_dou && right->value->type == V_int)
  72. makeDouValue(left->value->data.dou.num / (vdou) right->value->data.int_.num, LINEFILE, CNEXT_NT);
  73. else if (left->value->type == V_int && right->value->type == V_dou)
  74. makeDouValue((vdou) left->value->data.int_.num / right->value->data.dou.num, LINEFILE, CNEXT_NT);
  75. else if (left->value->type == V_dou && right->value->type == V_dou)
  76. makeDouValue(left->value->data.dou.num / right->value->data.dou.num, LINEFILE, CNEXT_NT);
  77. else
  78. OPERATION_DEFAULT(DIV, Div);
  79. }
  80. void vobject_intdiv_base(FUNC_VOBJ) {
  81. setResultCore(result);
  82. if (right->value->type == V_int && right->value->data.int_.num == 0 || right->value->type == V_dou &&
  83. (vint) right->value->data.dou.num ==
  84. 0) // !(right->value->data.dou.num != 0) 因为long double检查是否位0时容易出错
  85. setResultError(E_TypeException, L"divisor mustn't be 0", LINEFILE, true, CNEXT_NT);
  86. else if (left->value->type == V_int && right->value->type == V_int) {
  87. lldiv_t div_result = lldiv(left->value->data.int_.num, right->value->data.int_.num);
  88. makeIntValue(div_result.quot, LINEFILE, CNEXT_NT);
  89. } else if (left->value->type == V_dou && right->value->type == V_int)
  90. makeIntValue((vint) left->value->data.dou.num / right->value->data.int_.num, LINEFILE, CNEXT_NT);
  91. else if (left->value->type == V_int && right->value->type == V_dou)
  92. makeIntValue(left->value->data.int_.num / (vint) right->value->data.dou.num, LINEFILE, CNEXT_NT);
  93. else if (left->value->type == V_dou && right->value->type == V_dou)
  94. makeIntValue((vint) left->value->data.dou.num / (vint) right->value->data.dou.num, LINEFILE, CNEXT_NT);
  95. else
  96. OPERATION_DEFAULT(INTDIV, Int Div);
  97. }
  98. void vobject_mod_base(FUNC_VOBJ) {
  99. setResultCore(result);
  100. if (right->value->type == V_int &&
  101. right->value->data.int_.num == 0) // !(right->value->data.dou.num != 0) 因为long double检查是否位0时容易出错
  102. setResultError(E_TypeException, L"divisor mustn't be 0", LINEFILE, true, CNEXT_NT);
  103. else if (left->value->type == V_int && right->value->type == V_int) {
  104. lldiv_t div_result = lldiv(left->value->data.int_.num, right->value->data.int_.num);
  105. makeIntValue(div_result.rem, LINEFILE, CNEXT_NT);
  106. } else
  107. OPERATION_DEFAULT(MOD, Mod);
  108. }
  109. void vobject_pow_base(FUNC_VOBJ) {
  110. setResultCore(result);
  111. errno = 0; // 初始化error
  112. vdou re;
  113. if (left->value->type == V_int && right->value->type == V_int)
  114. re = pow(left->value->data.int_.num, right->value->data.int_.num);
  115. else if (left->value->type == V_dou && right->value->type == V_int)
  116. re = powl(left->value->data.dou.num, right->value->data.int_.num);
  117. else if (left->value->type == V_int && right->value->type == V_dou)
  118. re = powl(left->value->data.int_.num, right->value->data.dou.num);
  119. else if (left->value->type == V_dou && right->value->type == V_dou)
  120. re = powl(left->value->data.dou.num, right->value->data.dou.num);
  121. else {
  122. OPERATION_DEFAULT(POW, Pow);
  123. return;
  124. }
  125. if (errno != 0)
  126. setResultFromERR(E_ValueException, CNEXT_NT);
  127. else
  128. makeDouValue(re, LINEFILE, CNEXT_NT);
  129. }
  130. void vobject_eq_base(FUNC_VOBJ) {
  131. setResultCore(result);
  132. if (left->value->type == V_int && right->value->type == V_int)
  133. makeBoolValue(left->value->data.int_.num == right->value->data.int_.num, LINEFILE, CNEXT_NT);
  134. else if (left->value->type == V_int && right->value->type == V_dou)
  135. makeBoolValue(left->value->data.int_.num == right->value->data.dou.num, LINEFILE, CNEXT_NT);
  136. else if (left->value->type == V_dou && right->value->type == V_int)
  137. makeBoolValue(left->value->data.dou.num == right->value->data.int_.num, LINEFILE, CNEXT_NT);
  138. else if (left->value->type == V_dou && right->value->type == V_dou)
  139. makeBoolValue(left->value->data.dou.num == right->value->data.dou.num, LINEFILE, CNEXT_NT);
  140. else if (left->value->type == V_pointer && right->value->type == V_pointer)
  141. makeBoolValue((char *) left->value->data.pointer.pointer == (char *) right->value->data.pointer.pointer,
  142. LINEFILE, CNEXT_NT);
  143. else if (left->value->type == V_str && right->value->type == V_str)
  144. makeBoolValue(eqWide(left->value->data.str.str, left->value->data.str.str), LINEFILE, CNEXT_NT);
  145. else
  146. OPERATION_DEFAULT(EQ, Eq);
  147. }
  148. void vobject_noteq_base(FUNC_VOBJ) {
  149. setResultCore(result);
  150. if (left->value->type == V_int && right->value->type == V_int)
  151. makeBoolValue(left->value->data.int_.num != right->value->data.int_.num, LINEFILE, CNEXT_NT);
  152. else if (left->value->type == V_int && right->value->type == V_dou)
  153. makeBoolValue(left->value->data.int_.num != right->value->data.dou.num, LINEFILE, CNEXT_NT);
  154. else if (left->value->type == V_dou && right->value->type == V_int)
  155. makeBoolValue(left->value->data.dou.num != right->value->data.int_.num, LINEFILE, CNEXT_NT);
  156. else if (left->value->type == V_dou && right->value->type == V_dou)
  157. makeBoolValue(left->value->data.dou.num != right->value->data.dou.num, LINEFILE, CNEXT_NT);
  158. else if (left->value->type == V_pointer && right->value->type == V_pointer)
  159. makeBoolValue((char *) left->value->data.pointer.pointer != (char *) right->value->data.pointer.pointer,
  160. LINEFILE, CNEXT_NT);
  161. else if (left->value->type == V_str && right->value->type == V_str)
  162. makeBoolValue(!(eqWide(left->value->data.str.str, left->value->data.str.str)), LINEFILE, CNEXT_NT);
  163. else
  164. OPERATION_DEFAULT(NOTEQ, Not Eq);
  165. }
  166. #define BITMACRO(SYMBOL, M_NAME_, NAME, TYPE) void vobject_##NAME##_base(FUNC_VOBJ) { \
  167. setResultCore(result); \
  168. if (left->value->type == V_int && right->value->type == V_int) \
  169. makeIntValue(left->value->data.int_.num SYMBOL right->value->data.int_.num, LINEFILE, CNEXT_NT); \
  170. else OPERATION_DEFAULT(M_NAME_, TYPE); \
  171. }
  172. BITMACRO(&, BAND, band, Bit And)
  173. BITMACRO(|, BOR, bor, Bit Or)
  174. BITMACRO(^, BXOR, bxor, Bit Xor)
  175. #undef BITMACRO
  176. #define BITMOVEMACRO(SYMBOL1, SYMBOL2, M_NAME_, NAME, TYPE) void vobject_##NAME##_base(FUNC_VOBJ) { \
  177. setResultCore(result); \
  178. if (left->value->type == V_int && right->value->type == V_int) { \
  179. if (right->value->data.int_.num >= 0) \
  180. makeIntValue(left->value->data.int_.num SYMBOL1 (unsigned)right->value->data.int_.num, LINEFILE, CNEXT_NT); \
  181. else \
  182. makeIntValue(left->value->data.int_.num SYMBOL2 (unsigned)(-right->value->data.int_.num), LINEFILE, CNEXT_NT); \
  183. } else OPERATION_DEFAULT(M_NAME_, TYPE); \
  184. }
  185. BITMOVEMACRO(<<, >>, BL, bl, Bit Left)
  186. BITMOVEMACRO(>>, <<, BR, br, Bit Right)
  187. #undef BITMOVEMACRO
  188. #define COMPAREMACRO(SYMBOL, M_NAME_, NAME, TYPE) void vobject_##NAME##_base(FUNC_VOBJ) { \
  189. setResultCore(result); \
  190. if (left->value->type == V_int && right->value->type == V_int) \
  191. makeBoolValue(left->value->data.int_.num SYMBOL right->value->data.int_.num, LINEFILE, CNEXT_NT); \
  192. else if (left->value->type == V_int && right->value->type == V_dou) \
  193. makeBoolValue(left->value->data.int_.num SYMBOL right->value->data.dou.num, LINEFILE, CNEXT_NT); \
  194. else if (left->value->type == V_dou && right->value->type == V_int) \
  195. makeBoolValue(left->value->data.dou.num SYMBOL right->value->data.int_.num, LINEFILE, CNEXT_NT); \
  196. else if (left->value->type == V_dou && right->value->type == V_dou) \
  197. makeBoolValue(left->value->data.dou.num SYMBOL right->value->data.dou.num, LINEFILE, CNEXT_NT); \
  198. else if (left->value->type == V_pointer && right->value->type == V_pointer) \
  199. makeBoolValue((char *)left->value->data.pointer.pointer SYMBOL (char *)right->value->data.pointer.pointer, LINEFILE, CNEXT_NT); \
  200. else OPERATION_DEFAULT(M_NAME_, TYPE); \
  201. }
  202. COMPAREMACRO(>, MORE, more, More)
  203. COMPAREMACRO(>=, MOREEQ, moreeq, More Eq)
  204. COMPAREMACRO(<=, LESSEQ, lesseq, Less Eq)
  205. COMPAREMACRO(<, LESS, less, Less Eq)
  206. #undef COMPAREMACRO
  207. static ResultType vobject_opt_core(O_FUNC, base_opt func) {
  208. LinkValue *left;
  209. LinkValue *right;
  210. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  211. {.type=name_value, .name=L"left", .must=1, .long_arg=false},
  212. {.type=name_value, .name=L"right", .must=1, .long_arg=false},
  213. {.must=-1}};
  214. setResultCore(result);
  215. {
  216. parserArgumentUnion(ap, arg, CNEXT_NT);
  217. if (!CHECK_RESULT(result))
  218. return result->type;
  219. freeResult(result);
  220. }
  221. left = ap[1].value;
  222. right = ap[2].value;
  223. func(CFUNC_VOBJ(var_list, result, belong, left, right, (ap[0].value->value ==
  224. left->value))); // 如果 (ap[0].value->value == left->value) 为 true 则代表 is_left 模式
  225. return result->type;
  226. }
  227. #define COMPAREFUNCMACRO(TYPE) ResultType vobject_##TYPE(O_FUNC){ return vobject_opt_core(CO_FUNC(arg, var_list, result, belong), vobject_##TYPE##_base); }
  228. COMPAREFUNCMACRO(add)
  229. COMPAREFUNCMACRO(sub)
  230. COMPAREFUNCMACRO(mul)
  231. COMPAREFUNCMACRO(div)
  232. COMPAREFUNCMACRO(intdiv)
  233. COMPAREFUNCMACRO(mod)
  234. COMPAREFUNCMACRO(pow)
  235. COMPAREFUNCMACRO(eq)
  236. COMPAREFUNCMACRO(noteq)
  237. COMPAREFUNCMACRO(moreeq)
  238. COMPAREFUNCMACRO(lesseq)
  239. COMPAREFUNCMACRO(more)
  240. COMPAREFUNCMACRO(less)
  241. COMPAREFUNCMACRO(band)
  242. COMPAREFUNCMACRO(bor)
  243. COMPAREFUNCMACRO(bxor)
  244. COMPAREFUNCMACRO(bl)
  245. COMPAREFUNCMACRO(br)
  246. #undef COMPAREFUNCMACRO
  247. void vobject_negate_base(FUNC_VOBJR) {
  248. setResultCore(result);
  249. switch (left->value->type) {
  250. case V_int:
  251. makeIntValue(-(left->value->data.int_.num), LINEFILE, CNEXT_NT);
  252. break;
  253. case V_dou:
  254. makeDouValue(-(left->value->data.dou.num), LINEFILE, CNEXT_NT);
  255. break;
  256. case V_str: {
  257. wchar_t *new = memWidecpySelf(left->value->data.str.str, -1);
  258. makeStringValue(new, LINEFILE, CNEXT_NT);
  259. memFree(new);
  260. break;
  261. }
  262. case V_bool:
  263. makeBoolValue(!(left->value->data.bool_.bool_), LINEFILE, CNEXT_NT);
  264. break;
  265. case V_none:
  266. setResult(result, inter);
  267. break;
  268. default:
  269. setResultError(E_TypeException, CUL_ERROR(Negate), LINEFILE, true, CNEXT_NT);
  270. break;
  271. }
  272. }
  273. void vobject_bnot_base(FUNC_VOBJR) {
  274. setResultCore(result);
  275. switch (left->value->type) {
  276. case V_int:
  277. makeIntValue(~(unsigned long long) (left->value->data.int_.num), LINEFILE, CNEXT_NT);
  278. break;
  279. case V_bool:
  280. makeBoolValue(!(left->value->data.bool_.bool_), LINEFILE, CNEXT_NT);
  281. break;
  282. case V_none:
  283. setResult(result, inter);
  284. break;
  285. default:
  286. setResultError(E_TypeException, CUL_ERROR(Negate), LINEFILE, true, CNEXT_NT);
  287. break;
  288. }
  289. }
  290. static ResultType vobject_negate(O_FUNC) {
  291. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  292. {.type=name_value, .name=L"val", .must=1, .long_arg=false},
  293. {.must=-1}};
  294. setResultCore(result);
  295. parserArgumentUnion(ap, arg, CNEXT_NT);
  296. if (!CHECK_RESULT(result))
  297. return result->type;
  298. freeResult(result);
  299. vobject_negate_base(CFUNC_VOBJR(var_list, result, belong, ap[1].value));
  300. return result->type;
  301. }
  302. static ResultType vobject_bnot(O_FUNC) {
  303. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  304. {.type=name_value, .name=L"val", .must=1, .long_arg=false},
  305. {.must=-1}};
  306. setResultCore(result);
  307. parserArgumentUnion(ap, arg, CNEXT_NT);
  308. if (!CHECK_RESULT(result))
  309. return result->type;
  310. freeResult(result);
  311. vobject_bnot_base(CFUNC_VOBJR(var_list, result, belong, ap[1].value));
  312. return result->type;
  313. }
  314. static ResultType vobject_bool(O_FUNC) {
  315. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  316. {.must=-1}};
  317. bool result_ = false;
  318. Value *value = NULL;
  319. setResultCore(result);
  320. parserArgumentUnion(ap, arg, CNEXT_NT);
  321. if (!CHECK_RESULT(result))
  322. return result->type;
  323. freeResult(result);
  324. value = ap[0].value->value;
  325. switch (value->type) {
  326. case V_int:
  327. result_ = value->data.int_.num != 0;
  328. break;
  329. case V_dou:
  330. result_ = value->data.dou.num != 0;
  331. break;
  332. case V_pointer:
  333. result_ = value->data.pointer.pointer != NULL;
  334. break;
  335. case V_str:
  336. result_ = memWidelen(value->data.str.str) > 0;
  337. break;
  338. case V_bool:
  339. result_ = value->data.bool_.bool_;
  340. break;
  341. case V_ell:
  342. case V_none:
  343. result_ = false;
  344. break;
  345. case V_list:
  346. result_ = value->data.list.size > 0;
  347. break;
  348. case V_dict:
  349. result_ = value->data.dict.size > 0;
  350. break;
  351. case V_lib:
  352. result_ = value->data.lib.handle != NULL;
  353. break;
  354. case V_file:
  355. result_ = value->data.file.file != NULL;
  356. break;
  357. default:
  358. setResultError(E_TypeException, CUL_ERROR(bool), LINEFILE, true, CNEXT_NT);
  359. return R_error;
  360. }
  361. makeBoolValue(result_, LINEFILE, CNEXT_NT);
  362. return result->type;
  363. }
  364. static ResultType vobject_repo(O_FUNC) {
  365. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  366. {.must=-1}};
  367. wchar_t *repo = NULL;
  368. Value *value = NULL;
  369. setResultCore(result);
  370. parserArgumentUnion(ap, arg, CNEXT_NT);
  371. if (!CHECK_RESULT(result))
  372. return result->type;
  373. freeResult(result);
  374. value = ap[0].value->value;
  375. switch (value->type) { // node和list以及dict都不再此处设定
  376. case V_int: {
  377. char str[30] = {NUL};
  378. snprintf(str, 30, "%lld", value->data.int_.num);
  379. repo = memStrToWcs(str, false);
  380. break;
  381. }
  382. case V_pointer: {
  383. char str[30] = {NUL};
  384. snprintf(str, 30, "%p", value->data.pointer.pointer);
  385. repo = memStrToWcs(str, false);
  386. break;
  387. }
  388. case V_dou: {
  389. char str[30] = {NUL};
  390. if (value->data.dou.num != 0)
  391. snprintf(str, 30, "%Lg", value->data.dou.num);
  392. else
  393. str[0] = '0';
  394. repo = memStrToWcs(str, false);
  395. break;
  396. }
  397. case V_str:
  398. repo = memWidecpy(value->data.str.str);
  399. break;
  400. case V_func: {
  401. char str[30] = {NUL};
  402. snprintf(str, 30, "(func on %p)", value);
  403. repo = memStrToWcs(str, false);
  404. break;
  405. }
  406. case V_class: {
  407. char str[30] = {NUL};
  408. snprintf(str, 30, "(class on %p)", value);
  409. repo = memStrToWcs(str, false);
  410. break;
  411. }
  412. case V_bool:
  413. if (value->data.bool_.bool_)
  414. repo = memStrToWcs("true", false);
  415. else
  416. repo = memStrToWcs("false", false);
  417. break;
  418. case V_ell:
  419. repo = memStrToWcs("...", false);
  420. break;
  421. case V_file: {
  422. size_t len = memStrlen(value->data.file.path) + memStrlen(value->data.file.mode) + 20;
  423. char str[len]; // 变长数组
  424. snprintf(str, len, "(file on %s %s)", value->data.file.path, value->data.file.mode);
  425. repo = memStrToWcs(str, false);
  426. break;
  427. }
  428. default:
  429. setResultError(E_TypeException, CUL_ERROR(repo / str), LINEFILE, true, CNEXT_NT);
  430. return R_error;
  431. }
  432. makeStringValue(repo, LINEFILE, CNEXT_NT);
  433. memFree(repo);
  434. return result->type;
  435. }
  436. void registeredVObject(R_FUNC) {
  437. LinkValue *object = inter->data.base_obj[B_VOBJECT];
  438. NameFunc tmp[] = {{inter->data.mag_func[M_ADD], vobject_add, fp_obj, .var=nfv_notpush},
  439. {inter->data.mag_func[M_SUB], vobject_sub, fp_obj, .var=nfv_notpush},
  440. {inter->data.mag_func[M_MUL], vobject_mul, fp_obj, .var=nfv_notpush},
  441. {inter->data.mag_func[M_DIV], vobject_div, fp_obj, .var=nfv_notpush},
  442. {inter->data.mag_func[M_INTDIV], vobject_intdiv, fp_obj, .var=nfv_notpush},
  443. {inter->data.mag_func[M_MOD], vobject_mod, fp_obj, .var=nfv_notpush},
  444. {inter->data.mag_func[M_POW], vobject_pow, fp_obj, .var=nfv_notpush},
  445. {inter->data.mag_func[M_EQ], vobject_eq, fp_obj, .var=nfv_notpush},
  446. {inter->data.mag_func[M_NOTEQ], vobject_noteq, fp_obj, .var=nfv_notpush},
  447. {inter->data.mag_func[M_MOREEQ], vobject_moreeq, fp_obj, .var=nfv_notpush},
  448. {inter->data.mag_func[M_LESSEQ], vobject_lesseq, fp_obj, .var=nfv_notpush},
  449. {inter->data.mag_func[M_MORE], vobject_more, fp_obj, .var=nfv_notpush},
  450. {inter->data.mag_func[M_LESS], vobject_less, fp_obj, .var=nfv_notpush},
  451. {inter->data.mag_func[M_BAND], vobject_band, fp_obj, .var=nfv_notpush},
  452. {inter->data.mag_func[M_BOR], vobject_bor, fp_obj, .var=nfv_notpush},
  453. {inter->data.mag_func[M_BXOR], vobject_bxor, fp_obj, .var=nfv_notpush},
  454. {inter->data.mag_func[M_BL], vobject_bl, fp_obj, .var=nfv_notpush},
  455. {inter->data.mag_func[M_BR], vobject_br, fp_obj, .var=nfv_notpush},
  456. {inter->data.mag_func[M_NEGATE], vobject_negate, fp_obj, .var=nfv_notpush},
  457. {inter->data.mag_func[M_BNOT], vobject_bnot, fp_obj, .var=nfv_notpush},
  458. {inter->data.mag_func[M_BOOL], vobject_bool, fp_obj, .var=nfv_notpush},
  459. {inter->data.mag_func[M_REPO], vobject_repo, fp_obj, .var=nfv_notpush},
  460. {inter->data.mag_func[M_STR], vobject_repo, fp_obj, .var=nfv_notpush},
  461. {NULL, NULL}};
  462. gc_addTmpLink(&object->gc_status);
  463. addBaseClassVar(L"vobject", object, belong, inter);
  464. iterBaseClassFunc(tmp, object, CFUNC_CORE(inter->var_list));
  465. gc_freeTmpLink(&object->gc_status);
  466. }
  467. void makeBaseVObject(Inter *inter) {
  468. LinkValue *vobject = makeBaseChildClass(inter->data.base_obj[B_OBJECT], inter);
  469. gc_addStatementLink(&vobject->gc_status);
  470. inter->data.base_obj[B_VOBJECT] = vobject;
  471. }