mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
!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:
parent
23152a10b6
commit
24d4da89f0
2
port/linux/.vscode/launch.json
vendored
2
port/linux/.vscode/launch.json
vendored
@ -11,7 +11,7 @@
|
||||
"program": "${workspaceFolder}/build/test/pikascript_test",
|
||||
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
|
||||
"args": [
|
||||
// "--gtest_filter=parser.branket_issue3"
|
||||
"--gtest_filter=PikaCV.test1"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
|
@ -1,21 +1,17 @@
|
||||
from PikaObj import *
|
||||
import PikaStdLib
|
||||
import PikaStdData
|
||||
import PikaStdDevice
|
||||
import ctypes
|
||||
import GTestTask
|
||||
import PikaMath
|
||||
import PikaStdDevice
|
||||
import test_module1
|
||||
import test_cmodule
|
||||
import TempDevTest as dev
|
||||
import TemplateDevice
|
||||
import pika_cjson as cjson
|
||||
import TempDevTest
|
||||
import cjson_test
|
||||
import test_module4
|
||||
import pika_lua
|
||||
import import_test
|
||||
import pika_configparser as configparser
|
||||
from PikaStdData import String as S
|
||||
import pika_configparser
|
||||
import PikaDebug
|
||||
import PikaCV
|
||||
|
||||
|
@ -371,7 +371,7 @@ int Lib_loadLibraryFileToArray(char* origin_file_name, char* out_folder) {
|
||||
FILE* fp = __platform_fopen(output_file_path, "wb+");
|
||||
char* array_name = strsGetLastToken(&buffs, origin_file_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("/* warning: auto generated file, please do not modify */\n",
|
||||
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_path =
|
||||
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_path = NULL;
|
||||
output_file_path =
|
||||
@ -591,7 +591,7 @@ void pikaMaker_linkCompiledModulesFullPath(PikaMaker* self, char* lib_path) {
|
||||
Args context = {0};
|
||||
LibObj* lib = New_LibObj(NULL);
|
||||
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, "__maker", self);
|
||||
args_foreach(self->list, __foreach_handler_linkCompiledModules, &context);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import PikaStdLib
|
||||
import PyInfo
|
||||
import test
|
||||
from pika_cjson import cJSON
|
||||
print('hello pikascript!')
|
||||
mem = PikaStdLib.MemChecker()
|
||||
|
@ -7,6 +7,14 @@ use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
|
||||
enum PackageType {
|
||||
CPackageTop,
|
||||
CPackageInner,
|
||||
PyPackageTop,
|
||||
PyPackageInner,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Compiler {
|
||||
pub dist_path: String,
|
||||
@ -30,9 +38,17 @@ impl Compiler {
|
||||
return compiler;
|
||||
}
|
||||
|
||||
pub fn analyse_main_line(mut compiler: Compiler, line: &String) -> Compiler {
|
||||
let file_name = "main".to_string();
|
||||
let class_name = "PikaMain".to_string();
|
||||
pub fn analyse_py_line(mut compiler: Compiler, line: &String, is_top_pkg: bool) -> Compiler {
|
||||
let file_name = match is_top_pkg {
|
||||
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 */
|
||||
let class_now = match compiler.class_list.get_mut(&"PikaMain".to_string()) {
|
||||
Some(class_now) => class_now,
|
||||
@ -53,40 +69,18 @@ impl Compiler {
|
||||
if package_name == "PikaObj" {
|
||||
return compiler;
|
||||
}
|
||||
/* add to script */
|
||||
class_now.script_list.add(&line);
|
||||
|
||||
/* check file, break if *.py no found */
|
||||
match Compiler::open_file(format!("{}{}.pyi", compiler.source_path, package_name)) {
|
||||
Ok(_) => {}
|
||||
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;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
if is_top_pkg {
|
||||
/* add to script */
|
||||
class_now.script_list.add(&line);
|
||||
}
|
||||
|
||||
let package_obj_define = format!("{} = {}()", package_name, package_name);
|
||||
class_now.push_object(package_obj_define, &file_name);
|
||||
return Compiler::analyse_top_package(compiler, package_name.to_string());
|
||||
return Compiler::analyse_package_from_py(compiler, package_name.to_string());
|
||||
}
|
||||
|
||||
if is_top_pkg {
|
||||
class_now.script_list.add(&line);
|
||||
}
|
||||
class_now.script_list.add(&line);
|
||||
return compiler;
|
||||
}
|
||||
|
||||
@ -103,24 +97,66 @@ impl Compiler {
|
||||
return Err(std::io::Error::from(std::io::ErrorKind::NotFound));
|
||||
}
|
||||
|
||||
pub fn analyse_top_package(self: Compiler, file_name: String) -> Compiler {
|
||||
return self.__do_analyse_file(file_name, true);
|
||||
pub fn analyse_py_package_main(self: Compiler, file_name: String) -> Compiler {
|
||||
return self.__do_analyse_file(file_name, PackageType::PyPackageTop);
|
||||
}
|
||||
|
||||
pub fn analyse_inner_package(self: Compiler, file_name: String) -> Compiler {
|
||||
return self.__do_analyse_file(file_name, false);
|
||||
pub fn analyse_py_package_inner(self: Compiler, file_name: String) -> Compiler {
|
||||
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 */
|
||||
let file: std::result::Result<std::fs::File, std::io::Error>;
|
||||
if file_name == "main" {
|
||||
/* only the main.py is the .py file */
|
||||
file = Compiler::open_file(format!("{}main.py", self.source_path));
|
||||
} else {
|
||||
/* other module is CMoudle, which is .pyi file */
|
||||
file = Compiler::open_file(format!("{}{}.pyi", self.source_path, file_name));
|
||||
}
|
||||
file = Compiler::open_file(format!("{}{}.{}", self.source_path, file_name, suffix));
|
||||
match file {
|
||||
/* py import pyi => top_pyi */
|
||||
Ok(_) => {
|
||||
let class_now = match self.class_list.get_mut(&"PikaMain".to_string()) {
|
||||
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
|
||||
@ -130,32 +166,41 @@ impl Compiler {
|
||||
let mut file = match file {
|
||||
Ok(file) => file,
|
||||
Err(_) => {
|
||||
/* if *.py exits, not print warning */
|
||||
let file_py = Compiler::open_file(format!("{}{}.py", self.source_path, file_name));
|
||||
match file_py {
|
||||
Ok(_) => {
|
||||
return self;
|
||||
}
|
||||
Err(_) => {
|
||||
println!(
|
||||
" [warning]: file: '{}{}.pyi' or '{}{}.py' no found",
|
||||
self.source_path, file_name, self.source_path, file_name
|
||||
);
|
||||
return self;
|
||||
}
|
||||
};
|
||||
if suffix == "pyi" {
|
||||
/* if .pyi no exist, check .py exist */
|
||||
return self.analyse_py_package_inner(file_name.clone());
|
||||
}
|
||||
|
||||
/* .py no exist, error */
|
||||
println!(
|
||||
" [warning]: file: '{}{}.pyi' or '{}{}.py' no found",
|
||||
self.source_path, file_name, self.source_path, file_name
|
||||
);
|
||||
return self;
|
||||
}
|
||||
};
|
||||
|
||||
let mut file_str = String::new();
|
||||
file.read_to_string(&mut file_str).unwrap();
|
||||
|
||||
/* check if compiled */
|
||||
if self.compiled_list.contains(&file_name) {
|
||||
} else if file_name == "main" {
|
||||
println!(" scaning {}{}.py...", self.source_path, file_name);
|
||||
} else {
|
||||
println!(" binding {}{}.pyi...", self.source_path, file_name);
|
||||
/* return when compiled */
|
||||
if !self.compiled_list.contains(&file_name) {
|
||||
/* print info */
|
||||
match suffix {
|
||||
"py" => {
|
||||
println!(
|
||||
" scaning {}{}.{}...",
|
||||
self.source_path, file_name, suffix
|
||||
);
|
||||
}
|
||||
"pyi" => {
|
||||
println!(
|
||||
" binding {}{}.{}...",
|
||||
self.source_path, file_name, suffix
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
/* push to compiled list, only compile once */
|
||||
@ -170,8 +215,10 @@ impl Compiler {
|
||||
object. To implament this, a [package]-api.c file is created
|
||||
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
|
||||
[Example]:
|
||||
class PikaStdDevice(TinyObj):
|
||||
@ -187,18 +234,22 @@ impl Compiler {
|
||||
.or_insert(package_now);
|
||||
self.package_now_name = Some(package_name.clone());
|
||||
}
|
||||
|
||||
let lines: Vec<&str> = file_str.split('\n').collect();
|
||||
/* analyse each line of .pyi */
|
||||
/* analyse each line */
|
||||
for line in lines.iter() {
|
||||
let line = line.replace("\r", "");
|
||||
/* replace \t with 4 spaces */
|
||||
let line = line.replace("\t", " ");
|
||||
|
||||
if file_name == "main" {
|
||||
self = Compiler::analyse_main_line(self, &line);
|
||||
} else {
|
||||
self = Compiler::analyse_pyi_line(self, line.to_string(), &file_name, is_top_pkg);
|
||||
}
|
||||
self = match pkg_type {
|
||||
PackageType::CPackageTop | PackageType::CPackageInner => {
|
||||
Compiler::analyse_pyi_line(self, line.to_string(), &file_name, is_top_c_pkg)
|
||||
}
|
||||
PackageType::PyPackageTop | PackageType::PyPackageInner => {
|
||||
Compiler::analyse_py_line(self, &line, is_top_py_pkg)
|
||||
}
|
||||
};
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -212,7 +263,7 @@ impl Compiler {
|
||||
if line.starts_with("import ") {
|
||||
let tokens: Vec<&str> = line.split(" ").collect();
|
||||
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("#") {
|
||||
|
@ -15,7 +15,7 @@ pub fn pika_compiler_entry() {
|
||||
let mut compiler = Compiler::new(String::from(""), String::from("pikascript-api/"));
|
||||
|
||||
/* 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
|
||||
as the top packages.
|
||||
@ -26,13 +26,13 @@ pub fn pika_compiler_entry() {
|
||||
if package_name == "pikascript-core" {
|
||||
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 */
|
||||
compiler = Compiler::analyse_top_package(compiler, String::from("PikaStdTask"));
|
||||
compiler = Compiler::analyse_top_package(compiler, String::from("PikaStdData"));
|
||||
compiler = Compiler::analyse_top_package(compiler, String::from("PikaDebug"));
|
||||
compiler = Compiler::analyse_c_package_top(compiler, String::from("PikaStdTask"));
|
||||
compiler = Compiler::analyse_c_package_top(compiler, String::from("PikaStdData"));
|
||||
compiler = Compiler::analyse_c_package_top(compiler, String::from("PikaDebug"));
|
||||
|
||||
// println!();
|
||||
|
||||
|
1
tools/pikaCompiler/test.py
Normal file
1
tools/pikaCompiler/test.py
Normal file
@ -0,0 +1 @@
|
||||
import PyInfo
|
Loading…
x
Reference in New Issue
Block a user