浏览代码

feat: 新增变量式函数赋值

link #6
SongZihuan 4 年之前
父节点
当前提交
8c1af3bcd4

+ 39 - 2
VirtulMathCore/src/__run.c

@@ -265,14 +265,23 @@ void freeFunctionArgument(Argument *arg, Argument *base) {
     }
 }
 
-LinkValue *findStrVar(wchar_t *name, bool free_old, INTER_FUNCTIONSIG_CORE){
+LinkValue *findStrVar(wchar_t *name, bool free_old, fline line, char *file, bool nowrun, INTER_FUNCTIONSIG_NOT_ST){
     LinkValue *tmp = NULL;
     wchar_t *name_ = setStrVarName(name, free_old, inter);
     tmp = findFromVarList(name_, 0, get_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     memFree(name_);
+    if (nowrun) {
+        setResultCore(result);
+        if (!runVarFunc(tmp, line, file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
+            setResultOperationBase(result, tmp);
+    }
     return tmp;
 }
 
+LinkValue *findStrVarOnly(wchar_t *name, bool free_old, INTER_FUNCTIONSIG_CORE) {
+    return findStrVar(name, free_old, 0, "sys", false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, NULL, NULL));
+}
+
 LinkValue *checkStrVar(wchar_t *name, bool free_old, INTER_FUNCTIONSIG_CORE){
     LinkValue *tmp = NULL;
     wchar_t *name_ = setStrVarName(name, free_old, inter);
@@ -311,7 +320,7 @@ void addStrVar(wchar_t *name, bool free_old, bool setting, LinkValue *value, fli
 }
 
 LinkValue *findAttributes(wchar_t *name, bool free_old, LinkValue *value, Inter *inter) {
-    LinkValue *attr = findStrVar(name, free_old, CALL_INTER_FUNCTIONSIG_CORE(value->value->object.var));
+    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;
     return attr;
@@ -517,3 +526,31 @@ bool setBoolAttrible(bool value, wchar_t *var, fline line, char *file, LinkValue
     freeResult(result);
     return true;
 }
+
+bool runVarFunc(LinkValue *var, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
+    setResultCore(result);
+    if (var->value->type != V_func || !var->value->data.function.function_data.run)
+        return false;
+    gc_addTmpLink(&var->gc_status);
+    callBackCore(var, NULL, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    gc_freeTmpLink(&var->gc_status);
+    return true;
+}
+
+bool setVarFunc(LinkValue *var, LinkValue *new, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST) {
+    Argument *arg;
+    setResultCore(result);
+    if (var->value->type != V_func || !var->value->data.function.function_data.run)
+        return false;
+    gc_addTmpLink(&var->gc_status);
+    gc_addTmpLink(&new->gc_status);
+
+    arg = makeValueArgument(new);
+    callBackCore(var, arg, line, file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    freeArgument(arg, true);
+
+    gc_freeTmpLink(&var->gc_status);
+    gc_freeTmpLink(&new->gc_status);
+    return true;
+}
+

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

@@ -13,7 +13,8 @@ bool popYieldVarList(Statement *st, VarList **return_, VarList *out_var, Inter *
 
 ResultType setFunctionArgument(struct Argument **arg, struct Argument **base, LinkValue *_func, fline line, char *file, int pt_sep, INTER_FUNCTIONSIG_NOT_ST);
 void freeFunctionArgument(Argument *arg, Argument *base);
-LinkValue *findStrVar(wchar_t *name, bool free_old, INTER_FUNCTIONSIG_CORE);
+LinkValue *findStrVar(wchar_t *name, bool free_old, fline line, char *file, bool nowrun, INTER_FUNCTIONSIG_NOT_ST);
+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, INTER_FUNCTIONSIG_NOT_ST);
 LinkValue *findAttributes(wchar_t *name, bool free_old, LinkValue *value, Inter *inter);
@@ -30,4 +31,6 @@ bool checkAut(enum ValueAuthority value, enum ValueAuthority base, fline line, c
 LinkValue *make_new(Inter *inter, LinkValue *belong, LinkValue *class);
 int run_init(LinkValue *obj, Argument *arg, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 bool setBoolAttrible(bool value, wchar_t *var, fline line, char *file, LinkValue *obj, INTER_FUNCTIONSIG_NOT_ST);
+bool runVarFunc(LinkValue *var, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
+bool setVarFunc(LinkValue *var, LinkValue *new, fline line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 #endif //VIRTUALMATH___RUN_H

+ 16 - 13
VirtulMathCore/src/parameter.c

@@ -369,7 +369,7 @@ ResultType parameterFromVar(Parameter **function_ad, VarList *function_var, vnum
         }
 
         freeResult(result);
-        value = findFromVarList(str_name, int_times, del_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        value = findFromVarList(str_name, int_times, del_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));  // 形式参数取值不需要执行变量式函数
         memFree(str_name);
 
         if(value == NULL) {
@@ -565,9 +565,9 @@ ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *f
             status = default_status;
         else if (call == NULL && function->type == kwargs_par)
             status = space_kwargs;
-        else if (function->type == args_par)  // 根据前面的条件, 已经决定call不会为NULL
+        else if (function->type == args_par)
             status = mul_par;
-        else if (call->type == value_arg)
+        else if (call->type == value_arg)  // 根据前面的条件, 已经决定call不会为NULL
             status = match_status;
         else if (call->type == name_arg) {
             if (checkIsSep(function))
@@ -614,16 +614,19 @@ ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *f
             }
             case mul_par: {
                 LinkValue *tmp;
-                Argument *backup;
-                Argument *base = call;
-                for (PASS; call->next != NULL && call->next->type == value_arg; call = call->next)
-                    PASS;
 
-                backup = call->next;
-                call->next = NULL;  // 断开Argument,只把value_arg部分传入makeListValue
-                makeListValue(base, 0, "sys", L_tuple, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-                call->next = backup;
-                call = backup;
+                if (call != NULL) {
+                    Argument *backup;
+                    Argument *base = call;
+                    for (PASS; call->next != NULL && call->next->type == value_arg; call = call->next)
+                            PASS;
+                    backup = call->next;
+                    call->next = NULL;
+                    makeListValue(base, 0, "sys", L_tuple, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+                    call->next = backup;
+                    call = backup;
+                } else
+                    makeListValue(NULL, 0, "sys", L_tuple, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
                 returnResult(result);
                 tmp = result->value;
@@ -829,7 +832,7 @@ Argument *parserArgumentValueCore(Argument *arg, ArgumentParser *ap){
 
 int parserArgumentVar(ArgumentParser *ap, Inter *inter, VarList *var_list){
     LinkValue *value = NULL;
-    findStrVar(ap->name, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    findStrVarOnly(ap->name, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));  // 参数取值不执行变量式函数
     ap->value = value;
     if (value != NULL)
         return 1;

+ 0 - 1
VirtulMathCore/src/runbranch.c

@@ -652,7 +652,6 @@ static void setWithResult(bool yield_run, StatementList *sl, Statement *st, Resu
     }
 }
 
-// TODO-szh 检查yield是否能为代码的最后一个
 ResultType withBranch(INTER_FUNCTIONSIG) {
     StatementList *with_list = st->u.with_branch.with_list;
     Statement *else_st = st->u.with_branch.else_list;

+ 20 - 20
VirtulMathCore/src/runoperation.c

@@ -296,7 +296,9 @@ ResultType assCore(Statement *name, LinkValue *value, bool check_aut, bool setti
 ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool setting, INTER_FUNCTIONSIG_NOT_ST) {
     wchar_t *str_name = NULL;
     int int_times = 0;
-    LinkValue *var_value = NULL;
+    LinkValue *name_ = NULL;
+    LinkValue *tmp;
+    bool run = name->type == base_var ? name->u.base_var.run : name->type == base_svar ? name->u.base_svar.run : false;
 
     setResultCore(result);
     getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list, result, belong));
@@ -304,19 +306,24 @@ ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool settin
         memFree(str_name);
         return result->type;
     }
-    var_value = copyLinkValue(value, inter);
+    name_ = result->value;
+    result->value = NULL;
+    freeResult(result);
+
     if (name->aut != auto_aut)
-        var_value->aut = name->aut;
+        value->aut = name->aut;
+
+    tmp = findFromVarList(str_name, int_times, read_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     if (check_aut) {
-        LinkValue *tmp = findFromVarList(str_name, int_times, read_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         if (tmp != NULL && !checkAut(value->aut, tmp->aut, name->line, name->code_file, NULL, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
             goto error_;
-    } else if (name->aut != auto_aut){
-        LinkValue *tmp = findFromVarList(str_name, int_times, read_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-        if (tmp != NULL)
-            tmp->aut = name->aut;
-    }
-    addFromVarList(str_name, result->value, int_times, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    } else if (name->aut != auto_aut && tmp != NULL)
+        tmp->aut = value->aut;
+
+    if (tmp == NULL || !run || !setVarFunc(tmp, value, name->line, name->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))  // TODO-szh 其他变量获取函数也使用改方法
+        addFromVarList(str_name, name_, int_times, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    if (CHECK_RESULT(result))
+        goto error_;
     if (setting) {
         freeResult(result);
         newObjectSetting(value, name->line, name->code_file, value, result, inter, var_list);
@@ -330,6 +337,7 @@ ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool settin
     gc_addTmpLink(&result->value->gc_status);
 
     error_:
+    gc_freeTmpLink(&name_->gc_status);
     memFree(str_name);
     return result->type;
 }
@@ -444,16 +452,8 @@ ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
         memFree(message);
     }
     else if (checkAut(st->aut, var->aut, st->line, st->code_file, NULL, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong))) {
-        bool run = false;
-        if (st->type == base_var)
-            run = st->u.base_var.run;
-        else if (st->type == base_svar)
-            run = st->u.base_svar.run;
-        if (run && var->value->type == V_func && var->value->data.function.function_data.run) {  // TODO-szh 封装成函数, 其他获取变量的地方可以调用
-            gc_addTmpLink(&var->gc_status);
-            callBackCore(var, NULL, st->line, st->code_file, 0, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-            gc_freeTmpLink(&var->gc_status);
-        } else
+        bool run = st->type == base_var ? st->u.base_var.run : st->type == base_svar ? st->u.base_svar.run : false;
+        if (!run || !runVarFunc(var, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
             setResultOperationBase(result, var);
     }
     memFree(name);

+ 1 - 1
VirtulMathCore/src/value.c

@@ -583,7 +583,7 @@ bool needDel(Value *object_value, Inter *inter) {
 }
 
 bool callDel(Value *object_value, Result *result, Inter *inter, VarList *var_list) {
-    LinkValue *_del_ = findStrVar(inter->data.object_del, false, CALL_INTER_FUNCTIONSIG_CORE(object_value->object.var));
+    LinkValue *_del_ = findStrVarOnly(inter->data.object_del, false, CALL_INTER_FUNCTIONSIG_CORE(object_value->object.var));
     setResultCore(result);
 
     if (_del_ != NULL){