__run.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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, "Don't get a number value", 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. value = makeLinkValue(makeStringValue(st->u.base_var.name, inter), belong, inter);
  20. setResultOperation(result, value);
  21. return result->type;
  22. }
  23. ResultType getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
  24. freeResult(result);
  25. if (st->u.base_svar.times == NULL){
  26. *times = 0;
  27. goto not_times;
  28. }
  29. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_svar.times, var_list, result, belong)))
  30. return result->type;
  31. if (!isType(result->value->value, number)){
  32. setResultErrorSt(E_TypeException, "Don't get a number value", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  33. return result->type;
  34. }
  35. *times = (int)result->value->value->data.num.num;
  36. freeResult(result);
  37. not_times:
  38. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_svar.name, var_list, result, belong)))
  39. return result->type;
  40. *name = getNameFromValue(result->value->value, inter);
  41. result->type = operation_return; // 执行 operationSafeInterStatement 的时候已经初始化 result
  42. return result->type;
  43. }
  44. ResultType getVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
  45. if (st->type == base_var)
  46. getBaseVarInfo(name, times, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
  47. else if (st->type == base_svar)
  48. getBaseSVarInfo(name, times, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
  49. else{
  50. if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)))
  51. return result->type;
  52. *name = getNameFromValue(result->value->value, inter);
  53. *times = 0;
  54. }
  55. return result->type;
  56. }
  57. char *setStrVarName(char *old, bool free_old, Inter *inter) {
  58. return memStrcat(inter->data.var_str_prefix, old, false, free_old);
  59. }
  60. char *setNumVarName(vnum num, struct Inter *inter) {
  61. char name[50];
  62. snprintf(name, 50, "%lld", num);
  63. return memStrcat(inter->data.var_num_prefix, name, false, false);
  64. }
  65. char *getNameFromValue(Value *value, struct Inter *inter) {
  66. switch (value->type){
  67. case string:
  68. return setStrVarName(value->data.str.str, false, inter);
  69. case number:
  70. return setNumVarName(value->data.num.num, inter);
  71. case bool_:
  72. if (value->data.bool_.bool_)
  73. return memStrcat(inter->data.var_bool_prefix, "true", false, false);
  74. else
  75. return memStrcat(inter->data.var_bool_prefix, "false", false, false);
  76. case none:
  77. return memStrcpy(inter->data.var_none);
  78. case pass_:
  79. return memStrcpy(inter->data.var_pass);
  80. case class:{
  81. size_t len = memStrlen(inter->data.var_class_prefix) + 20;
  82. char *name = memString(len);
  83. char *return_ = NULL;
  84. snprintf(name, len, "%s%p", inter->data.var_class_prefix, value);
  85. return_ = memStrcpy(name);
  86. memFree(name);
  87. return return_;
  88. }
  89. default:{
  90. size_t len = memStrlen(inter->data.var_object_prefix) + 20;
  91. char *name = memString(len);
  92. char *return_ = NULL;
  93. snprintf(name, len, "%s%p", inter->data.var_object_prefix, value);
  94. return_ = memStrcpy(name);
  95. memFree(name);
  96. return return_;
  97. }
  98. }
  99. }
  100. bool popStatementVarList(Statement *funtion_st, VarList **function_var, VarList *out_var, Inter *inter){
  101. bool yield_run;
  102. if ((yield_run = funtion_st->info.have_info)) {
  103. *function_var = funtion_st->info.var_list;
  104. (*function_var)->next = out_var;
  105. }
  106. else
  107. *function_var = pushVarList(out_var, inter);
  108. return yield_run;
  109. }
  110. void newFunctionYield(Statement *funtion_st, Statement *node, VarList *new_var, Inter *inter){
  111. new_var->next = NULL;
  112. gc_freeze(inter, new_var, NULL, true);
  113. funtion_st->info.var_list = new_var;
  114. funtion_st->info.node = node->type == yield_code ? node->next : node;
  115. funtion_st->info.have_info = true;
  116. }
  117. void updateFunctionYield(Statement *function_st, Statement *node){
  118. function_st->info.node = node->type == yield_code ? node->next : node;
  119. function_st->info.have_info = true;
  120. }
  121. ResultType setFunctionArgument(Argument **arg, LinkValue *function_value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
  122. Argument *tmp = NULL;
  123. enum FunctionPtType pt_type = function_value->value->data.function.function_data.pt_type;
  124. setResultCore(result);
  125. if (function_value->belong == NULL){
  126. setResultError(E_ArgumentException, "Don't get self", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  127. return error_return;
  128. }
  129. switch (pt_type) {
  130. case static_:
  131. tmp = makeValueArgument(function_value);
  132. tmp->next = *arg;
  133. *arg = tmp;
  134. break;
  135. case class_static_:
  136. tmp = makeValueArgument(function_value);
  137. if (function_value->belong->value->type == class)
  138. tmp->next = makeValueArgument(function_value->belong);
  139. else if (function_value->value->object.inherit->value != NULL)
  140. tmp->next = makeValueArgument(function_value->belong->value->object.inherit->value);
  141. else {
  142. tmp->next = *arg;
  143. *arg = tmp;
  144. break;
  145. }
  146. tmp->next->next = *arg;
  147. *arg = tmp;
  148. break;
  149. case all_static_:
  150. tmp = makeValueArgument(function_value);
  151. tmp->next = makeValueArgument(function_value->belong);
  152. tmp->next->next = *arg;
  153. *arg = tmp;
  154. break;
  155. case object_static_:
  156. tmp = makeValueArgument(function_value);
  157. if (function_value->belong->value->type == class)
  158. tmp->next = *arg;
  159. else {
  160. tmp->next = makeValueArgument(function_value->belong);
  161. tmp->next->next = *arg;
  162. }
  163. *arg = tmp;
  164. break;
  165. case class_free_:
  166. if (function_value->belong->value->type == class)
  167. tmp = makeValueArgument(function_value->belong);
  168. else if (function_value->value->object.inherit->value != NULL)
  169. tmp = makeValueArgument(function_value->belong->value->object.inherit->value);
  170. else
  171. break;
  172. tmp->next = *arg;
  173. *arg = tmp;
  174. break;
  175. case object_free_:
  176. if (function_value->belong->value->type != class) {
  177. tmp = makeValueArgument(function_value->belong);
  178. tmp->next = *arg;
  179. *arg = tmp;
  180. }
  181. break;
  182. case all_free_:
  183. tmp = makeValueArgument(function_value->belong);
  184. tmp->next = *arg;
  185. *arg = tmp;
  186. break;
  187. default:
  188. break;
  189. }
  190. setResultBase(result, inter, belong);
  191. return result->type;
  192. }
  193. void freeFunctionArgument(Argument *arg, Argument *base) {
  194. for (Argument *tmp = arg; tmp != NULL; tmp = tmp->next) {
  195. if (tmp->next == base) {
  196. tmp->next = NULL;
  197. freeArgument(arg, true);
  198. break;
  199. }
  200. }
  201. }
  202. LinkValue *findStrVar(char *name, bool free_old, INTER_FUNCTIONSIG_CORE){
  203. LinkValue *tmp = NULL;
  204. char *name_ = setStrVarName(name, free_old, inter);
  205. tmp = findFromVarList(name_, 0, get_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
  206. memFree(name_);
  207. return tmp;
  208. }
  209. LinkValue *checkStrVar(char *name, bool free_old, INTER_FUNCTIONSIG_CORE){
  210. LinkValue *tmp = NULL;
  211. char *name_ = setStrVarName(name, free_old, inter);
  212. tmp = findFromVarList(name_, 0, read_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
  213. memFree(name_);
  214. return tmp;
  215. }
  216. void addStrVar(char *name, bool free_old, bool setting, LinkValue *value, LinkValue *belong, INTER_FUNCTIONSIG_CORE){
  217. char *var_name = setStrVarName(name, free_old, inter);
  218. LinkValue *name_ = makeLinkValue(makeStringValue(name, inter), belong, inter);
  219. addFromVarList(var_name, name_, 0, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
  220. if (setting)
  221. newObjectSetting(name_, value, inter);
  222. memFree(var_name);
  223. }
  224. LinkValue *findAttributes(char *name, bool free_old, LinkValue *value, Inter *inter) {
  225. LinkValue *attr = findStrVar(name, free_old, CALL_INTER_FUNCTIONSIG_CORE(value->value->object.var));
  226. if (attr != NULL && (attr->belong == NULL || attr->belong->value != value->value && checkAttribution(value->value, attr->belong->value)))
  227. attr->belong = value;
  228. return attr;
  229. }
  230. void addAttributes(char *name, bool free_old, LinkValue *value, LinkValue *belong, Inter *inter) {
  231. addStrVar(name, free_old, false, value, belong, inter, belong->value->object.var);
  232. }
  233. void newObjectSetting(LinkValue *name, LinkValue *belong, Inter *inter) {
  234. addAttributes(inter->data.object_name, false, name, belong, inter);
  235. addAttributes(inter->data.object_self, false, belong, belong, inter);
  236. if (belong->value->object.inherit != NULL)
  237. addAttributes(inter->data.object_father, false, belong->value->object.inherit->value, belong, inter);
  238. }
  239. ResultType elementDownOne(LinkValue *element, LinkValue *index, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
  240. LinkValue *_func_ = NULL;
  241. setResultCore(result);
  242. gc_addTmpLink(&element->gc_status);
  243. gc_addTmpLink(&index->gc_status);
  244. _func_ = findAttributes(inter->data.object_down, false, element, inter);
  245. if (_func_ != NULL){
  246. Argument *arg = NULL;
  247. gc_addTmpLink(&_func_->gc_status);
  248. arg = makeValueArgument(index);
  249. callBackCore(_func_,arg, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  250. gc_freeTmpLink(&_func_->gc_status);
  251. freeArgument(arg, true);
  252. }
  253. else
  254. setResultError(E_TypeException, "Don't find __down__", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  255. gc_freeTmpLink(&element->gc_status);
  256. gc_freeTmpLink(&index->gc_status);
  257. return result->type;
  258. }
  259. ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
  260. LinkValue *_func_ = NULL;
  261. setResultCore(result);
  262. if (status == 1)
  263. _func_ = findAttributes(inter->data.object_iter, false, value, inter);
  264. else
  265. _func_ = findAttributes(inter->data.object_next, false, value, inter);
  266. if (_func_ != NULL){
  267. gc_addTmpLink(&_func_->gc_status);
  268. callBackCore(_func_, NULL, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  269. gc_freeTmpLink(&_func_->gc_status);
  270. }
  271. else
  272. setResultError(E_TypeException, "Object Not Iterable", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  273. return result->type;
  274. }
  275. bool checkBool(LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
  276. LinkValue *_bool_ = findAttributes(inter->data.object_bool, false, value, inter);
  277. setResultCore(result);
  278. if (_bool_ != NULL){
  279. gc_addTmpLink(&_bool_->gc_status);
  280. callBackCore(_bool_, NULL, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  281. gc_freeTmpLink(&_bool_->gc_status);
  282. if (result->value->value->type != bool_)
  283. setResultError(E_TypeException, "__bool__ function should return bool type data", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  284. else
  285. return result->value->value->data.bool_.bool_;
  286. } else {
  287. setResultOperationBase(result, makeLinkValue(makeBoolValue(true, inter), belong, inter));
  288. return true;
  289. }
  290. return false;
  291. }
  292. char *getRepoStr(LinkValue *value, bool is_repot, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
  293. LinkValue *_repo_ = findAttributes(is_repot ? inter->data.object_repo : inter->data.object_str, false, value, inter);
  294. setResultCore(result);
  295. if (_repo_ != NULL){
  296. gc_addTmpLink(&value->gc_status);
  297. gc_addTmpLink(&_repo_->gc_status);
  298. callBackCore(_repo_, NULL, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  299. gc_freeTmpLink(&_repo_->gc_status);
  300. gc_freeTmpLink(&value->gc_status);
  301. if (!CHECK_RESULT(result))
  302. return NULL;
  303. else if (result->value->value->type != string){
  304. setResultError(E_TypeException, "__repo__/__str__ function should return str type data", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  305. return NULL;
  306. }
  307. return result->value->value->data.str.str;
  308. }
  309. else
  310. setResultError(E_TypeException, "__repo__/__str__ gets unsupported data", line, file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  311. return NULL;
  312. }
  313. bool is_iterStop(LinkValue *value, Inter *inter){
  314. return value->value == inter->data.iterstop_exc || checkAttribution(value->value, inter->data.iterstop_exc);
  315. }