__run.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. #include "__run.h"
  2. ResultType getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
  3. LinkValue *value;
  4. *name = setStrVarName(st->u.base_var.name, false, inter);
  5. *times = 0;
  6. if (st->u.base_var.times == NULL){
  7. *times = 0;
  8. goto not_times;
  9. }
  10. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list, result, belong)))
  11. return result->type;
  12. if (!isType(result->value->value, number)){
  13. setResultErrorSt(E_TypeException, "Variable operation got unsupported number of layers", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  14. return result->type;
  15. }
  16. *times = (int)result->value->value->data.num.num;
  17. freeResult(result);
  18. not_times:
  19. makeStringValue(st->u.base_var.name, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  20. return result->type;
  21. }
  22. ResultType getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
  23. freeResult(result);
  24. if (st->u.base_svar.times == NULL){
  25. *times = 0;
  26. goto not_times;
  27. }
  28. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_svar.times, var_list, result, belong)))
  29. return result->type;
  30. if (!isType(result->value->value, number)){
  31. setResultErrorSt(E_TypeException, "Variable operation got unsupported number of layers", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  32. return result->type;
  33. }
  34. *times = (int)result->value->value->data.num.num;
  35. freeResult(result);
  36. not_times:
  37. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_svar.name, var_list, result, belong)))
  38. return result->type;
  39. *name = getNameFromValue(result->value->value, inter);
  40. result->type = operation_return; // 执行 operationSafeInterStatement 的时候已经初始化 result
  41. return result->type;
  42. }
  43. ResultType getVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
  44. if (st->type == base_var)
  45. getBaseVarInfo(name, times, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
  46. else if (st->type == base_svar)
  47. getBaseSVarInfo(name, times, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
  48. else{
  49. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)))
  50. return result->type;
  51. *name = getNameFromValue(result->value->value, inter);
  52. *times = 0;
  53. }
  54. return result->type;
  55. }
  56. char *setStrVarName(char *old, bool free_old, Inter *inter) {
  57. return memStrcat(inter->data.var_str_prefix, old, false, free_old);
  58. }
  59. char *setNumVarName(vnum num, struct Inter *inter) {
  60. char name[50];
  61. snprintf(name, 50, "%lld", num);
  62. return memStrcat(inter->data.var_num_prefix, name, false, false);
  63. }
  64. char *getNameFromValue(Value *value, struct Inter *inter) {
  65. switch (value->type){
  66. case string:
  67. return setStrVarName(value->data.str.str, false, inter);
  68. case number:
  69. return setNumVarName(value->data.num.num, inter);
  70. case bool_:
  71. if (value->data.bool_.bool_)
  72. return memStrcat(inter->data.var_bool_prefix, "true", false, false);
  73. else
  74. return memStrcat(inter->data.var_bool_prefix, "false", false, false);
  75. case none:
  76. return memStrcpy(inter->data.var_none);
  77. case pass_:
  78. return memStrcpy(inter->data.var_pass);
  79. case class:{
  80. size_t len = memStrlen(inter->data.var_class_prefix) + 20;
  81. char *name = memString(len);
  82. char *return_ = NULL;
  83. snprintf(name, len, "%s%p", inter->data.var_class_prefix, value);
  84. return_ = memStrcpy(name);
  85. memFree(name);
  86. return return_;
  87. }
  88. default:{
  89. size_t len = memStrlen(inter->data.var_object_prefix) + 20;
  90. char *name = memString(len);
  91. char *return_ = NULL;
  92. snprintf(name, len, "%s%p", inter->data.var_object_prefix, value);
  93. return_ = memStrcpy(name);
  94. memFree(name);
  95. return return_;
  96. }
  97. }
  98. }
  99. bool popStatementVarList(Statement *funtion_st, VarList **function_var, VarList *out_var, Inter *inter){
  100. bool yield_run;
  101. if ((yield_run = funtion_st->info.have_info)) {
  102. *function_var = funtion_st->info.var_list;
  103. (*function_var)->next = out_var;
  104. }
  105. else
  106. *function_var = pushVarList(out_var, inter);
  107. return yield_run;
  108. }
  109. void newFunctionYield(Statement *funtion_st, Statement *node, VarList *new_var, Inter *inter){
  110. new_var->next = NULL;
  111. gc_freeze(inter, new_var, NULL, true);
  112. funtion_st->info.var_list = new_var;
  113. funtion_st->info.node = node->type == yield_code ? node->next : node;
  114. funtion_st->info.have_info = true;
  115. }
  116. void updateFunctionYield(Statement *function_st, Statement *node){
  117. function_st->info.node = node->type == yield_code ? node->next : node;
  118. function_st->info.have_info = true;
  119. }
  120. ResultType setFunctionArgument(Argument **arg, Argument **base, LinkValue *_func, fline line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST){
  121. Argument *tmp = NULL;
  122. LinkValue *self;
  123. LinkValue *func;
  124. enum FunctionPtType pt_type = _func->value->data.function.function_data.pt_type;
  125. setResultCore(result);
  126. switch (pt_sep) {
  127. case 0:
  128. func = _func;
  129. self = _func->belong;
  130. *base = *arg;
  131. break;
  132. case 1: {
  133. if (*arg != NULL) {
  134. if (pt_type == static_) {
  135. func = (*arg)->data.value;
  136. self = NULL; // static_模式不需要self
  137. }
  138. else {
  139. func = _func;
  140. self = (*arg)->data.value;
  141. }
  142. *arg = (*arg)->next; // 忽略第一个arg, 但是不释放(在该函数外部统一释放)
  143. *base = *arg;
  144. } else {
  145. error_:
  146. setResultError(E_ArgumentException, FEW_ARG, line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  147. return error_return;
  148. }
  149. break;
  150. }
  151. case 2: {
  152. if (*arg != NULL && (*arg)->next != NULL) {
  153. func = (*arg)->data.value;
  154. self = (*arg)->next->data.value; // 第一个参数是func, 第二个是self; 这样做保证了和形参调用的一致
  155. *arg = (*arg)->next->next;
  156. *base = *arg;
  157. } else
  158. goto error_;
  159. break;
  160. }
  161. default:
  162. setResultError(E_ArgumentException, MANY_ARG, line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  163. return error_return;
  164. }
  165. if (pt_type != free_ && self == NULL) {
  166. setResultError(E_ArgumentException, "Function does not belong to anything(not self)", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  167. return error_return;
  168. }
  169. switch (pt_type) {
  170. case static_:
  171. tmp = makeValueArgument(func);
  172. tmp->next = *arg;
  173. *arg = tmp;
  174. break;
  175. case class_static_:
  176. tmp = makeValueArgument(func);
  177. if (self->value->type != class) {
  178. self = NULL;
  179. for (Inherit *ih = self->value->object.inherit; ih != NULL; ih = ih->next) // 使用循环的方式检查
  180. if (ih->value->value->type == class) {
  181. self = ih->value;
  182. break;
  183. }
  184. }
  185. if (self != NULL) {
  186. tmp->next = makeValueArgument(self);
  187. tmp->next->next = *arg;
  188. } else // 若未检查到class, 则放弃该形参(由原arg补上)
  189. tmp->next = *arg;
  190. *arg = tmp;
  191. break;
  192. case all_static_:
  193. tmp = makeValueArgument(func);
  194. tmp->next = makeValueArgument(self);
  195. tmp->next->next = *arg;
  196. *arg = tmp;
  197. break;
  198. case object_static_:
  199. tmp = makeValueArgument(func);
  200. if (self->value->type != class){
  201. tmp->next = makeValueArgument(self);
  202. tmp->next->next = *arg;
  203. }
  204. else
  205. tmp->next = *arg;
  206. *arg = tmp;
  207. break;
  208. case class_free_:
  209. if (self->value->type != class){
  210. self = NULL;
  211. for (Inherit *ih = self->value->object.inherit; ih != NULL; ih = ih->next) // 循环检查
  212. if (ih->value->value->type == class) {
  213. self = ih->value;
  214. break;
  215. }
  216. }
  217. if (self != NULL) { // 若检查到class
  218. tmp = makeValueArgument(self);
  219. tmp->next = *arg;
  220. *arg = tmp;
  221. } // 若无class则不对arg做任何调整
  222. break;
  223. case object_free_:
  224. if (self->value->type != class) {
  225. tmp = makeValueArgument(self);
  226. tmp->next = *arg;
  227. *arg = tmp;
  228. }
  229. break;
  230. case all_free_:
  231. tmp = makeValueArgument(self);
  232. tmp->next = *arg;
  233. *arg = tmp;
  234. break;
  235. default:
  236. break;
  237. }
  238. setResultBase(result, inter);
  239. return result->type;
  240. }
  241. void freeFunctionArgument(Argument *arg, Argument *base) {
  242. for (Argument *tmp = arg; tmp != NULL; tmp = tmp->next) {
  243. if (tmp->next == base) {
  244. tmp->next = NULL;
  245. freeArgument(arg, true);
  246. break;
  247. }
  248. }
  249. }
  250. LinkValue *findStrVar(char *name, bool free_old, INTER_FUNCTIONSIG_CORE){
  251. LinkValue *tmp = NULL;
  252. char *name_ = setStrVarName(name, free_old, inter);
  253. tmp = findFromVarList(name_, 0, get_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
  254. memFree(name_);
  255. return tmp;
  256. }
  257. LinkValue *checkStrVar(char *name, bool free_old, INTER_FUNCTIONSIG_CORE){
  258. LinkValue *tmp = NULL;
  259. char *name_ = setStrVarName(name, free_old, inter);
  260. tmp = findFromVarList(name_, 0, read_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
  261. memFree(name_);
  262. return tmp;
  263. }
  264. void addStrVarCore(int setting, char *var_name, LinkValue *name_, LinkValue *value, fline line, char *file, VarList *out_var, INTER_FUNCTIONSIG_NOT_ST) {
  265. addFromVarList(var_name, name_, 0, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
  266. out_var = out_var == NULL ? var_list : out_var;
  267. if (setting)
  268. newObjectSetting(name_, line, file, value, result, inter, out_var);
  269. else
  270. setResult(result, inter, belong);
  271. }
  272. void addStrVar(char *name, bool free_old, bool setting, LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
  273. char *var_name = setStrVarName(name, free_old, inter);
  274. LinkValue *name_;
  275. setResultCore(result);
  276. makeStringValue(name, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  277. if (!CHECK_RESULT(result))
  278. goto return_;
  279. name_ = result->value;
  280. result->value = NULL;
  281. freeResult(result);
  282. addStrVarCore(setting, var_name, name_, value, line, file, NULL, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  283. gc_freeTmpLink(&name_->gc_status);
  284. return_: memFree(var_name);
  285. }
  286. LinkValue *findAttributes(char *name, bool free_old, LinkValue *value, Inter *inter) {
  287. LinkValue *attr = findStrVar(name, free_old, CALL_INTER_FUNCTIONSIG_CORE(value->value->object.var));
  288. if (attr != NULL && (attr->belong == NULL || attr->belong->value != value->value && checkAttribution(value->value, attr->belong->value)))
  289. attr->belong = value;
  290. return attr;
  291. }
  292. bool addAttributes(char *name, bool free_old, LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
  293. char *var_name = setStrVarName(name, free_old, inter);
  294. LinkValue *name_;
  295. setResultCore(result);
  296. makeStringValue(name, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  297. if (!CHECK_RESULT(result))
  298. goto return_;
  299. name_ = result->value;
  300. result->value = NULL;
  301. freeResult(result);
  302. gc_freeze(inter, var_list, belong->value->object.var, true);
  303. addStrVarCore(false, var_name, name_, value, line, file, var_list, CALL_INTER_FUNCTIONSIG_NOT_ST(belong->value->object.var, result, belong));
  304. gc_freeze(inter, var_list, belong->value->object.var, false);
  305. gc_freeTmpLink(&name_->gc_status);
  306. return_:
  307. memFree(var_name);
  308. return CHECK_RESULT(result);
  309. }
  310. void newObjectSetting(LinkValue *name, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
  311. setResultCore(result);
  312. addAttributes(inter->data.object_name, false, name, line, file, belong, result, inter, var_list);
  313. if (CHECK_RESULT(result))
  314. return;
  315. freeResult(result);
  316. addAttributes(inter->data.object_self, false, belong, line, file, belong, result, inter, var_list);
  317. if (CHECK_RESULT(result) && belong->value->object.inherit != NULL) {
  318. freeResult(result);
  319. addAttributes(inter->data.object_father, false, belong->value->object.inherit->value, line, file, belong,
  320. result, inter, var_list);
  321. }
  322. }
  323. ResultType getElement(LinkValue *from, LinkValue *index, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
  324. LinkValue *_func_ = NULL;
  325. setResultCore(result);
  326. gc_addTmpLink(&from->gc_status);
  327. gc_addTmpLink(&index->gc_status);
  328. _func_ = findAttributes(inter->data.object_down, false, from, inter);
  329. if (_func_ != NULL){
  330. Argument *arg = NULL;
  331. gc_addTmpLink(&_func_->gc_status);
  332. arg = makeValueArgument(index);
  333. callBackCore(_func_, arg, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  334. gc_freeTmpLink(&_func_->gc_status);
  335. freeArgument(arg, true);
  336. }
  337. else
  338. setResultError(E_TypeException, OBJ_NOTSUPPORT(subscript(__down__)), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  339. gc_freeTmpLink(&from->gc_status);
  340. gc_freeTmpLink(&index->gc_status);
  341. return result->type;
  342. }
  343. ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
  344. LinkValue *_func_ = NULL;
  345. setResultCore(result);
  346. if (status == 1)
  347. _func_ = findAttributes(inter->data.object_iter, false, value, inter);
  348. else
  349. _func_ = findAttributes(inter->data.object_next, false, value, inter);
  350. if (_func_ != NULL){
  351. gc_addTmpLink(&_func_->gc_status);
  352. callBackCore(_func_, NULL, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  353. gc_freeTmpLink(&_func_->gc_status);
  354. }
  355. else
  356. setResultError(E_TypeException, OBJ_NOTSUPPORT(iter), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  357. return result->type;
  358. }
  359. bool checkBool(LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
  360. LinkValue *_bool_ = findAttributes(inter->data.object_bool, false, value, inter);
  361. if (_bool_ != NULL){
  362. gc_addTmpLink(&_bool_->gc_status);
  363. callBackCore(_bool_, NULL, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  364. gc_freeTmpLink(&_bool_->gc_status);
  365. if (result->value->value->type != bool_)
  366. setResultError(E_TypeException, RETURN_ERROR(__bool__, bool), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  367. else
  368. return result->value->value->data.bool_.bool_;
  369. } else {
  370. makeBoolValue(true, 0, "sys.bool", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  371. return true;
  372. }
  373. return false;
  374. }
  375. char *getRepoStr(LinkValue *value, bool is_repo, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
  376. LinkValue *_repo_ = findAttributes(is_repo ? inter->data.object_repo : inter->data.object_str, false, value, inter);
  377. setResultCore(result);
  378. if (_repo_ != NULL){
  379. gc_addTmpLink(&value->gc_status);
  380. gc_addTmpLink(&_repo_->gc_status);
  381. callBackCore(_repo_, NULL, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  382. gc_freeTmpLink(&_repo_->gc_status);
  383. gc_freeTmpLink(&value->gc_status);
  384. if (!CHECK_RESULT(result))
  385. return NULL;
  386. else if (result->value->value->type != string){
  387. setResultError(E_TypeException, OBJ_NOTSUPPORT(repo(str)), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  388. return NULL;
  389. }
  390. return result->value->value->data.str.str;
  391. }
  392. else
  393. setResultError(E_TypeException, OBJ_NOTSUPPORT(repo(str)), line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  394. return NULL;
  395. }
  396. bool is_iterStop(LinkValue *value, Inter *inter) {
  397. return value->value == inter->data.iterstop_exc->value || checkAttribution(value->value, inter->data.iterstop_exc->value);
  398. }
  399. bool is_indexException(LinkValue *value, Inter *inter) {
  400. return value->value == inter->data.index_exc->value || checkAttribution(value->value, inter->data.index_exc->value);
  401. }
  402. bool checkAut(enum ValueAuthority value, enum ValueAuthority base, fline line, char *file, char *name, bool pri_auto, INTER_FUNCTIONSIG_NOT_ST) {
  403. if ((value == public_aut || (!pri_auto && value == auto_aut)) && (base != public_aut && base != auto_aut)) {
  404. if (name == NULL)
  405. setResultError(E_PermissionsException, "Wrong Permissions: access variables as public", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  406. else {
  407. char *message = memStrcat("Wrong Permissions: access variables as public: ", name, false, false);
  408. setResultError(E_PermissionsException, message, line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  409. memFree(message);
  410. }
  411. return false;
  412. }
  413. else if ((value == protect_aut) && (base == private_aut)) {
  414. if (name == NULL)
  415. setResultError(E_PermissionsException, "Wrong Permissions: access variables as protect", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  416. else {
  417. char *message = memStrcat("Wrong Permissions: access variables as protect: ", name, false, false);
  418. setResultError(E_PermissionsException, message, line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  419. memFree(message);
  420. }
  421. return false;
  422. }
  423. return true;
  424. }
  425. LinkValue *make_new(Inter *inter, LinkValue *belong, LinkValue *class){
  426. Inherit *object_father = getInheritFromValueCore(class);
  427. VarList *new_var = copyVarList(class->value->object.out_var, false, inter);
  428. Value *new_object = makeObject(inter, NULL, new_var, object_father);
  429. return makeLinkValue(new_object, belong, inter);
  430. }
  431. int init_new(LinkValue *obj, Argument *arg, char *message, INTER_FUNCTIONSIG_NOT_ST){
  432. LinkValue *_init_ = NULL;
  433. _init_ = findAttributes(inter->data.object_init, false, obj, inter);
  434. if (_init_ == NULL) {
  435. if (arg != NULL) {
  436. setResultError(E_ArgumentException, MANY_ARG, 0, message, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  437. return 0;
  438. } else
  439. return 1;
  440. }
  441. _init_->belong = obj;
  442. gc_addTmpLink(&_init_->gc_status);
  443. callBackCore(_init_, arg, 0, message, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, obj));
  444. gc_freeTmpLink(&_init_->gc_status);
  445. return CHECK_RESULT(result) ? 1 : -1;
  446. }
  447. bool setBoolAttrible(bool value, char *var, fline line, char *file, LinkValue *obj, INTER_FUNCTIONSIG_NOT_ST) {
  448. LinkValue *bool_value = NULL;
  449. setResultCore(result);
  450. makeBoolValue(value, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  451. if (!CHECK_RESULT(result))
  452. return false;
  453. bool_value = result->value;
  454. freeResult(result);
  455. if (!addAttributes(var, false, bool_value, line, file, obj, result, inter, var_list))
  456. return false;
  457. freeResult(result);
  458. return true;
  459. }