Explorar o código

support mod1 import mod2 import mod1

pikastech %!s(int64=3) %!d(string=hai) anos
pai
achega
6a9535470b

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

@@ -11,7 +11,7 @@
             "program": "${workspaceFolder}/build/test/pikascript_test",
             // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
             "args": [
-                "--gtest_filter=vm.*"
+                // "--gtest_filter=module.while_loop"
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",

+ 1 - 0
port/linux/package/pikascript/test_module2.py

@@ -1,2 +1,3 @@
+import test_module1
 def mytest():
     print('test_module_2_hello')

+ 0 - 2
port/linux/run.sh

@@ -1,4 +1,2 @@
-cp config/pika_config_void.h config/pika_config.h
-sh only_make.sh
 cd package/pikascript && \
 ./pika $1

+ 4 - 4
src/PikaCompiler.c

@@ -335,8 +335,8 @@ int LibObj_loadLibraryFile(LibObj* self, char* lib_file_name) {
                           lib_file_name);
         return PIKA_RES_ERR_IO_ERROR;
     }
-    /* save file_arg as __lib_buf to libObj */
-    obj_setArg_noCopy(self, "__lib_buf", file_arg);
+    /* save file_arg as @lib_buf to libObj */
+    obj_setArg_noCopy(self, "@lib_buf", file_arg);
     if (0 != LibObj_loadLibrary(self, arg_getBytes(file_arg))) {
         __platform_printf("Error: Could not load library from '%s'\n",
                           lib_file_name);
@@ -569,7 +569,7 @@ void pikaMaker_compileModuleWithDepends(PikaMaker* self, char* module_name) {
 int32_t __foreach_handler_linkCompiledModules(Arg* argEach, Args* context) {
     Args buffs = {0};
     if (argType_isObject(arg_getType(argEach))) {
-        LibObj* lib = args_getPtr(context, "__lib");
+        LibObj* lib = args_getPtr(context, "@lib");
         PikaMaker* maker = args_getPtr(context, "__maker");
         PikaObj* module_obj = arg_getPtr(argEach);
         char* module_name = obj_getStr(module_obj, "name");
@@ -592,7 +592,7 @@ void pikaMaker_linkCompiledModulesFullPath(PikaMaker* self, char* lib_path) {
     LibObj* lib = New_LibObj(NULL);
     Args buffs = {0};
     __platform_printf("  linking %s...\n", lib_path);
-    args_setPtr(&context, "__lib", lib);
+    args_setPtr(&context, "@lib", lib);
     args_setPtr(&context, "__maker", self);
     args_foreach(self->list, __foreach_handler_linkCompiledModules, &context);
     args_deinit_stack(&context);

+ 21 - 11
src/PikaObj.c

@@ -1074,8 +1074,18 @@ PikaObj* obj_importModuleWithByteCode(PikaObj* self,
                                       char* name,
                                       uint8_t* byteCode) {
     PikaObj* New_PikaStdLib_SysObj(Args * args);
-    obj_newDirectObj(self, name, New_PikaStdLib_SysObj);
-    pikaVM_runByteCode(obj_getObj(self, name), (uint8_t*)byteCode);
+    if (!obj_isArgExist(__pikaMain, name)) {
+        obj_newDirectObj(__pikaMain, name, New_PikaStdLib_SysObj);
+        pikaVM_runByteCode(obj_getObj(__pikaMain, name), (uint8_t*)byteCode);
+    }
+    if (self != __pikaMain) {
+        Arg* module_arg = obj_getArg(__pikaMain, name);
+        PikaObj* module_obj = arg_getPtr(module_arg);
+        obj_setArg(self, name, module_arg);
+        pika_assert(argType_isObject(arg_getType(module_arg)));
+        /* decrase refcnt to avoid circle reference */
+        obj_refcntDec(module_obj);
+    }
     return self;
 }
 
@@ -1089,33 +1099,33 @@ PikaObj* obj_importModuleWithByteCodeFrame(PikaObj* self,
 }
 
 PikaObj* Obj_linkLibraryFile(PikaObj* self, char* input_file_name) {
-    obj_newMetaObj(self, "__lib", New_LibObj);
-    LibObj* lib = obj_getObj(self, "__lib");
+    obj_newMetaObj(self, "@lib", New_LibObj);
+    LibObj* lib = obj_getObj(self, "@lib");
     LibObj_loadLibraryFile(lib, input_file_name);
     return self;
 }
 
 PikaObj* obj_linkLibrary(PikaObj* self, uint8_t* library_bytes) {
-    obj_newMetaObj(self, "__lib", New_LibObj);
-    LibObj* lib = obj_getObj(self, "__lib");
+    obj_newMetaObj(self, "@lib", New_LibObj);
+    LibObj* lib = obj_getObj(self, "@lib");
     LibObj_loadLibrary(lib, library_bytes);
     return self;
 }
 
 PikaObj* obj_linkLibObj(PikaObj* self, LibObj* library) {
-    obj_setPtr(self, "__lib", library);
+    obj_setPtr(self, "@lib", library);
     return self;
 }
 
 uint8_t* obj_getByteCodeFromModule(PikaObj* self, char* module_name) {
-    /* exit when no found '__lib' */
-    if (!obj_isArgExist(self, "__lib")) {
+    /* exit when no found '@lib' */
+    if (!obj_isArgExist(self, "@lib")) {
         return NULL;
     }
     /* find module from the library */
-    LibObj* lib = obj_getPtr(self, "__lib");
+    LibObj* lib = obj_getPtr(self, "@lib");
     PikaObj* module = obj_getObj(lib, module_name);
-    /* exit when no module in '__lib' */
+    /* exit when no module in '@lib' */
     if (NULL == module) {
         return NULL;
     }

+ 6 - 1
src/PikaVM.c

@@ -1152,6 +1152,11 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
         goto exit;
     }
 
+    if (strEqu(run_path, "object")) {
+        return_arg = arg_newMetaObj(New_TinyObj);
+        goto exit;
+    }
+
     /* get method host obj from reg */
     if (NULL == method_host && _checkLReg(run_path)) {
         uint8_t reg_index = _getLRegIndex(run_path);
@@ -2321,7 +2326,7 @@ static Arg* VM_instruction_handler_IMP(PikaObj* self,
         obj_setArg(self, data, obj_getArg(__pikaMain, data));
         return NULL;
     }
-    /* import module from '__lib' */
+    /* import module from '@lib' */
     if (0 == obj_importModule(self, data)) {
         return NULL;
     }

+ 1 - 1
src/PikaVersion.h

@@ -2,4 +2,4 @@
 #define PIKA_VERSION_MINOR       11
 #define PIKA_VERSION_MICRO       2
 
-#define PIKA_EDIT_TIME      "2022/10/02 00:00:51"
+#define PIKA_EDIT_TIME      "2022/10/02 16:29:46"

+ 20 - 0
test/module-test.cpp

@@ -368,4 +368,24 @@ TEST(issue, global) {
     EXPECT_EQ(pikaMemNow(), 0);
 }
 
+TEST(module, mod1_mod2_mod1) {
+    /* init */
+    pikaMemInfo.heapUsedMax = 0;
+    PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
+    extern unsigned char pikaModules_py_a[];
+    obj_linkLibrary(pikaMain, pikaModules_py_a);
+    /* run */
+    __platform_printf("BEGIN\r\n");
+    obj_run(pikaMain, 
+    "import test_module1\n"
+    "test_module1.test_module2.test_module1.mytest()"
+    );
+    /* collect */
+    /* assert */
+    EXPECT_STREQ(log_buff[0], "test_module_1_hello\r\n");
+    /* deinit */
+    obj_deinit(pikaMain);
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+
 #endif

+ 1 - 0
tools/pikaCompiler/main.py

@@ -1,6 +1,7 @@
 import PikaStdLib
 import test
 import TemplateDevice
+import module
 from pika_cjson import cJSON
 print('hello pikascript!')
 mem = PikaStdLib.MemChecker()

+ 1 - 1
tools/pikaCompiler/module2.py

@@ -1 +1 @@
-
+import module

BIN=BIN
tools/pikaCompiler/rust-msc-latest-win10.exe


+ 25 - 19
tools/pikaCompiler/src/compiler.rs

@@ -199,6 +199,25 @@ impl Compiler {
         let mut file_str = String::new();
         file.read_to_string(&mut file_str).unwrap();
 
+        if is_top_c_pkg {
+            /*
+                Push top C package to PikaMain.
+                Solve the package as a class
+                    [Example]:
+                        class PikaStdDevice(TinyObj):
+            */
+            let pkg_define = format!("class {}(TinyObj):", &file_name);
+            let package_now = match ClassInfo::new(&String::from(""), &pkg_define, true) {
+                Some(s) => s,
+                None => return self,
+            };
+            let package_name = package_now.this_class_name.clone();
+            self.class_list
+                .entry(package_name.clone())
+                .or_insert(package_now);
+            self.package_name_now = Some(package_name.clone());
+        }
+
         /* return when compiled */
         if !self.compiled_list.contains(&file_name) {
             /* print info */
@@ -214,6 +233,12 @@ impl Compiler {
                 }
                 _ => {}
             }
+        } else {
+            /* not scan *.py again */
+            match suffix {
+                "py" => return self,
+                _ => {}
+            }
         }
 
         /* push to compiled list, only compile once */
@@ -229,25 +254,6 @@ impl Compiler {
                 to supply the class of static object.
         */
 
-        if is_top_c_pkg {
-            /*
-                Push top C package to PikaMain.
-                Solve the package as a class
-                    [Example]:
-                        class PikaStdDevice(TinyObj):
-            */
-            let pkg_define = format!("class {}(TinyObj):", &file_name);
-            let package_now = match ClassInfo::new(&String::from(""), &pkg_define, true) {
-                Some(s) => s,
-                None => return self,
-            };
-            let package_name = package_now.this_class_name.clone();
-            self.class_list
-                .entry(package_name.clone())
-                .or_insert(package_now);
-            self.package_name_now = Some(package_name.clone());
-        }
-
         let lines: Vec<&str> = file_str.split('\n').collect();
         let mut last_line = String::from("");
         /* analyse each line */