Przeglądaj źródła

fix: 修复循环导入无法newObjectSetting的问题

该bug存在于提交dcb11c6ec094
因为多次导入同一个包导致newObjectSetting重复, 造成问题
现在只有第一次导入该包的时候会newObjectSetting
允许在import或者from语句中设置保护读取

link #5
SongZihuan 4 lat temu
rodzic
commit
8bd42e5173

+ 4 - 2
VirtulMathCore/include/statement.h

@@ -173,11 +173,13 @@ struct Statement{
         struct {
             struct Statement *file;
             struct Statement *as;
+            bool is_lock;
         } import_file;
         struct {
             struct Statement *file;
             struct Parameter *pt;
             struct Parameter *as;
+            bool is_lock;
         } from_import_file;
         struct {
             struct Parameter *var;
@@ -290,8 +292,8 @@ Statement *makeYieldStatement(Statement *value, fline line, char *file);
 Statement *makeRaiseStatement(Statement *value, fline line, char *file);
 Statement *makeAssertStatement(Statement *conditions, fline line, char *file);
 Statement *makeIncludeStatement(Statement *file, fline line, char *file_dir);
-Statement *makeImportStatement(Statement *file, Statement *as);
-Statement *makeFromImportStatement(Statement *file, Parameter *as, Parameter *pt);
+Statement *makeImportStatement(Statement *file, Statement *as, bool is_lock);
+Statement *makeFromImportStatement(Statement *file, Parameter *as, Parameter *pt, bool is_lock);
 Statement *makeDefaultVarStatement(Parameter *var, fline line, char *file_dir, enum DefaultType type);
 Statement *makeLabelStatement(Statement *var, Statement *command, char *label, fline line, char *file_dir);
 Statement *makeGotoStatement(Statement *return_, Statement *times, Statement *label, fline line, char *file_dir);

+ 19 - 2
VirtulMathCore/parser/grammar.c

@@ -375,8 +375,25 @@ void parserGoto(PASERSSIGNATURE){
 void parserImport(PASERSSIGNATURE) {
     Statement *opt = NULL;
     Statement *st = NULL;
+    bool is_lock = false;
     int token_type = readBackToken(pm);
     long int line = delToken(pm);
+
+    if (checkToken(pm, MATHER_COLON)) {
+        switch (readBackToken(pm)) {
+            case MATHER_PUBLIC:
+                break;
+            case MATHER_PRIVATE:
+            case MATHER_PROTECT:
+                is_lock = true;
+                break;
+            default:
+                syntaxError(pm, syntax_error, opt->line, 1, "Don't get a aut token");
+                goto return_;
+        }
+        delToken(pm);
+    }
+
     if (!callChildStatement(CALLPASERSSIGNATURE, parserOperation, OPERATION, &opt, "Don't get a import file"))
         goto return_;
     if (token_type == MATHER_IMPORT) {
@@ -385,7 +402,7 @@ void parserImport(PASERSSIGNATURE) {
             freeStatement(opt);
             goto return_;
         }
-        st = makeImportStatement(opt, as);
+        st = makeImportStatement(opt, as, is_lock);
     }
     else{
         Parameter *pt = NULL;
@@ -416,7 +433,7 @@ void parserImport(PASERSSIGNATURE) {
         }
 
         mul_:
-        st = makeFromImportStatement(opt, as, pt);
+        st = makeFromImportStatement(opt, as, pt, is_lock);
     }
 
     addStatementToken(IMPORT, st, pm);

+ 2 - 1
VirtulMathCore/src/inter.c

@@ -217,7 +217,8 @@ void mergeInter(Inter *new, Inter *base){
     *base_linkValue = new->link_base;
     *base_hash = new->hash_base;
     *base_var = new->base_var;
-    new->package = NULL;
+    if (base->package == NULL)
+        base->package = new->package;
     memFree(new);
 }
 

+ 39 - 15
VirtulMathCore/src/runfile.c

@@ -208,28 +208,33 @@ ResultType runImportFile(Inter *import_inter, char **path, int status, INTER_FUN
     return result->type;
 }
 
-static bool getPackage(LinkValue **imp_value, char *md5_str, char *split, int status, char **path, INTER_FUNCTIONSIG) {
+static bool getPackage(LinkValue **imp_value, char *md5_str, char *split, int status, char **path, int *is_new, bool is_lock, INTER_FUNCTIONSIG) {
     Value *pg;
     Inter *imp_inter;
-    if ((pg = checkPackage(inter->package, md5_str, split)) == NULL) {
+    if (is_lock || (pg = checkPackage(inter->package, md5_str, split)) == NULL) {
         setResultCore(result);
+        *is_new = true;
         imp_inter = deriveInter(belong, inter);
         pg = makeObject(inter, imp_inter->var_list, copyVarList(var_list, false, inter), NULL);
-        inter->package = makePackage(pg, md5_str, split, inter->package);
+        if (!is_lock)
+            inter->package = makePackage(pg, md5_str, split, inter->package);  // 只有当不是保护读入或私密读入的时才可以记录
         imp_inter->package = inter->package;
 
         freeResult(result);
-        runImportFile(imp_inter, path, status, CALL_INTER_FUNCTIONSIG(st->u.import_file.file, var_list, result, belong));
+        runImportFile(imp_inter, path, status, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
         if (!CHECK_RESULT(result))
             return false;
-    }
+    } else
+        *is_new = false;
     *imp_value = makeLinkValue(pg, belong, inter);
     gc_addTmpLink(&(*imp_value)->gc_status);
     return true;
 }
 
-
 ResultType importFile(INTER_FUNCTIONSIG) {
+    bool is_new = false;
+    bool is_lock = st->u.import_file.is_lock;
+    Statement *file = st->u.import_file.file;
     int status;
     char *split_path = NULL;
     char *path = NULL;
@@ -239,18 +244,19 @@ ResultType importFile(INTER_FUNCTIONSIG) {
     setResultCore(result);
     gc_freeze(inter, var_list, NULL, true);
 
-    importFileCore(&path, &split_path, &status, CALL_INTER_FUNCTIONSIG(st->u.import_file.file, var_list, result, belong));
+    importFileCore(&path, &split_path, &status, CALL_INTER_FUNCTIONSIG(file, var_list, result, belong));
     if (!CHECK_RESULT(result))
         goto return_;
 
     getFileMd5(path, md5_str);
-    if (!getPackage(&imp_value, md5_str, split_path, status, &path, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)))
+    if (!getPackage(&imp_value, md5_str, split_path, status, &path, &is_new, is_lock, CALL_INTER_FUNCTIONSIG(file, var_list, result, belong)))
         goto return_;
     freeResult(result);
     if (st->u.import_file.as == NULL)
-        addStrVar(split_path, false, false, imp_value, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        addStrVar(split_path, false, is_new, imp_value, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     else
-        assCore(st->u.import_file.as, imp_value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        assCore(st->u.import_file.as, imp_value, false, is_new, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+
     if (CHECK_RESULT(result))
         setResult(result, inter, belong);
     gc_freeTmpLink(&imp_value->gc_status);
@@ -279,6 +285,9 @@ static ResultType importParameter(fline line, char *file, Parameter *call_pt, Pa
 
 ResultType fromImportFile(INTER_FUNCTIONSIG) {
     int status;
+    bool is_new;
+    bool is_lock = st->u.from_import_file.is_lock;
+    Statement *file = st->u.from_import_file.file;
     char *split_path = NULL;
     char *path = NULL;
     char md5_str[MD5_STRING] = {};
@@ -288,29 +297,44 @@ ResultType fromImportFile(INTER_FUNCTIONSIG) {
     Parameter *as = st->u.from_import_file.as != NULL ? st->u.from_import_file.as : st->u.from_import_file.pt;
 
     setResultCore(result);
-    importFileCore(&path, &split_path, &status, CALL_INTER_FUNCTIONSIG(st->u.from_import_file.file, var_list, result, belong));
+    gc_freeze(inter, var_list, NULL, true);
+    importFileCore(&path, &split_path, &status, CALL_INTER_FUNCTIONSIG(file, var_list, result, belong));
     if (!CHECK_RESULT(result))
         goto return_;
 
     getFileMd5(path, md5_str);
-    if (!getPackage(&imp_value, md5_str, split_path, status, &path, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)))
+    if (!getPackage(&imp_value, md5_str, split_path, status, &path, &is_new, is_lock, CALL_INTER_FUNCTIONSIG(file, var_list, result, belong)))
         goto return_;
     imp_var = imp_value->value->object.var;
+    if (is_new) {
+        LinkValue *string;
+        freeResult(result);
+        makeStringValue(split_path, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, imp_value));
+        string = result->value;
+        result->value = NULL;
+        freeResult(result);
+
+        newObjectSetting(string, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, imp_value));
+        gc_freeTmpLink(&string->gc_status);
+    }
 
     freeResult(result);
     if (pt != NULL) {
         importParameter(st->line, st->code_file, pt, as, var_list, belong, CALL_INTER_FUNCTIONSIG_NOT_ST(imp_var, result, imp_value));
-        if (!CHECK_RESULT(result))
+        if (!CHECK_RESULT(result)) {
+            printf("TAG A\n");
+            gc_freeTmpLink(&imp_value->gc_status);
             goto return_;
+        }
     }
     else
         updateHashTable(var_list->hashtable, imp_var->hashtable, inter);
-    gc_freeTmpLink(&imp_value->value->gc_status);
     setResult(result, inter, belong);
+    gc_freeTmpLink(&imp_value->gc_status);
 
     return_:
     memFree(path);
     memFree(split_path);
-    freeVarList(imp_var);  // 当需要存储var_list的时候则不需要释放
+    gc_freeze(inter, var_list, NULL, false);
     return result->type;
 }

+ 6 - 2
VirtulMathCore/src/statement.c

@@ -299,20 +299,22 @@ Statement *makeIncludeStatement(Statement *file, fline line, char *file_dir){
     return tmp;
 }
 
-Statement *makeImportStatement(Statement *file, Statement *as) {
+Statement *makeImportStatement(Statement *file, Statement *as, bool is_lock) {
     Statement *tmp = makeStatement(file->line, file->code_file);
     tmp->type = import_file;
     tmp->u.import_file.file = file;
     tmp->u.import_file.as = as;
+    tmp->u.import_file.is_lock = is_lock;
     return tmp;
 }
 
-Statement *makeFromImportStatement(Statement *file, Parameter *as, Parameter *pt) {
+Statement *makeFromImportStatement(Statement *file, Parameter *as, Parameter *pt, bool is_lock) {
     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;
+    tmp->u.from_import_file.is_lock = is_lock;
     return tmp;
 }
 
@@ -634,11 +636,13 @@ Statement *copyStatementCore(Statement *st){
         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);
+            new->u.import_file.is_lock = st->u.import_file.is_lock;
             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);
+            new->u.from_import_file.is_lock = st->u.from_import_file.is_lock;
             break;
         case default_var:
             new->u.default_var.var = copyParameter(st->u.default_var.var);

+ 1 - 1
VirtulMathCore/src/var.c

@@ -149,7 +149,7 @@ vhashn time33(char *key){ // hash function
     return (hash & (vhashn)0x7FFFFFFF) % MAX_SIZE;
 }
 
-void addVarCore(Var **base, char *name, LinkValue *value, LinkValue *name_, Inter *inter) {
+static 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);