Pārlūkot izejas kodu

fix & feat: 修正gc机制的双向链表拼接错误, 加入字典

在Value、LinkValue和HashTable中使用双向链表管理内存,
其中链表拼接语句使用了:
list_tmp->next = tmp;
tmp->last = list_tmp->next;
该类型的语句, 已经修改为如下:
list_tmp->next = tmp;
tmp->last = list_tmp;
----------------------------------------------------
允许通过大括号{}创建字典
允许定义空字典和空列表
SongZihuan 4 gadi atpakaļ
vecāks
revīzija
f971faa7c4
15 mainītis faili ar 193 papildinājumiem un 76 dzēšanām
  1. 5 0
      include/parameter.h
  2. 1 0
      include/run.h
  3. 5 0
      include/statement.h
  4. 8 2
      include/value.h
  5. 10 1
      include/var.h
  6. 2 2
      main.c
  7. 3 3
      parser/__grammar.c
  8. 37 15
      parser/grammar.c
  9. 7 7
      src/inter.c
  10. 17 1
      src/operation.c
  11. 12 12
      src/parameter.c
  12. 3 0
      src/run.c
  13. 10 0
      src/statement.c
  14. 54 19
      src/value.c
  15. 19 14
      src/var.c

+ 5 - 0
include/parameter.h

@@ -53,4 +53,9 @@ Result setParameterCore(Argument *call, Parameter *function_base, VarList *funct
 Result setParameter(Parameter *call, Parameter *function, VarList *function_var, INTER_FUNCTIONSIG_CORE);
 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 parameterFromVar(Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE, NUMBER_TYPE *num);
+Result argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE);
 #endif //VIRTUALMATH_PARAMETER_H

+ 1 - 0
include/run.h

@@ -17,6 +17,7 @@ Result callFunction(INTER_FUNCTIONSIG);
 Result getVar(INTER_FUNCTIONSIG, VarInfo var_info);
 Result getBaseValue(INTER_FUNCTIONSIG);
 Result getList(INTER_FUNCTIONSIG);
+Result getDict(INTER_FUNCTIONSIG);
 Result ifBranch(INTER_FUNCTIONSIG);
 Result whileBranch(INTER_FUNCTIONSIG);
 Result tryBranch(INTER_FUNCTIONSIG);

+ 5 - 0
include/statement.h

@@ -7,6 +7,7 @@ struct Statement{
         start = 1,
         base_value,
         base_list,
+        base_dict,
         base_var,
         base_svar,
         operation,
@@ -40,6 +41,9 @@ struct Statement{
             enum ListType type;
             struct Parameter *list;
         } base_list;
+        struct {
+            struct Parameter *dict;
+        } base_dict;
         struct operation{
             enum OperationType{
                 ADD = 1,
@@ -140,6 +144,7 @@ Statement *makeOperationStatement(int type);
 Statement *makeBaseValueStatement(LinkValue *value);
 Statement *makeBaseVarStatement(char *name, Statement *times);
 Statement *makeBaseSVarStatement(Statement *name, Statement *times);
+Statement *makeBaseDictStatement(Parameter *pt);
 Statement *makeTupleStatement(struct Parameter *pt, enum ListType type);
 Statement *makeFunctionStatement(Statement *name, Statement *function, struct Parameter *pt);
 Statement *makeCallStatement(Statement *function, struct Parameter *pt);

+ 8 - 2
include/value.h

@@ -11,6 +11,7 @@ struct Value{
         string,
         function,
         list,
+        dict,
     } type;
     union data{
         struct Number{
@@ -19,12 +20,12 @@ struct Value{
         struct String{
             char *str;
         } str;
-        struct {
+        struct Function{
             struct Statement *function;
             struct VarList *var;
             struct Parameter *pt;
         } function;
-        struct {
+        struct List{
             enum ListType{
                 value_tuple,
                 value_list,
@@ -32,6 +33,10 @@ struct Value{
             struct LinkValue **list;
             long int size;
         } list;
+        struct Dict{
+            struct HashTable *dict;
+            NUMBER_TYPE size;
+        } dict;
     }data;
     struct Value *next;
     struct Value *last;
@@ -71,6 +76,7 @@ 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, Inter *inter);
 
 void setResult(Result *ru, bool link, Inter *inter);
 void setResultError(Result *ru, Inter *inter);

+ 10 - 1
include/var.h

@@ -27,11 +27,20 @@ typedef struct Var Var;
 typedef struct HashTable HashTable;
 typedef struct VarList VarList;
 
+Var *makeVar(char *name, LinkValue *value);
+Var *freeVar(Var *var, bool self);
+
+HashTable *makeHashTable(Inter *inter, bool supervision);
+void freeHashTable(HashTable *ht, Inter *inter, bool supervision);
+
 VarList *makeVarList(Inter *inter);
 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, VarList *var_list);
 void addFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, LinkValue *value);
-void freeHashTable(HashTable *ht, Inter *inter);
 
 VarList *pushVarList(VarList *base, Inter *inter);
 VarList *popVarList(VarList *base);

+ 2 - 2
main.c

@@ -117,9 +117,9 @@ void freeArgs(){
     memFree(args.file);
 }
 
-/*
+/**
+ *  TODO-szh 函数形式参数复制
  *  TODO-szh 字典
- *  TODO-szh SuperVar
  *  TODO-szh 运行错误的内存释放检查
  *  TODO-szh syntax错误的内存释放检查
  */

+ 3 - 3
parser/__grammar.c

@@ -8,7 +8,7 @@ inline void twoOperation(ParserMessage *pm, Inter *inter, PasersFunction callBac
         Token *right_token = NULL;
         struct Statement *st = NULL;
 
-        readBackToken(pm);
+
         if (readBackToken(pm) != self_type){
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
             if (!callChildStatement(CALLPASERSSIGNATURE, callBack, type, &st, NULL))
@@ -51,7 +51,7 @@ inline void twoOperation(ParserMessage *pm, Inter *inter, PasersFunction callBac
         is_right_ = is_right;  // 第一次is_right不生效
     }
     return_:
-    return;
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: return\n", self_name);
 }
 
 inline void tailOperation(PASERSSIGNATURE, PasersFunction callBack, TailFunction tailFunction, int type, int self_type,
@@ -89,7 +89,7 @@ inline void tailOperation(PASERSSIGNATURE, PasersFunction callBack, TailFunction
         goto return_;
     }
     return_:
-    return;
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: return\n", self_name);
 }
 
 /**

+ 37 - 15
parser/grammar.c

@@ -745,13 +745,19 @@ void parserCallBack(PASERSSIGNATURE){
 }
 
 int getOperation(PASERSSIGNATURE, int right_type, Statement **st, char *name){
+    *st = NULL;
+    if (readBackToken(pm) == right_type)  // TODO-szh checkToken_
+        goto return_;
+
     if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, st, NULL))
         return 0;
 
-    if (readBackToken(pm) != right_type){
+    if (readBackToken(pm) != right_type){  // TODO-szh checkToken_
         freeStatement(*st);
         return -1;
     }
+
+    return_:
     delToken(pm);
     return 1;
 }
@@ -766,26 +772,23 @@ void parserBaseValue(PASERSSIGNATURE){
     Token *value_token = NULL;
     Statement *st = NULL;
     token_type = readBackToken(pm);
-    if(MATHER_NUMBER == token_type){
+    value_token = popAheadToken(pm);
+    if (MATHER_NUMBER == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get number\n", NULL);
-        value_token = popAheadToken(pm);
         char *stop;
         st = makeBaseValueStatement(makeLinkValue(makeNumberValue(strtol(value_token->data.str, &stop, 10), inter), NULL, inter));
     }
-    else if(MATHER_STRING == token_type){
+    else if (MATHER_STRING == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get string\n", NULL);
-        value_token = popAheadToken(pm);
         st = makeBaseValueStatement(makeLinkValue(makeStringValue(value_token->data.str, inter), NULL, inter));
     }
-    else if(MATHER_VAR == token_type){
+    else if (MATHER_VAR == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get var\n", NULL);
-        value_token= popAheadToken(pm);
         st = makeBaseVarStatement(value_token->data.str, NULL);
     }
-    else if(MATHER_SVAR == token_type){
+    else if (MATHER_SVAR == token_type){
         Statement *svar_st;
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get super var\n", NULL);
-        value_token = popAheadToken(pm);
         if (!callChildStatement(CALLPASERSSIGNATURE, parserBaseValue, BASEVALUE, &svar_st, NULL)){
             freeToken(value_token, true, true);
             syntaxError(pm, syntax_error, 1, "Don't get super var after $");
@@ -793,16 +796,16 @@ void parserBaseValue(PASERSSIGNATURE){
         }
         st = makeBaseSVarStatement(svar_st, NULL);
     }
-    else if(MATHER_LB == token_type){
+    else if (MATHER_LB == token_type){
         int tmp;
         Statement *tmp_st = NULL;
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation\n", NULL);
-        value_token = popAheadToken(pm);
 
         tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RB, &tmp_st, "base value");
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation success\n", NULL);
         if (tmp == 0){
             freeToken(value_token, true, true);
-            syntaxError(pm, syntax_error, 1, "Don't get operation from list/var");
+            syntaxError(pm, syntax_error, 1, "Don't get operation from Base Value");
             goto return_;
         }
         else if(tmp == -1){
@@ -810,6 +813,7 @@ void parserBaseValue(PASERSSIGNATURE){
             syntaxError(pm, syntax_error, 1, "Don't get ] from list/var");
             goto return_;
         }
+
         if (MATHER_VAR == readBackToken(pm)){
             Token *var_token;
             var_token = popAheadToken(pm);
@@ -817,7 +821,9 @@ void parserBaseValue(PASERSSIGNATURE){
             freeToken(var_token, true, false);
         }
         else{
-            if (tmp_st->type == base_list && tmp_st->u.base_list.type == value_tuple){
+            if (tmp_st == NULL)
+                st = makeTupleStatement(NULL, value_list);
+            else if (tmp_st->type == base_list && tmp_st->u.base_list.type == value_tuple){
                 tmp_st->u.base_list.type = value_list;
                 st = tmp_st;
             }
@@ -825,9 +831,8 @@ void parserBaseValue(PASERSSIGNATURE){
                 st = makeTupleStatement(makeOnlyValueParameter(tmp_st), value_list);
         }
     }
-    else if(MATHER_LP == token_type){
+    else if (MATHER_LP == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get operation\n", NULL);
-        value_token = popAheadToken(pm);
         int tmp = getOperation(CALLPASERSSIGNATURE, MATHER_RP, &st, "base value");
         if (tmp == 0){
             freeToken(value_token, true, true);
@@ -840,8 +845,25 @@ void parserBaseValue(PASERSSIGNATURE){
             goto return_;
         }
     }
+    else if (MATHER_LC == token_type){
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "base value: get dict\n", NULL);
+        Parameter *pt;
+        if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, true, MATHER_COMMA, MATHER_COLON)) {
+            freeToken(value_token, true, true);
+            syntaxError(pm, syntax_error, 1, "Don't get a dict parameter");
+            goto return_;
+        }
+        if (!checkToken_(pm, MATHER_RC)) {
+            freeToken(value_token, true, true);
+            freeParameter(pt, true);
+            syntaxError(pm, syntax_error, 1, "Don't get a } after dict");
+            goto return_;
+        }
+        st = makeBaseDictStatement(pt);
+    }
     else{
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: else\n", NULL);
+        backToken_(pm, value_token);
         goto return_;
     }
     freeToken(value_token, true, false);

+ 7 - 7
src/inter.c

@@ -20,15 +20,15 @@ Inter *makeInter(char *debug){
 
 void freeInter(Inter *inter, bool self){
     freeBase(inter, return_);
-    while (inter->base != NULL){
+    while (inter->base != NULL)
         freeValue(inter->base, inter);
-    }
-    while (inter->link_base != NULL){
+
+    while (inter->link_base != NULL)
         freeLinkValue(inter->link_base, inter);
-    }
-    while (inter->hash_base != NULL){
-        freeHashTable(inter->hash_base, inter);
-    }
+
+    while (inter->hash_base != NULL)
+        freeHashTable(inter->hash_base, inter, true);
+
     freeStatement(inter->statement);
     freeVarList(inter->var_list, true);
     memFree(inter->log_dir);

+ 17 - 1
src/operation.c

@@ -224,6 +224,22 @@ Result getList(INTER_FUNCTIONSIG) {
     Value *value = makeListValue(&at, inter, type);
     setResultOperation(&result ,inter);
     result.value->value = value;
-    freeArgument(at_tmp, true);
+    freeArgument(at_tmp, false);
+    return result;
+}
+
+Result getDict(INTER_FUNCTIONSIG) {
+    Result result;
+    Argument *at = getArgument(st->u.base_dict.dict, &result, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+    Argument *at_tmp = at;
+    if (!run_continue(result)){
+        freeArgument(at_tmp, true);
+        return result;
+    }
+
+    Value *value = makeDictValue(&at, inter);
+    setResultOperation(&result ,inter);
+    result.value->value = value;
+    freeArgument(at_tmp, false);
     return result;
 }

+ 12 - 12
src/parameter.c

@@ -170,7 +170,7 @@ Result defaultParameter(Parameter **function_ad, Inter *inter, VarList *var_list
         }
 
         tmp_ass = assCore(function->data.name, tmp.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-        if (tmp_ass.type == error_return) {
+        if (!run_continue(tmp_ass)) {
             *function_ad = function;
             return tmp_ass;
         }
@@ -191,13 +191,13 @@ Result defaultParameter(Parameter **function_ad, Inter *inter, VarList *var_list
  * @param num
  * @return
  */
-Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *var_list, int *num) {
+Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *var_list, NUMBER_TYPE *num) {
     Argument *call = *call_ad;
     Result result;
     while (call != NULL && call->type == name_arg){
         Result tmp_ass;
         tmp_ass = assCore(call->data.name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-        if (tmp_ass.type == error_return) {
+        if (!run_continue(tmp_ass)) {
             *call_ad = call;
             return tmp_ass;
         }
@@ -219,7 +219,7 @@ Result argumentToVar(Argument **call_ad, struct Inter *inter, struct VarList *va
  * @param num
  * @return
  */
-Result parameterFromVar(Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE, int *num){
+Result parameterFromVar(Parameter **function_ad, VarList *function_var, INTER_FUNCTIONSIG_CORE, NUMBER_TYPE *num){
     Parameter *function = *function_ad;
     Result result;
     setResultOperation(&result, inter);
@@ -253,7 +253,7 @@ Result parameterFromVar(Parameter **function_ad, VarList *function_var, INTER_FU
         not_return:
 
         tmp = assCore(name, value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
-        if (tmp.type == error_return) {
+        if (!run_continue(tmp)) {
             *function_ad = function;
             return tmp;
         }
@@ -284,7 +284,7 @@ Result argumentToParameter(Argument **call_ad, Parameter **function_ad, VarList
         Result tmp_ass;
         Statement *name = function->type == value_par ? function->data.value : function->data.name;
         tmp_ass = assCore(name, call->data.value, CALL_INTER_FUNCTIONSIG_CORE(function_var));
-        if (tmp_ass.type == error_return) {
+        if (!run_continue(tmp_ass)) {
             *call_ad = call;
             *function_ad = function;
             return tmp_ass;
@@ -339,13 +339,13 @@ Argument *getArgument(Parameter *call, Result *result, INTER_FUNCTIONSIG_CORE){
 
 /**
  * 参数表:
- |实参 \ 形参| name | value | arg | null |
+ |实参 \ 形参| name | value | arg | kwarg | null |
  ----------------------------------------
- |name     | p_3  |  p_3  | p_4 | error |
- |value    | p_1  |  p_1  | p_4 | error |
- |null     | p_2  | error | p_4 | okay  |
+ |name     | p_3  |  p_3  | p_4 |  p_5! | error |
+ |value    | p_1  |  p_1  | p_4 | error | error |
+ |null     | p_2  | error | p_4 |  p_5  | okay  |
  ----------------------------------------
- * 注解: @p_1 match_status; @p_2 default_status; @p_3 self_ass; @p_4 mul_par
+ * 注解: @p_1 match_status; @p_2 default_status; @p_3 self_ass; @p_4 mul_par; @p_5 pow_par
  * @param call
  * @param function
  * @param function_var
@@ -405,7 +405,7 @@ Result setParameterCore(Argument *call, Parameter *function_base, VarList *funct
             }
             case self_ass: {
                 VarList *tmp = makeVarList(inter);
-                int set_num = 0, get_num = 0;
+                NUMBER_TYPE set_num = 0, get_num = 0;
                 result = argumentToVar(&call, CALL_INTER_FUNCTIONSIG_CORE(tmp), &set_num);
                 returnResult(result);
                 result = parameterFromVar(&function, function_var, CALL_INTER_FUNCTIONSIG_CORE(tmp), &get_num);

+ 3 - 0
src/run.c

@@ -22,6 +22,9 @@ Result runStatement(INTER_FUNCTIONSIG) {
         case base_list:
             result = getList(CALL_INTER_FUNCTIONSIG(st, var_list));
             break;
+        case base_dict:
+            result = getDict(CALL_INTER_FUNCTIONSIG(st, var_list));
+            break;
         case operation:
             result = operationStatement(CALL_INTER_FUNCTIONSIG(st, var_list));
             printLinkValue(result.value, "operation result = ", "\n", inter->debug);

+ 10 - 0
src/statement.c

@@ -55,6 +55,13 @@ Statement *makeBaseSVarStatement(Statement *name, Statement *times){
     return tmp;
 }
 
+Statement *makeBaseDictStatement(Parameter *pt){
+    Statement *tmp = makeStatement();
+    tmp->type = base_dict;
+    tmp->u.base_dict.dict = pt;
+    return tmp;
+}
+
 Statement *makeOperationStatement(int type){
     Statement *tmp = makeStatement();
     tmp->type = operation;
@@ -199,6 +206,9 @@ void freeStatement(Statement *st){
             case base_list:
                 freeParameter(st->u.base_list.list, true);
                 break;
+            case base_dict:
+                freeParameter(st->u.base_dict.dict, true);
+                break;
             case if_branch:
                 freeStatementList(st->u.if_branch.if_list);
                 freeStatement(st->u.if_branch.finally);

+ 54 - 19
src/value.c

@@ -15,7 +15,7 @@ Value *makeValue(Inter *inter) {
         list_tmp = list_tmp->next;
     }
     list_tmp->next = tmp;
-    tmp->last = list_tmp->next;
+    tmp->last = list_tmp;
 
     return_:
     return tmp;
@@ -65,17 +65,28 @@ Value *makeListValue(Argument **arg_ad, Inter *inter, enum ListType type) {
     return tmp;
 }
 
+Value *makeDictValue(Argument **arg_ad, Inter *inter){
+    Value *tmp;
+    VarList *hash = makeVarList(inter);
+    tmp = makeValue(inter);
+    tmp->data.dict.size = 0;
+    tmp->type = dict;
+    tmp->data.dict.dict = hash->hashtable;
+    argumentToVar(arg_ad, inter, hash, &tmp->data.dict.size);
+    freeVarList(hash, true);
+    return tmp;
+}
+
 void freeValue(Value *value, Inter *inter){
     freeBase(value, return_);
-    if (value->last == NULL){
+    if (value->last == NULL)
         inter->base = value->next;
-    }
-    else{
+    else
         value->last->next = value->next;
-    }
-    if (value->next != NULL){
+
+    if (value->next != NULL)
         value->next->last = value->last;
-    }
+
     switch (value->type) {
         case string:
             memFree(value->data.str.str);
@@ -90,6 +101,9 @@ void freeValue(Value *value, Inter *inter){
         case list:
             memFree(value->data.list.list);
             break;
+        case dict:
+            freeHashTable(value->data.dict.dict, inter, true);
+            break;
         default:
             break;
     }
@@ -110,11 +124,11 @@ LinkValue *makeLinkValue(Value *value, LinkValue *linkValue, Inter *inter){
         goto return_;
     }
 
-    while (list_tmp->next !=  NULL){
+    while (list_tmp->next !=  NULL)
         list_tmp = list_tmp->next;
-    }
+
     list_tmp->next = tmp;
-    tmp->last = list_tmp->next;
+    tmp->last = list_tmp;
 
     return_:
     return tmp;
@@ -122,15 +136,14 @@ LinkValue *makeLinkValue(Value *value, LinkValue *linkValue, Inter *inter){
 
 void freeLinkValue(LinkValue *value, Inter *inter){
     freeBase(value, return_);
-    if (value->last == NULL){
+    if (value->last == NULL)
         inter->link_base = value->next;
-    }
-    else{
+    else
         value->last->next = value->next;
-    }
-    if (value->next != NULL){
+
+    if (value->next != NULL)
         value->next->last = value->last;
-    }
+
     memFree(value);
     return_:
     return;
@@ -155,21 +168,43 @@ void setResultOperation(Result *ru, Inter *inter) {
 void printValue(Value *value, FILE *debug){
     switch (value->type){
         case number:
-            writeLog(debug, INFO, "<%"NUMBER_FORMAT">", value->data.num.num);
+            writeLog(debug, INFO, "%"NUMBER_FORMAT"", value->data.num.num);
             break;
         case string:
-            writeLog(debug, INFO, "<'%s'>", value->data.str.str);
+            writeLog(debug, INFO, "'%s'", value->data.str.str);
             break;
         case function:
             writeLog(debug, INFO, "function on <%lx>", (unsigned long )value);
             break;
         case list:
-            writeLog(debug, INFO, "list on %lx, size = %d, [", (unsigned long )value, (int)value->data.list.size);
+            writeLog(debug, INFO, "list on <%lx> size = %d [", (unsigned long )value, (int)value->data.list.size);
             for (int i=0;i < value->data.list.size;i++){
+                if (i > 0)
+                    writeLog(debug, INFO, ", ", NULL);
+
                 printLinkValue(value->data.list.list[i], "", "", debug);
             }
             writeLog(debug, INFO, "]", NULL);
             break;
+        case dict: {
+            bool print_comma = false;
+            writeLog(debug, INFO, "dict on <%lx> size = %d {", (unsigned long) value, (int) value->data.dict.size);
+            for (int i = 0; i < MAX_SIZE; i++) {
+                Var *tmp = value->data.dict.dict->hashtable[i];
+                while (tmp != NULL) {
+                    if (print_comma)
+                        writeLog(debug, INFO, ", ", NULL);
+                    else
+                        print_comma = true;
+
+                    writeLog(debug, INFO, "'%s' : ", tmp->name);
+                    printLinkValue(tmp->value, "", "", debug);
+                    tmp = tmp->next;
+                }
+            }
+            writeLog(debug, INFO, "}", NULL);
+            break;
+        }
         case none:
             writeLog(debug, INFO, "<None>", NULL);
             break;

+ 19 - 14
src/var.c

@@ -21,45 +21,50 @@ Var *freeVar(Var *var, bool self){
     return var;
 }
 
-HashTable *makeHashTable(Inter *inter) {
+HashTable *makeHashTable(Inter *inter, bool supervision) {
     HashTable *list_tmp = inter->hash_base;
     HashTable *tmp;
     tmp = memCalloc(1, sizeof(Value));
     tmp->hashtable = (Var **)calloc(MAX_SIZE, sizeof(Var *));
     tmp->next = NULL;
+    tmp->last = NULL;
+    if (!supervision)
+        goto return_;
+
     if (list_tmp == NULL){
         inter->hash_base = tmp;
         tmp->last = NULL;
         goto return_;
     }
 
-    while (list_tmp->next !=  NULL){
+    while (list_tmp->next !=  NULL)
         list_tmp = list_tmp->next;
-    }
     list_tmp->next = tmp;
-    tmp->last = list_tmp->next;
+    tmp->last = list_tmp;
 
     return_:
     return tmp;
 }
 
-void freeHashTable(HashTable *ht, Inter *inter){
+void freeHashTable(HashTable *ht, Inter *inter, bool supervision) {
     freeBase(ht, return_);
-    if (ht->last == NULL){
+    if (!supervision)
+        goto not_supervision;
+    if (ht->last == NULL)
         inter->hash_base = ht->next;
-    }
-    else{
+    else
         ht->last->next = ht->next;
-    }
-    if (ht->next != NULL){
-        ht->next->last = ht->last;
+
+    if (ht->next != NULL) {
+        HashTable *tmp = ht->last;
+        ht->next->last = tmp;
     }
 
+    not_supervision:
     for (int i=0; i < MAX_SIZE; i++){
         Var *tmp = ht->hashtable[i];
-        while (tmp != NULL){
+        while (tmp != NULL)
             tmp = freeVar(tmp, true);
-        }
     }
     memFree(ht->hashtable);
     memFree(ht);
@@ -70,7 +75,7 @@ void freeHashTable(HashTable *ht, Inter *inter){
 VarList *makeVarList(Inter *inter) {
     VarList *tmp = calloc(1, sizeof(VarList));
     tmp->next = NULL;
-    tmp->hashtable = makeHashTable(inter);
+    tmp->hashtable = makeHashTable(inter, true);
     return tmp;
 }