Procházet zdrojové kódy

support from subdir import module

lyon před 2 roky
rodič
revize
ebd5b01549

+ 3 - 1
port/linux/.vscode/launch.json

@@ -14,7 +14,9 @@
                 // "--gtest_filter=vm.keyword_2"
                 // "--gtest_filter=compiler.find_break_point"
                 // "--gtest_filter=pikaMain.REPL_pdb_set_break"
-                "--gtest_filter=vm.subsrc_import"
+                "--gtest_filter=vm.subsrc_import",
+                "--gtest_filter=PikaMath.test1"
+                // "--gtest_filter=stddata.encode_decode"
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",

+ 40 - 0
src/PikaCompiler.c

@@ -678,6 +678,46 @@ PikaObj* LibObj_getModule(LibObj* self, char* module_name) {
     return context.module;
 }
 
+/*
+    redirect import to module
+    example:
+        when IMP XXX.YYY.ZZZ and ZZZ is a calss
+        then redirect to IMP XXX.YYY
+*/
+char* LibObj_redirectModule(LibObj* self, Args* buffs_out, char* module_name) {
+    if (NULL == self) {
+        return NULL;
+    }
+    Args buffs = {0};
+    size_t token_num = strCountSign(module_name, '.');
+    if (0 == token_num) {
+        module_name = NULL;
+        goto __exit;
+    }
+    PikaObj* module_obj = LibObj_getModule(self, module_name);
+    if (NULL != module_obj) {
+        goto __exit;
+    }
+    module_name = strsCopy(&buffs, module_name);
+    for (int i = 0; i < token_num; i++) {
+        char* module_try = strsPopToken(&buffs, &module_try, '.');
+        PikaObj* module_obj = LibObj_getModule(self, module_try);
+        if (NULL != module_obj) {
+            char* module_name = obj_getStr(module_obj, "name");
+            if (NULL != module_name) {
+                goto __exit;
+            }
+        }
+    }
+    module_name = NULL;
+__exit:
+    if (NULL != module_name) {
+        module_name = strsCopy(buffs_out, module_name);
+    }
+    strsDeinit(&buffs);
+    return module_name;
+}
+
 int LibObj_loadLibrary(LibObj* self, uint8_t* library_bytes) {
     int module_num = _getModuleNum(library_bytes);
     if (module_num < 0) {

+ 1 - 0
src/PikaCompiler.h

@@ -25,6 +25,7 @@ int LibObj_linkFile(LibObj* self, char* output_file_name);
 int LibObj_loadLibraryFile(LibObj* self, char* input_file_name);
 PikaObj* LibObj_getModule(LibObj* self, char* module_name);
 int Lib_loadLibraryFileToArray(char* origin_file_name, char* pikascript_root);
+char* LibObj_redirectModule(LibObj* self, Args* buffs, char* module_name);
 PikaMaker* New_PikaMaker(void);
 void pikaMaker_setPWD(PikaMaker* self, char* pwd);
 PIKA_RES pikaMaker_compileModule(PikaMaker* self, char* module_name);

+ 25 - 7
src/PikaObj.c

@@ -57,6 +57,7 @@ volatile PikaObjState g_PikaObjState = {
 #endif
 };
 
+extern volatile PikaObj* __pikaMain;
 static volatile ShellConfig g_REPL;
 
 PikaObj* New_PikaStdData_Dict(Args* args);
@@ -151,7 +152,6 @@ static int32_t obj_deinit_no_del(PikaObj* self) {
         arg_deinit(self->aName);
     }
 #endif
-    extern volatile PikaObj* __pikaMain;
     /* remove self from gc chain */
     obj_removeGcChain(self);
     /* free the pointer */
@@ -2631,20 +2631,38 @@ PikaObj* obj_linkLibObj(PikaObj* self, LibObj* library) {
     return self;
 }
 
+LibObj* pika_getLibObj(void) {
+    // Ensure __pikaMain exists
+    if (__pikaMain == NULL) {
+        return NULL;
+    }
+
+    // Cast __pikaMain to PikaObj and fetch library
+    PikaObj* self = (PikaObj*)__pikaMain;
+    return obj_getPtr(self, "@lib");
+}
+
 uint8_t* pika_getByteCodeFromModule(char* module_name) {
+    // Check if module_name is not NULL
     pika_assert(NULL != module_name);
-    PikaObj* self = (PikaObj*)__pikaMain;
-    /* exit when no found '@lib' */
-    if (!obj_isArgExist(self, "@lib")) {
+
+    // Fetch library using pika_getLibObj
+    LibObj* lib = pika_getLibObj();
+
+    // Exit if there's no library
+    if (NULL == lib) {
         return NULL;
     }
-    /* find module from the library */
-    LibObj* lib = obj_getPtr(self, "@lib");
+
+    // Fetch the module from the library
     PikaObj* module = LibObj_getModule(lib, module_name);
-    /* exit when no module in '@lib' */
+
+    // Check if module exists
     if (NULL == module) {
         return NULL;
     }
+
+    // Return bytecode of the module
     return obj_getPtr(module, "bytecode");
 }
 

+ 1 - 0
src/PikaObj.h

@@ -550,6 +550,7 @@ static inline Arg* arg_newRef(PikaObj* obj) {
 }
 
 uint8_t* pika_getByteCodeFromModule(char* module_name);
+LibObj* pika_getLibObj(void);
 
 PikaObj* obj_importModuleWithByteCodeFrame(PikaObj* self,
                                            char* name,

+ 1 - 1
src/PikaParser.c

@@ -2639,7 +2639,7 @@ static char* Suger_from_import_as(Args* buffs_p, char* sLine) {
     sClass = sClassAfter;
 
     sLineOut = strsFormat(&buffs, PIKA_LINE_BUFF_SIZE, "import %s\n%s = %s",
-                          sModule, sAlias, sClass);
+                          sClass, sAlias, sClass);
     sLineOut = strsCopy(buffs_p, sLineOut);
 __exit:
     strsDeinit(&buffs);

+ 23 - 7
src/PikaVM.c

@@ -3388,23 +3388,39 @@ static Arg* VM_instruction_handler_IMP(PikaObj* self,
                                        PikaVMFrame* vm,
                                        char* data,
                                        Arg* arg_ret_reg) {
+    Args buffs = {0};
+    if (NULL == data) {
+        goto __exit;
+    }
+    char* module_name_redirect =
+        LibObj_redirectModule(pika_getLibObj(), &buffs, data);
+    if (NULL != module_name_redirect) {
+        data = module_name_redirect;
+    }
     /* the module is already imported, skip. */
     if (obj_isArgExist(self, data)) {
-        return NULL;
+        goto __exit;
     }
-    /* find cmodule in root object */
-    extern volatile PikaObj* __pikaMain;
-    if (obj_isArgExist((PikaObj*)__pikaMain, data)) {
-        obj_setArg(self, data, obj_getArg((PikaObj*)__pikaMain, data));
-        return NULL;
+    if (NULL == module_name_redirect) {
+        /* find cmodule in root object */
+        extern volatile PikaObj* __pikaMain;
+        char* cmodule_try = strsGetFirstToken(&buffs, data, '.');
+        if (obj_isArgExist((PikaObj*)__pikaMain, cmodule_try)) {
+            obj_setArg(self, cmodule_try,
+                       obj_getArg((PikaObj*)__pikaMain, cmodule_try));
+            goto __exit;
+        }
     }
+
     /* import module from '@lib' */
     if (0 == obj_importModule(self, data)) {
-        return NULL;
+        goto __exit;
     }
     PikaVMFrame_setErrorCode(vm, PIKA_RES_ERR_ARG_NO_FOUND);
     PikaVMFrame_setSysOut(vm, "ModuleNotFoundError: No module named '%s'",
                           data);
+__exit:
+    strsDeinit(&buffs);
     return NULL;
 }
 

+ 1 - 1
src/PikaVersion.h

@@ -2,4 +2,4 @@
 #define PIKA_VERSION_MINOR 12
 #define PIKA_VERSION_MICRO 7
 
-#define PIKA_EDIT_TIME "2023/10/27 22:18:28"
+#define PIKA_EDIT_TIME "2023/10/30 01:30:02"

+ 1 - 0
src/dataString.c

@@ -94,6 +94,7 @@ const char bracketEnd[] = {')', ']', '}', '\'', '\"'};
 #define BRACKET_TYPE_NUM (sizeof(bracketStart) / sizeof(char))
 
 int _strCountSign(char* strIn, char sign, pika_bool bracketDepth0) {
+    pika_assert(NULL != strIn);
     int32_t iCount = 0;
     int32_t iTotalDepth = 0;
     pika_bool bEscaped = pika_false;