Kaynağa Gözat

feat: findAttributes函数支持运行变量式函数

允许传入result运行指定函数
注意: 还未对此做gc适配, 即调用该函数的地方没有释放result

link #6
SongZihuan 4 yıl önce
ebeveyn
işleme
725e4ab9b4

+ 5 - 1
VirtulMathCore/ofunc/src/dict.c

@@ -178,7 +178,11 @@ ResultType dictRepoStrCore(OFFICAL_FUNCTIONSIG, bool is_repo){
         setResultError(E_TypeException, INSTANCE_ERROR(dict), 0, "dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return R_error;
     }
-    again = findAttributes(is_repo ? L"repo_again" : L"str_again", false, ap[0].value, inter);
+    again = findAttributes(is_repo ? L"repo_again" : L"str_again", false, 0, "dict", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, ap[0].value));
+    if (!CHECK_RESULT(result))
+        return result->type;
+    freeResult(result);
+
     if (again != NULL){
         bool again_ = checkBool(again, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         if (!CHECK_RESULT(result))

+ 4 - 4
VirtulMathCore/ofunc/src/dictiter.c

@@ -16,7 +16,7 @@ ResultType dictiter_init(OFFICAL_FUNCTIONSIG){
         return R_error;
     }
     {
-        LinkValue *keys = findAttributes(L"keys", false, ap[1].value, inter);
+        LinkValue *keys = findAttributes(L"keys", false, 0, "dictiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, ap[1].value));
         Argument *list_arg = NULL;
         LinkValue *listiter_class = NULL;
 
@@ -75,13 +75,13 @@ ResultType dictiter_next(OFFICAL_FUNCTIONSIG){
     parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     if (!CHECK_RESULT(result))
         return result->type;
-    list_ = findAttributes(L"__list", false, ap[0].value, inter);
+    list_ = findAttributes(L"__list", false, 0, "dictiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, ap[0].value));
     if (list_ == NULL){
         setResultError(E_TypeException, VALUE_ERROR(__list, listiter), 0, "dictiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return R_error;
     }
 
-    list_next = findAttributes(inter->data.object_next, false, list_, inter);
+    list_next = findAttributes(inter->data.object_next, false, 0, "dictiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, list_));
     if (list_next == NULL){
         setResultError(E_TypeException, L"Object is not iterable", 0, "dictiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return R_error;
@@ -100,7 +100,7 @@ ResultType dictiter_down(OFFICAL_FUNCTIONSIG){
     parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     if (!CHECK_RESULT(result))
         return result->type;
-    dict_ = findAttributes(L"__dict", false, ap[0].value, inter);
+    dict_ = findAttributes(L"__dict", false, 0, "dictiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, ap[0].value));
     if (dict_ == NULL || dict_->value->type != V_dict){
         setResultError(E_TypeException, VALUE_ERROR(__dict, dict), 0, "dictiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return R_error;

+ 2 - 2
VirtulMathCore/ofunc/src/list.c

@@ -357,11 +357,11 @@ ResultType listRepoStrCore(OFFICAL_FUNCTIONSIG, bool is_repo){
     value = ap[0].value->value;
 
     if (value->type != V_list){
-        setResultError(E_TypeException, INSTANCE_ERROR(list), 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        setResultError(E_TypeException, INSTANCE_ERROR(list), 0, "list.repo", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return R_error;
     }
     lt = value->data.list.type;
-    again = findAttributes(is_repo ? L"repo_again" : L"str_again", false, ap[0].value, inter);
+    again = findAttributes(is_repo ? L"repo_again" : L"str_again", false, 0, "list.repo", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, ap[0].value));
     if (again != NULL){
         bool again_ = checkBool(again, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         if (!CHECK_RESULT(result))

+ 2 - 2
VirtulMathCore/ofunc/src/listiter.c

@@ -38,8 +38,8 @@ ResultType listiter_next(OFFICAL_FUNCTIONSIG){
     parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     if (!CHECK_RESULT(result))
         return result->type;
-    list_ = findAttributes(L"__list", false, ap[0].value, inter);
-    index = findAttributes(L"__index", false, ap[0].value, inter);
+    list_ = findAttributes(L"__list", false, 0, "listiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, ap[0].value));
+    index = findAttributes(L"__index", false, 0, "listiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, ap[0].value));
 
     if (list_->value->type != V_list){
         setResultError(E_TypeException, VALUE_ERROR(listiter.__list, list), 0, "listiter", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));

+ 1 - 1
VirtulMathCore/ofunc/src/object.c

@@ -30,7 +30,7 @@ ResultType objectRepoStrCore(OFFICAL_FUNCTIONSIG, bool is_repo){
         return result->type;
     freeResult(result);
 
-    name_value = findAttributes(inter->data.object_name, false, ap[0].value, inter);
+    name_value = findAttributes(inter->data.object_name, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, ap[0].value));
     if (name_value != NULL){
         gc_addTmpLink(&name_value->gc_status);
         name = getRepoStr(name_value, is_repo, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));

+ 1 - 1
VirtulMathCore/ofunc/src/str.c

@@ -160,7 +160,7 @@ ResultType str_iter(OFFICAL_FUNCTIONSIG){
     if (!CHECK_RESULT(result))
         return result->type;
     freeResult(result);
-    to_list = findAttributes(L"to_list", false, ap[0].value, inter);
+    to_list = findAttributes(L"to_list", false, 0, "str", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, ap[0].value));
     if (to_list == NULL){
         setResultError(E_TypeException, L"String cannot be converted to list", 0, "str", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         return R_error;

+ 14 - 11
VirtulMathCore/src/__run.c

@@ -270,7 +270,7 @@ LinkValue *findStrVar(wchar_t *name, bool free_old, fline line, char *file, bool
     wchar_t *name_ = setStrVarName(name, free_old, inter);
     tmp = findFromVarList(name_, 0, get_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     memFree(name_);
-    if (nowrun) {
+    if (tmp != NULL && nowrun) {
         setResultCore(result);
         if (!runVarFunc(tmp, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
             setResultOperationBase(result, tmp);
@@ -324,10 +324,13 @@ void addStrVar(wchar_t *name, bool free_old, bool setting, LinkValue *value, fli
     memFree(var_name);
 }
 
-LinkValue *findAttributes(wchar_t *name, bool free_old, LinkValue *value, Inter *inter) {  // TODO-szh 此处使用findStrVar替代findStrVarOnly
-    LinkValue *attr = findStrVarOnly(name, free_old, CALL_INTER_FUNCTIONSIG_CORE(value->value->object.var));
-    if (attr != NULL && (attr->belong == NULL || attr->belong->value != value->value && checkAttribution(value->value, attr->belong->value)))
-        attr->belong = value;
+LinkValue *findAttributes(wchar_t *name, bool free_old, fline line, char *file, bool nowrun, INTER_FUNCTIONSIG_NOT_ST) {  // TODO-szh 处理调用该函数的地方释放result
+    LinkValue *attr;
+    gc_freeze(inter, var_list, belong->value->object.var, true);
+    attr = findStrVar(name, free_old, line, file, nowrun, CALL_INTER_FUNCTIONSIG_NOT_ST(belong->value->object.var, result, belong));
+    if (attr != NULL && (attr->belong == NULL || attr->belong->value != belong->value && checkAttribution(belong->value, attr->belong->value)))
+        attr->belong = belong;
+    gc_freeze(inter, var_list, belong->value->object.var, false);
     return attr;
 }
 
@@ -381,7 +384,7 @@ ResultType getElement(LinkValue *from, LinkValue *index, fline line, char *file,
     gc_addTmpLink(&from->gc_status);
     gc_addTmpLink(&index->gc_status);
 
-    _func_ = findAttributes(inter->data.object_down, false, from, inter);
+    _func_ = findAttributes(inter->data.object_down, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, from));
     if (_func_ != NULL){
         Argument *arg = NULL;
         gc_addTmpLink(&_func_->gc_status);
@@ -402,9 +405,9 @@ ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_F
     LinkValue *_func_ = NULL;
     setResultCore(result);
     if (status == 1)
-        _func_ = findAttributes(inter->data.object_iter, false, value, inter);
+        _func_ = findAttributes(inter->data.object_iter, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, value));
     else
-        _func_ = findAttributes(inter->data.object_next, false, value, inter);
+        _func_ = findAttributes(inter->data.object_next, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, value));
 
     if (_func_ != NULL){
         gc_addTmpLink(&_func_->gc_status);
@@ -418,7 +421,7 @@ ResultType getIter(LinkValue *value, int status, fline line, char *file, INTER_F
 }
 
 bool checkBool(LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
-    LinkValue *_bool_ = findAttributes(inter->data.object_bool, false, value, inter);
+    LinkValue *_bool_ = findAttributes(inter->data.object_bool, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, value));
     if (_bool_ != NULL){
         gc_addTmpLink(&_bool_->gc_status);
         callBackCore(_bool_, NULL, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
@@ -435,7 +438,7 @@ bool checkBool(LinkValue *value, fline line, char *file, INTER_FUNCTIONSIG_NOT_S
 }
 
 wchar_t *getRepoStr(LinkValue *value, bool is_repo, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST){
-    LinkValue *_repo_ = findAttributes(is_repo ? inter->data.object_repo : inter->data.object_str, false, value, inter);
+    LinkValue *_repo_ = findAttributes(is_repo ? inter->data.object_repo : inter->data.object_str, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, value));
     setResultCore(result);
     if (_repo_ != NULL){
         gc_addTmpLink(&value->gc_status);
@@ -497,7 +500,7 @@ LinkValue *make_new(Inter *inter, LinkValue *belong, LinkValue *class){
 
 static int init_new(LinkValue *obj, Argument *arg, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
     LinkValue *_init_ = NULL;
-    _init_ = findAttributes(inter->data.object_init, false, obj, inter);
+    _init_ = findAttributes(inter->data.object_init, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, obj));
 
     if (_init_ == NULL) {
         if (arg != NULL) {

+ 1 - 1
VirtulMathCore/src/include/__run.h

@@ -17,7 +17,7 @@ LinkValue *findStrVar(wchar_t *name, bool free_old, fline line, char *file, bool
 LinkValue *findStrVarOnly(wchar_t *name, bool free_old, INTER_FUNCTIONSIG_CORE);
 LinkValue *checkStrVar(wchar_t *name, bool free_old, INTER_FUNCTIONSIG_CORE);
 void addStrVar(wchar_t *name, bool free_old, bool setting, LinkValue *value, fline line, char *file, bool run, INTER_FUNCTIONSIG_NOT_ST);
-LinkValue *findAttributes(wchar_t *name, bool free_old, LinkValue *value, Inter *inter);
+LinkValue *findAttributes(wchar_t *name, bool free_old, fline line, char *file, bool nowrun, INTER_FUNCTIONSIG_NOT_ST);
 
 bool addAttributes(wchar_t *name, bool free_old, LinkValue *value, fline line, char *file, bool run, INTER_FUNCTIONSIG_NOT_ST);
 void newObjectSetting(LinkValue *name, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);

+ 4 - 4
VirtulMathCore/src/runbranch.c

@@ -565,8 +565,8 @@ ResultType forBranch(INTER_FUNCTIONSIG) {
 }
 
 static bool getEnterExit(LinkValue *value, LinkValue **_enter_, LinkValue **_exit_, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
-    *_enter_ = findAttributes(inter->data.object_enter, false, value, inter);
-    *_exit_ = findAttributes(inter->data.object_exit, false, value, inter);
+    *_enter_ = findAttributes(inter->data.object_enter, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, value));
+    *_exit_ = findAttributes(inter->data.object_exit, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, value));
     if (*_enter_ == NULL || *_exit_ == NULL) {
         *_enter_ = NULL;
         *_exit_ = NULL;
@@ -599,8 +599,8 @@ static int runWithList(StatementList *with_list, LinkValue **with_belong, LinkVa
         *with_belong = belong;
         gc_addTmpLink(&(*with_belong)->gc_status);
 
-        *_enter_ = findAttributes(inter->data.object_enter, false, *value, inter);
-        *_exit_ = findAttributes(inter->data.object_exit, false, *value, inter);
+        *_enter_ = findAttributes(inter->data.object_enter, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, *value));
+        *_exit_ = findAttributes(inter->data.object_exit, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, *value));
 
         if (!getEnterExit(*value, _enter_, _exit_, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong))) {
             gc_freeTmpLink(&(*value)->gc_status);

+ 3 - 3
VirtulMathCore/src/runcall.c

@@ -122,7 +122,7 @@ ResultType elementSlice(INTER_FUNCTIONSIG) {
     freeResult(result);
 
     func_name = st->u.slice_.type == SliceType_down_ ? inter->data.object_down : inter->data.object_slice;
-    _func_ = findAttributes(func_name, false, element, inter);
+    _func_ = findAttributes(func_name, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, element));
     if (_func_ != NULL){
         gc_addTmpLink(&_func_->gc_status);
         callBackCorePt(_func_, st->u.slice_.index, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
@@ -175,7 +175,7 @@ ResultType callBackCorePt(LinkValue *function_value, Parameter *pt, long line, c
 }
 
 static ResultType callClass(LinkValue *class_value, Argument *arg, fline line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST) {
-    LinkValue *_new_ = findAttributes(inter->data.object_new, false, class_value, inter);
+    LinkValue *_new_ = findAttributes(inter->data.object_new, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, class_value));
     setResultCore(result);
     if (_new_ != NULL){
         gc_addTmpLink(&_new_->gc_status);
@@ -190,7 +190,7 @@ static ResultType callClass(LinkValue *class_value, Argument *arg, fline line, c
 }
 
 static ResultType callObject(LinkValue *object_value, Argument *arg, fline line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST) {
-    LinkValue *_call_ = findAttributes(inter->data.object_call, false, object_value, inter);
+    LinkValue *_call_ = findAttributes(inter->data.object_call, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, object_value));
     setResultCore(result);
 
     if (_call_ != NULL){

+ 5 - 5
VirtulMathCore/src/runoperation.c

@@ -224,9 +224,9 @@ ResultType downDel(Statement *name, INTER_FUNCTIONSIG_NOT_ST) {
     result->value = NULL;
     freeResult(result);
     if (name->u.slice_.type == SliceType_down_)
-        _func_ = findAttributes(inter->data.object_down_del, false, iter, inter);
+        _func_ = findAttributes(inter->data.object_down_del, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, iter));
     else
-        _func_ = findAttributes(inter->data.object_slice_del, false, iter, inter);
+        _func_ = findAttributes(inter->data.object_slice_del, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, iter));
     if (_func_ != NULL){
         Argument *arg = NULL;
         gc_addTmpLink(&_func_->gc_status);
@@ -377,9 +377,9 @@ ResultType downAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST)
     result->value = NULL;
     freeResult(result);
     if (name->u.slice_.type == SliceType_down_)
-        _func_ = findAttributes(inter->data.object_down_assignment, false, iter, inter);
+        _func_ = findAttributes(inter->data.object_down_assignment, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, iter));
     else
-        _func_ = findAttributes(inter->data.object_slice_assignment, false, iter, inter);
+        _func_ = findAttributes(inter->data.object_slice_assignment, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, iter));
     if (_func_ != NULL){
         Argument *arg = makeValueArgument(value);
         gc_addTmpLink(&_func_->gc_status);
@@ -581,7 +581,7 @@ ResultType operationCore(INTER_FUNCTIONSIG, wchar_t *name) {
     if (getLeftRightValue(&left, &right, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)))
         return result->type;
 
-    _func_ = findAttributes(name, false, left.value, inter);
+    _func_ = findAttributes(name, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, left.value));
     if (_func_ != NULL){
         Argument *arg = makeValueArgument(right.value);
         gc_addTmpLink(&_func_->gc_status);

+ 16 - 5
VirtulMathCore/src/value.c

@@ -337,9 +337,9 @@ LinkValue *findBaseError(BaseErrorType type, Inter *inter){
     }
 }
 
-wchar_t *getErrorInfo(LinkValue *exc, int type, Inter *inter){
+static wchar_t *getErrorInfo(LinkValue *exc, int type, INTER_FUNCTIONSIG_NOT_ST){
     wchar_t *str_name = type == 1 ? inter->data.object_name : inter->data.object_message;
-    LinkValue *_info_ = findAttributes(str_name, false, exc, inter);
+    LinkValue *_info_ = findAttributes(str_name, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, exc));
     if (_info_ != NULL && _info_->value->type == V_str)
         return memWidecpy(_info_->value->data.str.str);
     else
@@ -347,7 +347,7 @@ wchar_t *getErrorInfo(LinkValue *exc, int type, Inter *inter){
 }
 
 void callException(LinkValue *exc, wchar_t *message, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
-    LinkValue *_new_ = findAttributes(inter->data.object_new, false, exc, inter);
+    LinkValue *_new_ = findAttributes(inter->data.object_new, false, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, exc));
     wchar_t *type = NULL;
     wchar_t *error_message = NULL;
     setResultCore(result);
@@ -355,6 +355,7 @@ void callException(LinkValue *exc, wchar_t *message, fline line, char *file, INT
 
     if (_new_ != NULL){
         Argument *arg = NULL;
+        LinkValue *error;
         makeStringValue(message, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         if (!CHECK_RESULT(result))
             goto return_;
@@ -363,10 +364,20 @@ void callException(LinkValue *exc, wchar_t *message, fline line, char *file, INT
 
         gc_addTmpLink(&_new_->gc_status);
         callBackCore(_new_, arg, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        error = result->value;
+        result->value = NULL;
+        freeResult(result);
         gc_freeTmpLink(&_new_->gc_status);
         freeArgument(arg, true);
-        type = getErrorInfo(result->value, 1, inter);
-        error_message = getErrorInfo(result->value, 2, inter);
+
+        type = getErrorInfo(error, 1, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        if (!CHECK_RESULT(result))
+            goto return_;
+        freeResult(result);
+        error_message = getErrorInfo(error, 2, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        if (!CHECK_RESULT(result))
+            goto return_;
+        freeResult(result);
     }
     else {
         result->value = exc;