Ver código fonte

feat: 加入C函数参数管理机制

SongZihuan 4 anos atrás
pai
commit
42ab3446f5
19 arquivos alterados com 407 adições e 95 exclusões
  1. 5 4
      include/__virtualmath.h
  2. 1 3
      include/ofunc.h
  3. 24 0
      include/parameter.h
  4. 1 0
      include/run.h
  5. 10 4
      include/value.h
  6. 1 0
      main.c
  7. 5 3
      ofunc/src/__ofunc.c
  8. 25 7
      ofunc/src/io.c
  9. 16 10
      ofunc/src/object.c
  10. 20 17
      ofunc/src/sys.c
  11. 34 13
      src/__run.c
  12. 3 3
      src/include/__run.h
  13. 50 7
      src/inter.c
  14. 200 15
      src/parameter.c
  15. 2 2
      src/runbranch.c
  16. 3 3
      src/runcall.c
  17. 1 1
      src/runfile.c
  18. 1 1
      src/runoperation.c
  19. 5 2
      src/var.c

+ 5 - 4
include/__virtualmath.h

@@ -5,11 +5,11 @@
 #include "mem.h"
 #include "gc.h"
 #include "inter.h"
-#include "ofunc.h"
 #include "value.h"
 #include "var.h"
 #include "parameter.h"
 #include "statement.h"
+#include "ofunc.h"
 #include "run.h"
 #include "lexical.h"
 #include "token.h"
@@ -19,9 +19,10 @@
 #include "file.h"
 
 /* DEBUG */
-void printLinkValueGC(char *tag, Inter *inter);
-void printValueGC(char *tag, Inter *inter);
+void printGC(Inter *inter);
+void printLinkValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link);
+void printValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link);
 void printVarGC(char *tag, Inter *inter);
-void printHashTableGC(char *tag, Inter *inter);
+void printHashTableGC(char *tag, Inter *inter, long *tmp_link);
 void printTokenStream(TokenStream *ts);
 #endif //VIRTUALMATH___VIRTUALMATH_H

+ 1 - 3
include/ofunc.h

@@ -8,16 +8,14 @@
 struct Argument;
 struct VarList;
 struct FatherValue;
-typedef enum ResultType (*OfficialFunction)(OfficialFunctionSig);
-typedef void (*Registered)(RegisteredFunctionSig);
 
 struct NameFunc{
     char *name;
     OfficialFunction of;
+    enum FunctionPtType type;
 };
 typedef struct NameFunc NameFunc;
 
-
 void registeredBaseFunction(struct LinkValue *father, Inter *inter);
 
 #endif //VIRTUALMATH_OFUNC_H

+ 24 - 0
include/parameter.h

@@ -35,8 +35,23 @@ struct Argument{
     struct Argument *next;
 };
 
+struct ArgumentParser{
+    struct LinkValue *value;
+    struct Argument *arg;
+    char *name;
+    enum ArgumentParserType{
+        only_value,
+        name_value,
+        only_name,
+    } type;
+    int must;
+    bool long_arg;
+    int c_count;
+};
+
 typedef struct Parameter Parameter;
 typedef struct Argument Argument;
+typedef struct ArgumentParser ArgumentParser;
 
 Argument *makeArgument(void);
 Argument *makeValueArgument(LinkValue *value);
@@ -77,4 +92,13 @@ ResultType argumentToParameter(Argument **call_ad, Parameter **function_ad, VarL
 FatherValue *setFatherCore(FatherValue *father_tmp);
 FatherValue *setFather(Argument *call);
 bool checkFormal(Parameter *pt);
+
+bool checkArgument(int c_value, int c_name, int type_value, int type_name, Argument *arg);
+Argument *parserValueArgument(ArgumentParser *ap, Argument *arg, int *status, ArgumentParser **bak);
+int parserNameArgument(ArgumentParser ap[], Argument *arg, ArgumentParser **bak, INTER_FUNCTIONSIG_NOT_ST);
+int parserArgumentUnion(ArgumentParser ap[], Argument *arg, INTER_FUNCTIONSIG_NOT_ST);
+Argument *parserArgumentValueCore(Argument *arg, ArgumentParser *ap);
+ArgumentParser *parserArgumentNameDefault(ArgumentParser *ap);
+ArgumentParser *parserArgumentValueDefault(ArgumentParser *ap);
+int parserArgumentVar(ArgumentParser *ap, Inter *inter, VarList *var_list);
 #endif //VIRTUALMATH_PARAMETER_H

+ 1 - 0
include/run.h

@@ -3,6 +3,7 @@
 #include "__macro.h"
 
 enum StatementInfoStatus;
+struct Argument;
 typedef struct Result Result;
 typedef enum ResultType ResultType;
 typedef struct LinkValue LinkValue;

+ 10 - 4
include/value.h

@@ -9,6 +9,9 @@ struct VarList;
 struct Argument;
 struct FatherValue;
 
+typedef enum ResultType (*OfficialFunction)(OfficialFunctionSig);
+typedef void (*Registered)(RegisteredFunctionSig);
+
 enum ValueAuthority{
     auto_aut,
     public_aut,
@@ -51,10 +54,13 @@ struct Value{
             struct Parameter *pt;
             OfficialFunction of;
             struct {
-                enum {
-                    static_,
-                    object_static_,
-                    class_static_,
+                enum FunctionPtType{
+                    free_,  // 不包含任何隐式传递的参数
+                    static_,  // 不包含self参数
+                    object_static_,  // self参数允许一切father
+                    class_static_,  // self参数不允许class
+                    object_free_,  // 同object_static_但不包含func参数
+                    class_free_,  // 同object_static_但不包含func参数
                 } pt_type;
             } function_data;
         } function;

+ 1 - 0
main.c

@@ -21,6 +21,7 @@ int main(int argc, char *argv[]) {
 
 
 /** TODO-szh List
+ * argument 设定 tmp_link
  * __call__ 设定
  * __var__ 设定
  * 下标和切片

+ 5 - 3
ofunc/src/__ofunc.c

@@ -3,7 +3,7 @@
 LinkValue *registeredFunctionCore(OfficialFunction of, char *name, struct LinkValue *father, INTER_FUNCTIONSIG_CORE) {
     LinkValue *value = NULL;
     LinkValue *name_ = NULL;
-    char *var_name = setStrVarName(name, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    char *var_name = setStrVarName(name, false, inter);
     name_ = makeLinkValue(makeStringValue(var_name, inter), father, inter);
     value = makeLinkValue(makeCFunctionValue(of, var_list, inter), father, inter);
     addFromVarList(var_name, name_, 0, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
@@ -12,6 +12,8 @@ LinkValue *registeredFunctionCore(OfficialFunction of, char *name, struct LinkVa
 }
 
 void iterNameFunc(NameFunc list[], LinkValue *father, INTER_FUNCTIONSIG_CORE){
-    for (PASS; list->of != NULL; list++)
-        registeredFunctionCore(list->of, list->name, father, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    for (PASS; list->of != NULL; list++) {
+        LinkValue *value = registeredFunctionCore(list->of, list->name, father, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        value->value->data.function.function_data.pt_type = list->type;
+    }
 }

+ 25 - 7
ofunc/src/io.c

@@ -1,18 +1,36 @@
 #include "__ofunc.h"
 
 ResultType vm_print(OfficialFunctionSig){
-    setResultBase(result, inter, father);
-    if (arg == NULL || arg->next == NULL){
-        setResultError(result, inter, "ArgumentException", "Don't get any Argument for print", 0, "sys", father, true);
-        return error_return;
+    setResultCore(result);
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=true},
+                           {.type=name_value, .name="end", .must=0, .value=NULL},
+                           {.must=-1}};
+    {
+        int status;
+        status = parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+        if (!run_continue(result))
+            return result->type;
+        if (status != 1) {
+            setResultError(result, inter, "ArgumentException", "Too less Argument", 0, "sys", father, true);
+            return error_return;
+        }
+        freeResult(result);
     }
-    for (arg = arg->next->next; arg != NULL; arg = arg->next)
+
+    arg = ap[0].arg;
+    for (int i=0; i < ap[0].c_count; arg = arg->next,i++)
         printValue(arg->data.value->value, stdout, true);
-    printf("\n");
+
+    if (ap[1].value != NULL && ap[1].value->value->type == string)
+        printf("%s", ap[1].value->value->data.str.str);
+    else
+        printf("\n");
+
+    setResultBase(result, inter, father);
     return result->type;
 }
 
 void registeredIOFunction(RegisteredFunctionSig){
-    NameFunc tmp[] = {{"print", vm_print}, {NULL, NULL}};
+    NameFunc tmp[] = {{"print", vm_print, free_}, {NULL, NULL}};
     iterNameFunc(tmp, father, CALL_INTER_FUNCTIONSIG_CORE(var_list));
 }

+ 16 - 10
ofunc/src/object.c

@@ -4,31 +4,39 @@ ResultType object_new_(OfficialFunctionSig){
     LinkValue *value = NULL;
     LinkValue *_init_ = NULL;
     setResultCore(result);
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    int status = 1;
+    arg = parserValueArgument(ap, arg, &status, NULL);
+    if (status != 1){
+        setResultError(result, inter, "ArgumentException", "Too less Argument", 0, "sys", father, true);
+        return error_return;
+    }
 
     {
         VarList *new_var = NULL;
         Value *new_object = NULL;
-        Argument *father_arg = makeValueArgument(arg->next->data.value);
+        Argument *father_arg = makeValueArgument(ap[1].value);
         FatherValue *object_father = setFather(father_arg);
         freeArgument(father_arg, true);
-        new_var = copyVarList(arg->next->data.value->value->object.out_var, false, inter);
+        new_var = copyVarList(ap[1].value->value->object.out_var, false, inter);
         new_object = makeObject(inter, NULL, new_var, object_father);
         value = makeLinkValue(new_object, father, inter);
         setResultOperation(result, value);
     }
 
-    char *init_name = setStrVarName(inter->data.object_init, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    char *init_name = setStrVarName(inter->data.object_init, false, inter);
     _init_ = findFromVarList(init_name, 0, false, CALL_INTER_FUNCTIONSIG_CORE(value->value->object.var));
     memFree(init_name);
 
     if (_init_ != NULL){
         Result _init_result;
-        Argument *init_arg = arg->next->next;
         setResultCore(&_init_result);
         _init_->father = value;
 
         gc_addTmpLink(&_init_->gc_status);
-        callBackCore(_init_, init_arg, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, &_init_result, value));
+        callBackCore(_init_, arg, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, &_init_result, value));
         gc_freeTmpLink(&_init_->gc_status);
         if (!run_continue_type(_init_result.type)){
             freeResult(result);
@@ -47,16 +55,14 @@ void registeredObject(RegisteredFunctionSig){
     VarList *object_var = object->object.var;
     LinkValue *name_ = NULL;
     char *name = NULL;
+    NameFunc tmp[] = {{"__new__", object_new_, class_static_}, {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
 
     object_var->next = inter->var_list;
-    {
-        LinkValue *new = registeredFunctionCore(object_new_, "__new__", father, CALL_INTER_FUNCTIONSIG_CORE(object_var));
-        new->value->data.function.function_data.pt_type = class_static_;
-    }
+    iterNameFunc(tmp, father, CALL_INTER_FUNCTIONSIG_CORE(object_var));
     object_var->next = NULL;
 
-    name = setStrVarName("object", false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    name = setStrVarName("object", false, inter);
     name_ = makeLinkValue(makeStringValue(name, inter), father, inter);
     addFromVarList(name, name_, 0, makeLinkValue(object, father, inter), CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
     memFree(name);

+ 20 - 17
ofunc/src/sys.c

@@ -5,23 +5,26 @@ ResultType vm_super(OfficialFunctionSig){
     Value *arg_child = NULL;
     LinkValue *next_father = NULL;
     setResultCore(result);
+    ArgumentParser ap[] = {{.type=name_value, .name="class_", .must=1, .long_arg=false},
+                           {.type=name_value, .name="obj_", .must=1, .long_arg=false},
+                           {.must=-1}};
+    {
+        parserArgumentUnion(ap, arg, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+        if (!run_continue(result))
+            return result->type;
+        freeResult(result);
+    }
 
-    arg = arg->next->next;
-    if (arg != NULL && arg->next != NULL){
-        arg_father = arg->data.value->value;
-        arg_child = arg->next->data.value->value;
-        if (arg_child == arg_father) {
-            if (arg_child->object.father != NULL){
-                result->value = copyLinkValue(arg_child->object.father->value, inter);
-                result->type = operation_return;
-                gc_addTmpLink(&result->value->gc_status);
-            } else
-                setResultError(result, inter, "SuperException", "Don't get next father", 0, "sys", father, true);
-            return result->type
-        }
-    } else{
-        setResultError(result, inter, "ArgumentException", "Don't get Enough Argument", 0, "sys", father, true);
-        return error_return;
+    arg_father = ap[0].value->value;
+    arg_child = ap[1].value->value;
+    if (arg_child == arg_father) {
+        if (arg_child->object.father != NULL){
+            result->value = copyLinkValue(arg_child->object.father->value, inter);
+            result->type = operation_return;
+            gc_addTmpLink(&result->value->gc_status);
+        } else
+            setResultError(result, inter, "SuperException", "Don't get next father", 0, "sys", father, true);
+        return result->type;
     }
 
     for (FatherValue *self_father = arg_child->object.father; self_father != NULL; self_father = self_father->next) {
@@ -44,6 +47,6 @@ ResultType vm_super(OfficialFunctionSig){
 }
 
 void registeredSysFunction(RegisteredFunctionSig){
-    NameFunc tmp[] = {{"super", vm_super}, {NULL, NULL}};
+    NameFunc tmp[] = {{"super", vm_super, free_}, {NULL, NULL}};
     iterNameFunc(tmp, father, CALL_INTER_FUNCTIONSIG_CORE(var_list));
 }

+ 34 - 13
src/__run.c

@@ -3,7 +3,7 @@
 ResultType getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     LinkValue *value;
 
-    *name = setStrVarName(st->u.base_var.name, false, inter, var_list);
+    *name = setStrVarName(st->u.base_var.name, false, inter);
     *times = 0;
     if (st->u.base_var.times == NULL){
         *times = 0;
@@ -45,7 +45,7 @@ ResultType getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.base_svar.name, var_list, result, father)))
         return result->type;
 
-    *name = getNameFromValue(result->value->value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    *name = getNameFromValue(result->value->value, inter);
     result->type = operation_return;  // 执行 operationSafeInterStatement 的时候已经初始化 result
 
     return result->type;
@@ -59,28 +59,28 @@ ResultType getVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     else{
         if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, father)))
             return result->type;
-        *name = getNameFromValue(result->value->value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        *name = getNameFromValue(result->value->value, inter);
         *times = 0;
     }
     return result->type;
 }
 
-char *setStrVarName(char *old, bool free_old, INTER_FUNCTIONSIG_CORE) {
+char *setStrVarName(char *old, bool free_old, Inter *inter) {
     return memStrcat(inter->data.var_str_prefix, old, false, free_old);
 }
 
-char *setNumVarName(NUMBER_TYPE num, INTER_FUNCTIONSIG_CORE) {
+char *setNumVarName(NUMBER_TYPE num, struct Inter *inter) {
     char name[50];
     snprintf(name, 50, "%"NUMBER_FORMAT, num);
     return memStrcat(inter->data.var_num_prefix, name, false, false);
 }
 
-char *getNameFromValue(Value *value, INTER_FUNCTIONSIG_CORE) {
+char *getNameFromValue(Value *value, struct Inter *inter) {
     switch (value->type){
         case string:
-            return setStrVarName(value->data.str.str, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            return setStrVarName(value->data.str.str, false, inter);
         case number:
-            return setNumVarName(value->data.num.num, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            return setNumVarName(value->data.num.num, inter);
         default:
             return memStrcpy(inter->data.var_defualt);
     }
@@ -125,39 +125,60 @@ Statement *getRunInfoStatement(Statement *funtion_st){  // TODO-szh 去除该函
 
 ResultType setFunctionArgument(Argument **arg, LinkValue *function_value, long line, char *file, INTER_FUNCTIONSIG_NOT_ST){
     Argument *tmp = NULL;
+    enum FunctionPtType pt_type = function_value->value->data.function.function_data.pt_type;
     setResultCore(result);
     if (function_value->father == NULL){
         setResultError(result, inter, "ArgumentException", "Don't get self", line, file, father, true);
         return error_return;
     }
-    tmp = makeValueArgument(function_value);
-    switch (function_value->value->data.function.function_data.pt_type) {
+
+    switch (pt_type) {
         case static_:
+            tmp = makeValueArgument(function_value);
             tmp->next = *arg;
+            *arg = tmp;
             break;
         case class_static_:
+            tmp = makeValueArgument(function_value);
             tmp->next = makeValueArgument(function_value->father);
             tmp->next->next = *arg;
+            *arg = tmp;
             break;
         case object_static_:
+            tmp = makeValueArgument(function_value);
             if (function_value->father->value->type == class)
                 tmp->next = *arg;
             else {
                 tmp->next = makeValueArgument(function_value->father);
                 tmp->next->next = *arg;
             }
+            *arg = tmp;
+            break;
+        case class_free_:
+            tmp = makeValueArgument(function_value->father);
+            tmp->next = *arg;
+            *arg = tmp;
+            break;
+        case object_free_:
+            if (function_value->father->value->type != class) {
+                tmp = makeValueArgument(function_value->father);
+                tmp->next = *arg;
+                *arg = tmp;
+            }
+            break;
+        default:
             break;
     }
-    *arg = tmp;
     setResultBase(result, inter, father);
     return result->type;
 }
 
 void freeFunctionArgument(Argument *arg, Argument *base) {
-    for (Argument *tmp = arg; tmp != NULL && tmp->next != NULL; tmp = tmp->next)
+    for (Argument *tmp = arg; tmp != NULL && tmp->next != NULL; tmp = tmp->next) {
         if (tmp->next == base) {
             tmp->next = NULL;
+            freeArgument(arg, true);
             break;
         }
-    freeArgument(arg, true);
+    }
 }

+ 3 - 3
src/include/__run.h

@@ -9,9 +9,9 @@
 #define writeLog_(...)
 #endif
 
-char *setStrVarName(char *old, bool free_old, INTER_FUNCTIONSIG_CORE);
-char *setNumVarName(NUMBER_TYPE num, INTER_FUNCTIONSIG_CORE);
-char *getNameFromValue(Value *value, INTER_FUNCTIONSIG_CORE);
+char *setStrVarName(char *old, bool free_old, struct Inter *inter);
+char *setNumVarName(NUMBER_TYPE num, struct Inter *inter);
+char *getNameFromValue(Value *value, struct Inter *inter);
 ResultType getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
 ResultType getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG);
 ResultType getVarInfo(char **name, int *times, INTER_FUNCTIONSIG);

+ 50 - 7
src/inter.c

@@ -85,10 +85,7 @@ void freeInter(Inter *inter, bool show_gc) {
     freeBaseInterData(inter);
 
     if (show_gc && (printf("Enter '1' to show gc: "), getc(stdin) == '1')) {
-        printLinkValueGC("\n\nprintLinkValueGC TAG : freeInter", inter);
-        printValueGC("\nprintValueGC TAG : freeInter", inter);
-        printVarGC("\nprintVarGC TAG : freeInter", inter);
-        printHashTableGC("\nprintHashTableGC TAG : freeInter", inter);
+        printGC(inter);
         while (getc(stdin) != '\n')
             PASS;
     }
@@ -136,10 +133,35 @@ void mergeInter(Inter *new, Inter *base){
 
 /* ***********************DEBUG 专用函数*********************************** */
 
-void printLinkValueGC(char *tag, Inter *inter){
+void printGC(Inter *inter){
+    long int st_lv = 0;
+    long int tmp_lv = 0;
+    long int st_v = 0;
+    long int tmp_v = 0;
+    long int tmp_h = 0;
+    printLinkValueGC("\n\nprintLinkValueGC TAG : freeInter", inter, &tmp_lv, &st_lv);
+    printValueGC("\nprintValueGC TAG : freeInter", inter, &tmp_v, &st_v);
+    printVarGC("\nprintVarGC TAG : freeInter", inter);
+    printHashTableGC("\nprintHashTableGC TAG : freeInter", inter, &tmp_h);
+    printf("\n");
+    printf("linkvalue tmp link   = %ld\n", tmp_lv);
+    printf("linkvalue tmp link   = %ld\n", tmp_v);
+    printf("hashtable tmp link   = %ld\n", tmp_h);
+    printf("statement tmp link   = %ld\n", st_lv);
+    printf("statement tmp link   = %ld\n", st_v);
+    printf("      tmp link count = %ld\n", tmp_lv + tmp_v + tmp_h);
+    printf("statement link count = %ld\n", st_lv + st_v);
+
+}
+
+void printLinkValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link) {
     LinkValue *base = inter->link_base;
+    long tmp = 0;
+    long st = 0;
     printf("%s\n", tag);
     while (base != NULL) {
+        tmp += base->gc_status.tmp_link;
+        st += base->gc_status.statement_link;
         printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
         printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
         printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
@@ -147,13 +169,23 @@ void printLinkValueGC(char *tag, Inter *inter){
         printf("-------------------------------------------\n");
         base = base->gc_next;
     }
+    printf("tmp link = %ld\n", tmp);
+    printf("st link = %ld\n", st);
     printf("printLinkValueGC TAG : END\n");
+    if (tmp_link != NULL)
+        *tmp_link = tmp;
+    if (st_link != NULL)
+        *st_link = tmp;
 }
 
-void printValueGC(char *tag, Inter *inter){
+void printValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link) {
     Value *base = inter->base;
+    long tmp = 0;
+    long st = 0;
     printf("%s\n", tag);
     while (base != NULL) {
+        tmp += base->gc_status.tmp_link;
+        st += base->gc_status.statement_link;
         printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
         printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
         printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
@@ -162,7 +194,13 @@ void printValueGC(char *tag, Inter *inter){
         printf("\n-------------------------------------------\n");
         base = base->gc_next;
     }
+    printf("tmp link = %ld\n", tmp);
+    printf("st link = %ld\n", st);
     printf("printValueGC TAG : END\n");
+    if (tmp_link != NULL)
+        *tmp_link = tmp;
+    if (st_link != NULL)
+        *st_link = tmp;
 }
 
 void printVarGC(char *tag, Inter *inter){
@@ -182,17 +220,22 @@ void printVarGC(char *tag, Inter *inter){
     printf("printVarGC TAG : END\n");
 }
 
-void printHashTableGC(char *tag, Inter *inter){
+void printHashTableGC(char *tag, Inter *inter, long *tmp_link) {
     HashTable *base = inter->hash_base;
+    long tmp = 0;
     printf("%s\n", tag);
     while (base != NULL) {
+        tmp += base->gc_status.tmp_link;
         printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
         printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
         printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
         printf("-------------------------------------------\n");
         base = base->gc_next;
     }
+    printf("tmp link = %ld\n", tmp);
     printf("printHashTableGC TAG : END\n");
+    if (tmp_link != NULL)
+        *tmp_link = tmp;
 }
 
 void printToken(Token *tk) {

+ 200 - 15
src/parameter.c

@@ -1,5 +1,7 @@
 #include "__run.h"
 
+static bool compareNumber(int a, int b, int type);
+
 #define returnResult(result) do{ \
 if (!run_continue(result)) { \
 goto return_; \
@@ -394,7 +396,7 @@ ResultType iterParameter(Parameter *call, Argument **base_ad, bool is_dict, INTE
                     gc_freeTmpLink(&value->gc_status);
                     goto return_;
                 }
-                char *name_str = getNameFromValue(result->value->value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+                char *name_str = getNameFromValue(result->value->value, inter);
                 base = connectCharNameArgument(value, result->value, name_str, base);
                 memFree(name_str);
                 gc_freeTmpLink(&value->gc_status);
@@ -421,8 +423,7 @@ ResultType iterParameter(Parameter *call, Argument **base_ad, bool is_dict, INTE
 
 Argument * getArgument(Parameter *call, bool is_dict, INTER_FUNCTIONSIG_NOT_ST) {
     Argument *new_arg = NULL;
-    freeResult(result);
-
+    setResultCore(result);
     iterParameter(call, &new_arg, is_dict, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     return new_arg;
 }
@@ -480,6 +481,8 @@ ResultType setParameterCore(long int line, char *file, Argument *call, Parameter
     function = copyParameter(function_base);
     tmp_function = function;
     setResultCore(result);
+    gc_freeze(inter, function_var, NULL, true);
+    gc_freeze(inter, var_list, NULL, true);
 
     while (true){
         if (call == NULL && function == NULL)
@@ -518,22 +521,19 @@ ResultType setParameterCore(long int line, char *file, Argument *call, Parameter
                 NUMBER_TYPE set_num = 0;
                 NUMBER_TYPE get_num = 0;
                 bool dict_status = false;
-                VarList *tmp = pushVarList(var_list, inter);
+                VarList *tmp = makeVarList(inter, true);
 
                 argumentToVar(&call, &set_num, CALL_INTER_FUNCTIONSIG_NOT_ST(tmp, result, father));
-                returnResult(result);
                 if (!run_continue(result)) {
-                    popVarList(tmp);
+                    freeVarList(tmp);
                     goto return_;
                 }
 
                 freeResult(result);
                 parameterFromVar(&function, function_var, &get_num, set_num, &dict_status, CALL_INTER_FUNCTIONSIG_NOT_ST(tmp, result, father));
-                if (!run_continue(result)) {
-                    popVarList(tmp);
+                freeVarList(tmp);
+                if (!run_continue(result))
                     goto return_;
-                }
-                popVarList(tmp);
 
                 if (!dict_status && set_num > get_num)
                     goto to_more;
@@ -541,11 +541,6 @@ ResultType setParameterCore(long int line, char *file, Argument *call, Parameter
             }
             case mul_par: {
                 LinkValue *tmp = makeLinkValue(makeListValue(&call, inter, value_tuple), father, inter);
-                if (!run_continue(result))
-                    goto return_;
-                else
-                    freeResult(result);
-
                 assCore(function->data.value, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, father));
                 returnResult(result);
                 function = function->next;
@@ -553,6 +548,9 @@ ResultType setParameterCore(long int line, char *file, Argument *call, Parameter
             }
             case space_kwargs:{
                 LinkValue *tmp = makeLinkValue(makeDictValue(NULL, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father)), father, inter);
+                returnResult(result);
+                freeResult(result);
+
                 assCore(function->data.value, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST(function_var, result, father));
                 returnResult(result);
                 function = function->next;
@@ -576,6 +574,8 @@ ResultType setParameterCore(long int line, char *file, Argument *call, Parameter
     setResult(result, inter, father);
 
     return_:
+    gc_freeze(inter, function_var, NULL, false);
+    gc_freeze(inter, var_list, NULL, false);
     freeParameter(tmp_function, true);
     return result->type;
 }
@@ -614,3 +614,188 @@ bool checkFormal(Parameter *pt) {
     }
     return true;
 }
+
+/**
+ *
+ * @param c_value value_类型的参数的最大值
+ * @param c_name name_类型参数的最大值
+ * @param type_value c_value [<= < == > >=] c_value_
+ * @param type_name c_name [<= < == > >=] c_name_
+ * @param arg
+ * @return
+ */
+bool checkArgument(int c_value, int c_name, int type_value, int type_name, Argument *arg) {
+    int c_value_ = 0;
+    int c_name_ = 0;
+    for (PASS; arg != NULL; arg = arg->next){
+        if (arg->type == value_arg)
+            c_value_++;
+        else
+            c_name_++;
+    }
+    if ((c_value == -1 || compareNumber(c_value, c_value_, type_value)) && (c_name == -1 || compareNumber(c_name, c_name_, type_name)))
+        return true;
+    return false;
+}
+
+int parserArgumentUnion(ArgumentParser ap[], Argument *arg, INTER_FUNCTIONSIG_NOT_ST){
+    setResultCore(result);
+    if (ap->type != only_name){
+        ArgumentParser *bak = NULL;
+        int status = 1;
+        arg = parserValueArgument(ap, arg, &status, &bak);
+        if (status != 1){
+            setResultError(result, inter, "ArgumentException", "Too less Argument", 0, "sys", father, true);
+            return 0;
+        }
+        ap = bak;
+    }
+    if (ap->must != -1){
+        ArgumentParser *bak = NULL;
+        int status;
+
+        if (arg != NULL && arg->type != name_arg) {
+            setResultError(result, inter, "ArgumentException", "Too many Argument", 0, "sys", father, true);
+            return -6;
+        }
+
+        status = parserNameArgument(ap, arg, &bak, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+        if (!run_continue(result))
+            return -1;
+        if (status == -3){
+            if (parserArgumentNameDefault(ap)->must != -1){
+                setResultError(result, inter, "ArgumentException", "Too less Argument", 0, "sys", father, true);
+                return -7;
+            }
+        }
+        else if (status == 0){
+            setResultError(result, inter, "ArgumentException", "Too many Argument", 0, "sys", father, true);
+            return -2;
+        } else if (status == -4){
+            setResultError(result, inter, "ArgumentException", "Too less Argument", 0, "sys", father, true);
+            return -3;
+        }
+    } else{
+        if (arg != NULL) {
+            setResultError(result, inter, "ArgumentException", "Too many Argument", 0, "sys", father, true);
+            return -4;
+        }
+    }
+    return 1;
+}
+
+Argument *parserValueArgument(ArgumentParser *ap, Argument *arg, int *status, ArgumentParser **bak){
+    *status = 1;
+    for (PASS; ap->must != -1 && (ap->type == only_value || ap->type == name_value); ap++){
+        if (arg == NULL || arg->name_type != value_arg) {  // 形参进入key=value模式
+            if ((ap = parserArgumentValueDefault(ap))->must != -1 && ap->type == only_value)  // 检查剩余的是否.must=1
+                *status = 0;  // 存在.must=1则返回 0
+            break;  // 正常情况返回 1
+        }
+        arg = parserArgumentValueCore(arg, ap);
+    }
+    if (bak != NULL)
+        *bak = ap;
+    return arg;
+}
+
+int parserNameArgument(ArgumentParser ap[], Argument *arg, ArgumentParser **bak, INTER_FUNCTIONSIG_NOT_ST){
+    VarList *tmp = NULL;
+    NUMBER_TYPE set_num = 0;
+    NUMBER_TYPE get_num = 0;
+    int return_;
+    setResultCore(result);
+
+    gc_freeze(inter, var_list, NULL, true);
+    for (PASS; arg != NULL && arg->type != name_arg; arg = arg->next)
+            PASS;
+    if (arg == NULL) {
+        return_ = -3;  // 参数缺失
+        goto return_;
+    }
+
+    tmp = makeVarList(inter, true);
+    argumentToVar(&arg, &set_num, CALL_INTER_FUNCTIONSIG_NOT_ST(tmp, result, father));
+    if (!run_continue(result)) {
+        return_ = -1;
+        goto return_;
+    }
+    setResultBase(result, inter, father);
+
+    for (PASS; ap->must != -1 && (ap->type == only_name || ap->type == name_value); ap++) {
+        int status = parserArgumentVar(ap, inter, tmp);
+        if (status == 1)
+            get_num ++;
+        else{
+            return_ = -2;  // 参数缺失
+            goto return_;
+        }
+    }
+    return_ = (get_num < set_num) ? 0 : ((get_num > set_num) ? -4 : 1);
+
+    return_:
+    freeVarList(tmp);
+    gc_freeze(inter, var_list, NULL, false);
+    if (bak != NULL)
+        *bak = ap;
+    return return_;
+}
+
+Argument *parserArgumentValueCore(Argument *arg, ArgumentParser *ap){
+    int count = 1;
+    ap->arg = arg;
+    ap->value = arg->data.value;
+    arg = arg->next;
+    if (ap->long_arg)
+        for (PASS; arg != NULL && arg->type == value_arg; arg = arg->next, count++)
+                PASS;
+    ap->c_count = count;
+    return arg;
+}
+
+int parserArgumentVar(ArgumentParser *ap, Inter *inter, VarList *var_list){
+    char *str_name = setStrVarName(ap->name, false, inter);
+    LinkValue *value = findFromVarList(str_name, 0, true, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    memFree(str_name);
+    ap->value = value;
+    if (value != NULL)
+        return 1;
+    else if (ap->must)
+        return -1;
+    return 0;
+}
+
+ArgumentParser *parserArgumentValueDefault(ArgumentParser *ap){
+    for (PASS; ap->type == only_value && ap->must == 0; ap++) {
+        ap->arg = NULL;
+        ap->value = NULL;
+        ap->c_count = 0;
+    }
+    return ap;
+}
+
+ArgumentParser *parserArgumentNameDefault(ArgumentParser *ap){
+    for (PASS; ap->must == 0; ap++) {
+        ap->arg = NULL;
+        ap->value = NULL;
+        ap->c_count = 0;
+    }
+    return ap;
+}
+
+static bool compareNumber(int a, int b, int type){
+    switch (type) {
+        case -2:
+            return a <= b;
+        case -1:
+            return a < b;
+        case 0:
+            return a == b;
+        case 1:
+            return a > b;
+        case 2:
+            return a >= b;
+        default:
+            return false;
+    }
+}

+ 2 - 2
src/runbranch.c

@@ -382,8 +382,8 @@ ResultType withBranch(INTER_FUNCTIONSIG) {
             value = result->value;
             result->value = NULL;
 
-            enter_name = setStrVarName(inter->data.object_enter, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-            exit_name = setStrVarName(inter->data.object_exit, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+            enter_name = setStrVarName(inter->data.object_enter, false, inter);
+            exit_name = setStrVarName(inter->data.object_exit, false, inter);
             _enter_ = findFromVarList(enter_name, 0, false, CALL_INTER_FUNCTIONSIG_CORE(value->value->object.var));
             _exit_ = findFromVarList(exit_name, 0, false, CALL_INTER_FUNCTIONSIG_CORE(value->value->object.var));
             memFree(enter_name);

+ 3 - 3
src/runcall.c

@@ -12,7 +12,7 @@ ResultType setClass(INTER_FUNCTIONSIG) {
         goto error_;
 
     class_father = setFather(call);
-    freeArgument(call, true);
+    freeArgument(call, false);
     tmp = makeLinkValue(makeClassValue(copyVarList(var_list, false, inter), inter, class_father), father, inter);
     gc_addTmpLink(&tmp->gc_status);
 
@@ -122,7 +122,7 @@ ResultType callBackCorePt(LinkValue *function_value, Parameter *pt, long line, c
 
     return_:
     gc_freeTmpLink(&function_value->gc_status);
-    freeArgument(arg, true);
+    freeArgument(arg, false);
     return result->type;
 }
 
@@ -150,7 +150,7 @@ ResultType callClass(LinkValue *class_value, Argument *arg, long int line, char
     LinkValue *_new_ = NULL;
     setResultCore(result);
 
-    char *init_name = setStrVarName(inter->data.object_new, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    char *init_name = setStrVarName(inter->data.object_new, false, inter);
     _new_ = findFromVarList(init_name, 0, false, CALL_INTER_FUNCTIONSIG_CORE(class_value->value->object.var));
     memFree(init_name);
 

+ 1 - 1
src/runfile.c

@@ -109,7 +109,7 @@ ResultType importFile(INTER_FUNCTIONSIG) {
         assCore(st->u.import_file.as, import_value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     else {
         char *name = splitDir(file_dir);
-        char *value_name = setStrVarName(name, false, inter, var_list);
+        char *value_name = setStrVarName(name, false, inter);
         addFromVarList(value_name, makeLinkValue(makeStringValue(value_name, inter), father, inter), 0, import_value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         memFree(name);
         memFree(value_name);

+ 1 - 1
src/runoperation.c

@@ -398,7 +398,7 @@ ResultType getList(INTER_FUNCTIONSIG) {
     at = getArgument(st->u.base_list.list, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     at_tmp = at;
     if (!run_continue(result)){
-        freeArgument(at_tmp, true);
+        freeArgument(at_tmp, false);
         return result->type;
     }
 

+ 5 - 2
src/var.c

@@ -198,8 +198,11 @@ LinkValue *findFromVarList(char *name, NUMBER_TYPE times, bool del_var, INTER_FU
     NUMBER_TYPE base = findDefault(var_list->default_var, name) + times;
     for (NUMBER_TYPE i = 0; i < base && var_list->next != NULL; i++)
         var_list = var_list->next;
-    for (PASS; var_list != NULL && tmp == NULL; var_list = var_list->next)
-        tmp = findVar(name, del_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    if (del_var && var_list != NULL)
+        tmp = findVar(name, true, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    else
+        for (PASS; var_list != NULL && tmp == NULL; var_list = var_list->next)
+            tmp = findVar(name, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     return tmp;
 }