Bläddra i källkod

feat & fix: 增加gc机制, 修改形式参数使用**语句的bug

形式参数使用**语句时, Argument没保存变量的name_value值
dict生成的时候需要传入外部var_list
加入了gc机制
应用gc结构体记录value的链接信息
SongZihuan 4 år sedan
förälder
incheckning
1c2dcd6d9c
21 ändrade filer med 815 tillägg och 209 borttagningar
  1. 2 1
      CMakeLists.txt
  2. 5 0
      file/file.c
  3. 153 0
      gc/gc.c
  4. 45 0
      gc/set.c
  5. 0 6
      include/__macro.h
  6. 4 0
      include/__virtualmath.h
  7. 44 0
      include/gc.h
  8. 2 1
      include/parameter.h
  9. 16 11
      include/value.h
  10. 3 3
      include/var.h
  11. 19 6
      src/__run.c
  12. 37 10
      src/inter.c
  13. 65 25
      src/parameter.c
  14. 19 4
      src/run.c
  15. 152 34
      src/runbranch.c
  16. 24 15
      src/runcall.c
  17. 10 4
      src/runfile.c
  18. 134 51
      src/runoperation.c
  19. 5 0
      src/statement.c
  20. 69 29
      src/value.c
  21. 7 9
      src/var.c

+ 2 - 1
CMakeLists.txt

@@ -10,8 +10,9 @@ AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/memory MEM_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/parser PASER_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src SRC_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/file FILE_LIST)
+AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/gc GC_LIST)
 
 MESSAGE("project dir is ${PROJECT_SOURCE_DIR}")
-ADD_LIBRARY(VirtualMathCore STATIC ${SRC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST})
+ADD_LIBRARY(VirtualMathCore STATIC ${SRC_LIST} ${GC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST})
 ADD_EXECUTABLE(VirtualMath main.c)
 TARGET_LINK_LIBRARIES(VirtualMath VirtualMathCore)

+ 5 - 0
file/file.c

@@ -1,5 +1,10 @@
 #include "__virtualmath.h"
 
+/**
+ *
+ * @param dir 文件地址
+ * @return 0-错误, 1-普通文件, 2-目录
+ */
 int checkFile(char *dir){
     struct stat my_stat;
     int status = stat(dir, &my_stat);

+ 153 - 0
gc/gc.c

@@ -0,0 +1,153 @@
+#include "__virtualmath.h"
+
+void gc_iterLinkValue(LinkValue *value){
+    if (value == NULL)
+        return;
+    gcAddLink(&value->gc_status);
+    if (!setIterAlready(&value->gc_status)){
+        gc_iterLinkValue(value->father);
+        gc_iterValue(value->value);
+    }
+}
+
+void gc_iterValue(Value *value){
+    if (value == NULL)
+        return;
+    gcAddLink(&value->gc_status);
+    if (setIterAlready(&value->gc_status))
+        return;
+    switch (value->type) {
+        case function:
+            gc_var_list(value->data.function.var);
+            break;
+        case list:
+            for (int i=0;i < value->data.list.size;i++)
+                gc_iterLinkValue(value->data.list.list[i]);
+            break;
+        case dict:
+            gc_iterHashTable(value->data.dict.dict);
+            break;
+        default:
+            break;
+    }
+}
+
+void gc_var_list(VarList *vl){
+    while (vl != NULL){
+        gc_iterHashTable(vl->hashtable);
+        vl = vl->next;
+    }
+}
+
+void gc_iterHashTable(HashTable *ht){
+    if (ht == NULL)
+        return;
+    gcAddLink(&ht->gc_status);
+    if (setIterAlready(&ht->gc_status))
+        return;
+    for (int i=0;i < MAX_SIZE;i++){
+        gc_iterVar(ht->hashtable[i]);
+    }
+}
+
+void gc_iterVar(Var *var){
+    while (var != NULL){
+        gc_iterLinkValue(var->name_);
+        gc_iterLinkValue(var->value);
+        var = var->next;
+    }
+}
+
+void gc_resetBase(Inter *inter){
+    Value *value_base = inter->base;
+    while (value_base != NULL){
+        resetGC(&value_base->gc_status);
+        value_base = value_base->next;
+    }
+
+    LinkValue *link_base = inter->link_base;
+    while (link_base != NULL){
+        resetGC(&link_base->gc_status);
+        link_base = link_base->next;
+    }
+
+    HashTable *hash_base = inter->hash_base;
+    while (hash_base != NULL){
+        resetGC(&hash_base->gc_status);
+        hash_base = hash_base->next;
+    }
+}
+
+void gc_checkBase(Inter *inter){
+    Value *value_base = inter->base;
+    while (value_base != NULL){
+        if (!needFree(&value_base->gc_status) && !value_base->gc_status.continue_)
+            gc_iterValue(value_base);
+        value_base = value_base->next;
+    }
+
+    LinkValue *link_base = inter->link_base;
+    while (link_base != NULL){
+        if (!needFree(&link_base->gc_status) && !link_base->gc_status.continue_)
+            gc_iterLinkValue(link_base);
+        link_base = link_base->next;
+    }
+
+    HashTable *hash_base = inter->hash_base;
+    while (hash_base != NULL){
+        if (!needFree(&hash_base->gc_status) && !hash_base->gc_status.continue_)
+            gc_iterHashTable(hash_base);
+        hash_base = hash_base->next;
+    }
+}
+
+void gc_freeBase(Inter *inter){
+#if START_GC
+    Value *value_base = inter->base;
+    while (value_base != NULL){
+        if (needFree(&value_base->gc_status))
+            value_base = freeValue(value_base, inter);
+        else
+            value_base = value_base->next;
+    }
+
+    LinkValue *link_base = inter->link_base;
+    while (link_base != NULL){
+        if (needFree(&link_base->gc_status))
+            link_base = freeLinkValue(link_base, inter);
+        else
+            link_base = link_base->next;
+    }
+
+    HashTable *hash_base = inter->hash_base;
+    while (hash_base != NULL){
+        if (needFree(&hash_base->gc_status))
+            hash_base = freeHashTable(hash_base, inter);
+        else
+            hash_base = hash_base->next;
+    }
+#endif
+}
+
+void runGC(Inter *inter, int var_list, int link_value, int value, ...){
+#if START_GC
+    gc_resetBase(inter);
+    va_list arg;
+    va_start(arg, value);
+    for (int i =0;i < var_list;i ++){
+        VarList *tmp = va_arg(arg, VarList *);
+        gc_var_list(tmp);
+    }
+    for (int i =0;i < link_value;i ++){
+        LinkValue *tmp = va_arg(arg, LinkValue *);
+        gc_iterLinkValue(tmp);
+    }
+    for (int i =0;i < value;i ++){
+        Value *tmp = va_arg(arg, Value *);
+        gc_iterValue(tmp);
+    }
+    va_end(arg);
+    gc_checkBase(inter);
+    gc_freeBase(inter);
+#endif
+}

+ 45 - 0
gc/set.c

@@ -0,0 +1,45 @@
+#include "__virtualmath.h"
+
+void resetGC(GCStatus *gcs){
+    gcs->continue_ = false;
+    gcs->link = 0;
+}
+
+void setGC(GCStatus *gcs){
+    resetGC(gcs);
+    gcs->tmp_link = 0;
+    gcs->statement_link = 0;
+}
+
+void gcAddTmp(GCStatus *gcs){
+    gcs->tmp_link ++;
+    gcs->continue_ = false;
+}
+
+void gcAddLink(GCStatus *gcs){
+    gcs->link ++;
+}
+
+void gcAddStatementLink(GCStatus *gcs){
+    gcs->statement_link ++;
+}
+
+void gcFreeStatementLink(GCStatus *gcs){
+    gcs->statement_link --;
+}
+
+void gcFreeTmpLink(GCStatus *gcs){
+    gcs->tmp_link --;
+}
+
+bool setIterAlready(GCStatus *gcs){
+    bool return_ = gcs->continue_;
+    gcs->continue_ = true;
+    return return_;
+}
+
+bool needFree(GCStatus *gcs){
+    if (gcs->statement_link == 0 && gcs->tmp_link == 0 && gcs->link == 0)
+        return true;
+    return false;
+}

+ 0 - 6
include/__macro.h

@@ -25,10 +25,4 @@ goto return_; \
 }while(0) \
 
 
-#define checkResult(check_result) do{ \
-if (is_error(check_result)){ \
-return check_result; \
-} \
-}while(0) \
-
 #endif //VIRTUALMATH___MACRO_H

+ 4 - 0
include/__virtualmath.h

@@ -3,6 +3,7 @@
 
 #include "__macro.h"
 #include "mem.h"
+#include "gc.h"
 #include "inter.h"
 #include "value.h"
 #include "var.h"
@@ -17,4 +18,7 @@
 #include "arguement.h"
 #include "file.h"
 
+/* DEBUG */
+void printLinkValueGC(char *tag, Inter *inter);
+void showLinkValue(struct LinkValue *base);
 #endif //VIRTUALMATH___VIRTUALMATH_H

+ 44 - 0
include/gc.h

@@ -0,0 +1,44 @@
+#ifndef VIRTUALMATH_GC_H
+#define VIRTUALMATH_GC_H
+
+#define START_GC true
+
+struct GCStatus{
+    long int tmp_link;  // tmp link的次数
+    long int statement_link;  // statement link的次数
+    long int link;  // 被直接link的次数
+    bool continue_;  // 是否迭代过
+};
+
+typedef struct GCStatus GCStatus;
+struct Inter;
+struct Value;
+struct LinkValue;
+struct HashTable;
+struct Var;
+struct VarList;
+
+
+void resetGC(GCStatus *gcs);
+void setGC(GCStatus *gcs);
+void gcAddTmp(GCStatus *gcs);
+void gcAddLink(GCStatus *gcs);
+void gcAddStatementLink(GCStatus *gcs);
+void gcFreeStatementLink(GCStatus *gcs);
+void gcFreeTmpLink(GCStatus *gcs);
+bool setIterAlready(GCStatus *gcs);
+bool needFree(GCStatus *gcs);
+
+void gc_freeBase(struct Inter *inter);
+void gc_checkBase(struct Inter *inter);
+void gc_resetBase(struct Inter *inter);
+
+void gc_iterValue(struct Value *value);
+void gc_iterLinkValue(struct LinkValue *value);
+void gc_iterHashTable(struct HashTable *ht);
+void gc_iterVar(struct Var *var);
+void gc_var_list(struct VarList *vl);
+
+void runGC(struct Inter *inter, int var_list, int link_value, int value, ...);
+
+#endif //VIRTUALMATH_GC_H

+ 2 - 1
include/parameter.h

@@ -71,7 +71,8 @@ Result iterParameter(Parameter *call, Argument **base_ad, INTER_FUNCTIONSIG_CORE
 Argument *getArgument(Parameter *call, Result *result, INTER_FUNCTIONSIG_CORE);
 
 Result defaultParameter(Parameter **function_ad, Inter *inter, VarList *var_list, int *num);
-Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *var_list, NUMBER_TYPE *num);
+Result
+argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *var_list, NUMBER_TYPE *num);
 Result parameterFromVar(Parameter **function_ad, VarList *function_var, struct Inter *inter, struct VarList *var_list,
                         NUMBER_TYPE *num, NUMBER_TYPE max, bool *status);
 Result argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE);

+ 16 - 11
include/value.h

@@ -7,13 +7,14 @@ struct VarList;
 struct Argument;
 
 struct Value{
+    GCStatus gc_status;
     enum ValueType{
         none=0,
         number=1,
-        string,
-        function,
-        list,
-        dict,
+        string=2,
+        function=3,
+        list=4,
+        dict=5,
     } type;
     union data{
         struct Number{
@@ -45,6 +46,7 @@ struct Value{
 };
 
 struct LinkValue{
+    GCStatus gc_status;
     struct Value *value;
     struct LinkValue *father;
     struct LinkValue *next;
@@ -81,25 +83,28 @@ typedef struct Result Result;
 typedef struct Error Error;
 
 Value *makeValue(Inter *inter);
-void freeValue(Value *value, Inter *inter);
+Value * freeValue(Value *value, Inter *inter);
 LinkValue *makeLinkValue(Value *value, LinkValue *linkValue,Inter *inter);
-void freeLinkValue(LinkValue *value, Inter *inter);
+LinkValue * freeLinkValue(LinkValue *value, 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 *makeListValue(struct Argument **arg_ad, Inter *inter, enum ListType type);
-Value *makeDictValue(struct Argument **arg_ad, bool new_hash, Inter *inter);
+Value *makeDictValue(struct Argument **arg_ad, bool new_hash, Result *result, Inter *inter, struct VarList *var_list);
 
 void setResultCore(Result *ru);
 void setResult(Result *ru, Inter *inter);
+void setResultBase(Result *ru, Inter *inter);
 void setResultError(Result *ru, Inter *inter, char *error_type, char *error_message, struct Statement *st, bool new);
-void setResultErrorCore(Result *ru, Inter *inter, char *error_type, char *error_message, long line, char *file, bool new);
-void setResultOperation(Result *ru, Inter *inter);
+void setResultOperationNone(Result *ru, Inter *inter);
+void setResultOperation(Result *ru, LinkValue *value, Inter *inter);
+void setResultOperationBase(Result *ru, LinkValue *value, Inter *inter);
+void freeResult(Result *ru);
 
 Error *makeError(char *type, char *message, long int line, char *file);
-void freeError(Error *base);
+void freeError(Result *base);
 Error *connectError(Error *new, Error *base);
-void printError(Error *error, Inter *inter, bool free);
+void printError(Result *result, Inter *inter, bool free);
 
 void printValue(Value *value, FILE *debug);
 void printLinkValue(LinkValue *value, char *first, char *last, FILE *debug);

+ 3 - 3
include/var.h

@@ -11,8 +11,8 @@ struct Var{
 };
 
 struct HashTable{
+    GCStatus gc_status;
     struct Var **hashtable;
-    int count;
     struct HashTable *next;
     struct HashTable *last;
 };
@@ -29,8 +29,8 @@ typedef struct VarList VarList;
 Var *makeVar(char *name, LinkValue *value, LinkValue *name_);
 Var *freeVar(Var *var, bool self);
 
-HashTable *makeHashTable(Inter *inter, bool supervision);
-void freeHashTable(HashTable *ht, Inter *inter, bool supervision);
+HashTable *makeHashTable(Inter *inter);
+HashTable * freeHashTable(HashTable *ht, Inter *inter);
 
 VarList *makeVarList(Inter *inter);
 VarList *freeVarList(VarList *vl, bool self);

+ 19 - 6
src/__run.c

@@ -3,6 +3,9 @@
 Result getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     Result result;
     Result times_tmp;
+    LinkValue *value;
+    setResultCore(&result);
+    setResultCore(&times_tmp);
 
     *name = setStrVarName(st->u.base_var.name, false, inter, var_list);
     *times = 0;
@@ -13,20 +16,27 @@ Result getBaseVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     if (operationSafeInterStatement(&times_tmp, CALL_INTER_FUNCTIONSIG(st->u.base_var.times, var_list)))
         return times_tmp;
     if (!isType(times_tmp.value->value, number)){
+        freeResult(&times_tmp);
         setResultError(&result, inter, "TypeException", "Don't get a number value", st, true);
         goto return_;
     }
     *times = (int)times_tmp.value->value->data.num.num;
+    freeResult(&times_tmp);
 
     not_times:
-    setResultOperation(&result, inter);
-    result.value->value = makeStringValue(st->u.base_var.name, inter);
-    return_: return result;
+    value = makeLinkValue(makeStringValue(st->u.base_var.name, inter), NULL, inter);
+    setResultOperation(&result, value, inter);
+
+    return_:
+    freeResult(&times_tmp);
+    return result;
 }
 
 Result getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     Result result;
     Result times_tmp;
+    setResultCore(&result);
+    setResultCore(&times_tmp);
 
     if (operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(st->u.base_svar.name, var_list)))
         return result;
@@ -39,18 +49,21 @@ Result getBaseSVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     if (operationSafeInterStatement(&times_tmp, CALL_INTER_FUNCTIONSIG(st->u.base_svar.times, var_list)))
         return times_tmp;
     if (!isType(times_tmp.value->value, number)){
+        freeResult(&times_tmp);
         setResultError(&result, inter, "TypeException", "Don't get a number value", st, true);
-        goto return_;
+        return result;
     }
     *times = (int)times_tmp.value->value->data.num.num;
 
     not_times:
-    result.type = operation_return;
-    return_: return result;
+    result.type = operation_return;  // 执行 operationSafeInterStatement 的时候已经初始化 result
+
+    return result;
 }
 
 Result getVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
     Result result;
+    setResultCore(&result);
     if (st->type == base_var)
         result = getBaseVarInfo(name, times, CALL_INTER_FUNCTIONSIG(st, var_list));
     else if (st->type == base_svar)

+ 37 - 10
src/inter.c

@@ -2,6 +2,7 @@
 
 Inter *runBaseInter(char *code_file, char *debug_dir, int *status) {
     Result global_result;
+    setResultCore(&global_result);
     return newInter(code_file, debug_dir, &global_result, status);
 }
 
@@ -15,7 +16,7 @@ Inter *newInter(char *code_file, char *debug_dir, Result *global_result, int *st
         return NULL;
     }
 
-    if (checkFile(debug_dir) != 1)
+    if (checkFile(debug_dir) != 2)
         debug_dir = NULL;
 
     global_inter = makeInter(code_file, debug_dir);
@@ -27,13 +28,9 @@ Inter *newInter(char *code_file, char *debug_dir, Result *global_result, int *st
         goto return_;
     }
 
-    struct Statement *tmp = copyStatement(global_inter->statement);
-    freeStatement(global_inter->statement);
-    global_inter->statement = tmp;
-
     *global_result = globalIterStatement(global_inter);
     if (global_result->type == error_return)
-        printError(global_result->error, global_inter, true);
+        printError(global_result, global_inter, true);
 
     return_:
     freeParserMessage(pm, true);
@@ -61,7 +58,8 @@ Inter *makeInter(char *code_file, char *debug) {
         tmp->data.error = stderr;
     }
 
-    makeValue(tmp);  // 注册None值
+    Value *none_value = makeValue(tmp);  // 注册None值
+    gcAddStatementLink(&none_value->gc_status);
     return tmp;
 }
 
@@ -75,6 +73,12 @@ void setBaseInterData(struct Inter *inter){
 
 void freeInter(Inter *inter, bool self){
     freeBase(inter, return_);
+
+    printLinkValueGC("\n\nprintLinkValueGC TAG : freeInter", inter);
+
+    freeStatement(inter->statement);  // Statement放在Value前面释放, 因为base_value的释放需要处理gc_status
+    freeVarList(inter->var_list, true);
+
     while (inter->base != NULL)
         freeValue(inter->base, inter);
 
@@ -82,10 +86,8 @@ void freeInter(Inter *inter, bool self){
         freeLinkValue(inter->link_base, inter);
 
     while (inter->hash_base != NULL)
-        freeHashTable(inter->hash_base, inter, true);
+        freeHashTable(inter->hash_base, inter);
 
-    freeStatement(inter->statement);
-    freeVarList(inter->var_list, true);
 
     memFree(inter->data.var_defualt);
     memFree(inter->data.var_num_prefix);
@@ -103,3 +105,28 @@ void freeInter(Inter *inter, bool self){
     return_:
     return;
 }
+
+/* ***********************DEBUG 专用函数*********************************** */
+
+void printLinkValueGC(char *tag, Inter *inter){
+    LinkValue *base = inter->link_base;
+    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);
+        printLinkValue(base, "value = ", "\n", stdout);
+        printf("-------------------------------------------\n");
+        base = base->next;
+    }
+    printf("printLinkValueGC 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);
+    printf("link           = %ld :: %p\n", base->gc_status.link, base);
+    printLinkValue(base, "value = ", "\n", stdout);
+    printf("--------------------------\n");
+}

+ 65 - 25
src/parameter.c

@@ -37,6 +37,7 @@ Argument *makeCharNameArgument(LinkValue *value, LinkValue *name_value, char *na
     tmp->name_type = name_char;
     tmp->data.value = value;
     tmp->data.name_ = memStrcpy(name, 0, false, false);
+    tmp->data.name_value = name_value;
     return tmp;
 }
 
@@ -88,7 +89,12 @@ Parameter *makeParameter(){
 Parameter *copyParameter(Parameter *base){
     if (base == NULL)
         return NULL;
-    Parameter *tmp = makeParameter(), *base_tmp = tmp;
+
+    Parameter *tmp = NULL;
+    Parameter *base_tmp = NULL;
+    tmp = makeParameter();
+    base_tmp = tmp;
+
     tmp->data.value = copyStatement(base->data.value);
     tmp->data.name = copyStatement(base->data.name);
     tmp->type = base->type;
@@ -205,6 +211,8 @@ Argument *dictToArgument(LinkValue *dict_value, INTER_FUNCTIONSIG_CORE){
 Result defaultParameter(Parameter **function_ad, Inter *inter, VarList *var_list, int *num) {
     Parameter *function = *function_ad;
     Result result;
+    setResultCore(&result);
+
     *num = 0;
     while (function != NULL && function->type == name_par){
         LinkValue *value = NULL;
@@ -212,6 +220,7 @@ Result defaultParameter(Parameter **function_ad, Inter *inter, VarList *var_list
             goto return_;
 
         value = result.value;
+        freeResult(&result);
         result = assCore(function->data.name, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         if (!run_continue(result))
             goto return_;
@@ -237,12 +246,15 @@ Result defaultParameter(Parameter **function_ad, Inter *inter, VarList *var_list
 Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *var_list, NUMBER_TYPE *num) {
     Argument *call = *call_ad;
     Result result;
+    setResultCore(&result);
+
     *num = 0;
     while (call != NULL && call->type == name_arg){
         if (call->name_type == name_char){
             addFromVarList(call->data.name_, var_list, 0, call->data.value, call->data.name_value);
             goto next;
         }
+        freeResult(&result);
         result = assCore(call->data.name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         if (!run_continue(result))
             goto return_;
@@ -251,8 +263,8 @@ Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *va
         (*num)++;
         call = call->next;
     }
-
     setResult(&result, inter);
+
     return_:
     *call_ad = call;
     return result;
@@ -269,52 +281,60 @@ Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *va
  */
 Result parameterFromVar(Parameter **function_ad, VarList *function_var, struct Inter *inter, struct VarList *var_list,
                         NUMBER_TYPE *num, NUMBER_TYPE max, bool *status) {
-    Result result;
     Parameter *function = *function_ad;
+    Result result;
+    setResultCore(&result);
+
     bool get;
     *num = 0;
     *status = false;
     while (function != NULL){
-        Result tmp;
-        Statement *name = function->type == name_par ? function->data.name : function->data.value;
-        char *str_name = NULL;
         int int_times;
+        char *str_name = NULL;
+        Statement *name = function->type == name_par ? function->data.name : function->data.value;
         LinkValue *value = NULL;
+
         get = true;
 
         if (function->type == kwargs_par){
-            value = makeLinkValue(makeDictValue(NULL, false, inter), NULL, inter);
+            value = makeLinkValue(makeDictValue(NULL, false, NULL, inter, var_list), NULL, inter);
             value->value->data.dict.dict = var_list->hashtable;
             value->value->data.dict.size = max - *num;
             *status = true;
             goto not_return;
         }
 
-        tmp = getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list));
-        if (!run_continue(tmp)) {
+        freeResult(&result);
+        result = getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list));
+        if (!run_continue(result)) {
             memFree(str_name);
-            return tmp;
+            return result;
         }
+        freeResult(&result);
         value = findFromVarList(str_name, var_list, int_times, true);
         memFree(str_name);
 
         if(value == NULL) {
             get = false;
-            if (function->type == name_par && !operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(function->data.value, var_list))) {
-                value = tmp.value;
+            if (function->type == name_par && !operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(function->data.value, var_list))) {
+                value = result.value;
                 goto not_return;
             }
-            setResultError(&tmp, inter, "ArgumentException", "Too less Argument", name, true);
+            setResultError(&result, inter, "ArgumentException", "Too less Argument", name, true);
             *function_ad = function;
-            return tmp;
+            return result;
         }
 
         not_return:
-        tmp = assCore(name, value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
-        if (!run_continue(tmp)) {
+        freeResult(&result);
+        result = assCore(name, value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
+        if (!run_continue(result)) {
             *function_ad = function;
-            return tmp;
+            return result;
         }
+        else
+            freeResult(&result);
+
         if (get)
             (*num)++;
         function = function->next;
@@ -338,6 +358,7 @@ Result argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList
     Argument *call = *call_ad;
     Parameter *function = *function_ad;
     Result result;
+    setResultCore(&result);
 
     while (call != NULL && function != NULL && (call->type == value_arg) && function->type != args_par){
         Statement *name = function->type == value_par ? function->data.value : function->data.name;
@@ -345,6 +366,7 @@ Result argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList
         if (!run_continue(result))
             goto return_;
 
+        freeResult(&result);
         call = call->next;
         function = function->next;
     }
@@ -364,12 +386,13 @@ Result argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList
  * @return
  */
 Result iterParameter(Parameter *call, Argument **base_ad, INTER_FUNCTIONSIG_CORE){
-    Result result;
     Argument *base = *base_ad;
+    Result result;
+    setResultCore(&result);
+
     while (call != NULL){
         if(operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(call->data.value, var_list)))
             goto return_;
-
         if (call->type == value_par)
             base = connectValueArgument(result.value, base);
         else if (call->type == name_par)
@@ -382,6 +405,7 @@ Result iterParameter(Parameter *call, Argument **base_ad, INTER_FUNCTIONSIG_CORE
             Argument *tmp_at = dictToArgument(result.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
             base = connectArgument(tmp_at, base);
         }
+        freeResult(&result);
         call = call->next;
     }
     setResult(&result, inter);
@@ -393,6 +417,7 @@ Result iterParameter(Parameter *call, Argument **base_ad, INTER_FUNCTIONSIG_CORE
 
 Argument *getArgument(Parameter *call, Result *result, INTER_FUNCTIONSIG_CORE){
     Argument *new_arg = NULL;
+    freeResult(result);
     *result = iterParameter(call, &new_arg, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     return new_arg;
 }
@@ -415,13 +440,15 @@ Argument *getArgument(Parameter *call, Result *result, INTER_FUNCTIONSIG_CORE){
  */
 Result setParameter(Parameter *call_base, Parameter *function_base, VarList *function_var, Statement *base,
                     struct Inter *inter, struct VarList *var_list) {
-    Result result;
     Argument *call;
+    Result result;
+    setResultCore(&result);
     call = getArgument(call_base, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     if (!run_continue(result)) {
         freeArgument(call, false);
         return result;
     }
+    freeResult(&result);
     result = setParameterCore(call, function_base, function_var, base, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     freeArgument(call, false);
     return result;
@@ -429,8 +456,9 @@ Result setParameter(Parameter *call_base, Parameter *function_base, VarList *fun
 
 Result setParameterCore(Argument *call, Parameter *function_base, VarList *function_var, Statement *base,
                         struct Inter *inter, struct VarList *var_list) {
+    Parameter *function = NULL, *tmp_function = NULL;  // 释放使用
     Result result;
-    Parameter *function = copyParameter(function_base), *tmp_function = function;  // 释放使用
+    setResultCore(&result);
     enum {
         match_status = 1,
         default_status = 2,
@@ -440,6 +468,9 @@ Result setParameterCore(Argument *call, Parameter *function_base, VarList *funct
         error = -1,
         finished = 0,
     } status = match_status;
+    function = copyParameter(function_base);
+    tmp_function = function;
+
     while (true){
         if (call == NULL && function == NULL)
             status = finished;
@@ -457,6 +488,7 @@ Result setParameterCore(Argument *call, Parameter *function_base, VarList *funct
         else if (call->type == name_arg)
             status = self_ass;
 
+        freeResult(&result);
         switch (status) {
             case match_status: {
                 result = argumentToParameter(&call, &function, function_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
@@ -470,7 +502,7 @@ Result setParameterCore(Argument *call, Parameter *function_base, VarList *funct
                 break;
             }
             case self_ass: {
-                VarList *tmp = makeVarList(inter);
+                VarList *tmp = pushVarList(var_list, inter);
                 NUMBER_TYPE set_num = 0, get_num = 0;
                 bool dict_status = false;
                 result = argumentToVar(&call, CALL_INTER_FUNCTIONSIG_CORE(tmp), &set_num);
@@ -479,28 +511,36 @@ Result setParameterCore(Argument *call, Parameter *function_base, VarList *funct
                     freeVarList(tmp, true);
                     goto return_;
                 }
+
+                freeResult(&result);
                 result = parameterFromVar(&function, function_var, CALL_INTER_FUNCTIONSIG_CORE(tmp), &get_num, set_num,
                                           &dict_status);
                 if (!run_continue(result)) {
-                    freeVarList(tmp, true);
+                    popVarList(tmp);
                     goto return_;
                 }
-                freeVarList(tmp, true);
+                popVarList(tmp);
 
                 if (!dict_status && set_num > get_num) {
+                    freeResult(&result);
                     goto error_;
                 }
                 break;
             }
             case mul_par: {
                 LinkValue *tmp = makeLinkValue(makeListValue(&call, inter, value_tuple), NULL, inter);
+                if (!run_continue(result))
+                    goto return_;
+                else
+                    freeResult(&result);
                 result = assCore(function->data.value, tmp, CALL_INTER_FUNCTIONSIG_CORE(function_var));
                 returnResult(result);
                 function = function->next;
                 break;
             }
             case space_kwargs:{
-                LinkValue *tmp = makeLinkValue(makeDictValue(NULL, true, inter), NULL, inter);
+                LinkValue *tmp = makeLinkValue(makeDictValue(NULL, true, &result, inter, var_list), NULL, inter);
+
                 result = assCore(function->data.value, tmp, CALL_INTER_FUNCTIONSIG_CORE(function_var));
                 returnResult(result);
                 function = function->next;

+ 19 - 4
src/run.c

@@ -9,6 +9,7 @@
  */
 Result runStatement(INTER_FUNCTIONSIG) {
     Result result;
+    setResultCore(&result);
     switch (st->type) {
         case base_value:
             result = getBaseValue(CALL_INTER_FUNCTIONSIG(st, var_list));
@@ -70,6 +71,8 @@ Result runStatement(INTER_FUNCTIONSIG) {
             setResult(&result, inter);
             break;
     }
+
+    runGC(inter, 1, 0, 0, var_list);
     return result;
 }
 
@@ -82,6 +85,7 @@ Result runStatement(INTER_FUNCTIONSIG) {
  */
 Result iterStatement(INTER_FUNCTIONSIG) {
     Result result;
+    setResultCore(&result);
     if (st == NULL){
         setResult(&result, inter);
         return result;
@@ -91,6 +95,7 @@ Result iterStatement(INTER_FUNCTIONSIG) {
     while (true) {
         base_st = st;
         while (base_st != NULL) {
+            freeResult(&result);
             result = runStatement(CALL_INTER_FUNCTIONSIG(base_st, var_list));
             if (!run_continue(result))
                 goto return_;
@@ -100,9 +105,10 @@ Result iterStatement(INTER_FUNCTIONSIG) {
         if (result.type != restart_return || result.times > 0)
             break;
     }
-
     if (result.type == not_return)
-        setResultOperation(&result, inter);
+        setResultOperationNone(&result, inter);
+
+    runGC(inter, 1, 0, 0, var_list);
     return_: return result;
 }
 
@@ -112,14 +118,16 @@ Result iterStatement(INTER_FUNCTIONSIG) {
  * @return
  */
 Result globalIterStatement(Inter *inter) {
-    Result result;
     Statement *base_st = NULL;
     VarList *var_list = NULL;
+    Result result;
+    setResultCore(&result);
 
     while (true) {
         base_st = inter->statement;
         var_list = inter->var_list;
         while (base_st != NULL) {
+            freeResult(&result);
             result = runStatement(CALL_INTER_FUNCTIONSIG(base_st, var_list));
             if (!run_continue(result))
                 break;
@@ -130,12 +138,15 @@ Result globalIterStatement(Inter *inter) {
     }
 
     if (result.type != error_return && result.type != function_return)
-        setResultOperation(&result, inter);
+        setResultOperationNone(&result, inter);
+
+    runGC(inter, 1, 0, 0, var_list);
     return result;
 }
 
 // 若需要中断执行, 则返回true
 bool operationSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
+    freeResult(result);
     *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
     if (run_continue_(result))
         return false;
@@ -143,6 +154,7 @@ bool operationSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
 }
 
 bool ifBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
+    freeResult(result);
     *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
     if (run_continue_(result)){
         return false;
@@ -158,6 +170,7 @@ bool ifBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
 }
 
 bool cycleBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
+    freeResult(result);
     *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
     if (run_continue_(result)){
         return false;
@@ -173,6 +186,7 @@ bool cycleBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
 }
 
 bool tryBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
+    freeResult(result);
     *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
     if (run_continue_(result)){
         return false;
@@ -183,6 +197,7 @@ bool tryBranchSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
 }
 
 bool functionSafeInterStatement(Result *result, INTER_FUNCTIONSIG){
+    freeResult(result);
     *result = iterStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
     if (result->type == error_return)
         return true;

+ 152 - 34
src/runbranch.c

@@ -2,6 +2,7 @@
 
 #define checkNumber(new_result) do{ \
 if (!isType(new_result.value->value, number)){ \
+freeResult(&new_result); \
 setResultError(&result, inter, "TypeException", "Don't get a number value", st, true); \
 return result; \
 }}while(0) /*该Macro只适用于控制分支*/
@@ -20,26 +21,49 @@ bool checkBool(Value *value){
 }
 
 Result ifBranch(INTER_FUNCTIONSIG) {
-    Result result;
-    Result else_tmp;
-    Result finally_tmp;
     StatementList *if_list = st->u.if_branch.if_list;
     bool set_result = true;
     bool is_rego = false;
 
+    Result result;
+    Result else_tmp;
+    Result finally_tmp;
+    setResultCore(&result);
+    setResultCore(&else_tmp);
+    setResultCore(&finally_tmp);
+
     var_list = pushVarList(var_list, inter);
     while (if_list != NULL){
         if (if_list->type == if_b){
-            Result tmp;
-            if (operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(if_list->condition, var_list))){
-                result = tmp;
+            Result condition_tmp;
+            Result var_tmp;
+            setResultCore(&condition_tmp);
+            setResultCore(&var_tmp);
+
+            if (operationSafeInterStatement(&condition_tmp, CALL_INTER_FUNCTIONSIG(if_list->condition, var_list))){
+                result = condition_tmp;
                 set_result = false;
                 goto not_else;
             }
-            if (if_list->var != NULL)
-                assCore(if_list->var, tmp.value, inter, var_list);
-            if (is_rego || checkBool(tmp.value->value)){
+
+            if (if_list->var != NULL) {
+                freeResult(&var_tmp);
+                var_tmp = assCore(if_list->var, condition_tmp.value, inter, var_list);
+                if (!run_continue(var_tmp)){
+                    freeResult(&condition_tmp);
+                    result = var_tmp;
+                    set_result = false;
+                    goto not_else;
+                }
+                freeResult(&var_tmp);  // 赋值的返回值被丢弃
+            }
+
+            bool condition = is_rego ? true : checkBool(condition_tmp.value->value);  // 若是rego则不执行checkbool的判断了
+            freeResult(&condition_tmp);
+            if (condition){
                 Result code_tmp;
+                setResultCore(&code_tmp);
+
                 is_rego = false;
                 if (ifBranchSafeInterStatement(&code_tmp, CALL_INTER_FUNCTIONSIG(if_list->code, var_list))){
                     result = code_tmp;
@@ -48,12 +72,17 @@ Result ifBranch(INTER_FUNCTIONSIG) {
                 }
                 if (code_tmp.type == rego_return)
                     is_rego = true;
-                else
+                else {
+                    freeResult(&code_tmp);
                     goto not_else;
+                }
+
+                freeResult(&code_tmp);
             }
         }
         else{
             Result code_tmp;
+            setResultCore(&code_tmp);
             if (ifBranchSafeInterStatement(&code_tmp, CALL_INTER_FUNCTIONSIG(if_list->code, var_list))){
                 result = code_tmp;
                 set_result = false;
@@ -61,6 +90,7 @@ Result ifBranch(INTER_FUNCTIONSIG) {
             }
             if (code_tmp.type == rego_return)
                 is_rego = true;
+            freeResult(&code_tmp);
         }
         if_list = if_list->next;
     }
@@ -68,14 +98,18 @@ Result ifBranch(INTER_FUNCTIONSIG) {
         set_result = false;
         result = else_tmp;
     }
-    not_else:
+    else
+        freeResult(&else_tmp);
 
+    not_else:
     if (st->u.if_branch.finally != NULL && ifBranchSafeInterStatement(&finally_tmp, CALL_INTER_FUNCTIONSIG(st->u.if_branch.finally, var_list))){
         if (!set_result)
-            freeError(result.error);
+            freeResult(&result);
         set_result = false;
         result = finally_tmp;
     }
+    else
+        freeResult(&finally_tmp);
 
     var_list = popVarList(var_list);
     if (set_result)
@@ -84,25 +118,47 @@ Result ifBranch(INTER_FUNCTIONSIG) {
 }
 
 Result whileBranch(INTER_FUNCTIONSIG) {
-    Result result;
-    Result else_tmp;
-    Result finally_tmp;
     StatementList *while_list = st->u.while_branch.while_list;
     bool set_result = true;
     bool is_break = false;
+    Result result;
+    Result else_tmp;
+    Result finally_tmp;
+    setResultCore(&result);
+    setResultCore(&else_tmp);
+    setResultCore(&finally_tmp);
 
     var_list = pushVarList(var_list, inter);
     while (!is_break){
-        Result tmp, do_tmp;
+        Result tmp;
+        Result var_tmp;
+        Result do_tmp;
+        setResultCore(&tmp);
+        setResultCore(&var_tmp);
+        setResultCore(&do_tmp);
+
         if (operationSafeInterStatement(&tmp, CALL_INTER_FUNCTIONSIG(while_list->condition, var_list))){
             result = tmp;
             set_result = false;
             goto not_else;
         }
-        if (while_list->var != NULL)
-            assCore(while_list->var, tmp.value, inter, var_list);
-        if (checkBool(tmp.value->value)){
+        if (while_list->var != NULL){
+            freeResult(&var_tmp);
+            var_tmp = assCore(while_list->var, tmp.value, inter, var_list);
+            if (!run_continue(var_tmp)){
+                freeResult(&tmp);
+                result = var_tmp;
+                set_result = false;
+                goto not_else;
+            }
+            freeResult(&var_tmp);  // 赋值的返回值被丢弃
+        }
+
+        bool condition = checkBool(tmp.value->value);
+        freeResult(&tmp);
+        if (condition){
             Result code_tmp;
+            setResultCore(&code_tmp);
             if (cycleBranchSafeInterStatement(&code_tmp, CALL_INTER_FUNCTIONSIG(while_list->code, var_list))){
                 result = code_tmp;
                 set_result = false;
@@ -112,32 +168,40 @@ Result whileBranch(INTER_FUNCTIONSIG) {
                 is_break = true;
             if (code_tmp.type == continue_return)
                 PASS;
+            freeResult(&code_tmp);
         }
-        else{
+        else
             break;
-        }
+
         if (st->u.while_branch.after == NULL)
             goto not_after_do;
+
         if (cycleBranchSafeInterStatement(&do_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.after, var_list))){
             result = do_tmp;
             set_result = false;
             goto not_else;
         }
-        if (do_tmp.type == break_return)
-            goto not_else;  // 直接跳转到not_else
+        if (do_tmp.type == break_return) {
+            freeResult(&do_tmp);
+            goto not_else;
+        }
         if (do_tmp.type == continue_return)
             PASS;
+
+        freeResult(&do_tmp);
         not_after_do: PASS;
     }
     if (!is_break && st->u.while_branch.else_list != NULL && cycleBranchSafeInterStatement(&else_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.else_list, var_list))){
         set_result = false;
         result = else_tmp;
     }
-    not_else:
+    else
+        freeResult(&else_tmp);
 
+    not_else:
     if (st->u.while_branch.finally != NULL && cycleBranchSafeInterStatement(&finally_tmp, CALL_INTER_FUNCTIONSIG(st->u.while_branch.finally, var_list))){
         if (!set_result)
-            freeError(result.error);
+            freeResult(&result);
         set_result = false;
         result = finally_tmp;
     }
@@ -149,30 +213,51 @@ Result whileBranch(INTER_FUNCTIONSIG) {
 }
 
 Result tryBranch(INTER_FUNCTIONSIG) {
+    bool set_result = true;
+    StatementList *except_list = st->u.try_branch.except_list;
     Result result;
     Result try_result;
+    Result var_tmp;
     Result except_result;
     Result else_tmp;
     Result finally_tmp;
-    StatementList *except_list = st->u.try_branch.except_list;
-    bool set_result = true;
+    setResultCore(&result);
+    setResultCore(&except_result);
+    setResultCore(&try_result);
+    setResultCore(&var_tmp);
+    setResultCore(&else_tmp);
+    setResultCore(&finally_tmp);
 
     var_list = pushVarList(var_list, inter);
-    if (!tryBranchSafeInterStatement(&try_result, CALL_INTER_FUNCTIONSIG(st->u.try_branch.try, var_list)))
+    if (!tryBranchSafeInterStatement(&try_result, CALL_INTER_FUNCTIONSIG(st->u.try_branch.try, var_list))){
+        freeResult(&try_result);
         goto not_except;
+    }
+
     if (except_list == NULL) {
         result = try_result;
         set_result = false;
         goto not_else;
     }
-    if (except_list->var != NULL)
-        assCore(except_list->var, try_result.value, inter, var_list);
-    freeError(try_result.error);
-
+    if (except_list->var != NULL){
+        freeResult(&var_tmp);
+        var_tmp = assCore(except_list->var, try_result.value, inter, var_list);
+        if (!run_continue(var_tmp)){
+            freeResult(&try_result);
+            result = var_tmp;
+            set_result = false;
+            goto not_else;
+        }
+        freeResult(&var_tmp);  // 赋值的返回值被丢弃
+    }
     if (tryBranchSafeInterStatement(&except_result, CALL_INTER_FUNCTIONSIG(except_list->code, var_list))){
         result = except_result;
         set_result = false;
     }
+    else
+        freeResult(&except_result);
+
+    freeResult(&try_result);
     goto not_else;
 
     not_except:
@@ -180,11 +265,13 @@ Result tryBranch(INTER_FUNCTIONSIG) {
         set_result = false;
         result = else_tmp;
     }
+    else
+        freeResult(&else_tmp);
 
     not_else:
     if (st->u.try_branch.finally != NULL && tryBranchSafeInterStatement(&finally_tmp, CALL_INTER_FUNCTIONSIG(st->u.try_branch.finally, var_list))){
         if (!set_result)
-            freeError(result.error);
+            freeResult(&result);
         set_result = false;
         result = finally_tmp;
     }
@@ -198,13 +285,20 @@ Result tryBranch(INTER_FUNCTIONSIG) {
 Result breakCycle(INTER_FUNCTIONSIG){
     Result result;
     Result times;
+    setResultCore(&result);
+    setResultCore(&times);
+
     int times_int = 0;
     if (st->u.break_cycle.times == NULL)
         goto not_times;
+
     if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.break_cycle.times, var_list)))
         return times;
+
     checkNumber(times);
     times_int = (int)times.value->value->data.num.num;
+    freeResult(&times);
+
     not_times:
     setResult(&result, inter);
     if (times_int >= 0) {
@@ -217,13 +311,19 @@ Result breakCycle(INTER_FUNCTIONSIG){
 Result continueCycle(INTER_FUNCTIONSIG){
     Result result;
     Result times;
+    setResultCore(&result);
+    setResultCore(&times);
+
     int times_int = 0;
     if (st->u.continue_cycle.times == NULL)
         goto not_times;
     if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.continue_cycle.times, var_list)))
         return times;
+
     checkNumber(times);
     times_int = (int)times.value->value->data.num.num;
+    freeResult(&times);
+
     not_times:
     setResult(&result, inter);
     if (times_int >= 0) {
@@ -236,13 +336,19 @@ Result continueCycle(INTER_FUNCTIONSIG){
 Result regoIf(INTER_FUNCTIONSIG){
     Result result;
     Result times;
+    setResultCore(&result);
+    setResultCore(&times);
+
     int times_int = 0;
     if (st->u.rego_if.times == NULL)
         goto not_times;
     if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.rego_if.times, var_list)))
         return times;
+
     checkNumber(times);
     times_int = (int)times.value->value->data.num.num;
+    freeResult(&times);
+
     not_times:
     setResult(&result, inter);
     if (times_int >= 0) {
@@ -255,13 +361,19 @@ Result regoIf(INTER_FUNCTIONSIG){
 Result restartCode(INTER_FUNCTIONSIG){
     Result result;
     Result times;
+    setResultCore(&result);
+    setResultCore(&times);
+
     int times_int = 0;
     if (st->u.restart.times == NULL)
         goto not_times;
     if (operationSafeInterStatement(&times, CALL_INTER_FUNCTIONSIG(st->u.restart.times, var_list)))
         return times;
+
     checkNumber(times);
     times_int = (int)times.value->value->data.num.num;
+    freeResult(&times);
+
     not_times:
     setResult(&result, inter);
     if (times_int >= 0) {
@@ -273,10 +385,13 @@ Result restartCode(INTER_FUNCTIONSIG){
 
 Result returnCode(INTER_FUNCTIONSIG){
     Result result;
+    setResultCore(&result);
+
     if (st->u.return_code.value == NULL) {
         setResult(&result, inter);
         goto set_result;
     }
+
     if (operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(st->u.return_code.value, var_list)))
         return result;
 
@@ -287,15 +402,18 @@ Result returnCode(INTER_FUNCTIONSIG){
 
 Result raiseCode(INTER_FUNCTIONSIG){
     Result result;
+    setResultCore(&result);
+
     if (st->u.raise_code.value == NULL) {
         setResult(&result, inter);
         goto set_result;
     }
+
     if (operationSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(st->u.raise_code.value, var_list)))
         return result;
 
     set_result:
     result.type = error_return;
-    setResultError(&result, inter, "RaiseException", "Exception was raise by user", st, true);
+    setResultError(&result, inter, "RaiseException", "Exception was raise by user", st, false);
     return result;
 }

+ 24 - 15
src/runcall.c

@@ -2,38 +2,47 @@
 
 Result setFunction(INTER_FUNCTIONSIG) {
     Result result;
-    Result tmp;
-    setResultOperation(&tmp, inter);
+    LinkValue *tmp = makeLinkValue(NULL, NULL, inter);
+    setResultCore(&result);
 
-    tmp.value->value = makeFunctionValue(st->u.set_function.function, st->u.set_function.parameter, var_list, inter);
-    result = assCore(st->u.set_function.name, tmp.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    tmp->value = makeFunctionValue(st->u.set_function.function, st->u.set_function.parameter, var_list, inter);
+    result = assCore(st->u.set_function.name, tmp, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    if (!run_continue(result))
+        return result;
+    setResult(&result, inter);
     return result;
 }
 
 Result callFunction(INTER_FUNCTIONSIG) {
     Result result;
-    Result call_function;
-
-    if (operationSafeInterStatement(&call_function, CALL_INTER_FUNCTIONSIG(st->u.call_function.function, var_list)))
-        return call_function;
+    Result function_value;
+    Result set_tmp;
+    setResultCore(&result);
+    setResultCore(&function_value);
+    setResultCore(&set_tmp);
 
-    if (call_function.value->value->type != function){
+    if (operationSafeInterStatement(&function_value, CALL_INTER_FUNCTIONSIG(st->u.call_function.function, var_list)))
+        return function_value;
+    if (function_value.value->value->type != function){
+        freeResult(&function_value);
         setResultError(&result, inter, "TypeException", "Object is not callable", st, true);
         result.type = error_return;
         goto return_;
     }
-    VarList *function_var = call_function.value->value->data.function.var;
-    Result set_tmp;
-    set_tmp = setParameter(st->u.call_function.parameter, call_function.value->value->data.function.pt, function_var,
+    VarList *function_var = function_value.value->value->data.function.var;
+    set_tmp = setParameter(st->u.call_function.parameter, function_value.value->value->data.function.pt, function_var,
                            st, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     if (set_tmp.type == error_return)
         return set_tmp;
+    else
+        freeResult(&set_tmp);
     function_var = pushVarList(function_var, inter);
-    functionSafeInterStatement(&result,
-                               CALL_INTER_FUNCTIONSIG(call_function.value->value->data.function.function, function_var));
-    setResultError(&result, inter, NULL, NULL, st, false);
+    functionSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(function_value.value->value->data.function.function, function_var));
     popVarList(function_var);
 
+    freeResult(&function_value);
+    setResultError(&result, inter, NULL, NULL, st, false);  // 自带检查
+
     return_:
     return result;
 }

+ 10 - 4
src/runfile.c

@@ -1,25 +1,31 @@
 #include "__run.h"
 
 Result includeFile(INTER_FUNCTIONSIG) {
+    Statement *new_st = NULL;
+    ParserMessage *pm = NULL;
+    char *file_dir = NULL;
     Result result;
     Result file;
-    char *file_dir = NULL;
-    ParserMessage *pm = NULL;
-    Statement *new_st = NULL;
+    setResultCore(&result);
+    setResultCore(&file);
 
     if (operationSafeInterStatement(&file, CALL_INTER_FUNCTIONSIG(st->u.include_file.file, var_list)))
         return file;
 
     if (!isType(file.value->value, string)){
+        freeResult(&file);
         setResultError(&result, inter, "TypeException", "Don't get a string value", st, true);
         goto return_;
     }
 
     file_dir = file.value->value->data.str.str;
-    if (checkFile(file_dir)){
+    freeResult(&file);
+
+    if (checkFile(file_dir) != 1){
         setResultError(&result, inter, "IncludeFileException", "File is not readable", st, true);
         goto return_;
     }
+
     new_st = makeStatement(0, file_dir);
     pm = makeParserMessage(file_dir, NULL);
     parserCommandList(pm, inter, true, new_st);

+ 134 - 51
src/runoperation.c

@@ -4,20 +4,30 @@
  */
 
 #define getresult(base, var, inter) do{ \
-if (operationSafeInterStatement(&var, CALL_INTER_FUNCTIONSIG(st->u.operation. base, var_list))){ return var; } \
+if (operationSafeInterStatement(&var, CALL_INTER_FUNCTIONSIG(st->u.operation.base, var_list))){ return var; }} while (0)
+
+#define getresultFree(base, var, other, inter) do{ \
+if (operationSafeInterStatement(&var, CALL_INTER_FUNCTIONSIG(st->u.operation.base, var_list))){ \
+freeResult(&other); \
+return var; \
+} \
 }while(0)
 #define viewtype_core(a, b, valuetype_a, valuetype_a_b) a .value->value->type == valuetype_a && b.value->value->type == valuetype_a_b
 #define viewtype(a, b, valuetype) viewtype_core(a, b, valuetype, valuetype)
 #define operationValue(a, b, type, symbol) a.value->value->data.type symbol b.value->value->data.type
 #define valueToResult(result, result_value, type, inter) result.value->value = make##type##Value(result_value, inter)
-#define noneOperation(left, right, result) do{ \
-if (left.value->value->type == none){ \
+#define noneOperation(left, right, result, st) \
+else if (left.value->value->type == none){ \
 result = right; \
+gcAddTmp(&result.value->gc_status); \
 } \
 else if (right.value->value->type == none){ \
 result = left; \
+gcAddTmp(&result.value->gc_status); \
 } \
-} while(0)
+else{ \
+setResultError(&result, inter, "TypeException", "Get Not Support Value", st, true); \
+}PASS
 
 Result addOperation(INTER_FUNCTIONSIG);
 Result subOperation(INTER_FUNCTIONSIG);
@@ -34,6 +44,7 @@ Result assOperation(INTER_FUNCTIONSIG);
  */
 Result operationStatement(INTER_FUNCTIONSIG) {
     Result result;
+    setResultCore(&result);
     switch (st->u.operation.OperationType) {
         case OPT_ADD:
             result = addOperation(CALL_INTER_FUNCTIONSIG(st, var_list));
@@ -61,18 +72,24 @@ Result addOperation(INTER_FUNCTIONSIG) {
     Result left;
     Result right;
     Result result;
-    setResultOperation(&result, inter);
+    setResultCore(&left);
+    setResultCore(&right);
+    setResultCore(&result);
+
     getresult(left, left, inter);
-    getresult(right, right, inter);
-    if (viewtype(left, right, number)){
+    getresultFree(right, right, left, inter);
+
+    setResultOperationBase(&result, makeLinkValue(NULL, NULL, inter), inter);
+    if (viewtype(left, right, number))
         valueToResult(result, (operationValue(left, right, num.num, +)), Number, inter);
-    }
     else if(viewtype(left, right, string)){
         char *new_string = memStrcat(left.value->value->data.str.str, right.value->value->data.str.str, false);
         valueToResult(result, new_string, String, inter);
         memFree(new_string);
     }
-    noneOperation(left, right, result);
+    noneOperation(left, right, result, st);
+    freeResult(&left);
+    freeResult(&right);
     return result;
 }
 
@@ -80,13 +97,20 @@ Result subOperation(INTER_FUNCTIONSIG) {
     Result left;
     Result right;
     Result result;
-    setResultOperation(&result, inter);
+    setResultCore(&left);
+    setResultCore(&right);
+    setResultCore(&result);
+
     getresult(left, left, inter);
-    getresult(right, right, inter);
-    if (viewtype(left, right, number)){
+    getresultFree(right, right, left, inter);
+
+    setResultOperationBase(&result, makeLinkValue(NULL, NULL, inter), inter);
+    if (viewtype(left, right, number))
         valueToResult(result, (operationValue(left, right, num.num, -)), Number, inter);
-    }
-    noneOperation(left, right, result);
+
+    noneOperation(left, right, result, st);
+    freeResult(&left);
+    freeResult(&right);
     return result;
 }
 
@@ -94,12 +118,16 @@ Result mulOperation(INTER_FUNCTIONSIG) {
     Result left;
     Result right;
     Result result;
-    setResultOperation(&result, inter);
+    setResultCore(&left);
+    setResultCore(&right);
+    setResultCore(&result);
+
     getresult(left, left, inter);
-    getresult(right, right, inter);
-    if (viewtype(left, right, number)){
+    getresultFree(right, right, left, inter);
+
+    setResultOperationBase(&result, makeLinkValue(NULL, NULL, inter), inter);
+    if (viewtype(left, right, number))
         valueToResult(result, (operationValue(left, right, num.num, *)), Number, inter);
-    }
     else if(viewtype_core(left, right, number, string)){
         Result tmp = left;
         left = right;
@@ -114,7 +142,10 @@ Result mulOperation(INTER_FUNCTIONSIG) {
             memFree(new_string);
         }
     }
-    noneOperation(left, right, result);
+    noneOperation(left, right, result, st);
+
+    freeResult(&left);
+    freeResult(&right);
     return result;
 }
 
@@ -122,125 +153,177 @@ Result divOperation(INTER_FUNCTIONSIG) {
     Result left;
     Result right;
     Result result;
-    setResultOperation(&result, inter);
+    setResultCore(&left);
+    setResultCore(&right);
+    setResultCore(&result);
+
     getresult(left, left, inter);
-    getresult(right, right, inter);
-    if (viewtype(left, right, number)){
+    getresultFree(right, right, left, inter);
+
+    setResultOperationBase(&result, makeLinkValue(NULL, NULL, inter), inter);
+    if (viewtype(left, right, number))
         valueToResult(result, (operationValue(left, right, num.num, /)), Number, inter);
-    }
-    noneOperation(left, right, result);
+    noneOperation(left, right, result, st);
+    freeResult(&left);
+    freeResult(&right);
+    printf("result.tmp = %ld, %p\n", result.value->gc_status.tmp_link, result.value);
     return result;
 }
 
 Result assOperation(INTER_FUNCTIONSIG) {
     Result result;
     Result times;
+    setResultCore(&result);
+    setResultCore(&times);
+
     getresult(right, result, inter);
     times = assCore(st->u.operation.left, result.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-    checkResult(times);
+    if (is_error(times)) {
+        freeResult(&result);
+        return times;
+    }
+    freeResult(&times);
     return result;
 }
 
 Result assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_CORE){
     Result result;
-    setResultOperation(&result, inter);
+    Result tmp_result;
+    setResultCore(&result);
+    setResultCore(&tmp_result);
+
     int int_times;
     if (name->type == base_list && name->u.base_list.type == value_tuple){
-        Result tmp_result;
+        Parameter *pt = NULL;
+        Argument *call = NULL;
         Statement *tmp_st = makeStatement(name->line, name->code_file);
+
         tmp_st->type = base_value;
         tmp_st->u.base_value.value = value;
-        Parameter *pt = makeArgsParameter(tmp_st);
-        Argument *call = getArgument(pt, &tmp_result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+
+        pt = makeArgsParameter(tmp_st);
+        call = getArgument(pt, &tmp_result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         if (!run_continue(tmp_result)) {
             freeArgument(call, false);
             freeParameter(pt, true);
             return tmp_result;
         }
+
+        freeResult(&tmp_result);
         tmp_result = setParameterCore(call, name->u.base_list.list, var_list, name, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         if (!run_continue(tmp_result))
             result = tmp_result;
         else{
             Argument *tmp = call;
-            result.value->value = makeListValue(&tmp, inter, value_tuple);
+            LinkValue *new_value = makeLinkValue(makeListValue(&tmp, inter, value_tuple), NULL, inter);
+            freeResult(&tmp_result);
+            setResultOperation(&result, new_value, inter);
         }
         freeArgument(call, false);
         freeParameter(pt, true);
     }
     else{
-        Result tmp;
         char *str_name = NULL;
 
-        tmp = getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list));
-        if (!run_continue(tmp)) {
+        tmp_result = getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list));
+        if (!run_continue(tmp_result)) {
             memFree(str_name);
-            return tmp;
+            return tmp_result;
         }
-        addFromVarList(str_name, var_list, int_times, value, tmp.value);
+        addFromVarList(str_name, var_list, int_times, value, tmp_result.value);
         memFree(str_name);
+        freeResult(&tmp_result);
+
+        setResultCore(&result);
+        result.type = operation_return;
         result.value = value;
+        gcAddTmp(&result.value->gc_status);
     }
     return result;
 }
 
 Result getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
+    int int_times = 0;
+    char *name = NULL;
     Result result;
     Result tmp;
-    char *name = NULL;
-    int int_times;
-    setResultOperation(&result, inter);
+    setResultCore(&result);
+    setResultCore(&tmp);
+
     tmp = var_info(&name, &int_times, CALL_INTER_FUNCTIONSIG(st, var_list));
     if (!run_continue(tmp)) {
         memFree(name);
         return tmp;
     }
+    freeResult(&tmp);
+
+    setResultCore(&result);
+    result.type = operation_return;
     result.value = findFromVarList(name, var_list, int_times, false);
     memFree(name);
+
     if (result.value == NULL){
         char *info = memStrcat("Name Not Found: ", st->u.base_var.name, false);
         setResultError(&result, inter, "NameException", info, st, true);
         memFree(info);
     }
+    else
+        gcAddTmp(&result.value->gc_status);
+
     return result;
 }
 
 Result getBaseValue(INTER_FUNCTIONSIG) {
     Result result;
-    setResult(&result, inter);
+    setResultCore(&result);
     result.value = st->u.base_value.value;
     result.type = operation_return;
+    gcAddTmp(&result.value->gc_status);
     return result;
 }
 
 Result getList(INTER_FUNCTIONSIG) {
+    Argument *at = NULL;
+    Argument *at_tmp = NULL;
     Result result;
-    Argument *at = getArgument(st->u.base_list.list, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-    Argument *at_tmp = at;
+    setResultCore(&result);
+
+    at = getArgument(st->u.base_list.list, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    at_tmp = at;
     if (!run_continue(result)){
         freeArgument(at_tmp, true);
         return result;
     }
 
-    int type = st->u.base_list.type == value_tuple ? value_tuple : value_list;
-    Value *value = makeListValue(&at, inter, type);
-    setResultOperation(&result ,inter);
-    result.value->value = value;
+    LinkValue *value = makeLinkValue(makeListValue(&at, inter, st->u.base_list.type), NULL, inter);
+    setResultOperation(&result, value, inter);
     freeArgument(at_tmp, false);
+
     return result;
 }
 
 Result getDict(INTER_FUNCTIONSIG) {
+    Argument *at = NULL;
+    Argument *at_tmp = NULL;
     Result result;
-    Argument *at = getArgument(st->u.base_dict.dict, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-    Argument *at_tmp = at;
+    setResultCore(&result);
+
+    at = getArgument(st->u.base_dict.dict, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    at_tmp = at;
     if (!run_continue(result)){
-        freeArgument(at_tmp, true);
+        freeArgument(at_tmp, false);
         return result;
     }
 
-    Value *value = makeDictValue(&at, true, inter);
-    setResultOperation(&result ,inter);
-    result.value->value = value;
+    Value *tmp_value = makeDictValue(&at, true, &result, inter, var_list);
+    if (!run_continue(result)) {
+        freeArgument(at_tmp, false);
+        return result;
+    }
+    freeResult(&result);
+    LinkValue *value = makeLinkValue(tmp_value, NULL, inter);
+    setResultOperation(&result, value, inter);
     freeArgument(at_tmp, false);
+
     return result;
 }

+ 5 - 0
src/statement.c

@@ -39,6 +39,7 @@ Statement *makeBaseValueStatement(LinkValue *value, long int line, char *file) {
     Statement *tmp = makeStatement(line, file);
     tmp->type = base_value;
     tmp->u.base_value.value = value;
+    gcAddStatementLink(&value->gc_status);
     return tmp;
 }
 
@@ -195,6 +196,9 @@ void freeStatement(Statement *st){
                 freeStatement(st->u.operation.right);
                 freeStatement(st->u.operation.left);
                 break;
+            case base_value:
+                gcFreeStatementLink(&st->u.base_value.value->gc_status);
+                break;
             case base_var:
                 memFree(st->u.base_var.name);
                 freeStatement(st->u.base_var.times);
@@ -303,6 +307,7 @@ Statement *copyStatementCore(Statement *st){
     switch (st->type) {
         case base_value:
             new->u.base_value.value = st->u.base_value.value;
+            gcAddStatementLink(&new->u.base_value.value->gc_status);
             break;
         case operation:
             new->u.operation.OperationType = st->u.operation.OperationType;

+ 69 - 29
src/value.c

@@ -5,6 +5,7 @@ Value *makeValue(Inter *inter) {
     Value *tmp, *list_tmp = inter->base;
     tmp = memCalloc(1, sizeof(Value));
     tmp->type = none;
+    setGC(&tmp->gc_status);
     tmp->next = NULL;
     if (list_tmp == NULL){
         inter->base = tmp;
@@ -66,24 +67,29 @@ Value *makeListValue(Argument **arg_ad, Inter *inter, enum ListType type) {
     return tmp;
 }
 
-Value *makeDictValue(Argument **arg_ad, bool new_hash, Inter *inter) {
+Value *makeDictValue(Argument **arg_ad, bool new_hash, Result *result, Inter *inter, VarList *var_list) {
     Value *tmp;
     tmp = makeValue(inter);
     tmp->data.dict.size = 0;
     tmp->type = dict;
     if (new_hash) {
-        VarList *hash = makeVarList(inter);
+        VarList *hash = pushVarList(var_list, inter);
+        gcAddTmp(&tmp->gc_status);
         tmp->data.dict.dict = hash->hashtable;
-        argumentToVar(arg_ad, inter, hash, &tmp->data.dict.size);
-        freeVarList(hash, true);
+        freeResult(result);
+        *result = argumentToVar(arg_ad, inter, hash, &tmp->data.dict.size);
+        popVarList(hash);
+        gcFreeTmpLink(&tmp->gc_status);
     }
     else
         tmp->data.dict.dict = NULL;
     return tmp;
 }
 
-void freeValue(Value *value, Inter *inter){
+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;
     else
@@ -112,13 +118,14 @@ void freeValue(Value *value, Inter *inter){
     }
     memFree(value);
     return_:
-    return;
+    return return_value;
 }
 
 LinkValue *makeLinkValue(Value *value, LinkValue *linkValue, Inter *inter){
     LinkValue *tmp;
     LinkValue *list_tmp = inter->link_base;
     tmp = memCalloc(1, sizeof(Value));
+    setGC(&tmp->gc_status);
     tmp->father = linkValue;
     tmp->value = value;
     if (list_tmp == NULL){
@@ -137,8 +144,10 @@ LinkValue *makeLinkValue(Value *value, LinkValue *linkValue, Inter *inter){
     return tmp;
 }
 
-void freeLinkValue(LinkValue *value, 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;
     else
@@ -149,7 +158,7 @@ void freeLinkValue(LinkValue *value, Inter *inter){
 
     memFree(value);
     return_:
-    return;
+    return return_value;
 }
 
 void setResultCore(Result *ru) {
@@ -160,17 +169,22 @@ void setResultCore(Result *ru) {
 }
 
 void setResult(Result *ru, Inter *inter) {
+    freeResult(ru);
+    setResultBase(ru, inter);
+}
+
+void setResultBase(Result *ru, Inter *inter) {
     setResultCore(ru);
     ru->value = makeLinkValue(inter->base, NULL, inter);
+    gcAddTmp(&ru->value->gc_status);
 }
 
 void setResultError(Result *ru, Inter *inter, char *error_type, char *error_message, Statement *st, bool new) {
     if (!new && ru->type != error_return)
         return;
     if (new) {
-        setResultCore(ru);
+        setResult(ru, inter);
         ru->type = error_return;
-        ru->value = makeLinkValue(inter->base, NULL, inter);
     }
     else{
         error_type = NULL;
@@ -179,10 +193,31 @@ void setResultError(Result *ru, Inter *inter, char *error_type, char *error_mess
     ru->error = connectError(makeError(error_type, error_message, st->line, st->code_file), ru->error);
 }
 
-void setResultOperation(Result *ru, Inter *inter) {
+void setResultOperationNone(Result *ru, Inter *inter) {
+    setResult(ru, inter);
+    ru->type = operation_return;
+}
+
+void setResultOperation(Result *ru, LinkValue *value, Inter *inter) {
+    freeResult(ru);
+    setResultOperationBase(ru, value, inter);
+}
+
+void setResultOperationBase(Result *ru, LinkValue *value, Inter *inter) {
     setResultCore(ru);
+    ru->value = value;
+    if (value != NULL)
+        gcAddTmp(&ru->value->gc_status);
     ru->type = operation_return;
-    ru->value = makeLinkValue(inter->base, NULL, inter);
+}
+
+void freeResult(Result *ru){
+    if (ru->error != NULL)
+        freeError(ru);
+    if (ru->value != NULL) {
+        gcFreeTmpLink(&ru->value->gc_status);
+        ru->value = NULL;
+    }
 }
 
 void printValue(Value *value, FILE *debug){
@@ -235,12 +270,15 @@ void printValue(Value *value, FILE *debug){
 }
 
 void printLinkValue(LinkValue *value, char *first, char *last, FILE *debug){
+    if (value == NULL)
+        return;
     writeLog(debug, INFO, "%s", first);
     if (value->father != NULL) {
         printLinkValue(value->father, "", "", debug);
         writeLog(debug, INFO, " . ", NULL);
     }
-    printValue(value->value, debug);
+    if (value->value != NULL)
+        printValue(value->value, debug);
     writeLog(debug, INFO, "%s", last);
 }
 
@@ -259,30 +297,32 @@ Error *connectError(Error *new, Error *base){
     return new;
 }
 
-void freeError(Error *base){
-    while (base != NULL){
-        memFree(base->messgae);
-        memFree(base->type);
-        memFree(base->file);
-        Error *tmp = base->next;
-        memFree(base);
-        base = tmp;
+void freeError(Result *base){
+    Error *error = base->error;
+    while (error != NULL){
+        Error *tmp = error->next;
+        memFree(error->messgae);
+        memFree(error->type);
+        memFree(error->file);
+        memFree(error);
+        error = tmp;
     }
+    base->error = NULL;
 }
 
-void printError(Error *error, Inter *inter, bool free) {
-    Error *base = error;
-    while (error != NULL){
-        if (error->next != NULL){
-            writeLog(inter->data.error, ERROR, "Error Backtracking:  On Line: %ld In file: %s Error ID: %p\n", error->line, error->file, error);
+void printError(Result *result, Inter *inter, bool free) {
+    Error *base = result->error;
+    while (base != NULL){
+        if (base->next != NULL){
+            writeLog(inter->data.error, ERROR, "Error Backtracking:  On Line: %ld In file: %s Error ID: %p\n", base->line, base->file, base);
         }
         else{
-            writeLog(inter->data.error, ERROR, "%s\n%s\nOn Line: %ld\nIn File: %s\nError ID: %p\n", error->type, error->messgae, error->line, error->file, error);
+            writeLog(inter->data.error, ERROR, "%s\n%s\nOn Line: %ld\nIn File: %s\nError ID: %p\n", base->type, base->messgae, base->line, base->file, base);
         }
-        error = error->next;
+        base = base->next;
     }
     if (free)
-        freeError(base);
+        freeError(result);
 }
 
 inline bool isType(Value *value, enum ValueType type){

+ 7 - 9
src/var.c

@@ -22,15 +22,14 @@ Var *freeVar(Var *var, bool self){
     return var;
 }
 
-HashTable *makeHashTable(Inter *inter, bool supervision) {
+HashTable *makeHashTable(Inter *inter) {
     HashTable *list_tmp = inter->hash_base;
     HashTable *tmp;
     tmp = memCalloc(1, sizeof(Value));
     tmp->hashtable = (Var **)calloc(MAX_SIZE, sizeof(Var *));
+    setGC(&tmp->gc_status);
     tmp->next = NULL;
     tmp->last = NULL;
-    if (!supervision)
-        goto return_;
 
     if (list_tmp == NULL){
         inter->hash_base = tmp;
@@ -47,10 +46,10 @@ HashTable *makeHashTable(Inter *inter, bool supervision) {
     return tmp;
 }
 
-void freeHashTable(HashTable *ht, Inter *inter, bool supervision) {
+HashTable *freeHashTable(HashTable *ht, Inter *inter) {
+    HashTable *return_value = NULL;
     freeBase(ht, return_);
-    if (!supervision)
-        goto not_supervision;
+    return_value = ht->next;
     if (ht->last == NULL)
         inter->hash_base = ht->next;
     else
@@ -61,7 +60,6 @@ void freeHashTable(HashTable *ht, Inter *inter, bool supervision) {
         ht->next->last = tmp;
     }
 
-    not_supervision:
     for (int i=0; i < MAX_SIZE; i++){
         Var *tmp = ht->hashtable[i];
         while (tmp != NULL)
@@ -70,13 +68,13 @@ void freeHashTable(HashTable *ht, Inter *inter, bool supervision) {
     memFree(ht->hashtable);
     memFree(ht);
     return_:
-    return;
+    return return_value;
 }
 
 VarList *makeVarList(Inter *inter) {
     VarList *tmp = calloc(1, sizeof(VarList));
     tmp->next = NULL;
-    tmp->hashtable = makeHashTable(inter, true);
+    tmp->hashtable = makeHashTable(inter);
     return tmp;
 }