Преглед изворни кода

feat: import语句

支持使用import语句
支持使用import as语句
支持使用from import语句
支持使用from import as 语句
支持使用from import *语句
SongZihuan пре 4 година
родитељ
комит
9b29f1a336
28 измењених фајлова са 436 додато и 166 уклоњено
  1. 32 2
      file/file.c
  2. 4 0
      gc/gc.c
  3. 1 0
      include/__virtualmath.h
  4. 1 0
      include/file.h
  5. 2 1
      include/inter.h
  6. 1 1
      include/mem.h
  7. 3 1
      include/run.h
  8. 13 0
      include/statement.h
  9. 3 1
      include/token.h
  10. 3 2
      include/var.h
  11. 1 1
      include/virtualmath.h
  12. 1 2
      main.c
  13. 10 9
      memory/mem.c
  14. 17 26
      parser/__grammar.c
  15. 79 25
      parser/grammar.c
  16. 2 1
      parser/include/__grammar.h
  17. 30 56
      parser/syntax.c
  18. 1 1
      parser/token.c
  19. 2 5
      src/__run.c
  20. 50 4
      src/inter.c
  21. 1 2
      src/parameter.c
  22. 8 2
      src/run.c
  23. 1 1
      src/runcall.c
  24. 97 1
      src/runfile.c
  25. 7 8
      src/runoperation.c
  26. 35 0
      src/statement.c
  27. 4 1
      src/value.c
  28. 27 13
      src/var.c

+ 32 - 2
file/file.c

@@ -7,7 +7,10 @@
  */
 int checkFile(char *dir){
     struct stat my_stat;
-    int status = stat(dir, &my_stat);
+    int status = 0;
+    if (dir == NULL)
+        return 3;
+    stat(dir, &my_stat);
     if (status != 0)
         return 0;
     else if (S_ISREG(my_stat.st_mode))
@@ -16,4 +19,31 @@ int checkFile(char *dir){
         return 2;
     else
         return 3;
-}
+}
+
+char *splitDir(char * dir){
+    char *slash = NULL;
+    char *point = NULL;
+    char *return_char = NULL;
+#ifdef __unix__
+    if ((slash = strrchr(dir, '/'))  == NULL)
+#else
+        if ((slash = strchr(dir, '\\'))  == NULL)
+#endif  // __unix__
+    { slash = dir; }
+    else
+        slash ++;
+
+    if ((point = strchr(dir, '.'))  != NULL)
+        *point = 0;
+
+    return_char = memStrcpy(slash);
+    if (point != NULL)
+        *point = '.';
+    if (!isalpha(*return_char) && *return_char != '_')
+        return_char = memStrcat("_", return_char, false, true);
+    for (char *tmp = return_char; *tmp != 0;tmp++)
+        if (!isalnum(*tmp) &&'_' != *tmp)
+            *tmp = '_';
+    return return_char;
+}

+ 4 - 0
gc/gc.c

@@ -90,6 +90,10 @@ void gc_checkBase(Inter *inter){
     for (HashTable *hash_base = inter->hash_base; hash_base != NULL; hash_base = hash_base->gc_next)
         if (!gc_needFree(&hash_base->gc_status) && !hash_base->gc_status.continue_)
             gc_iterHashTable(hash_base);
+
+    for (Var *var_base = inter->base_var; var_base != NULL; var_base = var_base->gc_next)
+        if (!gc_needFree(&var_base->gc_status) && !var_base->gc_status.continue_)
+            gc_iterVar(var_base);
 }
 
 void gc_freeBase(Inter *inter){

+ 1 - 0
include/__virtualmath.h

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

+ 1 - 0
include/file.h

@@ -2,5 +2,6 @@
 #define VIRTUALMATH_FILE_H
 
 int checkFile(char *dir);
+char *splitDir(char * dir);
 
 #endif //VIRTUALMATH_FILE_H

+ 2 - 1
include/inter.h

@@ -25,8 +25,9 @@ struct Inter{
 typedef struct Inter Inter;
 
 Inter *makeInter(char *code_file, char *debug);
-void freeInter(Inter *inter, bool self);
+void freeInter(Inter *inter, bool self, bool show_gc);
 void setBaseInterData(struct Inter *inter);
 Inter *newInter(char *code_file, char *debug_dir,struct Result *global_result, int *status);
 Inter *runBaseInter(char *code_file, char *debug_dir, int *status);
+void mergeInter(Inter *new, Inter *base);
 #endif //VIRTUALMATH_INTER_H

+ 1 - 1
include/mem.h

@@ -10,7 +10,7 @@ void *memCalloc(size_t num, size_t size);
 void *memRealloc(void *old, size_t size);
 char *memStrcpy(const char *const str);
 char *memStrCharcpy(char *str, size_t nsize, int free_old, int write, ...);
-char *memStrcat(char *first, char *second, bool free_old);
+char *memStrcat(char *first, char *second, bool free_first, bool free_last);
 char *memStrcpySelf(char *str, NUMBER_TYPE times);
 char *memStrrev(const char *const str);
 

+ 3 - 1
include/run.h

@@ -13,7 +13,7 @@ typedef struct Parameter Parameter;
 
 typedef ResultType (*VarInfo)(char **name, int *times, INTER_FUNCTIONSIG);
 
-ResultType globalIterStatement(Inter *inter, Result *result);
+ResultType globalIterStatement(Inter *inter, Result *result, LinkValue *base_father);
 bool operationSafeInterStatement(INTER_FUNCTIONSIG);
 bool ifBranchSafeInterStatement(INTER_FUNCTIONSIG);
 bool functionSafeInterStatement(INTER_FUNCTIONSIG);
@@ -41,6 +41,8 @@ ResultType returnCode(INTER_FUNCTIONSIG);
 ResultType raiseCode(INTER_FUNCTIONSIG);
 
 ResultType includeFile(INTER_FUNCTIONSIG);
+ResultType importFile(INTER_FUNCTIONSIG);
+ResultType fromImportFile(INTER_FUNCTIONSIG);
 
 ResultType pointAss(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST);
 ResultType assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST);

+ 13 - 0
include/statement.h

@@ -27,6 +27,8 @@ struct Statement{
         return_code,
         raise_code,
         include_file,
+        import_file,
+        from_import_file,
     } type;
     union StatementU{
         struct base_value{
@@ -134,6 +136,15 @@ struct Statement{
         struct {
             struct Statement *file;
         } include_file;
+        struct {
+            struct Statement *file;
+            struct Statement *as;
+        } import_file;
+        struct {
+            struct Statement *file;
+            struct Parameter *pt;
+            struct Parameter *as;
+        } from_import_file;
     }u;
     long int line;
     char *code_file;
@@ -182,6 +193,8 @@ Statement *makeRestartStatement(Statement *times, long int line, char *file);
 Statement *makeReturnStatement(Statement *value, long int line, char *file);
 Statement *makeRaiseStatement(Statement *value, long int line, char *file);
 Statement *makeIncludeStatement(Statement *file, long int line, char *file_dir);
+Statement *makeImportStatement(Statement *file, Statement *as);
+Statement *makeFromImportStatement(Statement *file, Parameter *as, Parameter *pt);
 struct Token *setOperationFromToken(Statement **st_ad, struct Token *left, struct Token *right, enum OperationType type, bool is_right);
 
 StatementList *makeStatementList(Statement *condition, Statement *var, Statement *code, int type);

+ 3 - 1
include/token.h

@@ -84,8 +84,9 @@
 #define MATHER_SEMICOLON 72
 #define MATHER_LINK 73
 #define MATHER_RAISE 74
+#define MATHER_FROM 75
 
-#define MATHER_MAX 75
+#define MATHER_MAX 76
 
 // 从-6开始是为了避开status的特殊值,尽管这并没有什么影响
 #define COMMAND -6
@@ -109,6 +110,7 @@
 #define TUPLE -24
 #define INCLUDE -25
 #define POINT -26
+#define IMPORT -27
 
 #define printTokenEnter(tk, debug, type, message) do{ \
 writeLog(debug, type, message, NULL); \

+ 3 - 2
include/var.h

@@ -39,9 +39,10 @@ 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);
+LinkValue *findVar(char *name, bool del_var, INTER_FUNCTIONSIG_CORE);
+LinkValue *findFromVarList(char *name, NUMBER_TYPE times, bool del_var, INTER_FUNCTIONSIG_CORE);
 void addVar(char *name, LinkValue *value, LinkValue *name_, INTER_FUNCTIONSIG_CORE);
+void updateHashTable(HashTable *update, HashTable *new, Inter *inter);
 void addFromVarList(char *name, LinkValue *name_, NUMBER_TYPE times, LinkValue *value, INTER_FUNCTIONSIG_CORE);
 
 VarList *pushVarList(VarList *base, Inter *inter);

+ 1 - 1
include/virtualmath.h

@@ -8,5 +8,5 @@ extern bool memVirtualMathUseJmp;
 typedef struct Inter Inter;
 typedef struct Result Result;
 Inter *runBaseInter(char *code_file, char *debug_dir, int *status);
-void freeInter(Inter *inter, int self);
+void freeInter(Inter *inter, bool self, bool show_gc);
 #endif //VIRTUALMATH_VIRTUALMATH_H

+ 1 - 2
main.c

@@ -12,7 +12,7 @@ int main(int argc, char *argv[]) {
 
     global_inter = runBaseInter(args.file, args.log_file, &status);
 
-    freeInter(global_inter, true);
+    freeInter(global_inter, true, true);
     args_error: freeArgs();
     return status;
 }
@@ -21,7 +21,6 @@ int main(int argc, char *argv[]) {
 /**
  * TODO-szh 类super语句
  * TODO-szh const声明
- * TODO-szh import语句
  * TODO-szh 生成语法树
  * TODO-szh 取反符号 -
  * TODO-szh 字面量后缀

+ 10 - 9
memory/mem.c

@@ -57,36 +57,37 @@ char *memStrCharcpy(char *str, size_t nsize, bool free_old, bool write, ...) {
     return tmp;
 }
 
-char *memStrcat(char *first, char *second, bool free_old) {
+char *memStrcat(char *first, char *second, bool free_first, bool free_last) {
     if (first == NULL && second == NULL)
         return NULL;
     else if (first == NULL){
         first = second;
         second = NULL;
-        free_old = false;
+        free_first = free_last;
+        free_last = false;
     }
 
     char *new = memStrCharcpy(first, memStrlen(second), false, false);
     if (second != NULL)
         strcat(new, second);
-    if (free_old)
+
+    if (free_first)
         memFree(first);
+    if (free_last)
+        memFree(second);
     return new;
 }
 
 char *memStrcpySelf(char *str, NUMBER_TYPE times){
     bool need_free = false;
+    char *new_str = NULL;
     if (times < 0){
         str = memStrrev(str);
         times = -times;
         need_free = true;
     }
-    char *new_str = memStrcpy(str), *tmp;
-    for (NUMBER_TYPE i=0; i < times - 1; i++){
-        tmp = memStrcat(new_str, str, false);
-        memFree(new_str);
-        new_str = tmp;
-    }
+    for (NUMBER_TYPE i=0; i < times; i++)
+        new_str = memStrcat(new_str, str, true, false);
     if (need_free)
         memFree(str);
     return new_str;

+ 17 - 26
parser/__grammar.c

@@ -45,12 +45,7 @@ inline void twoOperation(PASERSSIGNATURE, PasersFunction callBack, GetSymbolFunc
                   "%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, true);
-            freeStatement(st);
-            goto return_;
-        }
-        if (readBackToken(pm) != call_type){  // 若非正确数值
+        if (!call_success(pm) || readBackToken(pm) != call_type){  // 若非正确数值
             syntaxError(pm, syntax_error, line, 3, "ERROR from ", self_name, "(get right)");
             freeToken(left_token, true, true);
             freeStatement(st);
@@ -133,13 +128,13 @@ void syntaxError(ParserMessage *pm, int status, long int line, int num, ...) {
     va_list message_args;
     va_start(message_args, num);
     for (int i=0; i < num; i++)
-        message = memStrcat(message, va_arg(message_args, char *), true);
+        message = memStrcat(message, va_arg(message_args, char *), true, false);
     va_end(message_args);
 
     char info[100];
     snprintf(info, 100, "\non line %ld\nin file ", line);
-    message = memStrcat(message, info, true);
-    message = memStrcat(message, pm->file, true);
+    message = memStrcat(message, info, true, false);
+    message = memStrcat(message, pm->file, true, false);
 
     not_message:
     pm->status = status;
@@ -164,7 +159,7 @@ Token *popAheadToken(ParserMessage *pm){
     return popNewToken(pm->tm, pm->paser_debug);
 }
 
-bool checkToken_(ParserMessage *pm, int type){
+bool checkToken(ParserMessage *pm, int type){
     if (readBackToken(pm) != type)
         return false;
     delToken(pm);
@@ -194,9 +189,7 @@ bool callParserCode(PASERSSIGNATURE, Statement **st, char *message, long int lin
     Token *tmp;
     *st = NULL;
     parserCode(CALLPASERSSIGNATURE);
-    if (!call_success(pm))
-        return false;
-    if (readBackToken(pm) != CODE) {
+    if (!call_success(pm) || readBackToken(pm) != CODE) {
         if (message != NULL)
             syntaxError(pm, syntax_error, line, 1, message);
         return false;
@@ -220,9 +213,7 @@ bool callChildToken(PASERSSIGNATURE, PasersFunction callBack, int type, Token **
                     int error_type) {
     *tmp = NULL;
     callBack(CALLPASERSSIGNATURE);
-    if (!call_success(pm))
-        return false;
-    if (readBackToken(pm) != type) {
+    if (!call_success(pm) || readBackToken(pm) != type) {
         if (message != NULL) {
             *tmp = popAheadToken(pm);
             syntaxError(pm, error_type, (*tmp)->line, 1, message);
@@ -268,7 +259,7 @@ bool callChildStatement(PASERSSIGNATURE, PasersFunction callBack, int type, Stat
  *
  * @param is_formal 是否为形式参数, 若为true,则限定*args为only_value的结尾, **kwargs为name_value结尾
  * @param is_list 若为true则关闭对name_value和**kwargs的支持
- * @param is_dict 若为true则关闭对only_value和*args的支持
+ * @param is_dict 若为true则关闭对only_value和*args的支持  (is_list和is_dict同时为true表示纯 a,b,c 匹配)
  * @param sep 设定分割符号
  * @param ass 设定赋值符号
  * @return
@@ -285,16 +276,16 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_li
         s_4,  // name_args模式
     } status;
 
-    if (is_dict)
+    if (is_dict && !is_list)
         status = s_2;  // is_formal关闭对only_value的支持
     else
         status = s_1;
 
     while (!last_pt){
         tmp = NULL;
-        if (!is_dict && status != s_2 && checkToken_(pm, MATHER_MUL))  // is_formal关闭对*args的支持
+        if (!is_dict && status != s_2 && checkToken(pm, MATHER_MUL))  // is_formal关闭对*args的支持
             status = s_3;
-        else if (!is_list && checkToken_(pm, MATHER_POW))  // is_formal关闭对*args的支持
+        else if (!is_list && checkToken(pm, MATHER_POW))  // is_formal关闭对*args的支持
             status = s_4;
 
         parserPolynomial(CALLPASERSSIGNATURE);
@@ -312,8 +303,8 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_li
 
         int pt_type = value_par;
         if (status == s_1){
-            if (!checkToken_(pm, sep)){
-                if (is_list || !checkToken_(pm, ass))  // // is_list关闭对name_value的支持
+            if (!checkToken(pm, sep)){
+                if (is_list || !checkToken(pm, ass))  // // is_list关闭对name_value的支持
                     last_pt = true;
                 else {
                     pt_type = name_par;
@@ -323,17 +314,17 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_li
         }
         else if (status == s_2){
             pt_type = name_par;
-            if (!checkToken_(pm, ass))
+            if (!checkToken(pm, ass))
                 goto error_;
         }
         else if (status == s_3){
             pt_type = args_par;
-            if (!checkToken_(pm, sep))
+            if (!checkToken(pm, sep))
                 last_pt = true;
         }
         else {
             pt_type = kwargs_par;
-            if (!checkToken_(pm, sep))
+            if (!checkToken(pm, sep))
                 last_pt = true;
         }
 
@@ -344,7 +335,7 @@ bool parserParameter(PASERSSIGNATURE, Parameter **pt, bool is_formal, bool is_li
             if (!callChildStatement(CALLPASERSSIGNATURE, parserPolynomial, POLYNOMIAL, &tmp_value, "Don't get a parameter value"))
                 goto error_;
             new_pt = connectNameParameter(tmp_value, tmp->data.st, new_pt);
-            if (!checkToken_(pm, sep))
+            if (!checkToken(pm, sep))
                 last_pt = true;
         }
         else if (pt_type == args_par){

+ 79 - 25
parser/grammar.c

@@ -9,7 +9,8 @@ ParserMessage *makeParserMessage(char *file_dir, char *debug){
     tmp->count = 0;
 #if OUT_LOG
     if (debug != NULL){
-        char *debug_dir = memStrcat(debug, PASERS_LOG, false), *grammar_dir = memStrcat(debug, GRAMMAR_LOG, false);
+        char *debug_dir = memStrcat(debug, PASERS_LOG, false, false), *grammar_dir = memStrcat(debug, GRAMMAR_LOG, false,
+                                                                                               false);
         if (access(debug_dir, F_OK) != 0 || access(debug_dir, W_OK) == 0)
             tmp->paser_debug = fopen(debug_dir, "w");
         if (access(grammar_dir, F_OK) != 0 || access(debug_dir, W_OK) == 0)
@@ -83,7 +84,6 @@ void parserCommandList(PASERSSIGNATURE, bool global, Statement *st) {
                 delToken(pm);
             else  if(stop != MATHER_EOF){
                 if (global) {
-                    printf("stop = %d\n", stop);
                     syntaxError(pm, command_list_error, command_token->line, 1, "ERROR from parserCommand list(get stop)");
                     freeToken(command_token, true, true);
                 }
@@ -170,6 +170,10 @@ void parserCommand(PASERSSIGNATURE){
                                          "Command: call include\n", true,
                                          "parserInclude: Don't get file after include");
             break;
+        case MATHER_FROM :
+        case MATHER_IMPORT :
+            status = commandCallBack_(CALLPASERSSIGNATURE, parserImport, IMPORT, &st, "Command: call import\n");
+            break;
         case MATHER_STRING:
         case MATHER_NUMBER:
         case MATHER_VAR:
@@ -195,36 +199,86 @@ void parserCommand(PASERSSIGNATURE){
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "Command: get return\n", NULL);
 }
 
+/**
+ * import 匹配
+ * parserImport
+ * | parserControl AS parserOperation
+ * @param callBack statement生成函数
+ * @param type 输出token的类型
+ * @param must_operation 必须匹配 operation
+ */
+void parserImport(PASERSSIGNATURE) {
+    Statement *opt = NULL;
+    Statement *st = NULL;
+    int token_type = readBackToken(pm);
+    long int line = delToken(pm);
+
+    if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &opt, "Don't get a import file"))
+        goto return_;
+    if (token_type == MATHER_IMPORT) {
+        Statement *as = NULL;
+        if (checkToken(pm, MATHER_AS) && !callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &as, "Don't get a as after import")) {
+            freeStatement(opt);
+            goto return_;
+        }
+        st = makeImportStatement(opt, as);
+    }
+    else{
+        Parameter *pt = NULL;
+        Parameter *as = NULL;
+        if (!checkToken(pm, MATHER_IMPORT)) {
+            syntaxError(pm, syntax_error, opt->line, 1, "Don't get a as after import");
+            freeStatement(opt);
+            goto return_;
+        }
+        if (checkToken(pm, MATHER_MUL))  // 导入所有
+            goto mul_;
+        if (!parserParameter(CALLPASERSSIGNATURE, &pt, true, true, true, MATHER_COMMA, MATHER_ASSIGNMENT) || pt == NULL) {
+            syntaxError(pm, syntax_error, line, 1, "Don't get any value for import");
+            freeStatement(opt);
+            goto return_;
+        }
+        if (checkToken(pm, MATHER_AS) && (!parserParameter(CALLPASERSSIGNATURE, &as, true, true, false, MATHER_COMMA, MATHER_ASSIGNMENT) || as == NULL)) {
+            freeParameter(pt, true);
+            syntaxError(pm, syntax_error, opt->line, 1, "Don't get any value after import");
+            freeStatement(opt);
+            goto return_;
+        }
+
+
+        mul_:
+        st = makeFromImportStatement(opt, as, pt);
+    }
+
+    addStatementToken(IMPORT, st, pm);
+    return_:
+    return;
+}
+
 /**
  * 控制语句匹配
  * parserControl
  * | (control token) NULL
  * | (control token) parserOperation
- *
  * @param callBack statement生成函数
  * @param type 输出token的类型
  * @param must_operation 必须匹配 operation
  */
-void parserControl(PASERSSIGNATURE, MakeControlFunction callBack, int type, bool must_operation,
-                   char *message) {
-    Statement *times = NULL;
+void parserControl(PASERSSIGNATURE, MakeControlFunction callBack, int type, bool must_operation, char *message) {
+    Statement *opt = NULL;
     Statement *st = NULL;
+    Token *tmp = NULL;
     long int line = 0;
     line = delToken(pm);
     parserOperation(CALLPASERSSIGNATURE);
-    if (!call_success(pm))
-        goto return_;
-    if (readBackToken(pm) == OPERATION){
-        Token *tmp;
-        tmp = popAheadToken(pm);
-        times = tmp->data.st;
-        freeToken(tmp, true, false);
-    }
-    else if (must_operation){
+    if (!call_success(pm) || readBackToken(pm) != OPERATION && must_operation){
         syntaxError(pm, syntax_error, line, 1, message);
         goto return_;
     }
-    st = callBack(times, line, pm->file);
+    tmp = popAheadToken(pm);
+    opt = tmp->data.st;
+    freeToken(tmp, true, false);
+    st = callBack(opt, line, pm->file);
     addStatementToken(type, st, pm);
     return_:
     return;
@@ -553,7 +607,7 @@ void parserDef(PASERSSIGNATURE){
                             "Don't get a function/class name"))
         goto error_;
 
-    if (!checkToken_(pm, MATHER_LP)) {
+    if (!checkToken(pm, MATHER_LP)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get a function/class ( before parameter");
         goto error_;
     }
@@ -561,7 +615,7 @@ void parserDef(PASERSSIGNATURE){
         syntaxError(pm, syntax_error, line, 1, "Don't get a function/class parameter");
         goto error_;
     }
-    if (!checkToken_(pm, MATHER_RP)) {
+    if (!checkToken(pm, MATHER_RP)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get a function/class ) after parameter");
         goto error_;
     }
@@ -606,7 +660,7 @@ void parserCode(PASERSSIGNATURE) {
         }
         break;
         again_:
-        if (!checkToken_(pm, MATHER_ENTER))
+        if (!checkToken(pm, MATHER_ENTER))
             goto return_;
     }
     st = makeStatement(line, pm->file);
@@ -616,7 +670,7 @@ void parserCode(PASERSSIGNATURE) {
         goto error_;
 
     writeLog_(pm->grammar_debug, GRAMMAR_DEBUG, "parserCode: call parserCommandList success\n", NULL);
-    if (!checkToken_(pm, MATHER_RC)) {
+    if (!checkToken(pm, MATHER_RC)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get the }");  // 使用{的行号
         goto error_;
     }
@@ -773,14 +827,14 @@ int tailCall(PASERSSIGNATURE, Token *left_token, Statement **st){
         return -1;
     long int line = delToken(pm);
 
-    if (checkToken_(pm, MATHER_RP))
+    if (checkToken(pm, MATHER_RP))
         goto not_pt;
 
     if (!parserParameter(CALLPASERSSIGNATURE, &pt, false, false, false, MATHER_COMMA, MATHER_ASSIGNMENT)) {
         syntaxError(pm, syntax_error, line, 1, "Don't get call parameter");
         return 0;
     }
-    if (!checkToken_(pm, MATHER_RP)){
+    if (!checkToken(pm, MATHER_RP)){
         freeParameter(pt, true);
         syntaxError(pm, syntax_error, line, 1, "Don't get ) from call back");
         return 0;
@@ -825,13 +879,13 @@ void parserPoint(PASERSSIGNATURE){
  */
 int getOperation(PASERSSIGNATURE, int right_type, Statement **st, char *name){
     *st = NULL;
-    if (checkToken_(pm, right_type))
+    if (checkToken(pm, right_type))
         goto return_;
 
     if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, st, NULL))
         return 0;
 
-    if (!checkToken_(pm, right_type)){
+    if (!checkToken(pm, right_type)){
         freeStatement(*st);
         return -1;
     }
@@ -923,7 +977,7 @@ void parserBaseValue(PASERSSIGNATURE){
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a dict parameter");
             goto return_;
         }
-        if (!checkToken_(pm, MATHER_RC)) {
+        if (!checkToken(pm, MATHER_RC)) {
             freeToken(value_token, true, true);
             freeParameter(pt, true);
             syntaxError(pm, syntax_error, value_token->line, 1, "Don't get a } after dict");

+ 2 - 1
parser/include/__grammar.h

@@ -48,12 +48,13 @@ void parserPoint(PASERSSIGNATURE);
 void parserFactor(PASERSSIGNATURE);
 void parserAssignment(PASERSSIGNATURE);
 void parserTuple(PASERSSIGNATURE);
+void parserImport(PASERSSIGNATURE);
 
 void syntaxError(ParserMessage *pm, int status,long int line , int num, ...);
 
 int readBackToken(ParserMessage *pm);
 Token *popAheadToken(ParserMessage *pm);
-bool checkToken_(ParserMessage *pm, int type);
+bool checkToken(ParserMessage *pm, int type);
 
 bool commandCallControl_(PASERSSIGNATURE, MakeControlFunction callBack, int type, Statement **st,
                          char *log_message, bool must_operation, char *error_message);

+ 30 - 56
parser/syntax.c

@@ -13,7 +13,7 @@
  * @param mather
  */
 void numberMather(int p, LexMather *mather){
-    if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING || mather->status == LEXMATHER_INGPOINT){
+    if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING || mather->status == LEXMATHER_INGPOINT)
         if (isdigit(p) || '.' == p && mather->status == LEXMATHER_ING){
             mather->str = memStrCharcpy(mather->str, 1, true, true, p);
             mather->len += 1;
@@ -27,25 +27,18 @@ void numberMather(int p, LexMather *mather){
                 mather->second_str = memStrCharcpy(mather->second_str, 1, true, true, p);
                 mather->status = LEXMATHER_INGSECOND;
             }
-            else{
+            else
                 mather->status = LEXMATHER_END;
-            }
         }
-        else{
+        else
             mather->status = LEXMATHER_MISTAKE;
-        }
-    }
-    else if (mather->status == LEXMATHER_INGSECOND){
-        if (isalnum(p) ||'_' == p){
+    else if (mather->status == LEXMATHER_INGSECOND)
+        if (isalnum(p) ||'_' == p)
             mather->second_str = memStrCharcpy(mather->second_str, 1, true, true, p);
-        }
-        else{
+        else
             mather->status = LEXMATHER_END;
-        }
-    }
-    else{
+    else
         mather->status = LEXMATHER_MISTAKE;
-    }
 }
 
 /**
@@ -63,12 +56,10 @@ void varMather(int p, LexMather *mather){
             mather->len ++;
             mather->status = LEXMATHER_ING;
         }
-        else if(mather->status == LEXMATHER_ING){
+        else if(mather->status == LEXMATHER_ING)
             mather->status = LEXMATHER_END_SECOND;
-        }
-        else if(mather->status == LEXMATHER_START){
+        else if(mather->status == LEXMATHER_START)
             mather->status = LEXMATHER_MISTAKE;
-        }
     }
     else{
         mather->status = LEXMATHER_MISTAKE;
@@ -84,48 +75,37 @@ void varMather(int p, LexMather *mather){
  * @param mather
  */
 void stringMather(int p, LexMather *mather){
-    if (mather->status == LEXMATHER_START){
+    if (mather->status == LEXMATHER_START)
         if ('\"' == p || '\'' == p){
             mather->status = LEXMATHER_ING;
             mather->string_type = p;
         }
-        else{
+        else
             mather->status = LEXMATHER_MISTAKE;
-        }
-    }
-    else if (mather->status == LEXMATHER_ING){
-        if (mather->string_type == p){
+    else if (mather->status == LEXMATHER_ING)
+        if (mather->string_type == p)
             mather->status = LEXMATHER_INGPASS;
-        }
-        else if (EOF == p){
+        else if (EOF == p)
             mather->status = LEXMATHER_MISTAKE;
-        }
         else{
             mather->str = memStrCharcpy(mather->str, 1, true, true, p);
             mather->len ++;
             mather->status = LEXMATHER_ING;
         }
-    }
-    else if (mather->status == LEXMATHER_INGSECOND){
-        if (isalnum(p) ||'_' == p){
+    else if (mather->status == LEXMATHER_INGSECOND)
+        if (isalnum(p) ||'_' == p)
             mather->second_str = memStrCharcpy(mather->second_str, 1, true, true, p);
-        }
-        else{
+        else
             mather->status = LEXMATHER_END;
-        }
-    }
-    else if(mather->status == LEXMATHER_INGPASS){
+    else if(mather->status == LEXMATHER_INGPASS)
         if (isalpha(p) ||'_' == p){
             mather->second_str = memStrCharcpy(mather->second_str, 1, true, true, p);
             mather->status = LEXMATHER_INGSECOND;
         }
-        else{
+        else
             mather->status = LEXMATHER_END;
-        }
-    }
-    else{
+    else
         mather->status = LEXMATHER_MISTAKE;
-    }
 }
 
 /**
@@ -135,22 +115,18 @@ void stringMather(int p, LexMather *mather){
  * @param dest_p
  */
 void strMather(int p, LexMather *mather, const char *dest_p){
-    if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING){
+    if (mather->status == LEXMATHER_START || mather->status == LEXMATHER_ING)
         if (p == dest_p[mather->len]){
             mather->str = memStrCharcpy(mather->str, 1, true, true, p);
             mather->len ++;
             mather->status = LEXMATHER_ING;
         }
-        else if(mather->status == LEXMATHER_ING && mather->len == memStrlen((char *)dest_p)){
+        else if(mather->status == LEXMATHER_ING && mather->len == memStrlen((char *)dest_p))
             mather->status = LEXMATHER_END;
-        }
-        else{
+        else
             mather->status = LEXMATHER_MISTAKE;
-        }
-    }
-    else{
+    else
         mather->status = LEXMATHER_MISTAKE;
-    }
 }
 
 /**
@@ -165,12 +141,10 @@ void charMather(int p, LexMather *mather, int dest_p){
         mather->len ++;
         mather->status = LEXMATHER_ING;
     }
-    else if (mather->status == LEXMATHER_ING){
+    else if (mather->status == LEXMATHER_ING)
         mather->status = LEXMATHER_END;
-    }
-    else{
+    else
         mather->status = LEXMATHER_MISTAKE;
-    }
 }
 
 /**
@@ -277,6 +251,7 @@ int getMatherStatus(LexFile *file, LexMathers *mathers, FILE *debug) {
 
         strMatherMacro(MATHER_LINK, "->");
         strMatherMacro(MATHER_RAISE, "raise");
+        strMatherMacro(MATHER_FROM, "from");
 
         status = checkoutMather(mathers, MATHER_MAX, debug);
         writeLog_(debug, LEXICAL_DEBUG, "get status: %d\n", status);
@@ -292,12 +267,11 @@ int getMatherStatus(LexFile *file, LexMathers *mathers, FILE *debug) {
  * @return
  */
 Token *getToken(LexFile *file, LexMathers *mathers, FILE *debug) {
-    writeLog_(debug, DEBUG, "get token: [%ld]\n", file->count);
     int status = MATHER_SPACE;
-    while (status == MATHER_SPACE){
-        status = getMatherStatus(file, mathers, debug);
-    }
     Token *tmp;
+    writeLog_(debug, DEBUG, "get token: [%ld]\n", file->count);
+    while (status == MATHER_SPACE)
+        status = getMatherStatus(file, mathers, debug);
     if (status == -2){
         writeLog_(debug, ERROR, "lexical ERROR\n", NULL);
         tmp = makeLexToken(MATHER_ERROR_, NULL, NULL, file->line);

+ 1 - 1
parser/token.c

@@ -70,7 +70,7 @@ TokenMessage *makeTokenMessage(char *file_dir, char *debug) {
     tm->ts = makeTokenStream();
 #if OUT_LOG
     if (debug != NULL){
-        char *debug_dir = memStrcat(debug, LEXICAL_LOG, false);
+        char *debug_dir = memStrcat(debug, LEXICAL_LOG, false, false);
         if (access(debug_dir, F_OK) != 0 || access(debug_dir, W_OK) == 0)
             tm->debug = fopen(debug_dir, "w");
         memFree(debug_dir);

+ 2 - 5
src/__run.c

@@ -66,16 +66,13 @@ ResultType getVarInfo(char **name, int *times, INTER_FUNCTIONSIG){
 }
 
 char *setStrVarName(char *old, bool free_old, INTER_FUNCTIONSIG_CORE) {
-    char *name = memStrcat(inter->data.var_str_prefix, old, false);
-    if (free_old)
-        memFree(old);
-    return name;
+    return memStrcat(inter->data.var_str_prefix, old, false, free_old);
 }
 
 char *setNumVarName(NUMBER_TYPE num, INTER_FUNCTIONSIG_CORE) {
     char name[50];
     snprintf(name, 50, "%"NUMBER_FORMAT, num);
-    return memStrcat(inter->data.var_num_prefix, name, false);
+    return memStrcat(inter->data.var_num_prefix, name, false, false);
 }
 
 char *getNameFromValue(Value *value, INTER_FUNCTIONSIG_CORE) {

+ 50 - 4
src/inter.c

@@ -29,7 +29,7 @@ Inter *newInter(char *code_file, char *debug_dir, Result *global_result, int *st
         goto return_;
     }
 
-    type = globalIterStatement(global_inter, global_result);
+    type = globalIterStatement(global_inter, global_result, NULL);
     if (type == error_return)
         printError(global_result, global_inter, true);
 
@@ -43,12 +43,15 @@ Inter *makeInter(char *code_file, char *debug) {
     setBaseInterData(tmp);
     tmp->base = NULL;
     tmp->link_base = NULL;
+    tmp->hash_base = NULL;
+    tmp->base_var = NULL;
+
     tmp->statement = makeStatement(0, code_file);
     tmp->var_list = makeVarList(tmp);
     tmp->data.log_dir = memStrcpy(debug);
 
     if (debug != NULL && !args.stdout_inter){
-        char *debug_dir = memStrcat(debug, INTER_LOG, false), *error_dir = memStrcat(debug, INTER_ERROR, false);
+        char *debug_dir = memStrcat(debug, INTER_LOG, false, false), *error_dir = memStrcat(debug, INTER_ERROR, false, false);
         tmp->data.debug = fopen(debug_dir, "w");
         tmp->data.error = fopen(error_dir, "w");
         memFree(debug_dir);
@@ -86,13 +89,16 @@ void freeBaseInterData(struct Inter *inter){
     }
 }
 
-void freeInter(Inter *inter, bool self){
+void freeInter(Inter *inter, bool self, bool show_gc) {
     freeBase(inter, return_);
 
-    if (getc(stdin) == '1') {
+    if (show_gc && (printf("Enter '1' to show gc: "), getc(stdin) == '1')) {
         printLinkValueGC("\n\nprintLinkValueGC TAG : freeInter", inter);
         printValueGC("\nprintValueGC TAG : freeInter", inter);
         printVarGC("\nprintVarGC TAG : freeInter", inter);
+        printHashTableGC("\nprintHashTableGC TAG : freeInter", inter);
+        while (getc(stdin) != '\n')
+            PASS;
     }
 
     freeStatement(inter->statement);  // Statement放在Value前面释放, 因为base_value的释放需要处理gc_status
@@ -166,6 +172,19 @@ void printVarGC(char *tag, Inter *inter){
     printf("printVarGC TAG : END\n");
 }
 
+void printHashTableGC(char *tag, Inter *inter){
+    HashTable *base = inter->hash_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);
+        printf("-------------------------------------------\n");
+        base = base->gc_next;
+    }
+    printf("printHashTableGC 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);
@@ -173,3 +192,30 @@ void showLinkValue(struct LinkValue *base){
     printLinkValue(base, "value = ", "\n", stdout);
     printf("--------------------------\n");
 }
+
+void mergeInter(Inter *new, Inter *base){
+    Value **base_value = NULL;
+    LinkValue **base_linkValue = NULL;
+    HashTable **base_hash = NULL;
+    Var **base_var = NULL;
+
+    for (base_value = &base->base; *base_value != NULL; base_value = &(*base_value)->gc_next)
+        PASS;
+    for (base_linkValue = &base->link_base; *base_linkValue != NULL; base_linkValue = &(*base_linkValue)->gc_next)
+        PASS;
+    for (base_hash = &base->hash_base; *base_hash != NULL; base_hash = &(*base_hash)->gc_next)
+        PASS;
+    for (base_var = &base->base_var; *base_var != NULL; base_var = &(*base_var)->gc_next)
+        PASS;
+
+    *base_value = new->base;
+    *base_linkValue = new->link_base;
+    *base_hash = new->hash_base;
+    *base_var = new->base_var;
+
+    new->base = NULL;
+    new->link_base = NULL;
+    new->hash_base = NULL;
+    new->base_var = NULL;
+    freeInter(new, true, false);
+}

+ 1 - 2
src/parameter.c

@@ -297,7 +297,7 @@ ResultType parameterFromVar(Parameter **function_ad, VarList *function_var, NUMB
         }
 
         freeResult(result);
-        value = findFromVarList(str_name, var_list, int_times, true);
+        value = findFromVarList(str_name, int_times, true, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         memFree(str_name);
 
         if(value == NULL) {
@@ -319,7 +319,6 @@ ResultType parameterFromVar(Parameter **function_ad, VarList *function_var, NUMB
                            name, father, true);
             goto reutnr_;
         }
-        value = copyLinkValue(value, inter);
 
         not_return:
         freeResult(result);

+ 8 - 2
src/run.c

@@ -70,6 +70,12 @@ ResultType runStatement(INTER_FUNCTIONSIG) {
         case include_file:
             type = includeFile(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
             break;
+        case import_file:
+            type = importFile(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
+            break;
+        case from_import_file:
+            type = fromImportFile(CALL_INTER_FUNCTIONSIG(st, var_list, result, father));
+            break;
         default:
             setResult(result, inter, father);
             break;
@@ -119,8 +125,8 @@ ResultType iterStatement(INTER_FUNCTIONSIG) {
  * @param inter
  * @return
  */
-ResultType globalIterStatement(Inter *inter, Result *result) {
-    LinkValue *father = makeLinkValue(makeObject(inter, copyVarList(inter->var_list, false, inter), NULL, NULL), NULL, inter);
+ResultType globalIterStatement(Inter *inter, Result *result, LinkValue *base_father) {
+    LinkValue *father = makeLinkValue(makeObject(inter, copyVarList(inter->var_list, false, inter), NULL, NULL), base_father, inter);
     Statement *base_st = NULL;
     VarList *var_list = NULL;
     enum ResultType type;

+ 1 - 1
src/runcall.c

@@ -89,7 +89,7 @@ ResultType callClass(LinkValue *class_value, Parameter *parameter, INTER_FUNCTIO
     setResultOperation(result, value, inter);
 
     char *init_name = setStrVarName(inter->data.object_init, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-    __init__ = findFromVarList(init_name, value->value->object.var, 0, false);
+    __init__ = findFromVarList(init_name, 0, false, CALL_INTER_FUNCTIONSIG_CORE(value->value->object.var));
     memFree(init_name);
 
     if (__init__ != NULL && __init__->value->type == function){

+ 97 - 1
src/runfile.c

@@ -38,4 +38,100 @@ ResultType includeFile(INTER_FUNCTIONSIG) {
     freeStatement(new_st);
     freeParserMessage(pm, true);
     return result->type;
-}
+}
+
+ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONSIG) {
+    Inter *import_inter = NULL;
+    ParserMessage *pm = NULL;
+    setResultCore(result);
+    if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, father)))
+        goto return_;
+
+    if (!isType(result->value->value, string)) {
+        setResultError(result, inter, "TypeException", "Don't get a string value", st, father, true);
+        goto return_;
+    }
+
+    *file_dir = result->value->value->data.str.str;
+    freeResult(result);
+    if (checkFile(*file_dir) != 1) {
+        setResultError(result, inter, "ImportFileException", "File is not readable", st, father, true);
+        goto return_;
+    }
+
+    import_inter = makeInter(*file_dir, NULL);
+    pm = makeParserMessage(*file_dir, NULL);
+    parserCommandList(pm, import_inter, true, import_inter->statement);
+    if (pm->status != success) {
+        freeInter(import_inter, true, false);
+        setResultError(result, inter, "ImportSyntaxException", pm->status_message, st, father, true);
+        goto return_;
+    }
+    globalIterStatement(import_inter, result, father);
+    if (!run_continue(result)) {
+        freeInter(import_inter, true, false);
+        result->value = makeLinkValue(inter->base, father, inter);  // 重新设定none值
+        setResultError(result, inter, NULL, NULL, st, father, false);
+        goto return_;
+    }
+    *new_object = import_inter->var_list;
+    import_inter->var_list = NULL;
+    mergeInter(import_inter, inter);
+    setResult(result, inter, father);
+
+    return_:
+    freeParserMessage(pm, true);
+    return result->type;
+}
+
+ResultType importFile(INTER_FUNCTIONSIG) {
+    char *file_dir = NULL;
+    VarList *new_object = NULL;
+    LinkValue *import_value = NULL;
+    setResultCore(result);
+    importFileCore(&new_object, &file_dir, CALL_INTER_FUNCTIONSIG(st->u.import_file.file, var_list, result, father));
+    if (!run_continue(result))
+        goto return_;
+
+    freeResult(result);
+    import_value = makeLinkValue(makeObject(inter, new_object, copyVarList(var_list, false, inter), NULL), father, inter);
+    if (st->u.import_file.as != NULL)
+        assCore(st->u.import_file.as, import_value, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, father));
+    else {
+        char *name = splitDir(file_dir);
+        char *value_name = setStrVarName(name, false, inter, var_list);
+        addFromVarList(value_name, makeLinkValue(makeStringValue(value_name, inter), father, inter), 0, import_value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        memFree(name);
+        memFree(value_name);
+    }
+    setResult(result, inter, father);
+
+    return_:
+    return result->type;
+}
+
+
+ResultType fromImportFile(INTER_FUNCTIONSIG) {
+    char *file_dir = NULL;
+    VarList *new_object = NULL;
+    Parameter *pt = st->u.from_import_file.pt;
+    Parameter *as = st->u.from_import_file.as != NULL ? st->u.from_import_file.as : st->u.from_import_file.pt;
+    setResultCore(result);
+    importFileCore(&new_object, &file_dir, CALL_INTER_FUNCTIONSIG(st->u.from_import_file.file, var_list, result, father));
+    if (!run_continue(result))
+        goto return_;
+
+    freeResult(result);
+    if (pt != NULL) {
+        setParameter(pt, as, var_list, father, CALL_INTER_FUNCTIONSIG_NOT_ST(new_object, result, father));
+        if (!run_continue(result))
+            goto return_;
+    }
+    else
+        updateHashTable(var_list->hashtable, new_object->hashtable, inter);
+    setResult(result, inter, father);
+
+    return_:
+    freeVarList(new_object, true);
+    return result->type;
+}

+ 7 - 8
src/runoperation.c

@@ -67,7 +67,7 @@ ResultType addOperation(INTER_FUNCTIONSIG) {
     if (left.value->value->type == number && right.value->value->type == number)
         result->value->value = makeNumberValue(left.value->value->data.num.num + right.value->value->data.num.num, inter);
     else if(left.value->value->type == string && right.value->value->type == string){
-        char *new_string = memStrcat(left.value->value->data.str.str, right.value->value->data.str.str, false);
+        char *new_string = memStrcat(left.value->value->data.str.str, right.value->value->data.str.str, false, false);
         result->value->value = makeStringValue(new_string, inter);
         memFree(new_string);
     }
@@ -235,7 +235,6 @@ ResultType assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST){
         pointAss(name, value, CALL_INTER_FUNCTIONSIG_NOT_ST (var_list, result, father));
     else{
         char *str_name = NULL;
-
         getVarInfo(&str_name, &int_times, CALL_INTER_FUNCTIONSIG(name, var_list, result, father));
         if (!run_continue(result)) {
             memFree(str_name);
@@ -244,7 +243,7 @@ ResultType assCore(Statement *name, LinkValue *value, INTER_FUNCTIONSIG_NOT_ST){
         LinkValue *var_value = copyLinkValue(value, inter);
         if (var_value->aut == auto_aut)
             var_value->aut = name->aut;
-        addFromVarList(str_name, copyLinkValue(result->value, inter), int_times, var_value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
+        addFromVarList(str_name, result->value, int_times, var_value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
         memFree(str_name);
         freeResult(result);
 
@@ -290,26 +289,26 @@ ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
 
     freeResult(result);
     result->type = operation_return;
-    result->value = findFromVarList(name, var_list, int_times, false);
+    result->value = findFromVarList(name, int_times, false, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     if (result->value == NULL) {
-        char *info = memStrcat("Name Not Found: ", name, false);
+        char *info = memStrcat("Name Not Found: ", name, false, false);
         setResultError(result, inter, "NameException", info, st, father, true);
         memFree(info);
     }
     else if ((st->aut == public_aut) && (result->value->aut != public_aut && result->value->aut != auto_aut)){
         setResultCore(result);
-        char *info = memStrcat("Wrong Permissions: access variables as public ", name, false);
+        char *info = memStrcat("Wrong Permissions: access variables as public ", name, false, false);
         setResultError(result, inter, "PermissionsException", info, st, father, true);
         memFree(info);
     }
     else if ((st->aut == protect_aut) && (result->value->aut == private_aut)){
         setResultCore(result);
-        char *info = memStrcat("Wrong Permissions: access variables as protect ", name, false);
+        char *info = memStrcat("Wrong Permissions: access variables as protect ", name, false, false);
         setResultError(result, inter, "PermissionsException", info, st, father, true);
         memFree(info);
     }
     else
-        setResultOperationBase(result, copyLinkValue(result->value, inter), inter);
+        setResultOperationBase(result, result->value, inter);
 
     memFree(name);
     return result->type;

+ 35 - 0
src/statement.c

@@ -201,6 +201,23 @@ Statement *makeIncludeStatement(Statement *file, long int line, char *file_dir){
     return tmp;
 }
 
+Statement *makeImportStatement(Statement *file, Statement *as) {
+    Statement *tmp = makeStatement(file->line, file->code_file);
+    tmp->type = import_file;
+    tmp->u.import_file.file = file;
+    tmp->u.import_file.as = as;
+    return tmp;
+}
+
+Statement *makeFromImportStatement(Statement *file, Parameter *as, Parameter *pt) {
+    Statement *tmp = makeStatement(file->line, file->code_file);
+    tmp->type = from_import_file;
+    tmp->u.from_import_file.file = file;
+    tmp->u.from_import_file.as = as;
+    tmp->u.from_import_file.pt = pt;
+    return tmp;
+}
+
 void connectStatement(Statement *base, Statement *new){
     for (PASS; base->next != NULL; base = base->next)
         PASS;
@@ -303,6 +320,15 @@ void freeStatement(Statement *st){
             case include_file:
                 freeStatement(st->u.include_file.file);
                 break;
+            case import_file:
+                freeStatement(st->u.import_file.file);
+                freeStatement(st->u.import_file.as);
+                break;
+            case from_import_file:
+                freeStatement(st->u.from_import_file.file);
+                freeParameter(st->u.from_import_file.as, true);
+                freeParameter(st->u.from_import_file.pt, true);
+                break;
             default:
                 break;
         }
@@ -422,6 +448,15 @@ Statement *copyStatementCore(Statement *st){
         case include_file:
             new->u.include_file.file = copyStatement(st->u.include_file.file);
             break;
+        case import_file:
+            new->u.import_file.file = copyStatement(st->u.import_file.file);
+            new->u.import_file.as = copyStatement(st->u.import_file.as);
+            break;
+        case from_import_file:
+            new->u.from_import_file.file = copyStatement(st->u.from_import_file.file);
+            new->u.from_import_file.as = copyParameter(st->u.from_import_file.as);
+            new->u.from_import_file.pt = copyParameter(st->u.from_import_file.pt);
+            break;
         default:
             break;
     }

+ 4 - 1
src/value.c

@@ -171,7 +171,10 @@ void freeLinkValue(LinkValue **value) {
 }
 
 LinkValue *copyLinkValue(LinkValue *value, Inter *inter) {
-    LinkValue *tmp = makeLinkValue(value->value, value->father, inter);
+    LinkValue *tmp = NULL;
+    if (value == NULL)
+        return NULL;
+    tmp = makeLinkValue(value->value, value->father, inter);
     tmp->aut = value->aut;
     return tmp;
 }

+ 27 - 13
src/var.c

@@ -6,8 +6,8 @@ Var *makeVar(char *name, LinkValue *value, LinkValue *name_, Inter *inter) {
     tmp = memCalloc(1, sizeof(Var));
     setGC(&tmp->gc_status);
     tmp->name = memStrcpy(name);
-    tmp->value = value;
-    tmp->name_ = name_;
+    tmp->value = copyLinkValue(value, inter);
+    tmp->name_ = copyLinkValue(name_, inter);
     tmp->next = NULL;
 
     tmp->gc_next = NULL;
@@ -108,43 +108,57 @@ HASH_INDEX time33(char *key){ // hash function
     return (hash & (HASH_INDEX)0x7FFFFFFF) % MAX_SIZE;
 }
 
-
-void addVar(char *name, LinkValue *value, LinkValue *name_, INTER_FUNCTIONSIG_CORE) {
-    HASH_INDEX index = time33(name);
-    Var **base = &var_list->hashtable->hashtable[index];
+void addVarCore(Var **base, char *name, LinkValue *value, LinkValue *name_, Inter *inter) {
     for (PASS; true; base = &(*base)->next) {
         if (*base == NULL) {
             *base = makeVar(name, value, name_, inter);
             break;
         } else if (eqString((*base)->name, name)) {
-            (*base)->value = value;
+            (*base)->value->value = value->value;
+            (*base)->value->father = value->father;
             break;
         }
     }
 }
 
-LinkValue *findVar(char *name, VarList *var_list, bool del_var) {
+
+void addVar(char *name, LinkValue *value, LinkValue *name_, INTER_FUNCTIONSIG_CORE) {
+    HASH_INDEX index = time33(name);
+    addVarCore(&var_list->hashtable->hashtable[index], name, value, name_, inter);
+}
+
+void updateHashTable(HashTable *update, HashTable *new, Inter *inter) {
+    for (int i = 0; i < MAX_SIZE; i++)
+        for (Var *tmp = new->hashtable[i]; tmp != NULL; tmp = tmp->next)
+            addVarCore(&update->hashtable[i], tmp->name, tmp->value, tmp->name_, inter);
+}
+
+
+LinkValue *findVar(char *name, bool del_var, INTER_FUNCTIONSIG_CORE) {
     LinkValue *tmp = NULL;
     HASH_INDEX index = time33(name);
 
     for (Var **base = &var_list->hashtable->hashtable[index]; *base != NULL; base = &(*base)->next){
         if (eqString((*base)->name, name)){
             tmp = (*base)->value;
-            if (del_var)
-                *base = (*base)->next;
+            if (del_var) {
+                Var *next = (*base)->next;
+                (*base)->next = NULL;
+                *base = next;
+            }
             goto return_;
         }
     }
     return_:
-    return tmp;
+    return copyLinkValue(tmp, inter);
 }
 
-LinkValue *findFromVarList(char *name, VarList *var_list, NUMBER_TYPE times, bool del_var) {
+LinkValue *findFromVarList(char *name, NUMBER_TYPE times, bool del_var, INTER_FUNCTIONSIG_CORE) {
     LinkValue *tmp = NULL;
     for (NUMBER_TYPE i=0; i < times && var_list->next != NULL; i++)
         var_list = var_list->next;
     for (PASS; var_list != NULL && tmp == NULL; var_list = var_list->next)
-        tmp = findVar(name, var_list, del_var);
+        tmp = findVar(name, del_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     return tmp;
 }