dict.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #include "__ofunc.h"
  2. ResultType dict_new(OFFICAL_FUNCTIONSIG){
  3. LinkValue *value = NULL;
  4. VarList *hash = NULL;
  5. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  6. {.must=-1}};
  7. int status = 1;
  8. arg = parserValueArgument(ap, arg, &status, NULL);
  9. if (status != 1){
  10. setResultError(E_ArgumentException, FEW_ARG, 0, "bool.new", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  11. return R_error;
  12. }
  13. if (arg != NULL && arg->type == value_arg) {
  14. setResultError(E_ArgumentException, L"Too many argument", 0, "V_dict.new", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  15. return R_error;
  16. }
  17. value = make_new(inter, belong, ap[0].value);
  18. hash = pushVarList(var_list, inter);
  19. value->value->type = V_dict;
  20. value->value->data.dict.size = 0;
  21. value->value->data.dict.dict = hash->hashtable;
  22. gc_addTmpLink(&value->gc_status);
  23. argumentToVar(&arg, &value->value->data.dict.size, CALL_INTER_FUNCTIONSIG_NOT_ST(hash, result, belong));
  24. gc_freeTmpLink(&value->gc_status);
  25. popVarList(hash);
  26. freeResult(result);
  27. switch (init_new(value, NULL, "V_dict.new", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong))) {
  28. case 1:
  29. freeResult(result);
  30. setResultOperation(result, value);
  31. break;
  32. default:
  33. break;
  34. }
  35. freeResult(result);
  36. setResultOperation(result, value);
  37. return result->type;
  38. }
  39. ResultType dict_down(OFFICAL_FUNCTIONSIG){
  40. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  41. {.type=only_value, .must=1, .long_arg=false},
  42. {.must=-1}};
  43. setResultCore(result);
  44. parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  45. if (!CHECK_RESULT(result))
  46. return result->type;
  47. freeResult(result);
  48. if (ap[0].value->value->type != V_dict){
  49. setResultError(E_TypeException, INSTANCE_ERROR(V_dict), 0, "V_dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  50. return R_error;
  51. }
  52. {
  53. LinkValue *element = NULL;
  54. wchar_t *name = getNameFromValue(ap[1].value->value, inter);
  55. element = findVar(name, get_var, inter, ap[0].value->value->data.dict.dict);
  56. if (element != NULL)
  57. setResultOperationBase(result, copyLinkValue(element, inter));
  58. else {
  59. wchar_t *message = memWidecat(L"Dict could not find key value: ", name, false, false);
  60. setResultError(E_KeyException, message, 0, "V_dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  61. memFree(message);
  62. }
  63. memFree(name);
  64. }
  65. return result->type;
  66. }
  67. ResultType dict_down_del(OFFICAL_FUNCTIONSIG){
  68. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  69. {.type=only_value, .must=1, .long_arg=false},
  70. {.must=-1}};
  71. setResultCore(result);
  72. parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  73. if (!CHECK_RESULT(result))
  74. return result->type;
  75. freeResult(result);
  76. if (ap[0].value->value->type != V_dict){
  77. setResultError(E_TypeException, INSTANCE_ERROR(V_dict), 0, "V_dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  78. return R_error;
  79. }
  80. {
  81. LinkValue *element = NULL;
  82. wchar_t *name = getNameFromValue(ap[1].value->value, inter);
  83. element = findVar(name, del_var, inter, ap[0].value->value->data.dict.dict);
  84. if (element != NULL)
  85. setResult(result, inter);
  86. else{
  87. wchar_t *message = memWidecat(L"Cannot delete non-existent keys: ", name, false, false);
  88. setResultError(E_KeyException, message, 0, "V_dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  89. memFree(message);
  90. }
  91. memFree(name);
  92. }
  93. return result->type;
  94. }
  95. ResultType dict_down_assignment(OFFICAL_FUNCTIONSIG){
  96. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  97. {.type=only_value, .must=1, .long_arg=false},
  98. {.type=only_value, .must=1, .long_arg=false},
  99. {.must=-1}};
  100. wchar_t *name = NULL;
  101. setResultCore(result);
  102. parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  103. if (!CHECK_RESULT(result))
  104. return result->type;
  105. freeResult(result);
  106. if (ap[0].value->value->type != V_dict){
  107. setResultError(E_TypeException, INSTANCE_ERROR(V_dict), 0, "V_dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  108. return R_error;
  109. }
  110. name = getNameFromValue(ap[2].value->value, inter);
  111. addVar(name, ap[1].value, ap[2].value, inter, ap[0].value->value->data.dict.dict);
  112. memFree(name);
  113. return result->type;
  114. }
  115. ResultType dict_keys(OFFICAL_FUNCTIONSIG){
  116. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  117. {.must=-1}};
  118. Argument *list = NULL;
  119. setResultCore(result);
  120. parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  121. if (!CHECK_RESULT(result))
  122. return result->type;
  123. freeResult(result);
  124. if (ap[0].value->value->type != V_dict){
  125. setResultError(E_TypeException, INSTANCE_ERROR(V_dict), 0, "V_dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  126. return R_error;
  127. }
  128. for (int index=0; index < MAX_SIZE; index++){
  129. Var *tmp = ap[0].value->value->data.dict.dict->hashtable[index];
  130. for (PASS; tmp != NULL; tmp = tmp->next)
  131. list = connectValueArgument(copyLinkValue(tmp->name_, inter), list);
  132. }
  133. makeListValue(list, 0, "V_dict", L_list, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  134. freeArgument(list, true);
  135. return result->type;
  136. }
  137. ResultType dict_iter(OFFICAL_FUNCTIONSIG){
  138. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  139. {.must=-1}};
  140. setResultCore(result);
  141. parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  142. if (!CHECK_RESULT(result))
  143. return result->type;
  144. freeResult(result);
  145. if (ap[0].value->value->type != V_dict){
  146. setResultError(E_TypeException, INSTANCE_ERROR(V_dict), 0, "V_dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  147. return R_error;
  148. }
  149. {
  150. Argument *dict_iter_arg = makeValueArgument(ap[0].value);
  151. callBackCore(inter->data.dict_iter, dict_iter_arg, 0, "V_dict", 0,
  152. CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  153. freeArgument(dict_iter_arg, true);
  154. }
  155. return result->type;
  156. }
  157. ResultType dictRepoStrCore(OFFICAL_FUNCTIONSIG, bool is_repo){
  158. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  159. {.must=-1}};
  160. wchar_t *repo = NULL;
  161. Value *value = NULL;
  162. LinkValue *again = NULL;
  163. setResultCore(result);
  164. parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  165. if (!CHECK_RESULT(result))
  166. return result->type;
  167. freeResult(result);
  168. value = ap[0].value->value;
  169. if (value->type != V_dict){
  170. setResultError(E_TypeException, INSTANCE_ERROR(V_dict), 0, "V_dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  171. return R_error;
  172. }
  173. again = findAttributes(is_repo ? L"repo_again" : L"str_again", false, ap[0].value, inter);
  174. if (again != NULL){
  175. bool again_ = checkBool(again, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  176. if (!CHECK_RESULT(result))
  177. return result->type;
  178. if (again_) {
  179. makeStringValue(L"{...}", 0, "V_dict.repo", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  180. return result->type;
  181. }
  182. }
  183. setBoolAttrible(true, is_repo ? L"repo_again" : L"str_again", 0, "V_dict.repo", ap[0].value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  184. repo = memWidecpy(L"{");
  185. for (int i = 0, count = 0; i < MAX_SIZE; i++) {
  186. for (Var *var = value->data.dict.dict->hashtable[i]; var != NULL; var = var->next, count++) {
  187. wchar_t *name_tmp;
  188. wchar_t *value_tmp;
  189. if (count > 0)
  190. repo = memWidecat(repo, L", ", true, false);
  191. freeResult(result);
  192. name_tmp = getRepoStr(var->name_, is_repo, 0, "V_dict", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  193. if (!CHECK_RESULT(result))
  194. goto return_;
  195. repo = memWidecat(repo, name_tmp, true, false);
  196. repo = memWidecat(repo, L": ", true, false);
  197. freeResult(result);
  198. value_tmp = getRepoStr(var->value, is_repo, 0, "V_dict", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  199. if (!CHECK_RESULT(result))
  200. goto return_;
  201. repo = memWidecat(repo, value_tmp, true, false);
  202. }
  203. }
  204. freeResult(result);
  205. repo = memWidecat(repo, L"}", true, false);
  206. makeStringValue(repo, 0, "V_dict.repo", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  207. return_:
  208. {
  209. Result tmp;
  210. setResultCore(&tmp);
  211. setBoolAttrible(false, is_repo ? L"repo_again" : L"str_again", 0, "V_dict.repo", ap[0].value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, &tmp, belong));
  212. if (!RUN_TYPE(tmp.type)) {
  213. freeResult(result);
  214. *result = tmp;
  215. } else
  216. freeResult(&tmp);
  217. }
  218. memFree(repo);
  219. return result->type;
  220. }
  221. ResultType dict_repo(OFFICAL_FUNCTIONSIG){
  222. return dictRepoStrCore(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), true);
  223. }
  224. ResultType dict_str(OFFICAL_FUNCTIONSIG){
  225. return dictRepoStrCore(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), false);
  226. }
  227. void registeredDict(REGISTERED_FUNCTIONSIG){
  228. LinkValue *object = inter->data.dict;
  229. NameFunc tmp[] = {{L"keys", dict_keys, object_free_},
  230. {inter->data.object_new, dict_new, class_free_},
  231. {inter->data.object_down, dict_down, object_free_},
  232. {inter->data.object_iter, dict_iter, object_free_},
  233. {inter->data.object_repo, dict_repo, object_free_},
  234. {inter->data.object_str, dict_str, object_free_},
  235. {inter->data.object_down_assignment, dict_down_assignment, object_free_},
  236. {inter->data.object_down_del, dict_down_del, object_free_},
  237. {NULL, NULL}};
  238. gc_addTmpLink(&object->gc_status);
  239. addBaseClassVar(L"V_dict", object, belong, inter);
  240. iterBaseClassFunc(tmp, object, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
  241. gc_freeTmpLink(&object->gc_status);
  242. }
  243. void makeBaseDict(Inter *inter){
  244. LinkValue *dict = makeBaseChildClass(inter->data.vobject, inter);
  245. gc_addStatementLink(&dict->gc_status);
  246. inter->data.dict = dict;
  247. }