diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 53f9f87d8..87cba765b 100644 --- a/port/linux/.vscode/launch.json +++ b/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}", diff --git a/src/PikaCompiler.c b/src/PikaCompiler.c index 14a6b2d89..c6f318827 100644 --- a/src/PikaCompiler.c +++ b/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) { diff --git a/src/PikaCompiler.h b/src/PikaCompiler.h index 603646172..3535abb15 100644 --- a/src/PikaCompiler.h +++ b/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); diff --git a/src/PikaObj.c b/src/PikaObj.c index 95c85fa40..6d84f25ed 100644 --- a/src/PikaObj.c +++ b/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; } -uint8_t* pika_getByteCodeFromModule(char* module_name) { - pika_assert(NULL != module_name); - PikaObj* self = (PikaObj*)__pikaMain; - /* exit when no found '@lib' */ - if (!obj_isArgExist(self, "@lib")) { +LibObj* pika_getLibObj(void) { + // Ensure __pikaMain exists + if (__pikaMain == NULL) { return NULL; } - /* find module from the library */ - LibObj* lib = obj_getPtr(self, "@lib"); + + // 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); + + // Fetch library using pika_getLibObj + LibObj* lib = pika_getLibObj(); + + // Exit if there's no library + if (NULL == lib) { + return NULL; + } + + // 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"); } diff --git a/src/PikaObj.h b/src/PikaObj.h index 99ca8fe2a..0fbb55698 100644 --- a/src/PikaObj.h +++ b/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, diff --git a/src/PikaParser.c b/src/PikaParser.c index ae09eb79b..cdde55efe 100644 --- a/src/PikaParser.c +++ b/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); diff --git a/src/PikaVM.c b/src/PikaVM.c index 34df77371..2652026ec 100644 --- a/src/PikaVM.c +++ b/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; } diff --git a/src/PikaVersion.h b/src/PikaVersion.h index 9f8cae43b..956b1dfee 100644 --- a/src/PikaVersion.h +++ b/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" diff --git a/src/dataString.c b/src/dataString.c index 6149247a4..be6a884f2 100644 --- a/src/dataString.c +++ b/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;