Bladeren bron

feat & refactor: grammar匹配等号和变量

grammar新增允许使用变量和赋值符号
新增-s和--stdout选项控制log的输出

grammar.c代码重构, 使用twoOperation
SongZihuan 4 jaren geleden
bovenliggende
commit
22dc2b6a5f
15 gewijzigde bestanden met toevoegingen van 238 en 112 verwijderingen
  1. 26 2
      include/__grammar.h
  2. 6 0
      include/__macro.h
  3. 1 0
      include/__virtualmath.h
  4. 1 0
      include/grammar.h
  5. 3 0
      include/statement.h
  6. 3 1
      include/token.h
  7. 8 2
      main.c
  8. 135 101
      parser/grammar.c
  9. 6 0
      parser/lexical.c
  10. 0 1
      parser/syntax.c
  11. 6 0
      parser/token.c
  12. 4 1
      src/inter.c
  13. 26 3
      src/statement.c
  14. 6 0
      src/value.c
  15. 7 1
      src/var.c

+ 26 - 2
include/__grammar.h

@@ -43,16 +43,40 @@ backToken(pm->tm->ts, pm->paser_debug); \
 } while(0)
 
 #define backToken_(pm, token) do{ \
-addToken(pm->tm->ts, token, pm->paser_debug); \
+addToken(pm->tm->ts, (token), pm->paser_debug); \
 backToken(pm->tm->ts, pm->paser_debug); \
 }while(0)
 
+#define addToken_ backToken_
+
 #define call_success(pm) (pm->status == success)
 
+#define delToken(pm) do{ \
+Token *tmp_token; \
+popAheadToken(tmp_token, pm); \
+freeToken(tmp_token, true, false); \
+tmp_token = NULL; \
+}while(0)
+
+#define callChild(pm, status, token, call, type, error_) do{ \
+call(CALLPASERSSIGNATURE); \
+if (!call_success(pm)){ \
+goto error_; \
+} \
+readBackToken(status, pm); \
+if (status != type){ \
+goto error_; \
+} \
+popAheadToken(token, pm); \
+}while(0)
+
 void parserCommand(PASERSSIGNATURE);
 void parserOperation(PASERSSIGNATURE);
 void parserPolynomial(PASERSSIGNATURE);
 void parserBaseValue(PASERSSIGNATURE);
-
+void parserFactor(PASERSSIGNATURE);
+void parserAssignment(PASERSSIGNATURE);
 void syntaxError(ParserMessage *pm, char *message, int status);
+void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*getSymbol)(PASERSSIGNATURE, int symbol, Statement **st), int, int, char *, char *);
+
 #endif //VIRTUALMATH___GRAMMAR_H

+ 6 - 0
include/__macro.h

@@ -17,4 +17,10 @@
 #define INTER_FUNCTIONSIG Statement *st, Inter *inter, VarList *var_list
 #define CALL_INTER_FUNCTIONSIG(st, var_list) st, inter, var_list
 
+#define freeBase(element, return_) do{ \
+if (element == NULL){ \
+goto return_; \
+} \
+}while(0) \
+
 #endif //VIRTUALMATH___MACRO_H

+ 1 - 0
include/__virtualmath.h

@@ -20,6 +20,7 @@ struct Args{
     char *file;
     char *log_file;
     int level;
+    bool stdout_inter;
 } args;
 
 #endif //VIRTUALMATH___VIRTUALMATH_H

+ 1 - 0
include/grammar.h

@@ -22,4 +22,5 @@ typedef struct ParserMessage{
 ParserMessage *makeParserMessage(char *file_dir, char *debug);
 void freePasersMessage(ParserMessage *pm, bool self);
 void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *st);
+
 #endif //VIRTUALMATH_GRAMMAR_H

+ 3 - 0
include/statement.h

@@ -33,6 +33,9 @@ typedef struct Statement{
 } Statement;
 
 Statement *makeStatement();
+Statement *makeOperationStatement(int type);
+struct Token *setOperationFromToken(Statement *st, struct Token *left, struct Token *right, int type);
+
 void connectStatement(Statement *base, Statement *new);
 void freeStatement(Statement *st);
 

+ 3 - 1
include/token.h

@@ -91,7 +91,9 @@
 #define COMMAND -6
 #define OPERATION -7
 #define POLYNOMIAL -8
-#define BASEVALUE -9
+#define FACTOR -9
+#define BASEVALUE -10
+#define ASSIGNMENT -11
 
 typedef struct Token{
     int token_type;  // 记录token的类型,大于0的数字均为lex匹配器所匹配,小于0的为syntax解析器所匹配

+ 8 - 2
main.c

@@ -3,6 +3,7 @@
 
 static const struct option long_option[]={
         {"input",required_argument,NULL,'i'},
+        {"stdout",no_argument,NULL,'s'},
 
 #if OUT_LOG
         {"log",required_argument,NULL,'l'},
@@ -17,9 +18,9 @@ static const struct option long_option[]={
 };
 
 #if OUT_LOG
-static const char *short_option = "i:l:";
+static const char *short_option = "si:l:";
 #else
-static const char *short_option = "i:";
+static const char *short_option = "si:";
 #endif
 int getArgs(int argc, char *argv[]);
 void freeArgs();
@@ -34,6 +35,7 @@ int main(int argc, char *argv[]) {
     pasersCommandList(pm, global_iter, true, global_iter->statement);
     if (pm->status != success){
         writeLog(pm->paser_debug, ERROR, "Syntax Error: %s\n", pm->status_message);
+        writeLog(stdout, ERROR, "Syntax Error: %s\n", pm->status_message);
         goto return_;
     }
     globalIterStatement(global_iter);
@@ -60,6 +62,7 @@ int getArgs(int argc, char *argv[])
     args.file = NULL;
     args.log_file = NULL;
     args.level = LEXICAL_CHECKOUT_DEBUG;
+    args.stdout_inter = false;
     opterr = false;
     int opt;
     while((opt=getopt_long(argc,argv,short_option ,long_option,NULL))!=-1)
@@ -74,6 +77,9 @@ int getArgs(int argc, char *argv[])
             case 'l':
                 args.log_file = memStrcpy(optarg, 0, false, false);
                 break;
+            case 's':
+                args.stdout_inter = true;
+                break;
             case '?':
                 printf("[Error]: get not success args : -%c\n", (char)optopt);
                 return -1;

+ 135 - 101
parser/grammar.c

@@ -12,7 +12,7 @@ ParserMessage *makeParserMessage(char *file_dir, char *debug){
         tmp->paser_debug = fopen(debug_dir, "w");
         tmp->grammar_debug = fopen(grammar_dir, "w");
         memFree(debug_dir);
-        memFree(debug_dir);
+        memFree(grammar_dir);
     }
     else{
         tmp->paser_debug = NULL;
@@ -107,7 +107,6 @@ void pasersCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *
                 goto return_;
             }
             /*...do something for commandList...*/
-            // printf("do something for commandList\n");
             connectStatement(base_st, command_token->data.st);
             freeToken(command_token, true, false);
             writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command List: get command success\n", NULL);
@@ -144,7 +143,6 @@ void parserCommand(PASERSSIGNATURE){
         }
         popAheadToken(command_token, pm);
         /*...do something for command...*/
-        // printf("do something for command\n");
         st = command_token->data.st;
         freeToken(command_token, true, false);
     }
@@ -157,23 +155,14 @@ void parserCommand(PASERSSIGNATURE){
 /**
  * 表达式匹配
  * parserOperation:
- * | parserPolynomial
+ * | parserAssignment
  */
 void parserOperation(PASERSSIGNATURE){
     int operation_int;
-    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Operation: call polynomial\n", NULL);
-    parserPolynomial(CALLPASERSSIGNATURE);
-    if (!call_success(pm)){
-        goto return_;
-    }
-    readBackToken(operation_int, pm);
-    if (operation_int != POLYNOMIAL){
-        goto return_;
-    }
     Token *operation_token;
-    popAheadToken(operation_token, pm);
+    writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Operation: call assignment\n", NULL);
+    callChild(pm, operation_int, operation_token, parserAssignment, ASSIGNMENT, return_);
     /*...do something for operation...*/
-    // printf("do something for operation\n");
 
     addStatementToken(OPERATION, operation_token->data.st, pm);
     freeToken(operation_token, true, false);
@@ -183,94 +172,75 @@ void parserOperation(PASERSSIGNATURE){
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Operation: return\n", NULL);
 }
 
+/**
+ * 赋值表达式匹配
+ * parserAssignment:
+ * | parserPolynomial
+ * | parserAssignment ASSIGNMENT parserPolynomial
+ */
+bool switchAssignment(PASERSSIGNATURE, int symbol, Statement **st){
+    switch (symbol) {
+        case MATHER_ASSIGNMENT:
+            *st = makeOperationStatement(ASS);
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+void parserAssignment(PASERSSIGNATURE){
+    return twoOperation(CALLPASERSSIGNATURE, parserPolynomial, switchAssignment, POLYNOMIAL, ASSIGNMENT,
+                        "polynomial", "assignment");
+}
+
 /**
  * 多项式匹配
  * parserPolynomial:
- * | parserBaseValue [1]
- * | parserPolynomial ADD parserBaseValue
- * | parserPolynomial SUB parserBaseValue
+ * | parserBaseValue
+ * | parserPolynomial ADD parserFactor
+ * | parserPolynomial SUB parserFactor
  */
+bool switchPolynomial(PASERSSIGNATURE, int symbol, Statement **st){
+    switch (symbol) {
+        case MATHER_ADD:
+            *st = makeOperationStatement(ADD);
+            break;
+        case MATHER_SUB:
+            *st = makeOperationStatement(SUB);
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
 void parserPolynomial(PASERSSIGNATURE){
-    while(true){
-        int left, symbol, right;
-        Token *left_token, *symbol_token, *right_token;
-        struct Statement *st = NULL;
-        readBackToken(left, pm);
-        if (left != POLYNOMIAL){
-            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Polynomial: cal base value(left)\n", NULL);
-            // 情况[1]
-            parserBaseValue(CALLPASERSSIGNATURE);  // 获得左值
-            if (!call_success(pm)){
-                goto return_;
-            }
-            readBackToken(left, pm);
-            if (left != BASEVALUE){  // 若非正确数值
-                goto return_;
-            }
-            popAheadToken(left_token, pm);
-            addStatementToken(POLYNOMIAL, left_token->data.st, pm);
-            freeToken(left_token, true, false);
-            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
-                    "Polynomial: get base value(left) success[push polynomial]\n", NULL);
-            continue;
-        }
-        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Polynomial: call symbol\n", NULL);
-        popAheadToken(left_token, pm);
-        readBackToken(symbol, pm);
-        switch (symbol) {
-            case MATHER_ADD:
-                // printf("polynomial: get a add symbol\n");
-                popAheadToken(symbol_token, pm);
-                freeToken(symbol_token, true, false);
-                symbol_token = NULL;
-
-                st = makeStatement();
-                st->type = operation;
-                st->u.operation.OperationType = ADD;
-                break;
-            case MATHER_SUB:
-                // printf("polynomial: get a sub symbol\n");
-                popAheadToken(symbol_token, pm);
-                freeToken(symbol_token, true, false);
-                symbol_token = NULL;
-
-                st = makeStatement();
-                st->type = operation;
-                st->u.operation.OperationType = SUB;
-                break;
-            default:
-                // printf("polynomial: get another symbol\n");
-                backToken_(pm, left_token);
-                goto return_;
-        }
-        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
-                "Polynomial: get symbol success\nPolynomial: call base value[right]\n", NULL);
-        parserBaseValue(CALLPASERSSIGNATURE);  // 获得左值
-        if (!call_success(pm)){
-            freeToken(left_token, true, false);
-            freeStatement(st);
-            goto return_;
-        }
-        readBackToken(right, pm);
-        if (right != BASEVALUE){  // 若非正确数值
-            syntaxError(pm, "ERROR from parserPolynomial(get right)", syntax_error);
-            freeToken(left_token, true, true);
-            freeStatement(st);
-            goto return_;
-        }
-        popAheadToken(right_token, pm);
-
-        st->u.operation.left = left_token->data.st;
-        st->u.operation.right = right_token->data.st;
+    return twoOperation(CALLPASERSSIGNATURE, parserFactor, switchPolynomial, FACTOR, POLYNOMIAL,
+            "factor", "polynomial");
+}
 
-        freeToken(left_token, true, false);
-        freeToken(right_token, true, false);
-        addStatementToken(POLYNOMIAL, st, pm);
-        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Polynomial: get base value(right) success[push polynomial]\n", NULL);
-        // printf("polynomial: push token\n");
+/**
+ * 因式匹配
+ * parserFactor:
+ * | parserBaseValue [1]
+ * | switchFactor ADD parserBaseValue
+ * | switchFactor SUB parserBaseValue
+ */
+bool switchFactor(PASERSSIGNATURE, int symbol, Statement **st){
+    switch (symbol) {
+        case MATHER_MUL:
+            *st = makeOperationStatement(MUL);
+            break;
+        case MATHER_DIV:
+            *st = makeOperationStatement(DIV);
+            break;
+        default:
+            return false;
     }
-    return_:
-    return;
+    return true;
+}
+void parserFactor(PASERSSIGNATURE){
+    return twoOperation(CALLPASERSSIGNATURE, parserBaseValue, switchFactor, BASEVALUE, FACTOR,
+                        "base value", "factor");
 }
 
 /**
@@ -281,32 +251,96 @@ void parserPolynomial(PASERSSIGNATURE){
  */
 void parserBaseValue(PASERSSIGNATURE){
     int token_type;
+    Token *value_token;
     struct Statement *st = NULL;
     readBackToken(token_type, pm);
     if(MATHER_NUMBER == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get number\n", NULL);
-        Token *value_token;
-        char *stop;
         popAheadToken(value_token, pm);
+        char *stop;
         st = makeStatement();
         st->type = base_value;
         st->u.base_value.value = makeNumberValue(strtol(value_token->data.str, &stop, 10), inter);
-        freeToken(value_token, true, false);
     }
     else if(MATHER_STRING == token_type){
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get string\n", NULL);
-        Token *value_token;
         popAheadToken(value_token, pm);
         st = makeStatement();
         st->type = base_value;
         st->u.base_value.value = makeStringValue(value_token->data.str, inter);
-        freeToken(value_token, true, false);
+    }
+    else if(MATHER_VAR == token_type){
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: get var\n", NULL);
+        popAheadToken(value_token, pm);
+        st = makeStatement();
+        st->type = base_var;
+        st->u.base_var.name = memStrcpy(value_token->data.str, 0, false, false);
+        st->u.base_var.times = NULL;
     }
     else{
         writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Base Value: else\n", NULL);
         goto return_;
     }
+    freeToken(value_token, true, false);
     addStatementToken(BASEVALUE, st, pm);
+
+    return_:
+    return;
+}
+
+inline void twoOperation(PASERSSIGNATURE, void (*callBack)(PASERSSIGNATURE), int (*getSymbol)(PASERSSIGNATURE, int symbol, Statement **st), int type, int self_type, char *call_name, char *self_name){
+    while(true){
+        int left, symbol, right;
+        Token *left_token, *symbol_token, *right_token;
+        struct Statement *st = NULL;
+
+        readBackToken(left, pm);
+        if (left != self_type){
+            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call %s(left)\n", self_name, call_name);
+            callChild(pm, left, left_token, callBack, type, return_);
+            addStatementToken(self_type, left_token->data.st, pm);
+            freeToken(left_token, true, false);
+            writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
+                      "%s: get %s(left) success[push %s]\n", self_name, call_name, self_name);
+            continue;
+        }
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "%s: call symbol\n", self_name);
+        popAheadToken(left_token, pm);
+
+        readBackToken(symbol, pm);
+        if (getSymbol(CALLPASERSSIGNATURE, symbol, &st)){
+            delToken(pm);
+        }
+        else{
+            backToken_(pm, left_token);
+            goto return_;
+        }
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG,
+                  "%s: get symbol success\n%s: call %s[right]\n", self_name, self_name, call_name);
+
+        callBack(CALLPASERSSIGNATURE);  // 获得左值
+        if (!call_success(pm)){
+            freeToken(left_token, true, false);
+            freeStatement(st);
+            goto return_;
+        }
+        readBackToken(right, pm);
+        if (right != type){  // 若非正确数值
+            char *tmp1, *tmp2;
+            tmp1 = memStrcat("ERROR from ", self_name);
+            tmp2 = memStrcat(tmp1, "(get right)");
+            syntaxError(pm, tmp2, syntax_error);
+            memFree(tmp1);
+            memFree(tmp2);
+            freeToken(left_token, true, true);
+            freeStatement(st);
+            goto return_;
+        }
+
+        popAheadToken(right_token, pm);
+        addToken_(pm, setOperationFromToken(st, left_token, right_token, self_type));
+        writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Polynomial: get base value(right) success[push polynomial]\n", NULL);
+    }
     return_:
     return;
 }

+ 6 - 0
parser/lexical.c

@@ -33,10 +33,13 @@ LexFile *makeLexFile(char *dir){
 }
 
 void freeLexFile(LexFile *file, bool self){
+    freeBase(file, return_);
     fclose(file->file);
     if (self){
         memFree(file);
     }
+    return_:
+    return;
 }
 
 /**
@@ -77,6 +80,7 @@ LexMathers *makeMathers(int size){
 }
 
 void freeMathers(LexMathers *mathers, bool self){
+    freeBase(mathers, return_);
     for(int i=0;i < mathers->size; i++){
         freeMather(mathers->mathers[i], true);
     }
@@ -85,6 +89,8 @@ void freeMathers(LexMathers *mathers, bool self){
     if (self){
         memFree(mathers);
     }
+    return_:
+    return;
 }
 
 /**

+ 0 - 1
parser/syntax.c

@@ -145,7 +145,6 @@ void strMather(char p, LexMather *mather, const char *dest_p){
             mather->status = LEXMATHER_ING;
         }
         else if(mather->status == LEXMATHER_ING && mather->len == memStrlen((char *)dest_p)){
-            printf("G\n");
             mather->status = LEXMATHER_END;
         }
         else{

+ 6 - 0
parser/token.c

@@ -25,6 +25,7 @@ Token *makeStatementToken(int type, struct Statement *st){
 }
 
 void freeToken(Token *tk, bool self, bool error) {
+    freeBase(tk, return_);
     memFree(tk->data.str);
     memFree(tk->data.second_str);
     if (error){
@@ -33,6 +34,8 @@ void freeToken(Token *tk, bool self, bool error) {
     if (self){
         memFree(tk);
     }
+    return_:
+    return;
 }
 
 TokenStream *makeTokenStream(){
@@ -45,6 +48,7 @@ TokenStream *makeTokenStream(){
 }
 
 void freeToekStream(TokenStream *ts, bool self) {
+    freeBase(ts, return_);
     for (int i=0; i < ts->size; i++){
         freeToken(ts->token_list[i], true, false);
     }
@@ -56,6 +60,8 @@ void freeToekStream(TokenStream *ts, bool self) {
     if (self){
         memFree(ts);
     }
+    return_:
+    return;
 }
 
 TokenMessage *makeTokenMessage(char *file_dir, char *debug) {

+ 4 - 1
src/inter.c

@@ -7,7 +7,7 @@ Inter *makeInter(char *debug){
     tmp->statement = makeStatement();
     tmp->var_list = makeVarList(tmp);
     tmp->log_dir = memStrcpy(debug, 0, false, false);
-    if (debug != NULL){
+    if (debug != NULL && !args.stdout_inter){
         char *debug_dir = memStrcat(debug, INTER_LOG);
         tmp->debug = fopen(debug_dir, "w");
         memFree(debug_dir);
@@ -18,6 +18,7 @@ Inter *makeInter(char *debug){
 }
 
 void freeInter(Inter *inter, bool self){
+    freeBase(inter, return_);
     while (inter->base != NULL){
         freeValue(inter->base, inter);
     }
@@ -35,4 +36,6 @@ void freeInter(Inter *inter, bool self){
     if (self){
         memFree(inter);
     }
+    return_:
+    return;
 }

+ 26 - 3
src/statement.c

@@ -8,6 +8,29 @@ Statement *makeStatement(){
     return tmp;
 }
 
+Statement *makeOperationStatement(int type){
+    Statement *tmp;
+    tmp = memCalloc(1, sizeof(Statement));
+    tmp->type = operation;
+    tmp->u.operation.OperationType = type;
+    tmp->u.operation.left = NULL;
+    tmp->u.operation.right = NULL;
+    return tmp;
+}
+
+Token *setOperationFromToken(Statement *st, Token *left, Token *right, int type) {
+    Token *new_token;
+    st->u.operation.left = left->data.st;
+    st->u.operation.right = right->data.st;
+    new_token = makeToken();
+    new_token->token_type = type;
+    new_token->data.st = st;
+
+    freeToken(left, true, false);
+    freeToken(right, true, false);
+    return new_token;
+}
+
 void connectStatement(Statement *base, Statement *new){
     while (base->next != NULL){
         base = base->next;
@@ -16,9 +39,7 @@ void connectStatement(Statement *base, Statement *new){
 }
 
 void freeStatement(Statement *st){
-    if (st == NULL){
-        return;
-    }
+    freeBase(st, return_);
     Statement *next_tmp;
     while (st != NULL){
         switch (st->type) {
@@ -37,4 +58,6 @@ void freeStatement(Statement *st){
         memFree(st);
         st = next_tmp;
     }
+    return_:
+    return;
 }

+ 6 - 0
src/value.c

@@ -39,6 +39,7 @@ Value *makeStringValue(char *str, Inter *inter) {
 }
 
 void freeValue(Value *value, Inter *inter){
+    freeBase(value, return_);
     if (value->last == NULL){
         inter->base = value->next;
     }
@@ -56,6 +57,8 @@ void freeValue(Value *value, Inter *inter){
             break;
     }
     memFree(value);
+    return_:
+    return;
 }
 
 LinkValue *makeLinkValue(Value *value, LinkValue *linkValue, Inter *inter){
@@ -80,6 +83,7 @@ LinkValue *makeLinkValue(Value *value, LinkValue *linkValue, Inter *inter){
 }
 
 void freeLinkValue(LinkValue *value, Inter *inter){
+    freeBase(value, return_);
     if (value->last == NULL){
         inter->link_base = value->next;
     }
@@ -90,6 +94,8 @@ void freeLinkValue(LinkValue *value, Inter *inter){
         value->next->last = value->last;
     }
     memFree(value);
+    return_:
+    return;
 }
 
 void setResult(Result *ru, bool link, Inter *inter) {

+ 7 - 1
src/var.c

@@ -10,12 +10,14 @@ Var *makeVar(char *name, LinkValue *value){
 }
 
 Var *freeVar(Var *var, bool self){
+    freeBase(var, return_);
     memFree(var->name);
     if (self){
         Var *next_var = var->next;
         memFree(var);
         return next_var;
     }
+    return_:
     return var;
 }
 
@@ -41,6 +43,7 @@ HashTable *makeHashTable(Inter *inter) {
 }
 
 void freeHashTable(HashTable *ht, Inter *inter){
+    freeBase(ht, return_);
     if (ht->last == NULL){
         inter->hash_base = ht->next;
     }
@@ -59,6 +62,8 @@ void freeHashTable(HashTable *ht, Inter *inter){
     }
     memFree(ht->hashtable);
     memFree(ht);
+    return_:
+    return;
 }
 
 VarList *makeVarList(Inter *inter) {
@@ -69,13 +74,14 @@ VarList *makeVarList(Inter *inter) {
 }
 
 VarList *freeVarList(VarList *vl, bool self){
+    freeBase(vl, return_);
     if (self){
         VarList *next_var = vl->next;
         memFree(vl);
         return next_var;
     }
+    return_:
     return vl;
-
 }
 
 /**