소스 검색

feat: 实例化class

允许使用class实例化object
优化gc的冻结机制(只冻结一层hashTable)
point对class运算会短接外部out_var
调整了out_var的位置
实现继承
优化了复制函数的代码
var由gc机制管理
SongZihuan 4 년 전
부모
커밋
33ffcd9f31
20개의 변경된 파일443개의 추가작업 그리고 275개의 파일을 삭제
  1. 2 70
      gc/freeze.c
  2. 25 15
      gc/gc.c
  3. 1 1
      include/__macro.h
  4. 1 0
      include/__virtualmath.h
  5. 3 0
      include/inter.h
  6. 5 2
      include/parameter.h
  7. 4 1
      include/run.h
  8. 2 1
      include/statement.h
  9. 21 10
      include/value.h
  10. 13 6
      include/var.h
  11. 0 2
      main.c
  12. 1 1
      parser/grammar.c
  13. 38 13
      src/inter.c
  14. 31 13
      src/parameter.c
  15. 2 2
      src/run.c
  16. 88 24
      src/runcall.c
  17. 8 2
      src/runoperation.c
  18. 13 19
      src/statement.c
  19. 85 43
      src/value.c
  20. 100 50
      src/var.c

+ 2 - 70
gc/freeze.c

@@ -1,61 +1,5 @@
 #include "__virtualmath.h"
 
-void gc_freezeValue(Value *value, bool is_lock);
-void gc_freezeHashTable(HashTable *ht, bool is_lock);
-void gc_freezeVarList(VarList *vl, bool is_lock);
-void gc_freezeVar(Var *var, bool is_lock);
-
-void gc_freezeLinkValue(LinkValue *value, bool is_lock){
-    if (value == NULL)
-        return;
-
-    if (is_lock)
-        gcAddTmp(&value->gc_status);
-    else
-        gcFreeTmpLink(&value->gc_status);
-
-    if (!setIterAlready(&value->gc_status)){
-        gc_freezeLinkValue(value->father, is_lock);
-        gc_freezeValue(value->value, is_lock);
-    }
-}
-
-void gc_freezeValue(Value *value, bool is_lock){
-    if (value == NULL)
-        return;
-
-    if (is_lock)
-        gcAddTmp(&value->gc_status);
-    else
-        gcFreeTmpLink(&value->gc_status);
-
-    if (setIterAlready(&value->gc_status))
-        return;
-    gc_freezeVarList(value->object.var, is_lock);
-    switch (value->type) {
-        case function:
-            gc_freezeVarList(value->data.function.out_var, is_lock);
-            break;
-        case class:
-            gc_freezeVarList(value->data.class.out_var, is_lock);
-            break;
-        case list:
-            for (int i=0;i < value->data.list.size;i++)
-                gc_freezeLinkValue(value->data.list.list[i], is_lock);
-            break;
-        case dict:
-            gc_freezeHashTable(value->data.dict.dict, is_lock);
-            break;
-        default:
-            break;
-    }
-}
-
-void gc_freezeVarList(VarList *vl, bool is_lock){
-    for (PASS; vl != NULL; vl = vl->next)
-        gc_freezeHashTable(vl->hashtable, is_lock);
-}
-
 void gc_freezeHashTable(HashTable *ht, bool is_lock){
     if (ht == NULL)
         return;
@@ -65,29 +9,17 @@ void gc_freezeHashTable(HashTable *ht, bool is_lock){
     else
         gcFreeTmpLink(&ht->gc_status);
 
-    if (setIterAlready(&ht->gc_status))
-        return;
-
-    for (int i=0;i < MAX_SIZE;i++)
-        gc_freezeVar(ht->hashtable[i], is_lock);
-}
-
-void gc_freezeVar(Var *var, bool is_lock){
-    for (PASS; var != NULL; var = var->next){
-        gc_freezeLinkValue(var->name_, is_lock);
-        gc_freezeLinkValue(var->value, is_lock);
-    }
+    setIterAlready(&ht->gc_status);
 }
 
 void iterFreezeVarList(VarList *freeze, VarList *base, bool is_lock){
     for (PASS; freeze != NULL; freeze = freeze->next){
         bool need_freeze = true;
-        for (VarList *tmp = base; tmp != NULL;tmp = tmp->next){
+        for (VarList *tmp = base; tmp != NULL;tmp = tmp->next)
             if (tmp->hashtable == freeze->hashtable){
                 need_freeze = false;
                 break;
             }
-        }
         if (need_freeze)
             gc_freezeHashTable(freeze->hashtable, is_lock);
     }

+ 25 - 15
gc/gc.c

@@ -17,10 +17,9 @@ void gc_iterValue(Value *value){
     if (setIterAlready(&value->gc_status))
         return;
     gc_varList(value->object.var);
+    gc_varList(value->object.out_var);
+    // TODO-szh 处理father_value
     switch (value->type) {
-        case function:
-            gc_varList(value->data.function.out_var);
-            break;
         case list:
             for (int i=0;i < value->data.list.size;i++)
                 gc_iterLinkValue(value->data.list.list[i]);
@@ -28,9 +27,6 @@ void gc_iterValue(Value *value){
         case dict:
             gc_iterHashTable(value->data.dict.dict);
             break;
-        case class:
-            gc_varList(value->data.class.out_var);
-            break;
         default:
             break;
     }
@@ -52,6 +48,11 @@ void gc_iterHashTable(HashTable *ht){
 }
 
 void gc_iterVar(Var *var){
+    if (var == NULL)
+        return;
+    gcAddLink(&var->gc_status);
+    if (setIterAlready(&var->gc_status))
+        return;
     for (PASS; var != NULL; var = var->next){
         gc_iterLinkValue(var->name_);
         gc_iterLinkValue(var->value);
@@ -59,26 +60,29 @@ void gc_iterVar(Var *var){
 }
 
 void gc_resetBase(Inter *inter){
-    for (Value *value_base = inter->base; value_base != NULL; value_base = value_base->next)
+    for (Value *value_base = inter->base; value_base != NULL; value_base = value_base->gc_next)
         resetGC(&value_base->gc_status);
 
-    for (LinkValue *link_base = inter->link_base; link_base != NULL; link_base = link_base->next)
+    for (LinkValue *link_base = inter->link_base; link_base != NULL; link_base = link_base->gc_next)
         resetGC(&link_base->gc_status);
 
-    for (HashTable *hash_base = inter->hash_base; hash_base != NULL; hash_base = hash_base->next)
+    for (HashTable *hash_base = inter->hash_base; hash_base != NULL; hash_base = hash_base->gc_next)
         resetGC(&hash_base->gc_status);
+
+    for (Var *var_base = inter->base_var; var_base != NULL; var_base = var_base->gc_next)
+        resetGC(&var_base->gc_status);
 }
 
 void gc_checkBase(Inter *inter){
-    for (Value *value_base = inter->base; value_base != NULL; value_base = value_base->next)
+    for (Value *value_base = inter->base; value_base != NULL; value_base = value_base->gc_next)
         if (!needFree(&value_base->gc_status) && !value_base->gc_status.continue_)
             gc_iterValue(value_base);
 
-    for (LinkValue *link_base = inter->link_base; link_base != NULL; link_base = link_base->next)
+    for (LinkValue *link_base = inter->link_base; link_base != NULL; link_base = link_base->gc_next)
         if (!needFree(&link_base->gc_status) && !link_base->gc_status.continue_)
             gc_iterLinkValue(link_base);
 
-    for (HashTable *hash_base = inter->hash_base; hash_base != NULL; hash_base = hash_base->next)
+    for (HashTable *hash_base = inter->hash_base; hash_base != NULL; hash_base = hash_base->gc_next)
         if (!needFree(&hash_base->gc_status) && !hash_base->gc_status.continue_)
             gc_iterHashTable(hash_base);
 }
@@ -89,19 +93,25 @@ void gc_freeBase(Inter *inter){
         if (needFree(&value_base->gc_status))
             value_base = freeValue(value_base, inter);
         else
-            value_base = value_base->next;
+            value_base = value_base->gc_next;
 
     for (LinkValue *link_base = inter->link_base; link_base != NULL;)
         if (needFree(&link_base->gc_status))
             link_base = freeLinkValue(link_base, inter);
         else
-            link_base = link_base->next;
+            link_base = link_base->gc_next;
 
     for (HashTable *hash_base = inter->hash_base; hash_base != NULL;)
         if (needFree(&hash_base->gc_status))
             hash_base = freeHashTable(hash_base, inter);
         else
-            hash_base = hash_base->next;
+            hash_base = hash_base->gc_next;
+
+    for (Var *var_base = inter->base_var; var_base != NULL;)
+        if (needFree(&var_base->gc_status))
+            var_base = freeVar(var_base, inter);
+        else
+            var_base = var_base->gc_next;
 #endif
 }
 

+ 1 - 1
include/__macro.h

@@ -17,7 +17,7 @@
 #define CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father) father, result, CALL_INTER_FUNCTIONSIG_CORE(var_list)
 #define CALL_INTER_FUNCTIONSIG(st, var_list, result, father) st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father)
 
-#define run_continue_type(result) (type == not_return || type == operation_return)
+#define run_continue_type(type) (type == not_return || type == operation_return)
 #define run_continue(result) (result->type == not_return || result->type == operation_return)
 
 #define freeBase(element, return_) do{ \

+ 1 - 0
include/__virtualmath.h

@@ -21,5 +21,6 @@
 /* DEBUG */
 void printLinkValueGC(char *tag, Inter *inter);
 void printValueGC(char *tag, Inter *inter);
+void printVarGC(char *tag, Inter *inter);
 void showLinkValue(struct LinkValue *base);
 #endif //VIRTUALMATH___VIRTUALMATH_H

+ 3 - 0
include/inter.h

@@ -7,6 +7,8 @@ struct Inter{
     struct Value *base;
     struct LinkValue *link_base;
     struct HashTable *hash_base;
+    struct Var *base_var;
+
     struct Statement *statement;
     struct VarList *var_list;
     struct InterData{
@@ -16,6 +18,7 @@ struct Inter{
         char *var_str_prefix;
         char *var_num_prefix;
         char *var_defualt;
+        char *object_init;
     } data;
 };
 

+ 5 - 2
include/parameter.h

@@ -63,8 +63,8 @@ void freeParameter(Parameter *pt, bool free_st);
 Argument *listToArgument(LinkValue *list_value, INTER_FUNCTIONSIG_CORE);
 Argument *dictToArgument(LinkValue *dict_value, INTER_FUNCTIONSIG_CORE);
 
-ResultType setParameterCore(Argument *call, Parameter *function_base, VarList *function_var, struct Statement *base, INTER_FUNCTIONSIG_NOT_ST);
-ResultType setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, struct Statement *base, INTER_FUNCTIONSIG_NOT_ST);
+ResultType setParameterCore(Argument *call, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_NOT_ST);
+ResultType setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_NOT_ST);
 ResultType iterParameter(Parameter *call, Argument **base_ad, INTER_FUNCTIONSIG_NOT_ST);
 Argument *getArgument(Parameter *call, INTER_FUNCTIONSIG_NOT_ST);
 
@@ -73,4 +73,7 @@ ResultType argumentToVar(Argument **call_ad, NUMBER_TYPE *num, INTER_FUNCTIONSIG
 ResultType parameterFromVar(Parameter **function_ad, VarList *function_var, NUMBER_TYPE *num, NUMBER_TYPE max, bool *status,
                         INTER_FUNCTIONSIG_NOT_ST);
 ResultType argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_NOT_ST);
+
+FatherValue *setFatherCore(FatherValue *father_tmp);
+FatherValue *setFather(Argument *call, INTER_FUNCTIONSIG_NOT_ST);
 #endif //VIRTUALMATH_PARAMETER_H

+ 4 - 1
include/run.h

@@ -9,6 +9,7 @@ typedef struct Value Value;
 typedef struct Statement Statement;
 typedef struct Inter Inter;
 typedef struct VarList VarList;
+typedef struct Parameter Parameter;
 
 typedef ResultType (*VarInfo)(char **name, int *times, INTER_FUNCTIONSIG);
 
@@ -22,7 +23,9 @@ bool tryBranchSafeInterStatement(INTER_FUNCTIONSIG);
 ResultType operationStatement(INTER_FUNCTIONSIG);
 ResultType setClass(INTER_FUNCTIONSIG);
 ResultType setFunction(INTER_FUNCTIONSIG);
-ResultType callFunction(INTER_FUNCTIONSIG);
+ResultType callBack(INTER_FUNCTIONSIG);
+ResultType callClass(LinkValue *class_value, Parameter *parameter, INTER_FUNCTIONSIG_NOT_ST);
+ResultType callFunction(LinkValue *function_value, Parameter *parameter, INTER_FUNCTIONSIG_NOT_ST);
 ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info);
 ResultType getBaseValue(INTER_FUNCTIONSIG);
 ResultType getList(INTER_FUNCTIONSIG);

+ 2 - 1
include/statement.h

@@ -72,6 +72,7 @@ struct Statement{
         struct {
             struct Statement *name;
             struct Statement *st;
+            struct Parameter *father;
         } set_class;
         struct {
             struct Statement *function;
@@ -167,7 +168,7 @@ Statement *makeBaseVarStatement(char *name, Statement *times, long int line, cha
 Statement *makeBaseSVarStatement(Statement *name, Statement *times);
 Statement *makeBaseDictStatement(Parameter *pt, long int line, char *file);
 Statement *makeTupleStatement(Parameter *pt, enum ListType type, long int line, char *file);
-Statement *makeClassStatement(Statement *name, Statement *function);
+Statement *makeClassStatement(Statement *name, Statement *function, Parameter *pt);
 Statement *makeFunctionStatement(Statement *name, Statement *function, struct Parameter *pt);
 Statement *makeCallStatement(Statement *function, struct Parameter *pt);
 Statement *makeIfStatement(long int line, char *file);

+ 21 - 10
include/value.h

@@ -7,6 +7,7 @@
 
 struct VarList;
 struct Argument;
+struct FatherValue;
 
 struct Value{
     struct GCStatus gc_status;
@@ -22,6 +23,8 @@ struct Value{
     } type;
     struct {
         struct VarList *var;
+        struct VarList *out_var;
+        struct FatherValue *father;
     } object;
     union data{
         struct Number{
@@ -32,7 +35,6 @@ struct Value{
         } str;
         struct Function{
             struct Statement *function;
-            struct VarList *out_var;
             struct Parameter *pt;
         } function;
         struct List{
@@ -47,20 +49,17 @@ struct Value{
             struct HashTable *dict;
             NUMBER_TYPE size;
         } dict;
-        struct Class{
-            struct VarList *out_var;  // class 执行的外部环境
-        } class;
     }data;
-    struct Value *next;
-    struct Value *last;
+    struct Value *gc_next;
+    struct Value *gc_last;
 };
 
 struct LinkValue{
     struct GCStatus gc_status;
     struct Value *value;
     struct LinkValue *father;
-    struct LinkValue *next;
-    struct LinkValue *last;
+    struct LinkValue *gc_next;
+    struct LinkValue *gc_last;
 };
 
 struct Result{
@@ -87,14 +86,20 @@ struct Error{
     struct Error *next;
 };
 
+struct FatherValue{
+    struct LinkValue *value;
+    struct FatherValue *next;
+};
+
 typedef struct Inter Inter;
 typedef struct Value Value;
 typedef struct LinkValue LinkValue;
 typedef struct Result Result;
 typedef struct Error Error;
+typedef struct FatherValue FatherValue;
 typedef enum ResultType ResultType;
 
-Value *makeObject(Inter *inter, struct VarList *object);
+Value *makeObject(Inter *inter, VarList *object, VarList *out_var, FatherValue *father);
 Value * freeValue(Value *value, Inter *inter);
 LinkValue *makeLinkValue(Value *value, LinkValue *linkValue,Inter *inter);
 LinkValue * freeLinkValue(LinkValue *value, Inter *inter);
@@ -102,7 +107,7 @@ Value *makeNoneValue(Inter *inter);
 Value *makeNumberValue(long num, Inter *inter);
 Value *makeStringValue(char *str, Inter *inter);
 Value *makeFunctionValue(struct Statement *st, struct Parameter *pt, struct VarList *var_list, Inter *inter);
-Value *makeClassValue(struct VarList *var_list, Inter *inter);
+Value *makeClassValue(VarList *var_list, Inter *inter, FatherValue *father);
 Value *makeListValue(struct Argument **arg_ad, Inter *inter, enum ListType type);
 Value *makeDictValue(struct Argument **arg_ad, bool new_hash, INTER_FUNCTIONSIG_NOT_ST);
 
@@ -127,4 +132,10 @@ void printLinkValue(LinkValue *value, char *first, char *last, FILE *debug);
 
 bool isType(Value *value, enum ValueType type);
 
+FatherValue *makeFatherValue(LinkValue *value);
+FatherValue *copyFatherValue(FatherValue *value);
+FatherValue *freeFatherValue(FatherValue *value);
+FatherValue *connectFatherValue(FatherValue *base, FatherValue *back);
+FatherValue *connectSafeFatherValue(FatherValue *base, FatherValue *back);
+
 #endif //VIRTUALMATH_VALUE_H

+ 13 - 6
include/var.h

@@ -4,17 +4,20 @@
 #define MAX_SIZE (1024)
 
 struct Var{
+    GCStatus gc_status;
     char *name;
     struct LinkValue *value;
     struct LinkValue *name_;
     struct Var *next;
+    struct Var *gc_next;
+    struct Var *gc_last;
 };
 
 struct HashTable{
     GCStatus gc_status;
     struct Var **hashtable;
-    struct HashTable *next;
-    struct HashTable *last;
+    struct HashTable *gc_next;
+    struct HashTable *gc_last;
 };
 
 struct VarList{
@@ -26,8 +29,8 @@ typedef struct Var Var;
 typedef struct HashTable HashTable;
 typedef struct VarList VarList;
 
-Var *makeVar(char *name, LinkValue *value, LinkValue *name_);
-Var *freeVar(Var *var, bool self);
+Var *makeVar(char *name, LinkValue *value, LinkValue *name_, Inter *inter);
+Var *freeVar(Var *var, Inter *inter);
 
 HashTable *makeHashTable(Inter *inter);
 HashTable * freeHashTable(HashTable *ht, Inter *inter);
@@ -38,11 +41,15 @@ VarList *freeVarList(VarList *vl, bool self);
 HASH_INDEX time33(char *key);
 LinkValue *findVar(char *name, VarList *var_list, bool del_var);
 LinkValue *findFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, bool del_var);
-void addVar(char *name, LinkValue *value, LinkValue *name_, VarList *var_list);
-void addFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, LinkValue *value, LinkValue *name_);
+void addVar(char *name, LinkValue *value, LinkValue *name_, INTER_FUNCTIONSIG_CORE);
+void addFromVarList(char *name, LinkValue *name_, NUMBER_TYPE times, LinkValue *value, INTER_FUNCTIONSIG_CORE);
 
 VarList *pushVarList(VarList *base, Inter *inter);
 VarList *popVarList(VarList *base);
 VarList *copyVarList(VarList *base, bool n_new, Inter *inter);
+VarList *connectVarListBack(VarList *base, VarList *back);
+bool comparVarList(VarList *dest, VarList *src);
+VarList *connectSafeVarListBack(VarList *base, VarList *back);
+VarList *makeObjectVarList(FatherValue *value, Inter *inter);
 
 #endif //VIRTUALMATH_VAR_H

+ 0 - 2
main.c

@@ -19,8 +19,6 @@ int main(int argc, char *argv[]) {
 
 
 /**
- * TODO-szh 类->对象
- * TODO-szh 类继承
  * TODO-szh 类封装
  * TODO-szh 类super语句
  * TODO-szh const声明

+ 1 - 1
parser/grammar.c

@@ -573,7 +573,7 @@ void parserDef(PASERSSIGNATURE){
     if (type == MATHER_DEF)
         st = makeFunctionStatement(name_tmp, code_tmp, pt);
     else
-        st = makeClassStatement(name_tmp, code_tmp);  // TODO-szh 处理pt
+        st = makeClassStatement(name_tmp, code_tmp, pt);
     addLexToken(pm, MATHER_ENTER);
     addStatementToken(FUNCTION, st, pm);
     return;

+ 38 - 13
src/inter.c

@@ -68,15 +68,30 @@ void setBaseInterData(struct Inter *inter){
     inter->data.var_str_prefix = memStrcpy("str_");
     inter->data.var_num_prefix = memStrcpy("num_");
     inter->data.var_defualt = memStrcpy("default_var");
+    inter->data.object_init = memStrcpy("__init__");
     inter->data.debug = NULL;
     inter->data.log_dir = NULL;
 }
 
+void freeBaseInterData(struct Inter *inter){
+    memFree(inter->data.var_defualt);
+    memFree(inter->data.var_num_prefix);
+    memFree(inter->data.var_str_prefix);
+    memFree(inter->data.object_init);
+    memFree(inter->data.log_dir);
+
+    if (inter->data.log_dir != NULL) {
+        fclose(inter->data.debug);
+        fclose(inter->data.error);
+    }
+}
+
 void freeInter(Inter *inter, bool self){
     freeBase(inter, return_);
 
     printLinkValueGC("\n\nprintLinkValueGC TAG : freeInter", inter);
     printValueGC("\nprintValueGC TAG : freeInter", inter);
+    printVarGC("\nprintVarGC TAG : freeInter", inter);
 
     freeStatement(inter->statement);  // Statement放在Value前面释放, 因为base_value的释放需要处理gc_status
     freeVarList(inter->var_list, true);
@@ -84,23 +99,16 @@ void freeInter(Inter *inter, bool self){
     while (inter->base != NULL)
         freeValue(inter->base, inter);
 
+    while (inter->base_var != NULL)
+        freeVar(inter->base_var, inter);
+
     while (inter->link_base != NULL)
         freeLinkValue(inter->link_base, inter);
 
     while (inter->hash_base != NULL)
         freeHashTable(inter->hash_base, inter);
 
-
-    memFree(inter->data.var_defualt);
-    memFree(inter->data.var_num_prefix);
-    memFree(inter->data.var_str_prefix);
-
-    memFree(inter->data.log_dir);
-
-    if (inter->data.log_dir != NULL) {
-        fclose(inter->data.debug);
-        fclose(inter->data.error);
-    }
+    freeBaseInterData(inter);
 
     if (self)
         memFree(inter);
@@ -119,7 +127,7 @@ void printLinkValueGC(char *tag, Inter *inter){
         printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
         printLinkValue(base, "value = ", "\n", stdout);
         printf("-------------------------------------------\n");
-        base = base->next;
+        base = base->gc_next;
     }
     printf("printLinkValueGC TAG : END\n");
 }
@@ -134,11 +142,28 @@ void printValueGC(char *tag, Inter *inter){
         printf("value = ");
         printValue(base, stdout);
         printf("\n-------------------------------------------\n");
-        base = base->next;
+        base = base->gc_next;
     }
     printf("printValueGC TAG : END\n");
 }
 
+void printVarGC(char *tag, Inter *inter){
+    Var *base = inter->base_var;
+    printf("%s\n", tag);
+    while (base != NULL) {
+        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("value :\n");
+        printLinkValue(base->name_, "name_: ", "\n", stdout);
+        printLinkValue(base->value, "value_: ", "\n", stdout);
+        printf("str_name = %s\n", base->name);
+        printf("-------------------------------------------\n");
+        base = base->gc_next;
+    }
+    printf("printVarGC TAG : END\n");
+}
+
 void showLinkValue(struct LinkValue *base){
     printf("tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
     printf("statement_link = %ld :: %p\n", base->gc_status.statement_link, base);

+ 31 - 13
src/parameter.c

@@ -104,16 +104,11 @@ Parameter *copyenOneParameter(Parameter *base){
 }
 
 Parameter *copyParameter(Parameter *base){
-    Parameter *tmp = NULL;
     Parameter *base_tmp = NULL;
+    Parameter **tmp = &base_tmp;
 
-    if (base == NULL)
-        return NULL;
-
-    tmp = copyenOneParameter(base);
-    base_tmp = tmp;
-    for (; base->next != NULL; tmp = tmp->next,base = base->next)
-        tmp->next = copyenOneParameter(base->next);
+    for (PASS; base != NULL; tmp = &(*tmp)->next,base = base->next)
+        *tmp = copyenOneParameter(base);
 
     return base_tmp;
 }
@@ -248,7 +243,7 @@ ResultType argumentToVar(Argument **call_ad, NUMBER_TYPE *num, INTER_FUNCTIONSIG
 
     for (*num = 0; call != NULL && call->type == name_arg; (*num)++, call = call->next){
         if (call->name_type == name_char){
-            addFromVarList(call->data.name_, var_list, 0, call->data.value, call->data.name_value);
+            addFromVarList(call->data.name_, call->data.name_value, 0, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
             continue;
         }
         freeResult(result);
@@ -425,8 +420,7 @@ Argument *getArgument(Parameter *call, INTER_FUNCTIONSIG_NOT_ST){
  * @param var_list
  * @return
  */
-ResultType setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, Statement *base,
-                    INTER_FUNCTIONSIG_NOT_ST) {
+ResultType setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_NOT_ST) {
     Argument *call = NULL;
     setResultCore(result);
     call = getArgument(call_base, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
@@ -436,12 +430,12 @@ ResultType setParameter(Parameter *call_base, Parameter *function_base, VarList
     }
 
     freeResult(result);
-    setParameterCore(call, function_base, function_var, base, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
+    setParameterCore(call, function_base, function_var, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
     freeArgument(call, false);
     return result->type;
 }
 
-ResultType setParameterCore(Argument *call, Parameter *function_base, VarList *function_var, Statement *base,
+ResultType setParameterCore(Argument *call, Parameter *function_base, VarList *function_var,
                         INTER_FUNCTIONSIG_NOT_ST) {
     Parameter *function = NULL;
     Parameter *tmp_function = NULL;  // 释放使用
@@ -550,3 +544,27 @@ ResultType setParameterCore(Argument *call, Parameter *function_base, VarList *f
     freeParameter(tmp_function, true);
     return result->type;
 }
+
+FatherValue *setFather(Argument *call, INTER_FUNCTIONSIG_NOT_ST) {
+    setResultCore(result);
+
+    FatherValue *father_tmp = NULL;
+    for (Argument *tmp = call; tmp != NULL && tmp->type == value_arg; tmp = tmp->next)
+        if (tmp->data.value->value->type == class) {
+            father_tmp = connectFatherValue(father_tmp, makeFatherValue(tmp->data.value));
+            father_tmp = connectFatherValue(father_tmp, copyFatherValue(tmp->data.value->value->object.father));
+        }
+
+    return setFatherCore(father_tmp);
+}
+
+FatherValue *setFatherCore(FatherValue *father_tmp) {
+    FatherValue *base_father = NULL;
+    while (father_tmp != NULL){
+        FatherValue *next = father_tmp->next;
+        father_tmp->next = NULL;
+        base_father = connectSafeFatherValue(base_father, father_tmp);
+        father_tmp = next;
+    }
+    return base_father;
+}

+ 2 - 2
src/run.c

@@ -38,7 +38,7 @@ ResultType runStatement(INTER_FUNCTIONSIG) {
             type = setFunction(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
             break;
         case call_function:
-            type = callFunction(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
+            type = callBack(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
             break;
         case if_branch:
             type = ifBranch(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
@@ -118,7 +118,7 @@ ResultType iterStatement(INTER_FUNCTIONSIG) {
  * @return
  */
 ResultType globalIterStatement(Inter *inter, Result *result) {
-    LinkValue *father = makeLinkValue(makeObject(inter, inter->var_list), NULL, inter);
+    LinkValue *father = makeLinkValue(makeObject(inter, copyVarList(inter->var_list, false, inter), NULL, NULL), NULL, inter);
     Statement *base_st = NULL;
     VarList *var_list = NULL;
     enum ResultType type;

+ 88 - 24
src/runcall.c

@@ -1,35 +1,52 @@
 #include "__run.h"
 
 ResultType setClass(INTER_FUNCTIONSIG) {
+    Argument *call = NULL;
     LinkValue *tmp = NULL;
+    FatherValue *class_father = NULL;
+    VarList *father_var = NULL;
     setResultCore(result);
-    tmp = makeLinkValue(makeClassValue(var_list, inter), father, inter);
+
+    call = getArgument(st->u.set_class.father, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    if (!run_continue(result))
+        goto error_;
+
+    freeResult(result);
+    class_father = setFather(call, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    freeArgument(call, true);
+    if (!run_continue(result))
+        goto error_;
+
+    tmp = makeLinkValue(makeClassValue(copyVarList(var_list, false, inter), inter, class_father), father, inter);
     gcAddTmp(&tmp->gc_status);
 
+    father_var = tmp->value->object.var->next;
     tmp->value->object.var->next = var_list;
+    freeResult(result);
     functionSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.set_class.st, tmp->value->object.var, result, tmp));
-    tmp->value->object.var->next = NULL;
-
-    if (!run_continue(result)) {
-        setResultError(result, inter, NULL, NULL, st, father, false);
-        goto return_;
-    }
-    else
-        freeResult(result);
+    tmp->value->object.var->next = father_var;
+    if (!run_continue(result))
+        goto error_;
+    freeResult(result);
 
     assCore(st->u.set_class.name, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     if (run_continue(result))
         setResult(result, inter, father);
-    return_:
+
     gcFreeTmpLink(&tmp->gc_status);
     return result->type;
+
+    error_:
+    gcFreeTmpLink(&tmp->gc_status);
+    setResultError(result, inter, NULL, NULL, st, father, false);
+    return result->type;
 }
 
 ResultType setFunction(INTER_FUNCTIONSIG) {
     LinkValue *tmp = NULL;
     setResultCore(result);
 
-    tmp = makeLinkValue(makeFunctionValue(st->u.set_function.function, st->u.set_function.parameter, var_list, inter), father, inter);
+    tmp = makeLinkValue(makeFunctionValue(st->u.set_function.function, st->u.set_function.parameter, copyVarList(var_list, false, inter), inter), father, inter);
     assCore(st->u.set_function.name, tmp, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     if (run_continue(result))
         setResult(result, inter, father);
@@ -37,43 +54,90 @@ ResultType setFunction(INTER_FUNCTIONSIG) {
     return result->type;
 }
 
-ResultType callFunction(INTER_FUNCTIONSIG) {
+ResultType callBack(INTER_FUNCTIONSIG) {
     LinkValue *function_value = NULL;
-    VarList *function_var = NULL;
     setResultCore(result);
 
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.call_function.function, var_list, result, father)))
         goto return_;
-    if (result->value->value->type != function){
+
+    function_value = result->value;
+    freeResult(result);
+    if (function_value->value->type == function)
+        callFunction(function_value, st->u.call_function.parameter, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    else if (function_value->value->type == class)
+        callClass(function_value, st->u.call_function.parameter, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    else{
         setResultError(result, inter, "TypeException", "Object is not callable", st, father, true);
-        goto return_;
+        return result->type;
     }
 
-    function_value = result->value;
-    function_var = pushVarList(function_value->value->data.function.out_var, inter);
+
+    setResultError(result, inter, NULL, NULL, st, father, false);
+    return_:
+    return result->type;
+}
+
+ResultType callClass(LinkValue *class_value, Parameter *parameter, INTER_FUNCTIONSIG_NOT_ST) {
+    VarList *function_var = NULL;
+    LinkValue *value = NULL;
+    LinkValue *__init__ = NULL;
+    setResultCore(result);
+
+    value = makeLinkValue(makeObject(inter, NULL,copyVarList(class_value->value->object.out_var, false, inter),
+                          setFatherCore(makeFatherValue(class_value))), father, inter);
+    setResultOperation(result, value, inter);
+
+    char *init_name = setStrVarName(inter->data.object_init, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    __init__ = findFromVarList(init_name, value->value->object.var, 0, false);
+    memFree(init_name);
+
+    if (__init__ != NULL && __init__->value->type == function){
+        Result __init__result;
+        setResultCore(&__init__result);
+        __init__ = makeLinkValue(__init__->value, value, inter);
+
+        gcAddTmp(&__init__->gc_status);
+        callFunction(__init__, parameter, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, &__init__result, value));
+        gcFreeTmpLink(&__init__->gc_status);
+
+        if (!run_continue_type(__init__result.type)){
+            freeResult(result);
+            *result = __init__result;
+            goto return_;
+        }
+        freeResult(&__init__result);
+    }
+
+    return_:
+    return result->type;
+}
+
+ResultType callFunction(LinkValue *function_value, Parameter *parameter, INTER_FUNCTIONSIG_NOT_ST) {
+    VarList *function_var = NULL;
+    setResultCore(result);
+    gcAddTmp(&function_value->gc_status);
+
+    function_var = pushVarList(function_value->value->object.out_var, inter);
     gcAddTmp(&function_var->hashtable->gc_status);
     runFREEZE(inter, var_list, function_var, true);
 
-    freeResult(result);
-    setParameter(st->u.call_function.parameter, function_value->value->data.function.pt, function_var,
-                 st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    setParameter(parameter, function_value->value->data.function.pt, function_var, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
     if (!run_continue(result)) {
         gcAddTmp(&function_var->hashtable->gc_status);
         runFREEZE(inter, var_list, function_var, false);
         popVarList(function_var);
         goto return_;
     }
-    else
-        freeResult(result);
 
+    freeResult(result);
     functionSafeInterStatement(CALL_INTER_FUNCTIONSIG(function_value->value->data.function.function, function_var, result, father));
 
     gcFreeTmpLink(&function_var->hashtable->gc_status);
     runFREEZE(inter, var_list, function_var, false);
     popVarList(function_var);
 
-    setResultError(result, inter, NULL, NULL, st, father, false);
-
     return_:
+    gcFreeTmpLink(&function_value->gc_status);
     return result->type;
 }

+ 8 - 2
src/runoperation.c

@@ -159,12 +159,18 @@ ResultType pointOperation(INTER_FUNCTIONSIG) {
     left = result->value;
     setResultCore(result);
     VarList *object = left->value->object.var;
+    VarList *out_var = NULL;
+    for (out_var = object; out_var->next != NULL; out_var = out_var->next)
+        PASS;
+    out_var->next = left->value->object.out_var;
 
     runFREEZE(inter, var_list, object, true);
     operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st->u.operation.right, object, result, left));
     if (run_continue(result))
         result->value->father = left;
     runFREEZE(inter, var_list, object, false);
+    if (out_var != NULL)
+        out_var->next = NULL;
 
     gcFreeTmpLink(&left->gc_status);
     return result->type;
@@ -200,7 +206,7 @@ ResultType assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST){
         }
 
         freeResult(result);
-        setParameterCore(call, name->u.base_list.list, var_list, name, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
+        setParameterCore(call, name->u.base_list.list, var_list, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
         if (run_continue(result)){
             Argument *tmp = call;
             LinkValue *new_value = makeLinkValue(makeListValue(&tmp, inter, value_tuple), father, inter);
@@ -220,7 +226,7 @@ ResultType assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST){
             memFree(str_name);
             return result->type;
         }
-        addFromVarList(str_name, var_list, int_times, value, result->value);
+        addFromVarList(str_name, result->value, int_times, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         memFree(str_name);
         freeResult(result);
 

+ 13 - 19
src/statement.c

@@ -94,11 +94,12 @@ Statement *makeTupleStatement(Parameter *pt, enum ListType type, long int line,
     return tmp;
 }
 
-Statement *makeClassStatement(Statement *name, Statement *function) {
+Statement *makeClassStatement(Statement *name, Statement *function, Parameter *pt) {
     Statement *tmp = makeStatement(name->line, name->code_file);
     tmp->type = set_class;
     tmp->u.set_class.name = name;
     tmp->u.set_class.st = function;
+    tmp->u.set_class.father = pt;
     return tmp;
 }
 
@@ -238,6 +239,7 @@ void freeStatement(Statement *st){
             case set_class:
                 freeStatement(st->u.set_class.name);
                 freeStatement(st->u.set_class.st);
+                freeParameter(st->u.set_class.father, true);
                 break;
             case call_function:
                 freeStatement(st->u.call_function.function);
@@ -311,14 +313,11 @@ void freeStatement(Statement *st){
 }
 
 Statement *copyStatement(Statement *st){
-    if (st == NULL)
-        return NULL;
-
-    Statement *tmp = copyStatementCore(st);
     Statement *base_tmp = NULL;
+    Statement **tmp = &base_tmp;
 
-    for (base_tmp = tmp; st->next != NULL;st = st->next, tmp = tmp->next)
-        tmp->next = copyStatementCore(st->next);
+    for (PASS; st != NULL; st = st->next, tmp = &(*tmp)->next)
+        *tmp = copyStatementCore(st);
     return base_tmp;
 }
 
@@ -357,6 +356,7 @@ Statement *copyStatementCore(Statement *st){
         case set_class:
             new->u.set_class.name = copyStatement(st->u.set_class.name);
             new->u.set_class.st = copyStatement(st->u.set_class.st);
+            new->u.set_class.father = copyParameter(st->u.set_class.father);
             break;
         case call_function:
             new->u.call_function.function = copyStatement(st->u.call_function.function);
@@ -438,12 +438,10 @@ StatementList *makeStatementList(Statement *condition, Statement *var, Statement
 }
 
 StatementList *connectStatementList(StatementList *base, StatementList *new){
-    StatementList *tmp = base;
-    if (base == NULL)
-        return new;
-    for (PASS; tmp->next != NULL; tmp = tmp->next)
+    StatementList **tmp = &base;
+    for (PASS; *tmp != NULL; tmp = &(*tmp)->next)
         PASS;
-    tmp->next = new;
+    *tmp = new;
     return base;
 }
 
@@ -459,14 +457,10 @@ void freeStatementList(StatementList *base){
 }
 
 StatementList *copyStatementList(StatementList *sl){
-    StatementList *tmp = NULL;
     StatementList *base_tmp = NULL;
+    StatementList **tmp = &base_tmp;
 
-    if (sl == NULL)
-        return NULL;
-
-    tmp = makeStatementList(copyStatement(sl->condition), copyStatement(sl->var),copyStatement(sl->code), sl->type);
-    for (base_tmp = tmp; sl->next != NULL;tmp = tmp->next, sl = sl->next)
-        tmp->next = makeStatementList(copyStatement(sl->condition), copyStatement(sl->var), copyStatement(sl->code), sl->type);
+    for (PASS; sl != NULL; sl = sl->next, tmp = &(*tmp)->next)
+        *tmp = makeStatementList(copyStatement(sl->condition), copyStatement(sl->var), copyStatement(sl->code), sl->type);
     return base_tmp;
 }

+ 85 - 43
src/value.c

@@ -1,25 +1,27 @@
 #include "__virtualmath.h"
 
 
-Value *makeObject(Inter *inter, VarList *object) {
+Value *makeObject(Inter *inter, VarList *object, VarList *out_var, FatherValue *father) {
     Value *tmp, *list_tmp = inter->base;
     tmp = memCalloc(1, sizeof(Value));
     setGC(&tmp->gc_status);
     tmp->type = object_;
-    tmp->next = NULL;
-    tmp->object.var = object == NULL ? makeVarList(inter) : copyVarList(object, false, inter);
+    tmp->gc_next = NULL;
+    tmp->object.var = object == NULL ? makeObjectVarList(father, inter) : object;
+    tmp->object.out_var = out_var;
+    tmp->object.father = father;
 
     if (list_tmp == NULL){
         inter->base = tmp;
-        tmp->last = NULL;
+        tmp->gc_last = NULL;
         goto return_;
     }
 
-    for (PASS; list_tmp->next !=  NULL; list_tmp = list_tmp->next)
+    for (PASS; list_tmp->gc_next != NULL; list_tmp = list_tmp->gc_next)
         PASS;
 
-    list_tmp->next = tmp;
-    tmp->last = list_tmp;
+    list_tmp->gc_next = tmp;
+    tmp->gc_last = list_tmp;
 
     return_:
     return tmp;
@@ -27,14 +29,14 @@ Value *makeObject(Inter *inter, VarList *object) {
 
 Value *makeNoneValue(Inter *inter) {
     Value *tmp;
-    tmp = makeObject(inter, NULL);
+    tmp = makeObject(inter, NULL, NULL, NULL);
     tmp->type = none;
     return tmp;
 }
 
 Value *makeNumberValue(NUMBER_TYPE num, Inter *inter) {
     Value *tmp;
-    tmp = makeObject(inter, NULL);
+    tmp = makeObject(inter, NULL, NULL, NULL);
     tmp->type = number;
     tmp->data.num.num = num;
     return tmp;
@@ -42,7 +44,7 @@ Value *makeNumberValue(NUMBER_TYPE num, Inter *inter) {
 
 Value *makeStringValue(char *str, Inter *inter) {
     Value *tmp;
-    tmp = makeObject(inter, NULL);
+    tmp = makeObject(inter, NULL, NULL, NULL);
     tmp->type = string;
     tmp->data.str.str = memStrcpy(str);
     return tmp;
@@ -50,26 +52,24 @@ Value *makeStringValue(char *str, Inter *inter) {
 
 Value *makeFunctionValue(Statement *st, Parameter *pt, VarList *var_list, Inter *inter) {
     Value *tmp;
-    tmp = makeObject(inter, NULL);
+    tmp = makeObject(inter, NULL, var_list, NULL);
     tmp->type = function;
     tmp->data.function.function = copyStatement(st);
     tmp->data.function.pt = copyParameter(pt);
-    tmp->data.function.out_var = copyVarList(var_list, false, inter);
     return tmp;
 }
 
-Value *makeClassValue(VarList *var_list, Inter *inter) {
+Value *makeClassValue(VarList *var_list, Inter *inter, FatherValue *father) {
     Value *tmp;
-    tmp = makeObject(inter, NULL);
+    tmp = makeObject(inter, NULL, var_list, father);
     tmp->type = class;
-    tmp->data.class.out_var = copyVarList(var_list, false, inter);
     return tmp;
 }
 
 Value *makeListValue(Argument **arg_ad, Inter *inter, enum ListType type) {
     Value *tmp;
     Argument *at = *arg_ad;
-    tmp = makeObject(inter, NULL);
+    tmp = makeObject(inter, NULL, NULL, NULL);
     tmp->type = list;
     tmp->data.list.type = type;
     tmp->data.list.list = NULL;
@@ -85,7 +85,7 @@ Value *makeListValue(Argument **arg_ad, Inter *inter, enum ListType type) {
 
 Value *makeDictValue(Argument **arg_ad, bool new_hash, INTER_FUNCTIONSIG_NOT_ST) {
     Value *tmp;
-    tmp = makeObject(inter, NULL);
+    tmp = makeObject(inter, NULL, NULL, NULL);
     tmp->data.dict.size = 0;
     tmp->type = dict;
     if (new_hash) {
@@ -105,32 +105,28 @@ Value *makeDictValue(Argument **arg_ad, bool new_hash, INTER_FUNCTIONSIG_NOT_ST)
 Value *freeValue(Value *value, Inter *inter){
     Value *return_value = NULL;
     freeBase(value, return_);
-    return_value = value->next;
-    if (value->last == NULL)
-        inter->base = value->next;
+    return_value = value->gc_next;
+    if (value->gc_last == NULL)
+        inter->base = value->gc_next;
     else
-        value->last->next = value->next;
+        value->gc_last->gc_next = value->gc_next;
 
-    if (value->next != NULL)
-        value->next->last = value->last;
+    if (value->gc_next != NULL)
+        value->gc_next->gc_last = value->gc_last;
 
-    freeVarList(value->object.var, true);
+    for (VarList *tmp = value->object.var; tmp != NULL; tmp = freeVarList(tmp, true))
+        PASS;
+    for (VarList *tmp = value->object.out_var; tmp != NULL; tmp = freeVarList(tmp, true))
+        PASS;
+    for (struct FatherValue *tmp = value->object.father; tmp != NULL; tmp = freeFatherValue(tmp))
+        PASS;
     switch (value->type) {
         case string:
             memFree(value->data.str.str);
             break;
         case function: {
-            VarList *tmp = value->data.function.out_var;
             freeParameter(value->data.function.pt, true);
             freeStatement(value->data.function.function);
-            while (tmp != NULL)
-                tmp = freeVarList(tmp, true);
-            break;
-        }
-        case class: {
-            VarList *tmp = value->data.class.out_var;
-            while (tmp != NULL)
-                tmp = freeVarList(tmp, true);
             break;
         }
         case list:
@@ -153,15 +149,15 @@ LinkValue *makeLinkValue(Value *value, LinkValue *linkValue, Inter *inter){
     tmp->value = value;
     if (list_tmp == NULL){
         inter->link_base = tmp;
-        tmp->last = NULL;
+        tmp->gc_last = NULL;
         goto return_;
     }
 
-    for (PASS; list_tmp->next !=  NULL; list_tmp = list_tmp->next)
+    for (PASS; list_tmp->gc_next != NULL; list_tmp = list_tmp->gc_next)
         PASS;
 
-    list_tmp->next = tmp;
-    tmp->last = list_tmp;
+    list_tmp->gc_next = tmp;
+    tmp->gc_last = list_tmp;
 
     return_:
     return tmp;
@@ -170,14 +166,14 @@ LinkValue *makeLinkValue(Value *value, LinkValue *linkValue, Inter *inter){
 LinkValue * freeLinkValue(LinkValue *value, Inter *inter){
     LinkValue *return_value = NULL;
     freeBase(value, return_);
-    return_value = value->next;
-    if (value->last == NULL)
-        inter->link_base = value->next;
+    return_value = value->gc_next;
+    if (value->gc_last == NULL)
+        inter->link_base = value->gc_next;
     else
-        value->last->next = value->next;
+        value->gc_last->gc_next = value->gc_next;
 
-    if (value->next != NULL)
-        value->next->last = value->last;
+    if (value->gc_next != NULL)
+        value->gc_next->gc_last = value->gc_last;
 
     memFree(value);
     return_:
@@ -358,3 +354,49 @@ void printError(Result *result, Inter *inter, bool free) {
 inline bool isType(Value *value, enum ValueType type){
     return value->type == type;
 }
+
+FatherValue *makeFatherValue(LinkValue *value){
+    FatherValue *tmp;
+    tmp = memCalloc(1, sizeof(FatherValue));
+    tmp->value = value;
+    tmp->next = NULL;
+    return tmp;
+}
+
+FatherValue *copyFatherValue(FatherValue *value){
+    FatherValue *tmp;
+    if (value == NULL)
+        return NULL;
+    tmp = makeFatherValue(value->value);
+    return tmp;
+}
+
+FatherValue *freeFatherValue(FatherValue *value){
+    freeBase(value, error_);
+    FatherValue *next = value->next;
+    memFree(value);
+    return next;
+    error_: return NULL;
+}
+
+FatherValue *connectFatherValue(FatherValue *base, FatherValue *back){
+    FatherValue **tmp = &base;
+    for (tmp = &base; *tmp != NULL; tmp = &(*tmp)->next)
+        PASS;
+    *tmp = back;
+    return base;
+}
+
+FatherValue *connectSafeFatherValue(FatherValue *base, FatherValue *back){
+    FatherValue **last_node = &base;
+    if (back == NULL)
+        goto reutrn_;
+    for (PASS; *last_node != NULL; ){
+        if ((*last_node)->value->value == back->value->value)
+            *last_node = freeFatherValue(*last_node);
+        else
+            last_node = &(*last_node)->next;
+    }
+    *last_node = back;
+    reutrn_: return base;
+}

+ 100 - 50
src/var.c

@@ -1,25 +1,52 @@
 #include "__virtualmath.h"
 
-Var *makeVar(char *name, LinkValue *value, LinkValue *name_) {
+Var *makeVar(char *name, LinkValue *value, LinkValue *name_, Inter *inter) {
+    Var *list_tmp = inter->base_var;
     Var *tmp;
     tmp = memCalloc(1, sizeof(Var));
+    setGC(&tmp->gc_status);
     tmp->name = memStrcpy(name);
     tmp->value = value;
     tmp->name_ = name_;
     tmp->next = NULL;
+
+    tmp->gc_next = NULL;
+    tmp->gc_last = NULL;
+
+    if (list_tmp == NULL){
+        inter->base_var = tmp;
+        tmp->gc_last = NULL;
+        goto return_;
+    }
+
+    for (PASS; list_tmp->gc_next !=  NULL; list_tmp = list_tmp->gc_next)
+            PASS;
+    list_tmp->gc_next = tmp;
+    tmp->gc_last = list_tmp;
+
+    return_:
     return tmp;
 }
 
-Var *freeVar(Var *var, bool self){
+Var *freeVar(Var *var, Inter *inter) {
+    Var *return_value = NULL;
     freeBase(var, return_);
     memFree(var->name);
-    if (self){
-        Var *next_var = var->next;
-        memFree(var);
-        return next_var;
+
+    return_value = var->gc_next;
+    if (var->gc_last == NULL)
+        inter->base_var = var->gc_next;
+    else
+        var->gc_last->gc_next = var->gc_next;
+
+    if (var->gc_next != NULL) {  // TODO-szh 优化
+        Var *tmp = var->gc_last;
+        var->gc_next->gc_last = tmp;
     }
+
+    memFree(var);
     return_:
-    return var;
+    return return_value;
 }
 
 HashTable *makeHashTable(Inter *inter) {
@@ -28,19 +55,19 @@ HashTable *makeHashTable(Inter *inter) {
     tmp = memCalloc(1, sizeof(Value));
     tmp->hashtable = (Var **)calloc(MAX_SIZE, sizeof(Var *));
     setGC(&tmp->gc_status);
-    tmp->next = NULL;
-    tmp->last = NULL;
+    tmp->gc_next = NULL;
+    tmp->gc_last = NULL;
 
     if (list_tmp == NULL){
         inter->hash_base = tmp;
-        tmp->last = NULL;
+        tmp->gc_last = NULL;
         goto return_;
     }
 
-    for (PASS; list_tmp->next !=  NULL; list_tmp = list_tmp->next)
+    for (PASS; list_tmp->gc_next != NULL; list_tmp = list_tmp->gc_next)
         PASS;
-    list_tmp->next = tmp;
-    tmp->last = list_tmp;
+    list_tmp->gc_next = tmp;
+    tmp->gc_last = list_tmp;
 
     return_:
     return tmp;
@@ -49,22 +76,17 @@ HashTable *makeHashTable(Inter *inter) {
 HashTable *freeHashTable(HashTable *ht, Inter *inter) {
     HashTable *return_value = NULL;
     freeBase(ht, return_);
-    return_value = ht->next;
-    if (ht->last == NULL)
-        inter->hash_base = ht->next;
+    return_value = ht->gc_next;
+    if (ht->gc_last == NULL)
+        inter->hash_base = ht->gc_next;
     else
-        ht->last->next = ht->next;
+        ht->gc_last->gc_next = ht->gc_next;
 
-    if (ht->next != NULL) {
-        HashTable *tmp = ht->last;
-        ht->next->last = tmp;
+    if (ht->gc_next != NULL) {
+        HashTable *tmp = ht->gc_last;
+        ht->gc_next->gc_last = tmp;
     }
 
-    for (int i=0; i < MAX_SIZE; i++){
-        Var *tmp = ht->hashtable[i];
-        while (tmp != NULL)
-            tmp = freeVar(tmp, true);
-    }
     memFree(ht->hashtable);
     memFree(ht);
     return_:
@@ -102,22 +124,18 @@ HASH_INDEX time33(char *key){ // hash function
 }
 
 
-void addVar(char *name, LinkValue *value, LinkValue *name_, VarList *var_list) {
+void addVar(char *name, LinkValue *value, LinkValue *name_, INTER_FUNCTIONSIG_CORE) {
     HASH_INDEX index = time33(name);
-    Var *base = var_list->hashtable->hashtable[index];
-    if (base == NULL){
-        var_list->hashtable->hashtable[index] = makeVar(name, value, name_);
-        return;
-    }
-    for (PASS; true; base = base->next)
-        if (base->next != NULL) {
-            base->next = makeVar(name, value, name_);
+    Var **base = &var_list->hashtable->hashtable[index];
+    for (PASS; true; base = &(*base)->next) {
+        if (*base == NULL) {
+            *base = makeVar(name, value, name_, inter);
             break;
-        }
-        else if (eqString(base->name, name)) {
-            base->value = value;
+        } else if (eqString((*base)->name, name)) {
+            (*base)->value = value;
             break;
         }
+    }
 }
 
 LinkValue *findVar(char *name, VarList *var_list, bool del_var) {
@@ -126,17 +144,14 @@ LinkValue *findVar(char *name, VarList *var_list, bool del_var) {
     Var *base = var_list->hashtable->hashtable[index];
     Var *last = NULL;
 
-    if (base == NULL)
-        goto return_;
-
     for (PASS; base != NULL; last = base, base = base->next){
         if (eqString(base->name, name)){
             tmp = base->value;
-            if (del_var){
+            if (del_var){  // TODO-szh 使用指针优化
                 if (last == NULL)
-                    var_list->hashtable->hashtable[index] = freeVar(base, true);
+                    var_list->hashtable->hashtable[index] = base->next;
                 else
-                    last->next = freeVar(base, true);
+                    last->next = base->next;
             }
             goto return_;
         }
@@ -154,10 +169,10 @@ LinkValue *findFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, boo
     return tmp;
 }
 
-void addFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, LinkValue *value, LinkValue *name_) {
+void addFromVarList(char *name, LinkValue *name_, NUMBER_TYPE times, LinkValue *value, INTER_FUNCTIONSIG_CORE) {
     for (NUMBER_TYPE i=0; i < times && var_list->next != NULL; i++)
         var_list = var_list->next;
-    addVar(name, value, name_, var_list);
+    addVar(name, value, name_, CALL_INTER_FUNCTIONSIG_CORE(var_list));
 }
 
 VarList *pushVarList(VarList *base, Inter *inter){
@@ -180,11 +195,46 @@ VarList *copyVarListCore(VarList *base, Inter *inter){
 
 VarList *copyVarList(VarList *base, bool n_new, Inter *inter){
     VarList *new = NULL;
-    VarList *tmp = NULL;
-    new = tmp = copyVarListCore(base, inter);
-    for (PASS; base->next != NULL; tmp = tmp->next, base = base->next)
-        tmp->next = copyVarListCore(base->next, inter);
+    VarList **tmp = &new;
+    for (int i=0; base != NULL; tmp = &(*tmp)->next, base = base->next,i++)
+        *tmp = copyVarListCore(base, inter);
     if (n_new)
-        new = pushVarList(new, inter);
+        return pushVarList(new, inter);
     return new;
 }
+
+VarList *connectVarListBack(VarList *base, VarList *back){
+    VarList **tmp = NULL;
+    for (tmp = &base; *tmp != NULL; tmp = &(*tmp)->next)
+        PASS;
+    *tmp = back;
+    return base;
+}
+
+bool comparVarList(VarList *dest, VarList *src) {  // TODO-szh GC使用这个函数
+    for (PASS; src != NULL; src = src->next)
+        if (src->hashtable == dest->hashtable)
+            return true;
+    return false;
+}
+
+VarList *connectSafeVarListBack(VarList *base, VarList *back){
+    VarList **last_node = &base;
+    for (PASS; *last_node != NULL; ){
+        if ((*last_node)->hashtable == back->hashtable)
+            *last_node = freeVarList(*last_node, true);
+        else
+            last_node = &(*last_node)->next;
+    }
+    *last_node = back;
+    return base;
+}
+
+VarList *makeObjectVarList(FatherValue *value, Inter *inter){
+    VarList *tmp = makeVarList(inter);
+    for (PASS; value != NULL; value = value->next) {
+        VarList *new = copyVarList(value->value->value->object.var, false, inter);
+        tmp = connectVarListBack(tmp, new);
+    }
+    return tmp;
+}