Browse Source

feat: 允许import循环导入

该提交存在bug
对import的内容无法做newObjectSetting, 会发生内存错误
SongZihuan 4 năm trước cách đây
mục cha
commit
dcb11c6ec0

+ 3 - 1
VirtulMathCore/CMakeLists.txt

@@ -6,6 +6,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/parser/include)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/include)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/ofunc/include)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/md5/include)
 
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/memory MEM_LIST)
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/parser PASER_LIST)
@@ -15,8 +16,9 @@ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/gc GC_LIST)
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ofunc/src OFUNC_LIST)
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ofunc/clib CLIB_LIST)
 AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/signalhandler HANDLER_LIST)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/md5 MD5_LIST)
 
-ADD_LIBRARY(VirtualMathCore STATIC ${SRC_LIST} ${GC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST} ${ARGUMENT_LIST} ${OFUNC_LIST} ${HANDLER_LIST} ${CLIB_LIST})
+ADD_LIBRARY(VirtualMathCore STATIC ${SRC_LIST} ${GC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST} ${ARGUMENT_LIST} ${OFUNC_LIST} ${HANDLER_LIST} ${CLIB_LIST} ${MD5_LIST})
 IF (NOT (${CMAKE_SYSTEM_NAME} STREQUAL "Windows"))
     TARGET_LINK_LIBRARIES(VirtualMathCore dl)
 ELSE()

+ 8 - 1
VirtulMathCore/file/file.c

@@ -1,7 +1,6 @@
 #include "__virtualmath.h"
 
 /**
- *
  * @param dir 文件地址
  * @return 0-错误, 1-普通文件, 2-目录
  */
@@ -25,6 +24,14 @@ char *splitDir(char * dir){
     char *slash = NULL;
     char *point = NULL;
     char *return_char = NULL;
+
+#ifdef __unix__
+    if (dir[memStrlen(dir) - 1] == '/')
+#else
+    if (dir[memStrlen(dir) - 1] == '\\')
+#endif  // __unix__
+    { dir[memStrlen(dir) - 1] = NUL; }
+
 #ifdef __unix__
     if ((slash = strrchr(dir, '/'))  == NULL)
 #else

+ 4 - 0
VirtulMathCore/include/__macro.h

@@ -23,6 +23,10 @@
 #define REGISTERED_FUNCTIONSIG struct LinkValue *belong, INTER_FUNCTIONSIG_CORE
 #define CALL_REGISTERED_FUNCTION(belong, var_list) belong, CALL_INTER_FUNCTIONSIG_CORE(var_list)
 
+#define MD5_SIZE 16
+#define MD5_STR_LEN (MD5_SIZE * 2)
+#define MD5_STRING MD5_STR_LEN + 1
+
 typedef long long vnum;
 typedef unsigned long long vhashn;
 typedef unsigned long long fline;

+ 1 - 0
VirtulMathCore/include/__virtualmath.h

@@ -6,6 +6,7 @@
 #include "mem.h"
 #include "handler.h"
 #include "file.h"
+#include "md5.h"
 
 #include "gc.h"
 #include "value.h"

+ 1 - 1
VirtulMathCore/include/clib.h

@@ -4,6 +4,6 @@
 
 struct Inter;
 struct LinkValue;
-void runClib(char *file, struct LinkValue *belong, INTER_FUNCTIONSIG_CORE);
+void importClibCore(char *file, struct LinkValue *belong, INTER_FUNCTIONSIG_CORE);
 bool checkCLib(char *file);
 #endif //VIRTUALMATH_CLIB_H

+ 2 - 1
VirtulMathCore/include/inter.h

@@ -8,7 +8,8 @@ struct Inter{
     struct LinkValue *link_base;
     struct HashTable *hash_base;
     struct Var *base_var;
-    struct LinkValue *base_father;
+    struct LinkValue *base_belong;
+    struct Package *package;
 
     struct VarList *var_list;
     struct InterData{

+ 8 - 0
VirtulMathCore/include/md5.h

@@ -0,0 +1,8 @@
+#ifndef MD5_H
+#define MD5_H
+#include "__macro.h"
+
+#define READ_DATA_SIZE	(1024)
+int getFileMd5(const char *path, char *md5str);
+
+#endif

+ 0 - 1
VirtulMathCore/include/parameter.h

@@ -79,7 +79,6 @@ Argument *listToArgument(LinkValue *list_value, long line, char *file, INTER_FUN
 Argument *dictToArgument(LinkValue *dict_value, long line, char *file, INTER_FUNCTIONSIG_NOT_ST);
 
 ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *function_base, VarList *function_var, INTER_FUNCTIONSIG_NOT_ST);
-ResultType setParameter(fline line, char *file, Parameter *call_base, Parameter *function_base, VarList *function_var, LinkValue *function_father, INTER_FUNCTIONSIG_NOT_ST);
 ResultType iterParameter(Parameter *call, Argument **base_ad, bool is_dict, INTER_FUNCTIONSIG_NOT_ST);
 Argument *getArgument(Parameter *call, bool is_dict, INTER_FUNCTIONSIG_NOT_ST);
 

+ 35 - 23
VirtulMathCore/include/value.h

@@ -1,6 +1,5 @@
 #ifndef VIRTUALMATH_VALUE_H
 #define VIRTUALMATH_VALUE_H
-
 #include "__macro.h"
 
 // 标准错误信息定义
@@ -15,28 +14,30 @@
 #define RETURN_ERROR(func, type) #func" function should return "#type" type data"
 #define KEY_INTERRUPT "KeyInterrupt"
 
-typedef struct Value Value;
 typedef struct Argument Argument;
 typedef struct Inter Inter;
+typedef struct VarList VarList;
+typedef enum ResultType ResultType;
+typedef enum BaseErrorType BaseErrorType;
+
+typedef struct Value Value;
 typedef struct LinkValue LinkValue;
 typedef struct Result Result;
 typedef struct Error Error;
 typedef struct Inherit Inherit;
-typedef struct VarList VarList;
-typedef enum ResultType ResultType;
-typedef enum BaseErrorType BaseErrorType;
+typedef struct Package Package;
 
 typedef enum ResultType (*OfficialFunction)(OFFICAL_FUNCTIONSIG);
 typedef void (*Registered)(REGISTERED_FUNCTIONSIG);
 
-enum ValueAuthority{
+enum ValueAuthority {
     auto_aut,
     public_aut,
     protect_aut,
     private_aut
 };
 
-enum ValueType{
+enum ValueType {
     none=0,
     number=1,
     string=2,
@@ -49,16 +50,16 @@ enum ValueType{
     pass_=9,
 };
 
-struct Number{
+struct Number {
     vnum num;
 };
 
-struct String{
+struct String {
     char *str;
 };
 
 struct Function{
-    enum{
+    enum {
         c_function,
         vm_function,
     } type;
@@ -66,7 +67,7 @@ struct Function{
     struct Parameter *pt;
     OfficialFunction of;
     struct {
-        enum FunctionPtType{
+        enum FunctionPtType {
             free_,  // 不包含任何隐式传递的参数
             static_,  // 不包含self参数
             object_static_,  // self参数不允许class
@@ -79,8 +80,8 @@ struct Function{
     } function_data;
 };
 
-struct List{
-    enum ListType{
+struct List {
+    enum ListType {
         value_tuple,
         value_list,
     } type;
@@ -88,7 +89,7 @@ struct List{
     vnum size;
 };
 
-struct Dict{
+struct Dict {
     struct HashTable *dict;
     vnum size;
 };
@@ -98,7 +99,6 @@ struct Bool{
 };
 
 struct Value{
-    struct GCStatus gc_status;
     enum ValueType type;
 
     struct {
@@ -107,30 +107,31 @@ struct Value{
         struct Inherit *inherit;
     } object;
 
-    union data{
+    union data {
         struct Number num;
         struct String str;
         struct Function function;
         struct List list;
         struct Dict dict;
         struct Bool bool_;
-    }data;
+    } data;
 
     struct Value *gc_next;
     struct Value *gc_last;
+    struct GCStatus gc_status;
 };
 
-struct LinkValue{
-    struct GCStatus gc_status;
+struct LinkValue {
     enum ValueAuthority aut;
     struct Value *value;
     struct LinkValue *belong;
     struct LinkValue *gc_next;
     struct LinkValue *gc_last;
+    struct GCStatus gc_status;
 };
 
-struct Result{
-    enum ResultType{
+struct Result {
+    enum ResultType {
         not_return = 1,  // 无返回值
         function_return=2,  // 函数返回值
         operation_return=3,  // 表达式返回值
@@ -149,7 +150,7 @@ struct Result{
     struct Statement *node;
 };
 
-struct Error{
+struct Error {
     char *type;
     char *messgae;
     char *file;
@@ -157,11 +158,18 @@ struct Error{
     struct Error *next;
 };
 
-struct Inherit{
+struct Inherit {
     struct LinkValue *value;
     struct Inherit *next;
 };
 
+struct Package {
+    struct Value *package;
+    char *name;  // split dir的name
+    char *md5;  // md5地址
+    struct Package *next;
+};
+
 enum BaseErrorType{
     E_BaseException,
     E_Exception,
@@ -212,6 +220,10 @@ void setResultOperationBase(Result *ru, LinkValue *value);
 void freeResult(Result *ru);
 void freeResultSafe(Result *ru);
 
+Package *makePackage(Value *value, char *md5, char *name, Package *base);
+void freePackage(Package *base);
+Value *checkPackage(Package *base, char *md5, char *name);
+
 Error *makeError(char *type, char *message, fline line, char *file);
 void freeError(Result *base);
 Error *connectError(Error *new, Error *base);

+ 38 - 0
VirtulMathCore/md5/include/__md5.h

@@ -0,0 +1,38 @@
+#ifndef VIRTUALMATH___MD5_H
+#define VIRTUALMATH___MD5_H
+#include "__virtualmath.h"
+
+#define F(x,y,z) ((x & y) | (~x & z))
+#define G(x,y,z) ((x & z) | (y & ~z))
+#define H(x,y,z) (x^y^z)
+#define I(x,y,z) (y ^ (x | ~z))
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
+#define FF(a,b,c,d,x,s,ac) \
+          do { \
+          a += F(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a, (unsigned)s); \
+          a += b; \
+          } while(0)
+
+#define GG(a,b,c,d,x,s,ac) \
+          do { \
+          a += G(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a, (unsigned)s); \
+          a += b; \
+          } while(0)
+
+#define HH(a,b,c,d,x,s,ac) \
+          do { \
+          a += H(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a, (unsigned)s); \
+          a += b; \
+          } while(0)
+
+#define II(a,b,c,d,x,s,ac) \
+          do { \
+          a += I(b,c,d) + x + ac; \
+          a = ROTATE_LEFT(a, (unsigned)s); \
+          a += b; \
+          } while(0)
+
+#endif //VIRTUALMATH___MD5_H

+ 210 - 0
VirtulMathCore/md5/md5.c

@@ -0,0 +1,210 @@
+#include "__md5.h"
+
+struct MD5_CTX {
+    unsigned int count[2];
+    unsigned int state[4];
+    unsigned char buffer[64];
+};
+
+typedef struct MD5_CTX MD5_CTX;
+
+static void MD5Init(MD5_CTX *context);
+static void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
+static void MD5Final(MD5_CTX *context,unsigned char digest[16]);
+static void MD5Transform(unsigned int state[4],unsigned char block[64]);
+static void MD5Encode(unsigned char *output,const unsigned int *input,unsigned int len);
+static void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
+
+unsigned char PADDING[] = {
+                0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+        };
+
+static void MD5Init(MD5_CTX *context) {
+    context->count[0] = 0;
+    context->count[1] = 0;
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+}
+
+static void MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputlen) {
+    unsigned int i;
+    unsigned int index;
+    unsigned int partlen;
+
+    index = (context->count[0] >> (unsigned)3) & (unsigned)0x3F;
+    partlen = 64 - index;
+    context->count[0] += inputlen << (unsigned)3;
+
+    if(context->count[0] < (inputlen << (unsigned)3))
+        context->count[1]++;
+    context->count[1] += inputlen >> (unsigned)29;
+
+    if(inputlen >= partlen) {
+        memcpy(&context->buffer[index], input,partlen);
+        MD5Transform(context->state, context->buffer);
+
+        for(i = partlen; i+64 <= inputlen; i+=64)
+            MD5Transform(context->state, &input[i]);
+
+        index = 0;
+    }
+    else
+        i = 0;
+    memcpy(&context->buffer[index], &input[i], inputlen-i);
+}
+
+static void MD5Final(MD5_CTX *context, unsigned char digest[16]) {
+    unsigned int index;
+    unsigned int pad_len;
+    unsigned char bits[8];
+
+    index = (context->count[0] >> (unsigned)3) & (unsigned)0x3F;
+    pad_len = (index < 56) ? (56 - index) : (120 - index);
+    MD5Encode(bits, context->count, 8);
+    MD5Update(context, PADDING, pad_len);
+    MD5Update(context, bits, 8);
+    MD5Encode(digest, context->state, 16);
+}
+
+static void MD5Encode(unsigned char *output,const unsigned int *input, unsigned int len) {
+    unsigned int i = 0;
+    unsigned int j = 0;
+
+    while(j < len)
+    {
+        output[j] = input[i] & (unsigned)0xFF;
+        output[j+1] = (input[i] >> (unsigned)8) & (unsigned)0xFF;
+        output[j+2] = (input[i] >> (unsigned)16) & (unsigned)0xFF;
+        output[j+3] = (input[i] >> (unsigned)24) & (unsigned)0xFF;
+        i++;
+        j += 4;
+    }
+}
+
+static void MD5Decode(unsigned int *output, unsigned char *input, unsigned int len) {
+    for (unsigned int i=0, j=0; j < len; i++, j+=4) {
+        output[i] = (input[j]) |
+                    (input[j+1] << (unsigned)8) |
+                    (input[j+2] << (unsigned)16) |
+                    (input[j+3] << (unsigned)24);
+    }
+}
+
+static void MD5Transform(unsigned int state[4], unsigned char block[64]) {
+    unsigned int a = state[0];
+    unsigned int b = state[1];
+    unsigned int c = state[2];
+    unsigned int d = state[3];
+    unsigned int x[64];
+
+    MD5Decode(x,block,64);
+
+    FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
+    FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
+    FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
+    FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
+    FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
+    FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
+    FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
+    FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
+    FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
+    FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
+    FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
+    FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
+    FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
+    FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
+    FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
+    FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
+
+    /* Round 2 */
+    GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
+    GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
+    GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
+    GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
+    GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
+    GG(d, a, b, c, x[10], 9,  0x2441453); /* 22 */
+    GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
+    GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
+    GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
+    GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
+    GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
+    GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
+    GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
+    GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
+    GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
+    GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
+
+    /* Round 3 */
+    HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
+    HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
+    HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
+    HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
+    HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
+    HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
+    HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
+    HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
+    HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
+    HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
+    HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
+    HH(b, c, d, a, x[ 6], 23,  0x4881d05); /* 44 */
+    HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
+    HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
+    HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
+    HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
+
+    /* Round 4 */
+    II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
+    II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
+    II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
+    II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
+    II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
+    II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
+    II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
+    II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
+    II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
+    II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
+    II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
+    II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
+    II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
+    II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
+    II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
+    II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+}
+
+
+int getFileMd5(const char *path, char *md5str) {
+    FILE *fd;
+
+    unsigned long ret;
+    unsigned char data[READ_DATA_SIZE];
+    unsigned char md5_value[MD5_SIZE];
+    MD5_CTX md5;
+
+    if ((fd = fopen(path, "rb")) == NULL)
+        return -1;
+
+    MD5Init(&md5);
+    while (1) {
+        ret = fread(data, 1, READ_DATA_SIZE, fd);
+        MD5Update(&md5, data, ret);
+        if (ret < READ_DATA_SIZE)
+            break;
+    }
+
+    fclose(fd);
+    MD5Final(&md5, md5_value);
+
+    for(int i = 0; i < MD5_SIZE; i++)
+        snprintf(md5str + i * 2, 2 + 1, "%02x", md5_value[i]);
+
+    return 0;
+}

+ 1 - 1
VirtulMathCore/memory/mem.c

@@ -54,7 +54,7 @@ char *memStrcatIter(char *base, bool free_base, ...) {
     va_start(ap, free_base);
     for (char *ch = va_arg(ap, char *); ch != NULL; ch = va_arg(ap, char *)) {
         base = memStrcat(base, ch, free_base, false);
-        free_base = false;
+        free_base = true;
     }
     va_end(ap);
     return base;

+ 1 - 1
VirtulMathCore/ofunc/clib/manager.c

@@ -14,7 +14,7 @@ bool checkCLib(char *file) {
     return false;
 }
 
-void runClib(char *file, struct LinkValue *belong, INTER_FUNCTIONSIG_CORE){
+void importClibCore(char *file, struct LinkValue *belong, INTER_FUNCTIONSIG_CORE){
     for (struct InFo *info = ManagerInFo; info->name != NULL; info++) {
         if (eqString(file, info->name))
             info->reg(CALL_REGISTERED_FUNCTION(belong, var_list));

+ 4 - 4
VirtulMathCore/ofunc/src/__ofunc.c

@@ -71,7 +71,7 @@ Value *makeBaseChildClass(Value *inherit, Inter *inter) {
     Inherit *father_value = NULL;
     Value *new = NULL;
     {
-        LinkValue *father_ = makeLinkValue(inherit, inter->base_father, inter);
+        LinkValue *father_ = makeLinkValue(inherit, inter->base_belong, inter);
         Argument *arg = makeValueArgument(father_);
         gc_addTmpLink(&father_->gc_status);
         father_value = setFather(arg);
@@ -100,7 +100,7 @@ LinkValue *makeBaseChildClass3(Value *inherit, Inter *inter) {
     Inherit *father_value = NULL;
     Value *new = NULL;
     {
-        LinkValue *father_ = makeLinkValue(inherit, inter->base_father, inter);
+        LinkValue *father_ = makeLinkValue(inherit, inter->base_belong, inter);
         Argument *arg = makeValueArgument(father_);
         gc_addTmpLink(&father_->gc_status);
         father_value = setFather(arg);
@@ -108,7 +108,7 @@ LinkValue *makeBaseChildClass3(Value *inherit, Inter *inter) {
         gc_freeTmpLink(&father_->gc_status);
     }
     new = makeClassValue(inter->var_list, inter, father_value);
-    return makeLinkValue(new, inter->base_father, inter);
+    return makeLinkValue(new, inter->base_belong, inter);
 }
 
 LinkValue *makeBaseChildClass4(LinkValue *inherit, Inter *inter) {  // TODO-szh 最终函数
@@ -122,7 +122,7 @@ LinkValue *makeBaseChildClass4(LinkValue *inherit, Inter *inter) {  // TODO-szh
         gc_freeTmpLink(&inherit->gc_status);
     }
     new = makeClassValue(inter->var_list, inter, father_value);
-    return makeLinkValue(new, inter->base_father, inter);
+    return makeLinkValue(new, inter->base_belong, inter);
 }
 
 bool checkIndex(vnum *index, const vnum *size, INTER_FUNCTIONSIG_NOT_ST){

+ 2 - 2
VirtulMathCore/ofunc/src/object.c

@@ -93,8 +93,8 @@ void makeBaseObject(Inter *inter, LinkValue *belong){
     {
         Value *global_belong = makeObject(inter, copyVarList(inter->var_list, false, inter), NULL, NULL);
         g_belong = makeLinkValue(global_belong, belong, inter);
-        inter->base_father = g_belong;
-        gc_addStatementLink(&inter->base_father->gc_status);
+        inter->base_belong = g_belong;
+        gc_addStatementLink(&inter->base_belong->gc_status);
     }
 
     inter->data.object = makeLinkValue(object, g_belong, inter);

+ 4 - 2
VirtulMathCore/src/inter.c

@@ -6,6 +6,7 @@ Inter *makeInter(char *out, char *error_, char *in, LinkValue *belong) {
     tmp->link_base = NULL;
     tmp->hash_base = NULL;
     tmp->base_var = NULL;
+    tmp->package = NULL;
 
     setBaseInterData(tmp);
     tmp->var_list = makeVarList(tmp, true);
@@ -84,11 +85,10 @@ void setBaseInterData(struct Inter *inter){
     inter->data.object_down_del = memStrcpy("__down_del__");
     inter->data.object_slice_del = memStrcpy("__slice_del__");
     inter->data.default_pt_type = free_;
-
 }
 
 void freeBaseInterData(struct Inter *inter){
-    gc_freeStatementLink(&inter->base_father->gc_status);
+    gc_freeStatementLink(&inter->base_belong->gc_status);
     gc_freeStatementLink(&inter->data.object->gc_status);
     gc_freeStatementLink(&inter->data.vobject->gc_status);
     gc_freeStatementLink(&inter->data.num->gc_status);
@@ -172,6 +172,7 @@ void freeInter(Inter *inter, bool show_gc) {
     FREE_BASE(inter, return_);
     gc_runDelAll(inter);
     freeBaseInterData(inter);
+    freePackage(inter->package);
 #if DEBUG
     if (show_gc && (printf("\nEnter '1' to show gc: "), getc(stdin) == '1')) {
         printGC(inter);
@@ -216,6 +217,7 @@ void mergeInter(Inter *new, Inter *base){
     *base_linkValue = new->link_base;
     *base_hash = new->hash_base;
     *base_var = new->base_var;
+    new->package = NULL;
     memFree(new);
 }
 

+ 2 - 2
VirtulMathCore/src/ofunc.c

@@ -47,6 +47,6 @@ void registeredFunctionName(Inter *inter, LinkValue *belong){
 
     makeBaseStr(inter);
     presetting(inter);
-    registeredObject(inter->base_father, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
-    registeredBaseFunction(inter->base_father, inter);
+    registeredObject(inter->base_belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
+    registeredBaseFunction(inter->base_belong, inter);
 }

+ 1 - 20
VirtulMathCore/src/parameter.c

@@ -504,30 +504,11 @@ Argument * getArgument(Parameter *call, bool is_dict, INTER_FUNCTIONSIG_NOT_ST)
  * 注解: @p_1 match_status; @p_2 default_status; @p_3 self_ass; @p_4 mul_par; @p_5 pow_par; @p_3! 通过p_3处理**kwargs
  * @param call
  * @param function
- * @param function_var
+ * @param func_var
  * @param inter
  * @param var_list
  * @return
  */
-ResultType setParameter(fline line, char *file, Parameter *call_base, Parameter *function_base, VarList *function_var, LinkValue *function_father, INTER_FUNCTIONSIG_NOT_ST) {
-    Argument *self_tmp = makeValueArgument(function_father);
-    Argument *father_tmp = makeValueArgument(function_father->belong);
-    Argument *call = NULL;
-    setResultCore(result);
-    call = getArgument(call_base, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-    self_tmp->next = father_tmp;
-    father_tmp->next = call;
-    if (!CHECK_RESULT(result)) {
-        freeArgument(call, false);
-        return result->type;
-    }
-
-    freeResult(result);
-    setParameterCore(line, file, self_tmp, function_base, function_var, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, function_father));
-    freeArgument(self_tmp, false);
-    return result->type;
-}
-
 ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *function_base, VarList *function_var,
                         INTER_FUNCTIONSIG_NOT_ST) {
     Parameter *function = NULL;

+ 1 - 1
VirtulMathCore/src/run.c

@@ -194,7 +194,7 @@ ResultType globalIterStatement(Result *result, Inter *inter, Statement *st) {
     ResultType type;
     VarList *var_list = NULL;
     Statement *base;
-    LinkValue *belong = inter->base_father;
+    LinkValue *belong = inter->base_belong;
     void *bak = NULL;
 
     if (st == NULL){

+ 107 - 75
VirtulMathCore/src/runfile.c

@@ -84,28 +84,28 @@ int checkFileDir(char **file_dir, INTER_FUNCTIONSIG) {
     }
 
     path: {
-        char *path = memStrcpy(getenv("VIRTUALMATHPATH"));
-        for (char *tmp = strtok(path, ";"), *new_dir; tmp != NULL; tmp = strtok(NULL, ";")) {
+    char *path = memStrcpy(getenv("VIRTUALMATHPATH"));
+    for (char *tmp = strtok(path, ";"), *new_dir; tmp != NULL; tmp = strtok(NULL, ";")) {
 #ifdef __linux__
-            if (*(tmp + (memStrlen(tmp) - 1)) != '/')
-                new_dir = memStrcatIter(tmp, false, "/", *file_dir, NULL);
+        if (*(tmp + (memStrlen(tmp) - 1)) != '/')
+            new_dir = memStrcatIter(tmp, false, "/", *file_dir, NULL);
 #else
             if (*(tmp + (memStrlen(tmp) - 1)) != '\\')
                 new_dir = memStrcatIter(tmp, false, "\\", *file_dir);
 #endif
-            else
-                new_dir = memStrcat(tmp, *file_dir, false, false);
-
-            if (isExist(&new_dir, false, "__init__.vm")) {
-                memFree(*file_dir);
-                *file_dir = new_dir;
-                return 1;
-            }
-            memFree(new_dir);
+        else
+            new_dir = memStrcat(tmp, *file_dir, false, false);
 
+        if (isExist(&new_dir, false, "__init__.vm")) {
+            memFree(*file_dir);
+            *file_dir = new_dir;
+            return 1;
         }
-        memFree(path);
+        memFree(new_dir);
+
     }
+    memFree(path);
+}
 
     clib:
     if (checkCLib(*file_dir))
@@ -153,32 +153,22 @@ ResultType includeFile(INTER_FUNCTIONSIG) {
     return result->type;
 }
 
-ResultType importVMFileCore(VarList **new_object, char *file_dir, fline line, char *code_file, INTER_FUNCTIONSIG_NOT_ST) {
-    Inter *import_inter = NULL;
+ResultType importVMFileCore(Inter *import_inter, char *path, fline line, char *code_file, INTER_FUNCTIONSIG_NOT_ST) {
     ParserMessage *pm = NULL;
     Statement *run_st = NULL;
     setResultCore(result);
 
-    import_inter = deriveInter(belong, inter);
-    pm = makeParserMessage(file_dir);
-    run_st = makeStatement(0, file_dir);
+    pm = makeParserMessage(path);
+    run_st = makeStatement(0, path);
 
-    if (!importRunParser(pm, line, code_file, run_st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong))) {
-        freeInter(import_inter, false);
+    if (!importRunParser(pm, line, code_file, run_st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
         goto return_;
-    }
 
     globalIterStatement(result, import_inter, run_st);
-    if (!CHECK_RESULT(result)) {
-        freeInter(import_inter, false);
+    if (!CHECK_RESULT(result))
         setResultError(E_BaseException, NULL, line, code_file, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-        goto return_;
-    }
-
-    *new_object = import_inter->var_list;
-    import_inter->var_list = NULL;
-    mergeInter(import_inter, inter);
-    setResult(result, inter, belong);
+    else
+        setResult(result, inter, belong);
 
     return_:
     freeStatement(run_st);
@@ -186,22 +176,8 @@ ResultType importVMFileCore(VarList **new_object, char *file_dir, fline line, ch
     return result->type;
 }
 
-ResultType importCLibFileCore(VarList **new_object, char *file_dir, INTER_FUNCTIONSIG_NOT_ST) {
-    Inter *import_inter;
-    setResultCore(result);
-    import_inter = deriveInter(belong, inter);
-
-    runClib(file_dir, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
-
-    *new_object = import_inter->var_list;
-    import_inter->var_list = NULL;
-    mergeInter(import_inter, inter);
-    setResult(result, inter, belong);
-    return result->type;
-}
 
-ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONSIG) {
-    int status;
+ResultType importFileCore(char **path, char **split, int *status, INTER_FUNCTIONSIG) {
     setResultCore(result);
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)))
         return result->type;
@@ -211,74 +187,130 @@ ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONS
         return error_return;
     }
 
-    *file_dir = memStrcpy(result->value->value->data.str.str);
+    *path = memStrcpy(result->value->value->data.str.str);
+    *split = splitDir(*path);  // 自动去除末尾路径分隔符
     freeResult(result);
-    if ((status = checkFileDir(file_dir, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong))) == 0)
+    if ((*status = checkFileDir(path, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong))) == 0)
         return result->type;
 
+    return result->type;
+}
+
+ResultType runImportFile(Inter *import_inter, char **path, int status, INTER_FUNCTIONSIG) {
+    setResultCore(result);
     if (status == 2)
-        importCLibFileCore(new_object, *file_dir, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        importClibCore(*path, belong, CALL_INTER_FUNCTIONSIG_CORE(inter->var_list));
     else
-        importVMFileCore(new_object, *file_dir, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        importVMFileCore(import_inter, *path, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
 
+    import_inter->var_list = NULL;
+    mergeInter(import_inter, inter);
     return result->type;
 }
 
+static bool getPackage(LinkValue **imp_value, char *md5_str, char *split, int status, char **path, INTER_FUNCTIONSIG) {
+    Value *pg;
+    Inter *imp_inter;
+    if ((pg = checkPackage(inter->package, md5_str, split)) == NULL) {
+        setResultCore(result);
+        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);
+        imp_inter->package = inter->package;
+
+        freeResult(result);
+        runImportFile(imp_inter, path, status, CALL_INTER_FUNCTIONSIG(st->u.import_file.file, var_list, result, belong));
+        if (!CHECK_RESULT(result))
+            return false;
+    }
+    *imp_value = makeLinkValue(pg, belong, inter);
+    gc_addTmpLink(&(*imp_value)->gc_status);
+    return true;
+}
+
+
 ResultType importFile(INTER_FUNCTIONSIG) {
-    char *file_dir = NULL;
-    VarList *new_object = NULL;
-    LinkValue *import_value = NULL;
+    int status;
+    char *split_path = NULL;
+    char *path = NULL;
+    LinkValue *imp_value = NULL;
+    char md5_str[MD5_STRING] = {};
+
     setResultCore(result);
     gc_freeze(inter, var_list, NULL, true);
 
-    importFileCore(&new_object, &file_dir, CALL_INTER_FUNCTIONSIG(st->u.import_file.file, var_list, result, belong));
+    importFileCore(&path, &split_path, &status, CALL_INTER_FUNCTIONSIG(st->u.import_file.file, var_list, result, belong));
     if (!CHECK_RESULT(result))
         goto return_;
 
-    {
-        VarList *import_var = copyVarList(var_list, false, inter);
-        Value *import_obj = makeObject(inter, new_object, import_var, NULL);
-        import_value = makeLinkValue(import_obj, belong, inter);
-    }
-
+    getFileMd5(path, md5_str);
+    if (!getPackage(&imp_value, md5_str, split_path, status, &path, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)))
+        goto return_;
     freeResult(result);
-    if (st->u.import_file.as != NULL)
-        assCore(st->u.import_file.as, import_value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-    else {
-        addStrVar(splitDir(file_dir), true, true, import_value, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-        if (!CHECK_RESULT(result))
-            goto return_;
-    }
-    setResult(result, inter, belong);
+    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));
+    else
+        assCore(st->u.import_file.as, imp_value, false, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (CHECK_RESULT(result))
+        setResult(result, inter, belong);
+    gc_freeTmpLink(&imp_value->gc_status);
 
     return_:
-    memFree(file_dir);
+    memFree(split_path);
+    memFree(path);
     gc_freeze(inter, var_list, NULL, false);
     return result->type;
 }
 
+static ResultType importParameter(fline line, char *file, Parameter *call_pt, Parameter *func_pt, VarList *func_var, LinkValue *func_belong, INTER_FUNCTIONSIG_NOT_ST) {
+    Argument *call = NULL;
+    setResultCore(result);
+    call = getArgument(call_pt, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    if (!CHECK_RESULT(result)) {
+        freeArgument(call, false);
+        return result->type;
+    }
+
+    freeResult(result);
+    setParameterCore(line, file, call, func_pt, func_var, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, func_belong));
+    freeArgument(call, false);
+    return result->type;
+}
 
 ResultType fromImportFile(INTER_FUNCTIONSIG) {
-    char *file_dir = NULL;
-    VarList *new_object = NULL;
+    int status;
+    char *split_path = NULL;
+    char *path = NULL;
+    char md5_str[MD5_STRING] = {};
+    VarList *imp_var = NULL;
+    LinkValue *imp_value;
     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, belong));
+    importFileCore(&path, &split_path, &status, CALL_INTER_FUNCTIONSIG(st->u.from_import_file.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)))
+        goto return_;
+    imp_var = imp_value->value->object.var;
+
     freeResult(result);
     if (pt != NULL) {
-        setParameter(st->line, st->code_file, pt, as, var_list, belong, CALL_INTER_FUNCTIONSIG_NOT_ST(new_object, result, belong));
+        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))
             goto return_;
     }
     else
-        updateHashTable(var_list->hashtable, new_object->hashtable, inter);
+        updateHashTable(var_list->hashtable, imp_var->hashtable, inter);
+    gc_freeTmpLink(&imp_value->value->gc_status);
     setResult(result, inter, belong);
 
     return_:
-    freeVarList(new_object);
+    memFree(path);
+    memFree(split_path);
+    freeVarList(imp_var);  // 当需要存储var_list的时候则不需要释放
     return result->type;
 }

+ 1 - 4
VirtulMathCore/src/runoperation.c

@@ -275,11 +275,8 @@ ResultType varAss(Statement *name, LinkValue *value, bool check_aut, bool settin
     }
     addFromVarList(str_name, result->value, int_times, value, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     if (setting) {
-        LinkValue *name_value = result->value;
-        result->value = NULL;
         freeResult(result);
-        newObjectSetting(name_value, name->line, name->code_file, value, result, inter);
-        gc_freeTmpLink(&name_value->gc_status);
+        newObjectSetting(value, name->line, name->code_file, value, result, inter);
         if (CHECK_RESULT(result))
             goto error_;
     }

+ 38 - 2
VirtulMathCore/src/value.c

@@ -456,6 +456,7 @@ void printError(Result *result, Inter *inter, bool free) {
     }
     if (free)
         freeError(result);
+    fflush(inter->data.inter_stderr);
 }
 
 inline bool isType(Value *value, enum ValueType type){
@@ -525,6 +526,41 @@ Inherit *getInheritFromValueCore(LinkValue *num_father) {
     return object_father;
 }
 
+Package *makePackage(Value *value, char *md5, char *name, Package *base) {
+    Package *tmp = memCalloc(1, sizeof(Package));
+    Package *tmp_base = base;
+    tmp->name = memStrcpy(name);
+    tmp->md5 = memStrcpy(md5);
+    tmp->package = value;
+    gc_addStatementLink(&value->gc_status);
+    tmp->next = NULL;
+    if (base == NULL)
+        return tmp;
+
+    for (PASS; tmp_base->next != NULL; tmp_base = tmp_base->next)
+            PASS;
+    tmp_base->next = tmp;
+    return base;
+}
+
+void freePackage(Package *base) {
+    for (Package *next; base != NULL; base = next) {
+        next = base->next;
+        gc_freeStatementLink(&base->package->gc_status);
+        memFree(base->name);
+        memFree(base->md5);
+        memFree(base);
+    }
+}
+
+Value *checkPackage(Package *base, char *md5, char *name) {
+    for (PASS; base != NULL; base = base->next) {
+        if (eqString(name, base->name) && eqString(md5, base->md5))
+            return base->package;
+    }
+    return NULL;
+}
+
 bool needDel(Value *object_value, Inter *inter) {
     LinkValue *_del_ = checkStrVar(inter->data.object_del, false, CALL_INTER_FUNCTIONSIG_CORE(object_value->object.var));
     enum FunctionPtType type;
@@ -545,8 +581,8 @@ bool callDel(Value *object_value, Result *result, Inter *inter, VarList *var_lis
     if (_del_ != NULL){
         gc_addTmpLink(&_del_->gc_status);
         if (_del_->belong == NULL || _del_->belong->value != object_value && checkAttribution(object_value, _del_->belong->value))
-            _del_->belong = makeLinkValue(object_value, inter->base_father, inter);
-        callBackCore(_del_, NULL, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, inter->base_father));
+            _del_->belong = makeLinkValue(object_value, inter->base_belong, inter);
+        callBackCore(_del_, NULL, 0, "sys", CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, inter->base_belong));
         gc_freeTmpLink(&_del_->gc_status);
         return true;
     } else