1
0
Эх сурвалжийг харах

feat: 支持变量式函数

link #6
SongZihuan 4 жил өмнө
parent
commit
e45106679c

+ 2 - 0
VirtulMathCore/include/statement.h

@@ -55,6 +55,7 @@ struct Statement{
         struct base_var{
             wchar_t *name;
             struct Statement *times;
+            bool run;
         } base_var;
         struct{
             struct Statement *var;
@@ -62,6 +63,7 @@ struct Statement{
         struct base_svar{
             struct Statement *name;
             struct Statement *times;
+            bool run;
         } base_svar;
         struct {
             enum ListType type;

+ 1 - 0
VirtulMathCore/include/value.h

@@ -80,6 +80,7 @@ struct Function{
             cls_free_,  // 使用function自带的cls作为参数
         } pt_type;
         LinkValue *cls;
+        bool run;  // 是否为即时调用
     } function_data;
 };
 

+ 1 - 0
VirtulMathCore/ofunc/src/function.c

@@ -3,6 +3,7 @@
 static void setFunctionData(Value *value, LinkValue *cls, Inter *inter) {
     value->data.function.function_data.pt_type = inter->data.default_pt_type;
     value->data.function.function_data.cls = cls;
+    value->data.function.function_data.run = false;
 }
 
 ResultType function_new(OFFICAL_FUNCTIONSIG){

+ 28 - 0
VirtulMathCore/ofunc/src/sys.c

@@ -44,6 +44,24 @@ ResultType vm_super(OFFICAL_FUNCTIONSIG){
     return result->type;
 }
 
+ResultType vm_setNowRunCore(OFFICAL_FUNCTIONSIG, bool type){
+    LinkValue *function_value = NULL;
+    ArgumentParser ap[] = {{.type=name_value, .name=L"func", .must=1, .long_arg=false}, {.must=-1}};
+    setResultCore(result);
+    {
+        parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        if (!CHECK_RESULT(result))
+            return result->type;
+        freeResult(result);
+    }
+    function_value = ap[0].value;
+    function_value->value->data.function.function_data.run = type;
+    result->value = function_value;
+    gc_addTmpLink(&result->value->gc_status);
+    result->type = R_opt;
+    return R_opt;
+}
+
 ResultType vm_setMethodCore(OFFICAL_FUNCTIONSIG, enum FunctionPtType type){
     LinkValue *function_value = NULL;
     ArgumentParser ap[] = {{.type=name_value, .name=L"func", .must=1, .long_arg=false}, {.must=-1}};
@@ -102,6 +120,14 @@ ResultType vm_allstaticmethod(OFFICAL_FUNCTIONSIG){
     return vm_setMethodCore(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), all_static_);
 }
 
+ResultType vm_isnowrun(OFFICAL_FUNCTIONSIG){
+    return vm_setNowRunCore(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), true);
+}
+
+ResultType vm_disnowrun(OFFICAL_FUNCTIONSIG){
+    return vm_setNowRunCore(CALL_OFFICAL_FUNCTION(arg, var_list, result, belong), false);
+}
+
 ResultType vm_quit(OFFICAL_FUNCTIONSIG){
     if (arg != NULL)
         setResultError(E_ArgumentException, MANY_ARG, 0, "sys", true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
@@ -122,6 +148,8 @@ void registeredSysFunction(REGISTERED_FUNCTIONSIG){
                       {L"simplestaticmethod", vm_allstaticmethod, free_},
                       {L"clsmethod", vm_clsfreemethod, free_},
                       {L"clsstaticmethod", vm_clsmethod, free_},
+                      {L"isnowrun", vm_isnowrun, free_},
+                      {L"disnowrun", vm_disnowrun, free_},
                       {L"quit", vm_quit, free_},
                       {NULL, NULL}};
     iterBaseNameFunc(tmp, belong, CALL_INTER_FUNCTIONSIG_CORE(var_list));

+ 4 - 1
VirtulMathCore/parser/grammar.c

@@ -1342,7 +1342,6 @@ void parserBaseValue(PASERSSIGNATURE){
             }
             break;
         }
-
         case MATHER_STRING:{
             Statement *tmp = NULL;
             tmp = makeBaseStrValueStatement(value_token->data.str, string_str, value_token->line, pm->file);
@@ -1446,6 +1445,10 @@ void parserBaseValue(PASERSSIGNATURE){
                 syntaxError(pm, syntax_error, value_token->line, 1, "Don't get ) from Base Value");
                 goto return_;
             }
+            if (st->type == base_var)
+                st->u.base_var.run = false;
+            else if (st->type == base_svar)
+                st->u.base_svar.run = false;
             break;
         }
         case MATHER_LC: {

+ 14 - 2
VirtulMathCore/src/runoperation.c

@@ -443,9 +443,21 @@ ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
         setResultErrorSt(E_NameExceptiom, message, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         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)))
-        setResultOperationBase(result, var);
+    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
+            setResultOperationBase(result, var);
+    }
     memFree(name);
+
     return result->type;
 }
 

+ 4 - 0
VirtulMathCore/src/statement.c

@@ -100,6 +100,7 @@ Statement *makeBaseVarStatement(wchar_t *name, Statement *times, fline line, cha
     tmp->type = base_var;
     tmp->u.base_var.name = memWidecpy(name);
     tmp->u.base_var.times = times;
+    tmp->u.base_var.run = true;
     return tmp;
 }
 
@@ -108,6 +109,7 @@ Statement *makeBaseSVarStatement(Statement *name, Statement *times){
     tmp->type = base_svar;
     tmp->u.base_svar.name = name;
     tmp->u.base_svar.times = times;
+    tmp->u.base_svar.run = true;
     return tmp;
 }
 
@@ -542,6 +544,7 @@ Statement *copyStatementCore(Statement *st){
         case base_var:
             new->u.base_var.name = memWidecpy(st->u.base_var.name);
             new->u.base_var.times = copyStatement(st->u.base_var.times);
+            new->u.base_var.run = st->u.base_var.run;
             break;
         case del_:
             new->u.del_.var = copyStatement(st->u.del_.var);
@@ -549,6 +552,7 @@ Statement *copyStatementCore(Statement *st){
         case base_svar:
             new->u.base_svar.name = copyStatement(st->u.base_svar.name);
             new->u.base_svar.times = copyStatement(st->u.base_svar.times);
+            new->u.base_svar.run = st->u.base_svar.run;
             break;
         case base_lambda:
             new->u.base_lambda.function = copyStatement(st->u.base_lambda.function);

+ 2 - 1
VirtulMathCore/src/var.c

@@ -206,9 +206,10 @@ LinkValue *findFromVarList(wchar_t *name, vnum times, VarOperation operating, IN
         var_list = var_list->next;
     if (operating == del_var && var_list != NULL)
         tmp = findVar(name, del_var, inter, var_list->hashtable);
-    else
+    else {
         for (PASS; var_list != NULL && tmp == NULL; var_list = var_list->next)
             tmp = findVar(name, operating, inter, var_list->hashtable);
+    }
     return tmp;
 }