vobject.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #include "__ofunc.h"
  2. typedef void (*base_opt)(LinkValue *, Result *, struct Inter *, VarList *var_list, Value *, Value *);
  3. void vobject_add_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
  4. setResultOperationBase(result, makeLinkValue(NULL, belong, inter));
  5. if (left->type == number && right->type == number)
  6. result->value->value = makeNumberValue(left->data.num.num + right->data.num.num, inter);
  7. else if(left->type == string && right->type == string){
  8. char *new_string = memStrcat(left->data.str.str, right->data.str.str, false, false);
  9. result->value->value = makeStringValue(new_string, inter);
  10. memFree(new_string);
  11. }
  12. else
  13. setResultError(E_TypeException, CUL_ERROR(Add), 0, "vobject", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  14. }
  15. void vobject_sub_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
  16. setResultOperationBase(result, makeLinkValue(NULL, belong, inter));
  17. if (left->type == number && right->type == number)
  18. result->value->value = makeNumberValue(left->data.num.num - right->data.num.num, inter);
  19. else
  20. setResultError(E_TypeException, CUL_ERROR(Sub), 0, "vobject", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  21. }
  22. void vobject_mul_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
  23. setResultOperationBase(result, makeLinkValue(NULL, belong, inter));
  24. if (left->type == number && right->type == number)
  25. result->value->value = makeNumberValue(left->data.num.num * right->data.num.num, inter);
  26. else if(left->type == number && right->type == string) {
  27. Value *tmp = left;
  28. left = right;
  29. right = tmp;
  30. goto mul_str;
  31. }
  32. else if(left->type == string && right->type == number) mul_str: {
  33. char *new_string = memStrcpySelf(left->data.str.str, right->data.num.num);
  34. result->value->value = makeStringValue(new_string, inter);
  35. memFree(new_string);
  36. }
  37. else
  38. setResultError(E_TypeException, CUL_ERROR(Mul), 0, "vobject", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  39. }
  40. void vobject_div_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
  41. setResultOperationBase(result, makeLinkValue(NULL, belong, inter));
  42. if (left->type == number && right->type == number) {
  43. lldiv_t div_result = lldiv(left->data.num.num, right->data.num.num);
  44. result->value->value = makeNumberValue(div_result.quot, inter);
  45. }
  46. else
  47. setResultError(E_TypeException, CUL_ERROR(Div), 0, "vobject", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  48. }
  49. ResultType vobject_opt_core(OFFICAL_FUNCTIONSIG, base_opt func){
  50. Value *left = NULL;
  51. Value *right = NULL;
  52. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  53. {.type=name_value, .name="right", .must=1, .long_arg=false},
  54. {.must=-1}};
  55. setResultCore(result);
  56. {
  57. parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  58. if (!CHECK_RESULT(result))
  59. return result->type;
  60. freeResult(result);
  61. }
  62. left = ap[0].value->value;
  63. right = ap[1].value->value;
  64. func(belong, result, inter, var_list, left, right);
  65. return result->type;
  66. }
  67. ResultType vobject_add(OFFICAL_FUNCTIONSIG){
  68. return vobject_opt_core(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), vobject_add_base);
  69. }
  70. ResultType vobject_sub(OFFICAL_FUNCTIONSIG){
  71. return vobject_opt_core(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), vobject_sub_base);
  72. }
  73. ResultType vobject_mul(OFFICAL_FUNCTIONSIG){
  74. return vobject_opt_core(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), vobject_mul_base);
  75. }
  76. ResultType vobject_div(OFFICAL_FUNCTIONSIG){
  77. return vobject_opt_core(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), vobject_div_base);
  78. }
  79. ResultType vobject_bool(OFFICAL_FUNCTIONSIG){
  80. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  81. {.must=-1}};
  82. bool result_ = false;
  83. Value *value = NULL;
  84. Value *return_value = NULL;
  85. setResultCore(result);
  86. {
  87. parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  88. if (!CHECK_RESULT(result))
  89. return result->type;
  90. freeResult(result);
  91. }
  92. value = ap[0].value->value;
  93. switch (value->type) {
  94. case number:
  95. result_ = value->data.num.num != 0;
  96. break;
  97. case string:
  98. result_ = memStrlen(value->data.str.str) > 0;
  99. break;
  100. case bool_:
  101. result_ = value->data.bool_.bool_;
  102. break;
  103. case pass_:
  104. case none:
  105. result_ = false;
  106. break;
  107. case list:
  108. result_ = value->data.list.size > 0;
  109. break;
  110. case dict:
  111. result_ = value->data.dict.size > 0;
  112. break;
  113. default:
  114. setResultError(E_TypeException, CUL_ERROR(bool), 0, "vobject", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  115. return error_return;
  116. }
  117. return_value = makeBoolValue(result_, inter);
  118. setResultOperationBase(result, makeLinkValue(return_value, belong, inter));
  119. return result->type;
  120. }
  121. ResultType vobject_repo(OFFICAL_FUNCTIONSIG){
  122. ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
  123. {.must=-1}};
  124. char *repo = NULL;
  125. Value *value = NULL;
  126. setResultCore(result);
  127. parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  128. if (!CHECK_RESULT(result))
  129. return result->type;
  130. freeResult(result);
  131. value = ap[0].value->value;
  132. switch (value->type){
  133. case number: {
  134. char str[30] = {};
  135. snprintf(str, 30, "%lld", value->data.num.num);
  136. repo = memStrcpy(str);
  137. break;
  138. }
  139. case string:
  140. repo = memStrcpy(value->data.str.str);
  141. break;
  142. case function: {
  143. char str[30] = {};
  144. snprintf(str, 30, "(function on %p)", value);
  145. repo = memStrcpy(str);
  146. break;
  147. }
  148. case none:
  149. repo = memStrcpy("(null)");
  150. break;
  151. case class: {
  152. char str[30] = {};
  153. snprintf(str, 30, "(class on %p)", value);
  154. repo = memStrcpy(str);
  155. break;
  156. }
  157. case bool_:
  158. if (value->data.bool_.bool_)
  159. repo = memStrcpy("true");
  160. else
  161. repo = memStrcpy("false");
  162. break;
  163. case pass_:
  164. repo = memStrcpy("...");
  165. break;
  166. default:
  167. setResultError(E_TypeException, CUL_ERROR(repo/str), 0, "vobject", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
  168. return error_return;
  169. }
  170. setResultOperationBase(result, makeLinkValue(makeStringValue(repo, inter), belong, inter));
  171. memFree(repo);
  172. return result->type;
  173. }
  174. void registeredVObject(REGISTERED_FUNCTIONSIG){
  175. LinkValue *object = makeLinkValue(inter->data.vobject, inter->base_father, inter);
  176. NameFunc tmp[] = {{inter->data.object_add, vobject_add, object_free_},
  177. {inter->data.object_sub, vobject_sub, object_free_},
  178. {inter->data.object_mul, vobject_mul, object_free_},
  179. {inter->data.object_div, vobject_div, object_free_},
  180. {inter->data.object_bool, vobject_bool, object_free_},
  181. {inter->data.object_repo, vobject_repo, object_free_},
  182. {inter->data.object_str, vobject_repo, object_free_},
  183. {NULL, NULL}};
  184. gc_addTmpLink(&object->gc_status);
  185. addStrVar("vobject", false, true, object, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
  186. iterClassFunc(tmp, object, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
  187. gc_freeTmpLink(&object->gc_status);
  188. }
  189. void makeBaseVObject(Inter *inter){
  190. Value *vobject = makeClassValue(copyVarList(inter->var_list, false, inter), inter, NULL);
  191. gc_addStatementLink(&vobject->gc_status);
  192. inter->data.vobject = vobject;
  193. }