Răsfoiți Sursa

feat: 设置了import查找范围

SongZihuan 4 ani în urmă
părinte
comite
55a0841f68
9 a modificat fișierele cu 141 adăugiri și 38 ștergeri
  1. 3 2
      CMakeLists.txt
  2. 1 0
      include/__virtualmath.h
  3. 9 0
      include/clib.h
  4. 1 0
      include/inter.h
  5. 21 0
      ofunc/c_lib/manager.c
  6. 11 0
      src/inter.c
  7. 92 34
      src/runfile.c
  8. 0 2
      src/runoperation.c
  9. 3 0
      vm_lib/hello.vm

+ 3 - 2
CMakeLists.txt

@@ -14,8 +14,9 @@ AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/file FILE_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/gc GC_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/argument ARGUMENT_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/ofunc/src OFUNC_LIST)
+AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/ofunc/c_lib CLIB_LIST)
 AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/signalhandler HANDLER_LIST)
 
 MESSAGE("project dir is ${PROJECT_SOURCE_DIR}")
-ADD_EXECUTABLE(VirtualMath main.c ${SRC_LIST} ${GC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST} ${ARGUMENT_LIST} ${OFUNC_LIST} ${HANDLER_LIST})
-TARGET_LINK_LIBRARIES(VirtualMath dlfcn)
+ADD_EXECUTABLE(VirtualMath main.c ${SRC_LIST} ${GC_LIST} ${PASER_LIST} ${MEM_LIST} ${FILE_LIST} ${ARGUMENT_LIST} ${OFUNC_LIST} ${HANDLER_LIST} ${CLIB_LIST})
+TARGET_LINK_LIBRARIES(VirtualMath dl)

+ 1 - 0
include/__virtualmath.h

@@ -15,6 +15,7 @@
 #include "var.h"
 #include "inter.h"
 #include "ofunc.h"
+#include "clib.h"
 #include "run.h"
 
 #include "lexical.h"

+ 9 - 0
include/clib.h

@@ -0,0 +1,9 @@
+#ifndef VIRTUALMATH_CLIB_H
+#define VIRTUALMATH_CLIB_H
+#include "__macro.h"
+
+struct Inter;
+struct LinkValue;
+void runClib(char *file, struct LinkValue *belong, INTER_FUNCTIONSIG_CORE);
+bool checkCLib(char *file);
+#endif //VIRTUALMATH_CLIB_H

+ 1 - 0
include/inter.h

@@ -101,4 +101,5 @@ void runCodeStdin(Inter *inter);
 void runCodeFile(Inter *inter, char *file[]);
 bool runParser(char *code_file, Inter *inter, bool is_one, Statement **st);
 void mergeInter(Inter *new, Inter *base);
+Inter *deriveInter(LinkValue *belong, Inter *inter);
 #endif //VIRTUALMATH_INTER_H

+ 21 - 0
ofunc/c_lib/manager.c

@@ -0,0 +1,21 @@
+#include "__virtualmath.h"
+#include "clib.h"
+
+static struct InFo{
+    char *name;
+    Registered reg;
+} ManagerInFo[] = {{"sys", registeredSysFunction},
+                   {NULL, NULL}};
+
+bool checkCLib(char *file) {
+    for (struct InFo *info = ManagerInFo; info->name != NULL; info++)
+        if (eqString(file, info->name))
+            return true;
+    return false;
+}
+
+void runClib(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));
+}

+ 11 - 0
src/inter.c

@@ -232,6 +232,17 @@ void mergeInter(Inter *new, Inter *base){
     memFree(new);
 }
 
+Inter *deriveInter(LinkValue *belong, Inter *inter) {
+    Inter *import_inter = makeInter(NULL, NULL, NULL, belong);
+    import_inter->data.inter_stdout = inter->data.inter_stdout;
+    import_inter->data.inter_stderr = inter->data.inter_stderr;
+    import_inter->data.inter_stdin = inter->data.inter_stdin;
+    import_inter->data.is_stdout = true;
+    import_inter->data.is_stderr = true;
+    import_inter->data.is_stdin = true;
+    return import_inter;
+}
+
 #if DEBUG == 1
 /* ***********************DEBUG 专用函数*********************************** */
 

+ 92 - 34
src/runfile.c

@@ -1,5 +1,55 @@
 #include "__run.h"
 
+int checkFileDir(char **file_dir, INTER_FUNCTIONSIG) {
+    if (checkFile(*file_dir) == 1)
+        return 1;
+
+    {
+        char cwd[200] = {};
+        char *cwd_tmp = NULL;
+        getcwd(cwd, 200);
+        cwd_tmp = memStrcat(cwd, "/", false, false);
+        cwd_tmp = memStrcat(cwd_tmp, *file_dir, true, false);
+        if (checkFile(cwd_tmp) == 1 || checkFile(cwd_tmp = memStrcat(cwd_tmp, ".vm", true, false)) == 1) {
+            memFree(*file_dir);
+            *file_dir = cwd_tmp;
+            return 1;
+        } else
+            memFree(cwd_tmp);
+    }
+
+    {
+        char *path = memStrcpy(getenv("VIRTUALMATHPATH"));
+        for (char *tmp = strtok(path, ";"), *new_dir, *new_tmp; tmp != NULL; tmp = strtok(NULL, ";")) {
+#ifdef __linux__
+            if (*(tmp + (memStrlen(tmp) - 1)) != '/')
+                new_tmp = memStrcat(tmp, "/", false, false);
+#else
+                if (*(tmp + (memStrlen(tmp) - 1)) != '\\')
+                    new_tmp = memStrcat(tmp, "\\", false, false);
+#endif
+            else
+                new_tmp = memStrcpy(tmp);
+            new_dir = memStrcat(new_tmp, *file_dir, false, false);
+            memFree(new_tmp);
+
+            if (checkFile(new_dir) == 1 || checkFile(new_dir = memStrcat(new_dir, ".vm", true, false)) == 1) {
+                memFree(*file_dir);
+                *file_dir = new_dir;
+                return 1;
+            } else
+                memFree(new_dir);
+        }
+        memFree(path);
+    }
+
+    if (checkCLib(*file_dir))
+        return 2;
+
+    setResultErrorSt(E_ImportException, "import file is not readable", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    return 0;
+}
+
 ResultType includeFile(INTER_FUNCTIONSIG) {
     Statement *new_st = NULL;
     ParserMessage *pm = NULL;
@@ -16,11 +66,9 @@ ResultType includeFile(INTER_FUNCTIONSIG) {
 
     file_dir = result->value->value->data.str.str;
     freeResult(result);
-
-    if (checkFile(file_dir) != 1){
-        setResultErrorSt(E_IncludeException, "include file is not readable", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+    freeResult(result);
+    if (checkFileDir(&file_dir, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)) != 1)
         goto return_;
-    }
 
     new_st = makeStatement(0, file_dir);
     pm = makeParserMessage(file_dir);
@@ -46,30 +94,24 @@ ResultType includeFile(INTER_FUNCTIONSIG) {
     return result->type;
 }
 
-ResultType importVMFileCore(VarList **new_object, char *file_dir, INTER_FUNCTIONSIG) {
+ResultType importVMFileCore(VarList **new_object, char *file_dir, fline line, char *code_file, INTER_FUNCTIONSIG_NOT_ST) {
     Inter *import_inter = NULL;
     ParserMessage *pm = NULL;
     Statement *run_st = NULL;
     setResultCore(result);
 
-    import_inter = makeInter(NULL, NULL, NULL, belong);
-    import_inter->data.inter_stdout = inter->data.inter_stdout;
-    import_inter->data.inter_stderr = inter->data.inter_stderr;
-    import_inter->data.inter_stdin = inter->data.inter_stdin;
-    import_inter->data.is_stdout = true;
-    import_inter->data.is_stderr = true;
-    import_inter->data.is_stdin = true;
-
+    import_inter = deriveInter(belong, inter);
     pm = makeParserMessage(file_dir);
     run_st = makeStatement(0, file_dir);
+
     parserCommandList(pm, import_inter, true, false, run_st);
     if (pm->status == int_error) {
-        setResultErrorSt(E_KeyInterrupt, KEY_INTERRUPT, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        setResultError(E_KeyInterrupt, KEY_INTERRUPT, line, code_file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         freeInter(import_inter, false);
         goto return_;
     }
     else if (pm->status != success) {
-        setResultErrorSt(E_TypeException, pm->status_message, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        setResultError(E_TypeException, pm->status_message, line, code_file, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         freeInter(import_inter, false);
         goto return_;
     }
@@ -78,7 +120,7 @@ ResultType importVMFileCore(VarList **new_object, char *file_dir, INTER_FUNCTION
     if (!CHECK_RESULT(result)) {
         freeInter(import_inter, false);
         result->value = makeLinkValue(makeNoneValue(inter), belong, inter);
-        setResultErrorSt(E_BaseException, NULL, false, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        setResultError(E_BaseException, NULL, line, code_file, false, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         goto return_;
     }
 
@@ -93,22 +135,31 @@ ResultType importVMFileCore(VarList **new_object, char *file_dir, INTER_FUNCTION
     return result->type;
 }
 
-ResultType importShareFileCore(VarList **new_object, char *file_dir, INTER_FUNCTIONSIG) {
+ResultType importShareFileCore(VarList **new_object, char *file_dir, INTER_FUNCTIONSIG_NOT_ST) {
     Inter *import_inter;
     setResultCore(result);
-    void* handle = dlopen(file_dir, RTLD_LAZY);
     Registered reg;
-    reg = dlsym(handle, "registered");
+    void* handle = dlopen(file_dir, RTLD_LAZY);
 
-    import_inter = makeInter(NULL, NULL, NULL, belong);
-    import_inter->data.inter_stdout = inter->data.inter_stdout;
-    import_inter->data.inter_stderr = inter->data.inter_stderr;
-    import_inter->data.inter_stdin = inter->data.inter_stdin;
-    import_inter->data.is_stdout = true;
-    import_inter->data.is_stderr = true;
-    import_inter->data.is_stdin = true;
+    reg = dlsym(handle, "registered");
+    import_inter = deriveInter(belong, inter);
 
     reg(belong, import_inter, import_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 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);
@@ -117,6 +168,7 @@ ResultType importShareFileCore(VarList **new_object, char *file_dir, INTER_FUNCT
 }
 
 ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONSIG) {
+    int status;
     setResultCore(result);
     if (operationSafeInterStatement(CALL_INTER_FUNCTIONSIG(st, var_list, result, belong)))
         return result->type;
@@ -126,19 +178,21 @@ ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONS
         return error_return;
     }
 
-    *file_dir = result->value->value->data.str.str;
+    *file_dir = memStrcpy(result->value->value->data.str.str);
     freeResult(result);
-    if (checkFile(*file_dir) != 1) {
-        setResultErrorSt(E_ImportException, "import file is not readable", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
-        return error_return;
-    }
+    if ((status = checkFileDir(file_dir, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong))) == 0)
+        return result->type;
+
     {
         char *file = strrchr(*file_dir, '.');
-        if (eqString(file, ".vm"))
-            importVMFileCore(new_object, *file_dir, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
+        if (status == 2)
+            importCLibFileCore(new_object, *file_dir, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        else if (file != NULL && eqString(file, ".vm"))
+            importVMFileCore(new_object, *file_dir, st->line, st->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         else
-            importShareFileCore(new_object, *file_dir, CALL_INTER_FUNCTIONSIG(st, var_list, result, belong));
+            importShareFileCore(new_object, *file_dir, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
     }
+
     return result->type;
 }
 
@@ -147,6 +201,8 @@ ResultType importFile(INTER_FUNCTIONSIG) {
     VarList *new_object = NULL;
     LinkValue *import_value = NULL;
     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));
     if (!CHECK_RESULT(result))
         goto return_;
@@ -164,6 +220,8 @@ ResultType importFile(INTER_FUNCTIONSIG) {
     setResult(result, inter, belong);
 
     return_:
+    memFree(file_dir);
+    gc_freeze(inter, var_list, NULL, false);
     return result->type;
 }
 

+ 0 - 2
src/runoperation.c

@@ -385,7 +385,6 @@ ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
 
     freeResult(result);
     var = findFromVarList(name, int_times, get_var, CALL_INTER_FUNCTIONSIG_CORE(var_list));
-    gc_addTmpLink(&var->gc_status);
     if (var == NULL) {
         char *info = memStrcat("Variable not found: ", name, false, false);
         setResultErrorSt(E_NameExceptiom, info, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
@@ -393,7 +392,6 @@ ResultType getVar(INTER_FUNCTIONSIG, VarInfo var_info) {
     }
     else if (checkAut(st->aut, var->aut, st->line, st->code_file, NULL, true, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
         setResultOperationBase(result, var);
-    gc_freeTmpLink(&var->gc_status);
     memFree(name);
     return result->type;
 }

+ 3 - 0
vm_lib/hello.vm

@@ -0,0 +1,3 @@
+def printHello(){
+    print("HelloVirtualMath")
+}