!51 Support bind .pyi from other *.py expect main.py

* Support bind .pyi from other *.py expect main.py
* update rust
* fix suffix format
* fix name case
* supporting import pyi from other py
* supporting import pyi from other py
This commit is contained in:
李昂 2022-07-13 08:29:42 +00:00 committed by pikastech
parent 23152a10b6
commit 24d4da89f0
7 changed files with 139 additions and 91 deletions

View File

@ -11,7 +11,7 @@
"program": "${workspaceFolder}/build/test/pikascript_test", "program": "${workspaceFolder}/build/test/pikascript_test",
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain", // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
"args": [ "args": [
// "--gtest_filter=parser.branket_issue3" "--gtest_filter=PikaCV.test1"
], ],
"stopAtEntry": false, "stopAtEntry": false,
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",

View File

@ -1,21 +1,17 @@
from PikaObj import * from PikaObj import *
import PikaStdLib import PikaStdLib
import PikaStdData import PikaStdDevice
import ctypes import ctypes
import GTestTask import GTestTask
import PikaMath import PikaMath
import PikaStdDevice
import test_module1 import test_module1
import test_cmodule import test_cmodule
import TempDevTest as dev import TempDevTest
import TemplateDevice
import pika_cjson as cjson
import cjson_test import cjson_test
import test_module4 import test_module4
import pika_lua import pika_lua
import import_test import import_test
import pika_configparser as configparser import pika_configparser
from PikaStdData import String as S
import PikaDebug import PikaDebug
import PikaCV import PikaCV

View File

@ -371,7 +371,7 @@ int Lib_loadLibraryFileToArray(char* origin_file_name, char* out_folder) {
FILE* fp = __platform_fopen(output_file_path, "wb+"); FILE* fp = __platform_fopen(output_file_path, "wb+");
char* array_name = strsGetLastToken(&buffs, origin_file_name, '/'); char* array_name = strsGetLastToken(&buffs, origin_file_name, '/');
array_name = strsReplace(&buffs, array_name, ".", "_"); array_name = strsReplace(&buffs, array_name, ".", "_");
__platform_printf(" loading %s[]...\n", array_name); __platform_printf(" loading %s[]...\n", array_name);
pika_fputs("#include \"PikaPlatform.h\"\n", fp); pika_fputs("#include \"PikaPlatform.h\"\n", fp);
pika_fputs("/* warning: auto generated file, please do not modify */\n", pika_fputs("/* warning: auto generated file, please do not modify */\n",
fp); fp);
@ -404,7 +404,7 @@ static void __Maker_compileModuleWithInfo(PikaMaker* self, char* module_name) {
char* input_file_name = strsAppend(&buffs, module_name, ".py"); char* input_file_name = strsAppend(&buffs, module_name, ".py");
char* input_file_path = char* input_file_path =
strsAppend(&buffs, obj_getStr(self, "pwd"), input_file_name); strsAppend(&buffs, obj_getStr(self, "pwd"), input_file_name);
__platform_printf(" compiling %s...\r\n", input_file_name); __platform_printf(" compiling %s...\r\n", input_file_name);
char* output_file_name = strsAppend(&buffs, module_name, ".py.o"); char* output_file_name = strsAppend(&buffs, module_name, ".py.o");
char* output_file_path = NULL; char* output_file_path = NULL;
output_file_path = output_file_path =
@ -591,7 +591,7 @@ void pikaMaker_linkCompiledModulesFullPath(PikaMaker* self, char* lib_path) {
Args context = {0}; Args context = {0};
LibObj* lib = New_LibObj(NULL); LibObj* lib = New_LibObj(NULL);
Args buffs = {0}; Args buffs = {0};
__platform_printf(" linking %s...\n", lib_path); __platform_printf(" linking %s...\n", lib_path);
args_setPtr(&context, "__lib", lib); args_setPtr(&context, "__lib", lib);
args_setPtr(&context, "__maker", self); args_setPtr(&context, "__maker", self);
args_foreach(self->list, __foreach_handler_linkCompiledModules, &context); args_foreach(self->list, __foreach_handler_linkCompiledModules, &context);

View File

@ -1,5 +1,5 @@
import PikaStdLib import PikaStdLib
import PyInfo import test
from pika_cjson import cJSON from pika_cjson import cJSON
print('hello pikascript!') print('hello pikascript!')
mem = PikaStdLib.MemChecker() mem = PikaStdLib.MemChecker()

View File

@ -7,6 +7,14 @@ use std::fs;
use std::fs::File; use std::fs::File;
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
enum PackageType {
CPackageTop,
CPackageInner,
PyPackageTop,
PyPackageInner,
}
#[derive(Debug)] #[derive(Debug)]
pub struct Compiler { pub struct Compiler {
pub dist_path: String, pub dist_path: String,
@ -30,9 +38,17 @@ impl Compiler {
return compiler; return compiler;
} }
pub fn analyse_main_line(mut compiler: Compiler, line: &String) -> Compiler { pub fn analyse_py_line(mut compiler: Compiler, line: &String, is_top_pkg: bool) -> Compiler {
let file_name = "main".to_string(); let file_name = match is_top_pkg {
let class_name = "PikaMain".to_string(); true => "main".to_string(),
false => "".to_string(),
};
let class_name = match is_top_pkg {
true => "PikaMain".to_string(),
false => "".to_string(),
};
/* get class now or create one */ /* get class now or create one */
let class_now = match compiler.class_list.get_mut(&"PikaMain".to_string()) { let class_now = match compiler.class_list.get_mut(&"PikaMain".to_string()) {
Some(class_now) => class_now, Some(class_now) => class_now,
@ -53,40 +69,18 @@ impl Compiler {
if package_name == "PikaObj" { if package_name == "PikaObj" {
return compiler; return compiler;
} }
/* add to script */
class_now.script_list.add(&line);
/* check file, break if *.py no found */ if is_top_pkg {
match Compiler::open_file(format!("{}{}.pyi", compiler.source_path, package_name)) { /* add to script */
Ok(_) => {} class_now.script_list.add(&line);
Err(_) => { }
/* if *.py exits, not print warning */
match Compiler::open_file(format!(
"{}{}.py",
compiler.source_path, package_name
)) {
Ok(_) => {
return compiler;
}
Err(_) => {
println!(
" [warning]: file: '{}{}.pyi' or '{}{}.py' no found",
compiler.source_path,
package_name,
compiler.source_path,
package_name
);
return compiler;
}
};
}
};
let package_obj_define = format!("{} = {}()", package_name, package_name); return Compiler::analyse_package_from_py(compiler, package_name.to_string());
class_now.push_object(package_obj_define, &file_name); }
return Compiler::analyse_top_package(compiler, package_name.to_string());
if is_top_pkg {
class_now.script_list.add(&line);
} }
class_now.script_list.add(&line);
return compiler; return compiler;
} }
@ -103,24 +97,66 @@ impl Compiler {
return Err(std::io::Error::from(std::io::ErrorKind::NotFound)); return Err(std::io::Error::from(std::io::ErrorKind::NotFound));
} }
pub fn analyse_top_package(self: Compiler, file_name: String) -> Compiler { pub fn analyse_py_package_main(self: Compiler, file_name: String) -> Compiler {
return self.__do_analyse_file(file_name, true); return self.__do_analyse_file(file_name, PackageType::PyPackageTop);
} }
pub fn analyse_inner_package(self: Compiler, file_name: String) -> Compiler { pub fn analyse_py_package_inner(self: Compiler, file_name: String) -> Compiler {
return self.__do_analyse_file(file_name, false); return self.__do_analyse_file(file_name, PackageType::PyPackageInner);
} }
fn __do_analyse_file(mut self: Compiler, file_name: String, is_top_pkg: bool) -> Compiler { pub fn analyse_c_package_top(self: Compiler, file_name: String) -> Compiler {
return self.__do_analyse_file(file_name, PackageType::CPackageTop);
}
pub fn analyse_c_package_inner(self: Compiler, file_name: String) -> Compiler {
return self.__do_analyse_file(file_name, PackageType::CPackageInner);
}
pub fn analyse_package_from_py(mut self: Compiler, file_name: String) -> Compiler {
let suffix = String::from("pyi");
/* open file */ /* open file */
let file: std::result::Result<std::fs::File, std::io::Error>; let file: std::result::Result<std::fs::File, std::io::Error>;
if file_name == "main" { file = Compiler::open_file(format!("{}{}.{}", self.source_path, file_name, suffix));
/* only the main.py is the .py file */ match file {
file = Compiler::open_file(format!("{}main.py", self.source_path)); /* py import pyi => top_pyi */
} else { Ok(_) => {
/* other module is CMoudle, which is .pyi file */ let class_now = match self.class_list.get_mut(&"PikaMain".to_string()) {
file = Compiler::open_file(format!("{}{}.pyi", self.source_path, file_name)); Some(class_now) => class_now,
} None => return self,
};
/* create constructor for PikaMain */
let package_obj_define = format!("{} = {}()", file_name, file_name);
class_now.push_object(package_obj_define, &"main".to_string());
return Compiler::analyse_c_package_top(self, file_name);
}
Err(_) => {
/* py import py => inner_py */
return self.analyse_py_package_inner(file_name.clone());
}
};
}
fn __do_analyse_file(mut self: Compiler, file_name: String, pkg_type: PackageType) -> Compiler {
let is_top_c_pkg = match pkg_type {
PackageType::CPackageTop => true,
_ => false,
};
let is_top_py_pkg: bool = match pkg_type {
PackageType::PyPackageTop => true,
_ => false,
};
let suffix = match pkg_type {
PackageType::CPackageTop | PackageType::CPackageInner => "pyi",
PackageType::PyPackageTop | PackageType::PyPackageInner => "py",
};
/* open file */
let file: std::result::Result<std::fs::File, std::io::Error>;
file = Compiler::open_file(format!("{}{}.{}", self.source_path, file_name, suffix));
/* /*
If the .pyi no exist, check if the .py exist If the .pyi no exist, check if the .py exist
@ -130,32 +166,41 @@ impl Compiler {
let mut file = match file { let mut file = match file {
Ok(file) => file, Ok(file) => file,
Err(_) => { Err(_) => {
/* if *.py exits, not print warning */ if suffix == "pyi" {
let file_py = Compiler::open_file(format!("{}{}.py", self.source_path, file_name)); /* if .pyi no exist, check .py exist */
match file_py { return self.analyse_py_package_inner(file_name.clone());
Ok(_) => { }
return self;
} /* .py no exist, error */
Err(_) => { println!(
println!( " [warning]: file: '{}{}.pyi' or '{}{}.py' no found",
" [warning]: file: '{}{}.pyi' or '{}{}.py' no found", self.source_path, file_name, self.source_path, file_name
self.source_path, file_name, self.source_path, file_name );
); return self;
return self;
}
};
} }
}; };
let mut file_str = String::new(); let mut file_str = String::new();
file.read_to_string(&mut file_str).unwrap(); file.read_to_string(&mut file_str).unwrap();
/* check if compiled */ /* return when compiled */
if self.compiled_list.contains(&file_name) { if !self.compiled_list.contains(&file_name) {
} else if file_name == "main" { /* print info */
println!(" scaning {}{}.py...", self.source_path, file_name); match suffix {
} else { "py" => {
println!(" binding {}{}.pyi...", self.source_path, file_name); println!(
" scaning {}{}.{}...",
self.source_path, file_name, suffix
);
}
"pyi" => {
println!(
" binding {}{}.{}...",
self.source_path, file_name, suffix
);
}
_ => {}
}
} }
/* push to compiled list, only compile once */ /* push to compiled list, only compile once */
@ -170,8 +215,10 @@ impl Compiler {
object. To implament this, a [package]-api.c file is created object. To implament this, a [package]-api.c file is created
to supply the class of static object. to supply the class of static object.
*/ */
if file_name != "main" && is_top_pkg {
if is_top_c_pkg {
/* /*
Push top C package to PikaMain.
Solve the package as a class Solve the package as a class
[Example]: [Example]:
class PikaStdDevice(TinyObj): class PikaStdDevice(TinyObj):
@ -187,18 +234,22 @@ impl Compiler {
.or_insert(package_now); .or_insert(package_now);
self.package_now_name = Some(package_name.clone()); self.package_now_name = Some(package_name.clone());
} }
let lines: Vec<&str> = file_str.split('\n').collect(); let lines: Vec<&str> = file_str.split('\n').collect();
/* analyse each line of .pyi */ /* analyse each line */
for line in lines.iter() { for line in lines.iter() {
let line = line.replace("\r", ""); let line = line.replace("\r", "");
/* replace \t with 4 spaces */ /* replace \t with 4 spaces */
let line = line.replace("\t", " "); let line = line.replace("\t", " ");
if file_name == "main" { self = match pkg_type {
self = Compiler::analyse_main_line(self, &line); PackageType::CPackageTop | PackageType::CPackageInner => {
} else { Compiler::analyse_pyi_line(self, line.to_string(), &file_name, is_top_c_pkg)
self = Compiler::analyse_pyi_line(self, line.to_string(), &file_name, is_top_pkg); }
} PackageType::PyPackageTop | PackageType::PyPackageInner => {
Compiler::analyse_py_line(self, &line, is_top_py_pkg)
}
};
} }
return self; return self;
} }
@ -212,7 +263,7 @@ impl Compiler {
if line.starts_with("import ") { if line.starts_with("import ") {
let tokens: Vec<&str> = line.split(" ").collect(); let tokens: Vec<&str> = line.split(" ").collect();
let file = tokens[1]; let file = tokens[1];
return Compiler::analyse_inner_package(compiler, file.to_string()); return Compiler::analyse_c_package_inner(compiler, file.to_string());
} }
if line.starts_with("#") { if line.starts_with("#") {

View File

@ -15,7 +15,7 @@ pub fn pika_compiler_entry() {
let mut compiler = Compiler::new(String::from(""), String::from("pikascript-api/")); let mut compiler = Compiler::new(String::from(""), String::from("pikascript-api/"));
/* analyse file begin with main.py */ /* analyse file begin with main.py */
compiler = Compiler::analyse_top_package(compiler, String::from("main")); compiler = Compiler::analyse_py_package_main(compiler, String::from("main"));
/* /*
Compile packages in requestment.txt, solve the packages Compile packages in requestment.txt, solve the packages
as the top packages. as the top packages.
@ -26,13 +26,13 @@ pub fn pika_compiler_entry() {
if package_name == "pikascript-core" { if package_name == "pikascript-core" {
continue; continue;
} }
compiler = Compiler::analyse_top_package(compiler, String::from(package_name)); compiler = Compiler::analyse_c_package_top(compiler, String::from(package_name));
} }
/* Compile packages in PikaStdLib */ /* Compile packages in PikaStdLib */
compiler = Compiler::analyse_top_package(compiler, String::from("PikaStdTask")); compiler = Compiler::analyse_c_package_top(compiler, String::from("PikaStdTask"));
compiler = Compiler::analyse_top_package(compiler, String::from("PikaStdData")); compiler = Compiler::analyse_c_package_top(compiler, String::from("PikaStdData"));
compiler = Compiler::analyse_top_package(compiler, String::from("PikaDebug")); compiler = Compiler::analyse_c_package_top(compiler, String::from("PikaDebug"));
// println!(); // println!();

View File

@ -0,0 +1 @@
import PyInfo