diff --git a/.cargo/config.toml b/.cargo/config.toml index b50b52b..f8164cd 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -3,4 +3,6 @@ linker = "rust-lld" rustflags = ["-C", "linker-flavor=ld.lld"] [target.x86_64-pc-windows-msvc] +rustflags = ["-C", "link-arg=./.cargo/icon.RES"] +[target.aarch64-pc-windows-msvc] rustflags = ["-C", "link-arg=./.cargo/icon.RES"] \ No newline at end of file diff --git a/src/c.rs b/src/c.rs index 29ab5c5..845000c 100644 --- a/src/c.rs +++ b/src/c.rs @@ -1,7 +1,5 @@ //! 所有跨平台相关的函数都在这 -use std::ptr::NonNull; - #[cfg(windows)] mod dl { extern { @@ -47,7 +45,7 @@ impl Clib { } /// 从动态库中寻找一个函数 pub fn get(&self, sym:&[u8])-> Option<*const ()> { - let mut s = [sym,&[0]].concat(); + let s = [sym,&[0]].concat(); unsafe { let v = dlsym(self.0, s.as_ptr()); if v.is_null() { diff --git a/src/intern.rs b/src/intern.rs index cbbd405..9179b08 100644 --- a/src/intern.rs +++ b/src/intern.rs @@ -31,9 +31,9 @@ impl Interned { pub fn str(&self)-> String { String::from_utf8_lossy(self.vec()).into_owned() } - pub const fn ptr(&self)-> *const Vec { - self.p as *const Vec - } + // pub const fn ptr(&self)-> *const Vec { + // self.p as *const Vec + // } } impl std::fmt::Debug for Interned { diff --git a/src/main.rs b/src/main.rs index d10b83c..24f19e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ -#![allow(unused)] #![feature(hash_set_entry)] -use std::{fs, collections::HashMap, mem::transmute, hash::{BuildHasher, Hash}, vec}; +use std::fs; use std::process::ExitCode; mod intern; @@ -24,11 +23,11 @@ static mut GLOBAL_OPTIONS:GlobalOptions = GlobalOptions { /// 标志目前走到的行号 static mut LINE:usize = 1; -/// 用于标记报错文件 -static mut PLACE:String = String::new(); +/// 用于标记目前文件路径 在模块导入搜索时使用此作为搜索目录 +static mut FILE_PATH:&str = ""; /// 标志解释器的版本 -static VERSION:usize = 100006; +static VERSION:usize = 100062; /// 解释器发行者(用于区分主版本和魔改版) /// @@ -47,7 +46,7 @@ fn main()-> ExitCode { let mut args = std::env::args(); args.next(); let path = if let Some(s) = args.next() { - utils::to_absolute_path(s) + utils::to_absolute_path(s).leak() }else { println!("> Key Lang\n version: {}\n by: {}", VERSION, DISTRIBUTION); return ExitCode::SUCCESS; @@ -62,17 +61,26 @@ fn main()-> ExitCode { } // 自定义报错 - unsafe {PLACE = path.clone()} + unsafe {FILE_PATH = path} std::panic::set_hook(Box::new(|inf| { use crate::utils::date; let line = unsafe{LINE}; - let place = unsafe{&*PLACE}; + let place = unsafe{&*FILE_PATH}; let s = if let Some(mes) = inf.payload().downcast_ref::<&'static str>() { mes }else if let Some(mes) = inf.payload().downcast_ref::() { mes }else{"错误"}; - println!("\n> {}\n {}:第{}行\n\n> Key Script CopyLeft by Subkey\n {}\n", s, place, line, date()); + + let stack = unsafe{ + let mut s = String::new(); + use std::fmt::Write; + for n in runtime::call::CALL_STACK.iter().rev() { + let _ = s.write_fmt(format_args!("\n {} at {}:{}",n.fname,n.file,n.line)); + } + s + }; + println!("\n> {}\n {}:第{}行{}\n\n> Key Script CopyLeft by {}\n {}", s, place, line, stack, DISTRIBUTION, date()); })); // 运行并返回 @@ -80,7 +88,7 @@ fn main()-> ExitCode { panic!("无法读取'{}': {}", path, e))); if unsafe{GLOBAL_OPTIONS.print_ast} {println!("{scanned:?}")} - let exit = runtime::run(&scanned); + let exit = runtime::run(&scanned, path); // 如果原生模块调用了wait_inc就堵住当前线程 unsafe { diff --git a/src/native.rs b/src/native.rs index 58a2aff..b0fe915 100644 --- a/src/native.rs +++ b/src/native.rs @@ -9,8 +9,7 @@ use crate::{ litr::{Instance, Litr}, planet }, - runtime::{outlive::{self, LocalFunc}, Variant}, - scan::stmt::LocalMod + runtime::{outlive::{self, LocalFunc}, Variant} }; use crate::runtime::{calc::CalcRef, Scope}; diff --git a/src/primitive/buf.rs b/src/primitive/buf.rs index 626c891..9b6f32b 100644 --- a/src/primitive/buf.rs +++ b/src/primitive/buf.rs @@ -317,10 +317,10 @@ fn insert(v:&mut Vec, args:Vec)-> Litr { match &**args.next().expect("buf.insert需要传入第二个参数:整数,列表或数组作为插入内容") { Litr::Buf(b)=> { - v.splice(index..index, b.iter().copied()).collect::>(); + let _ = v.splice(index..index, b.iter().copied()).collect::>(); }, Litr::List(b)=> { - v.splice(index..index, b.iter() + let _ = v.splice(index..index, b.iter() .map(|n|to_u8(n))).collect::>(); } n=> v.insert(index, to_u8(n)) @@ -418,17 +418,18 @@ fn join(v:&mut Vec, args:Vec)-> Litr { }else {""}; use std::fmt::Write; + const WRITE_ERR: &str = "buf.join写入错误"; let mut s = String::new(); - s.write_fmt(format_args!("{:02X}",v[0])); + s.write_fmt(format_args!("{:02X}",v[0])).expect(WRITE_ERR); for n in &v[1..] { - s.write_fmt(format_args!("{sep}{n:02X}")); + s.write_fmt(format_args!("{sep}{n:02X}")).expect(WRITE_ERR); } Litr::Str(s) } /// 嘎嘎复制和计算, 将整个数组折叠成一个值 fn fold(v:&mut Vec, args:Vec, scope:Scope)-> Litr { - let mut init = args.get(0).expect("buf.fold需要一个初始值").clone().own(); + let init = args.get(0).expect("buf.fold需要一个初始值").clone().own(); let f = match &**args.get(1).expect("buf.fold需要第二个参数的函数来处理数据") { Litr::Func(f)=> f, _=> panic!("buf.fold第二个参数只能是函数") @@ -653,14 +654,14 @@ pub fn statics()-> Vec<(Interned, NativeFn)> { } /// 创建n长度的Buf -fn s_new(args:Vec, cx:Scope)-> Litr { +fn s_new(args:Vec, _cx:Scope)-> Litr { // 如果传入了大小就按大小分配 if let Some(n) = args.get(0) { let n = to_usize(n); unsafe { let layout = std::alloc::Layout::from_size_align_unchecked(n, 1); - let alc = unsafe {std::alloc::alloc_zeroed(layout)}; + let alc = std::alloc::alloc_zeroed(layout); Litr::Buf(Vec::from_raw_parts(alc, n, n)) } }else { @@ -676,7 +677,7 @@ fn s_new_uninit(args:Vec, _cx:Scope)-> Litr { unsafe { let layout = std::alloc::Layout::from_size_align_unchecked(n, 1); - let alc = unsafe {std::alloc::alloc(layout)}; + let alc = std::alloc::alloc(layout); Litr::Buf(Vec::from_raw_parts(alc, n, n)) } }else { diff --git a/src/primitive/func.rs b/src/primitive/func.rs index a72f87f..1ef60d0 100644 --- a/src/primitive/func.rs +++ b/src/primitive/func.rs @@ -16,7 +16,7 @@ pub fn method(f:&Function, name:Interned, cx: Scope, args:Vec)-> Litr { } /// 传入self并调用 -pub fn kcall(f:&Function, mut args:Vec, mut cx:Scope)-> Litr { +pub fn kcall(f:&Function, mut args:Vec, cx:Scope)-> Litr { assert!(args.len()>=1, "func.call必须传入一个值作为self"); let trans_args = args.split_off(1); let mut kself = args.pop().unwrap(); @@ -32,7 +32,7 @@ pub fn kcall(f:&Function, mut args:Vec, mut cx:Scope)-> Litr { } /// 复制一个函数,但上下文在当前作用域 -pub fn clone_here(f:&Function, mut args:Vec, mut cx:Scope)-> Litr { +pub fn clone_here(f:&Function, _args:Vec, cx:Scope)-> Litr { Litr::Func(match f { Function::Local(f)=> Function::Local(LocalFunc::new(f.ptr, cx)), // 如果不是local就正常调用 @@ -41,7 +41,7 @@ pub fn clone_here(f:&Function, mut args:Vec, mut cx:Scope)-> Litr { } /// 复制一个函数,但上下文在当前作用域 -pub fn call_here(f:&Function, mut args:Vec, mut cx:Scope)-> Litr { +pub fn call_here(f:&Function, mut args:Vec, cx:Scope)-> Litr { assert!(args.len()>=1, "func.call_here必须传入一个值作为self"); let trans_args = args.split_off(1); let mut kself = args.pop().unwrap(); @@ -57,7 +57,7 @@ pub fn call_here(f:&Function, mut args:Vec, mut cx:Scope)-> Litr { } /// 复制一个函数,但上下文在该模块的顶级作用域 -pub fn clone_top(f:&Function, mut args:Vec, mut cx:Scope)-> Litr { +pub fn clone_top(f:&Function, _args:Vec, mut cx:Scope)-> Litr { // 获取顶级作用域 while let Some(s) = &cx.parent { cx = s.clone() @@ -124,6 +124,6 @@ fn s_new(mut s:Vec, cx:Scope)-> Litr { } Litr::Func(Function::Local(LocalFunc::new(Box::into_raw(Box::new( - LocalFuncRaw {argdecl:LocalFuncRawArg::Normal(argdecl), stmts} + LocalFuncRaw {argdecl:LocalFuncRawArg::Normal(argdecl), stmts, name: intern(b"unnamed")} )),cx))) } diff --git a/src/primitive/iter.rs b/src/primitive/iter.rs index 7dc1e6c..cd6c736 100644 --- a/src/primitive/iter.rs +++ b/src/primitive/iter.rs @@ -1,10 +1,8 @@ -use std::cell::UnsafeCell; - use crate::{ intern::intern, - native::{NativeInstance, NativeMethod}, + native::NativeInstance, primitive::litr::{Litr, LocalFunc}, - runtime::{calc::CalcRef, Scope} + runtime::Scope }; /// instance类型专用的迭代器 @@ -56,7 +54,7 @@ impl<'a> LitrIterator<'a> { Litr::List(v)=> Box::new(v.iter().cloned()), Litr::Inst(inst)=> { let f = & unsafe{&*inst.cls}.methods.iter() - .find(|f|f.name == intern(b"@next")) + .find(|f|f.f.name == intern(b"@next")) .expect("迭代class需要定义'.@next()'方法").f; let f = LocalFunc::new(f, unsafe{&*inst.cls}.cx); Box::new(InstanceIter { f, kself:v }) diff --git a/src/primitive/kstd.rs b/src/primitive/kstd.rs index 93ac211..9de6d8c 100644 --- a/src/primitive/kstd.rs +++ b/src/primitive/kstd.rs @@ -1,6 +1,6 @@ //! 定义顶级作用域的函数 -use crate::intern::{Interned,intern}; +use crate::intern::intern; use crate::primitive::litr::{Litr, Function}; use crate::runtime::{calc::CalcRef, Scope, Variant}; @@ -47,17 +47,15 @@ fn run_ks(args:Vec, mut cx:Scope)-> Litr { unsafe { // 将报错位置写为evil 并保存原先的报错数据 - let mut place = std::mem::take(&mut crate::PLACE); + let mut file_dir = std::mem::take(&mut crate::FILE_PATH); let line = crate::LINE; - crate::PLACE = format!("run_ks: {}({})", place, line); + crate::FILE_PATH = "run_ks"; crate::LINE = 1; // 解析并运行 let scanned = crate::scan::scan(s); for (l, sm) in &scanned.v { - unsafe{ - crate::LINE = *l; - } + crate::LINE = *l; cx.evil(sm); // 如果evil到return或break就在这停下 if cx.ended { @@ -66,7 +64,7 @@ fn run_ks(args:Vec, mut cx:Scope)-> Litr { } // 还原报错信息 - crate::PLACE = std::mem::take(&mut place); + crate::FILE_PATH = std::mem::take(&mut file_dir); crate::LINE = line; } Litr::Uninit diff --git a/src/primitive/kstr.rs b/src/primitive/kstr.rs index 4c55d67..e2ec7a9 100644 --- a/src/primitive/kstr.rs +++ b/src/primitive/kstr.rs @@ -12,7 +12,7 @@ fn to_usize(n:&Litr)-> usize { static mut ITER_LINES: *mut NativeClassDef = std::ptr::null_mut(); -pub fn method(s:&mut String, scope:Scope, name:Interned, args:Vec)-> Litr { +pub fn method(s:&mut String, _scope:Scope, name:Interned, args:Vec)-> Litr { macro_rules! get_arg0 { // 解析为usize (usize)=> { diff --git a/src/primitive/list.rs b/src/primitive/list.rs index 770405c..256efa3 100644 --- a/src/primitive/list.rs +++ b/src/primitive/list.rs @@ -138,16 +138,6 @@ fn map_clone(v:&mut Vec, args:Vec, scope:Scope)-> Litr { .map(|a| scope.call(vec![CalcRef::Ref(a)], f) ).collect()) } -/// map_clone的原地版本 -fn map(v:&mut Vec, args:Vec, scope:Scope)-> Litr { - let f = match &**args.get(0).expect("list.map需要一个函数作为参数") { - Litr::Func(f)=> f, - _=> panic!("list.map第一个参数只能传函数") - }; - *v = v.iter_mut().map(|a| scope.call(vec![CalcRef::Ref(a)], f)).collect(); - Litr::Uninit -} - /// 从末尾切去一个, 可传一个数字作为切去数量 fn pop(v:&mut Vec, args:Vec)-> Litr { if let Some(arg0) = args.get(0) { @@ -234,10 +224,10 @@ fn insert_many(v:&mut Vec, args:Vec)-> Litr { match &**args.get(1).expect("list.insert_many需要传入第二个参数作为插入内容") { Litr::Buf(b)=> { - v.splice(index..index, b.iter().map(|n|Litr::Uint(*n as usize))).collect::>(); + let _ = v.splice(index..index, b.iter().map(|n|Litr::Uint(*n as usize))).collect::>(); }, Litr::List(b)=> { - v.splice(index..index, b.iter() + let _ = v.splice(index..index, b.iter() .map(|n|n.clone())).collect::>(); } _=> panic!("list.insert_many第二个参数必须是List或Buf") @@ -349,13 +339,14 @@ fn join(v:&mut Vec, args:Vec)-> Litr { }else {""}; use std::fmt::Write; + const WRITE_ERR: &str = "list.join错误"; let mut res = String::new(); - res.write_fmt(format_args!("{}", v[0].str())); + res.write_fmt(format_args!("{}", v[0].str())).expect(WRITE_ERR); for n in &mut v[1..] { if let Litr::Str(s) = n { - res.write_fmt(format_args!("{sep}{}",s)); + res.write_fmt(format_args!("{sep}{}",s)).expect(WRITE_ERR); }else { - res.write_fmt(format_args!("{sep}{}",n.str())); + res.write_fmt(format_args!("{sep}{}",n.str())).expect(WRITE_ERR); } } Litr::Str(res) @@ -364,7 +355,7 @@ fn join(v:&mut Vec, args:Vec)-> Litr { /// 嘎嘎复制和计算, 将整个数组折叠成一个值 fn fold(v:&mut Vec, args:Vec, scope:Scope)-> Litr { let mut args = args.into_iter(); - let mut init = args.next().expect("list.fold需要一个初始值").clone().own(); + let init = args.next().expect("list.fold需要一个初始值").clone().own(); let f_ = args.next().expect("list.fold需要第二个参数的函数来处理数据"); let f = match &*f_ { Litr::Func(f)=> f, @@ -397,7 +388,7 @@ fn includes(v:&mut Vec, args:Vec)-> Litr { } /// 找数组中第一个所指数字, 也可以传函数来自定义判断 -fn index_of(v:&mut Vec, args:Vec, scope:Scope)-> Litr { +fn index_of(v:&mut Vec, args:Vec, _cx:Scope)-> Litr { let find = &**args.get(0).expect("list.index_of需要传入一个值"); let res = v.iter().position(|n|n==find); match res { @@ -407,11 +398,11 @@ fn index_of(v:&mut Vec, args:Vec, scope:Scope)-> Litr { } /// index_of反向版 -fn r_index_of(v:&mut Vec, args:Vec, scope:Scope)-> Litr { +fn r_index_of(v:&mut Vec, args:Vec, _cx:Scope)-> Litr { let find = &**args.get(0).expect("list.r_index_of需要传入一个值"); let res = v.iter().rev().position(|n|n==find); match res { - Some(n)=> Litr::Uint((v.len() - n - 1)), + Some(n)=> Litr::Uint(v.len() - n - 1), None=> Litr::Uninit } } diff --git a/src/primitive/litr.rs b/src/primitive/litr.rs index 8b09011..8675f1f 100644 --- a/src/primitive/litr.rs +++ b/src/primitive/litr.rs @@ -36,8 +36,8 @@ impl Litr { Float(n)=> n.to_string(), Bool(n)=> n.to_string(), Func(f)=> { - match *f { - Function::Local(_)=> "".to_string(), + match f { + Function::Local(f)=> format!("", f.name), Function::Extern(_)=> "".to_string(), Function::Native(_)=> "".to_string() } @@ -92,7 +92,7 @@ impl Litr { s.push_str(": "); s.push_str(&next_v); } - }}}; + }}} s.push_str(&cls.name.str()); s.push_str(" { "); @@ -144,6 +144,7 @@ pub struct ArgDecl { /// 未绑定作用域的本地定义函数 #[derive(Debug, Clone)] pub struct LocalFuncRaw { + pub name: Interned, pub argdecl: LocalFuncRawArg, pub stmts: Statements } @@ -175,7 +176,7 @@ impl Clone for Instance { /// 为想要管理内存的实例提供@clone方法 fn clone(&self) -> Self { let fname = intern(b"@clone"); - let opt = unsafe{&*self.cls}.methods.iter().find(|f|f.name==fname); + let opt = unsafe{&*self.cls}.methods.iter().find(|f|f.f.name==fname); let cloned = Instance { cls: self.cls.clone(), v: self.v.clone() }; match opt { Some(cls_f)=> { @@ -184,7 +185,7 @@ impl Clone for Instance { if let Litr::Inst(v) = res { v }else { - panic!("'{}'的@clone方法必须返回实例", cls_f.name); + panic!("'{}'的@clone方法必须返回实例", cls_f.f.name); } } None=> cloned @@ -196,7 +197,7 @@ impl Drop for Instance { /// 调用自定义drop fn drop(&mut self) { let fname = intern(b"@drop"); - let opt = unsafe{&*self.cls}.methods.iter().find(|f|f.name==fname); + let opt = unsafe{&*self.cls}.methods.iter().find(|f|f.f.name==fname); match opt { Some(cls_f)=> { let f = LocalFunc::new(&cls_f.f, unsafe{&*self.cls}.cx); @@ -240,7 +241,6 @@ impl KsType { $( KsType::$t=> matches!(arg, Litr::$t(_)), )* - KsType::Bool=> matches!(arg, Litr::Bool(_)), KsType::Class(cls)=> { let cls = cx.find_class(*cls).unwrap_or_else(||panic!("无法找到'{}'类型",cls)); match cls { @@ -313,7 +313,7 @@ impl PartialOrd for Litr { (Str(l), Str(r))=> l.partial_cmp(r), (Buf(l), Buf(r))=> l.partial_cmp(r), (List(l), List(r))=> match_list(l,r), - (Obj(l), Obj(r))=> None, + (Obj(_), Obj(_))=> None, (Inst(l),Inst(r))=> { if l.cls==r.cls { match_list(&*l.v, &*r.v) diff --git a/src/primitive/mod.rs b/src/primitive/mod.rs index c7c24c9..2b8b6d3 100644 --- a/src/primitive/mod.rs +++ b/src/primitive/mod.rs @@ -139,6 +139,11 @@ pub fn get_prop(this:Scope, mut from:CalcRef, find:Interned)-> CalcRef { }), Litr::Func(f)=> CalcRef::Own(match find.vec() { + b"name"=> match f { + Function::Local(f)=> Litr::Str(f.name.str()), + Function::Extern(_)=> Litr::Str("@extern".to_owned()), + Function::Native(_)=> Litr::Str("@native".to_owned()) + } b"type"=> match f { Function::Local(_)=> Litr::Str("local".to_owned()), Function::Extern(_)=> Litr::Str("extern".to_owned()), diff --git a/src/primitive/planet.rs b/src/primitive/planet.rs index cce81d9..06b6919 100644 --- a/src/primitive/planet.rs +++ b/src/primitive/planet.rs @@ -2,7 +2,6 @@ //! //! 可阻塞可回调, 类似Promise -use self::litr::LocalFunc; use super::*; use std::sync::{Mutex, Condvar}; @@ -55,7 +54,7 @@ pub fn init()-> (Interned, *mut NativeClassDef) { planet.methods.push((intern(b"fall"), fall)); planet.methods.push((intern(b"then"), fall)); planet.onclone = |_|panic!("无法复制行星!请尝试使用`take`函数."); - planet.ondrop = |inst|unsafe {std::ptr::drop_in_place(inst.v as *mut Planet)}; + planet.ondrop = |inst|std::ptr::drop_in_place(inst.v as *mut Planet); // 初始化Planet okay调用者的类 PLANET_CALLER_CLASS = new_static_class(b"Planet.okay", vec![]).1; @@ -77,14 +76,14 @@ fn to_func(args:&Vec)-> &Function { } /// 让行星坠落阻塞主线程 -fn fall(inst:&mut NativeInstance, args:Vec, cx:Scope)-> Litr { +fn fall(inst:&mut NativeInstance, _args:Vec, _cx:Scope)-> Litr { let plan = unsafe{&mut*(inst.v as *mut Planet)}; rust_fall(plan) } /// 完成行星任务并传回答案 -fn ok(inst:&mut NativeInstance, args:Vec, cx:Scope)-> Litr { +fn ok(inst:&mut NativeInstance, args:Vec, _cx:Scope)-> Litr { let plan = unsafe{&mut*(inst.v as *mut Planet)}; if !matches!(plan.state, PlanetState::Scroll) {return Litr::Uninit;} @@ -114,7 +113,7 @@ fn new(args:Vec, cx:Scope)-> Litr { /// 降落所有行星并返回参数长度的列表作为结果 -fn all(args:Vec, cx:Scope)-> Litr { +fn all(args:Vec, _cx:Scope)-> Litr { let mut res = Vec::with_capacity(args.len()); for arg in args { let plan = if let Litr::Ninst(inst) = &*arg { diff --git a/src/primitive/sym.rs b/src/primitive/sym.rs index e2cc81a..173fa2f 100644 --- a/src/primitive/sym.rs +++ b/src/primitive/sym.rs @@ -1,5 +1,5 @@ use crate::{ - intern::{intern, Interned}, native::{NativeClassDef, NativeFn, NativeInstance}, primitive::litr::Litr, runtime::{calc::CalcRef, Scope} + intern::{intern, Interned}, native::{NativeClassDef, NativeInstance}, primitive::litr::Litr }; pub const ITER_END:usize = 1; diff --git a/src/runtime/calc.rs b/src/runtime/calc.rs index ef433d5..5fac63d 100644 --- a/src/runtime/calc.rs +++ b/src/runtime/calc.rs @@ -1,9 +1,6 @@ //! 注释都在mod.rs里,这没有注解 -use crate::{ - native::NativeInstance, - primitive::{self, litr::*, get_prop} -}; +use crate::primitive::{litr::*, get_prop}; use super::*; /// calc_ref既可能得到引用,也可能得到计算过的值 @@ -55,7 +52,7 @@ impl Scope { /// 解析一个表达式,对应Expr /// /// 该函数必定发生复制 - pub fn calc(mut self,e:&Expr)-> Litr { + pub fn calc(self,e:&Expr)-> Litr { match e { Expr::Call { args, targ }=> { let targ_ = self.calc_ref(targ); @@ -92,7 +89,7 @@ impl Scope { // 函数表达式 Expr::LocalDecl(local)=> { - let exec = LocalFunc::new(local, self); + let exec = LocalFunc::new(*local, self); Litr::Func(Function::Local(exec)) } @@ -149,9 +146,9 @@ impl Scope { if let Class::Local(cls) = cls { let cls = unsafe {&*cls}; let mut v = vec![Litr::Uninit;cls.props.len()]; - /// 记录哪个属性没有写入 + // 记录哪个属性没有写入 let mut writen = vec![false; cls.props.len()]; - /// 确认你在模块内还是模块外 + // 确认你在模块内还是模块外 let can_access_private = self.exports == cls.cx.exports; 'a: for (id, e) in val.iter() { for (n, prop) in cls.props.iter().enumerate() { @@ -226,7 +223,7 @@ impl Scope { let cls = unsafe {&*m}; let can_access_private = cls.cx.exports == this_module; for func in cls.statics.iter() { - if func.name == find { + if func.f.name == find { assert!(func.public || can_access_private, "'{}'类型的静态方法'{}'是私有的。", cls.name, find); @@ -235,7 +232,7 @@ impl Scope { } } for func in cls.methods.iter() { - if func.name == find { + if func.f.name == find { assert!(!func.public || can_access_private, "'{}'类型中的方法'{}'是私有的。", cls.name, find); @@ -272,7 +269,6 @@ impl Scope { } Expr::Property(e, find)=> { - let scope = self; let from = self.calc_ref(&**e); get_prop(self, from, *find).own() } @@ -307,8 +303,8 @@ impl Scope { _=> false }), Litr::Ninst(inst)=> Litr::Bool(match self.find_class(*right) { + Some(Class::Native(c))=> c == inst.cls, _=> false, - Some(Class::Native(c))=> c == inst.cls }), Litr::Uninit=> Litr::Bool(false), $( @@ -393,7 +389,7 @@ impl Scope { /// 在一个作用域设置一个表达式为v -fn expr_set(mut this: Scope, left: &Expr, right: Litr) { +fn expr_set(this: Scope, left: &Expr, right: Litr) { match left { // 捕获native instance的setter Expr::Property(e, find)=> { @@ -445,7 +441,7 @@ fn expr_set(mut this: Scope, left: &Expr, right: Litr) { Litr::Inst(inst)=> { let fname = intern(b"@index_set"); let cls = unsafe{&*inst.cls}; - let opt = cls.methods.iter().find(|v|v.name == fname); + let opt = cls.methods.iter().find(|v|v.f.name == fname); match opt { Some(f)=> { let f = LocalFunc::new(&f.f, cls.cx); @@ -492,7 +488,7 @@ fn expr_set(mut this: Scope, left: &Expr, right: Litr) { /// 先读后写版的expr_set -fn expr_set_diff(mut this: Scope, left: &Expr, f:impl Fn(&Litr)-> Litr) { +fn expr_set_diff(this: Scope, left: &Expr, f:impl Fn(&Litr)-> Litr) { match left { // 捕获native instance的setter Expr::Property(e, find)=> { @@ -545,7 +541,7 @@ fn expr_set_diff(mut this: Scope, left: &Expr, f:impl Fn(&Litr)-> Litr) { let cls = unsafe{&*inst.cls}; let write = { let fname = intern(b"@index_get"); - let opt = cls.methods.iter().find(|v|v.name == fname); + let opt = cls.methods.iter().find(|v|v.f.name == fname); match opt { Some(func_raw)=> { let ori = Scope::call_local_with_self(&LocalFunc::new(&func_raw.f, cls.cx), vec![i.clone().own()], left); @@ -555,7 +551,7 @@ fn expr_set_diff(mut this: Scope, left: &Expr, f:impl Fn(&Litr)-> Litr) { } }; let fname = intern(b"@index_set"); - let opt = cls.methods.iter().find(|v|v.name == fname); + let opt = cls.methods.iter().find(|v|v.f.name == fname); match opt { Some(f)=> { let f = LocalFunc::new(&f.f, cls.cx); @@ -627,7 +623,7 @@ fn get_index(mut left:CalcRef, i:CalcRef)-> CalcRef { if let Litr::Inst(inst) = left { let fname = intern(b"@index_get"); let cls = unsafe{&*inst.cls}; - let opt = cls.methods.iter().find(|v|v.name == fname); + let opt = cls.methods.iter().find(|v|v.f.name == fname); if let Some(f) = opt { let f = LocalFunc::new(&f.f, cls.cx); return CalcRef::Own(Scope::call_local_with_self(&f, vec![i.own()], left)); @@ -674,7 +670,7 @@ fn get_index(mut left:CalcRef, i:CalcRef)-> CalcRef { } -fn binary(mut this: Scope, left:&Box, right:&Box, op:&Box<[u8]>)-> Litr { +fn binary(this: Scope, left:&Box, right:&Box, op:&Box<[u8]>)-> Litr { use Litr::*; // 先捕获赋值行为 @@ -761,7 +757,7 @@ fn binary(mut this: Scope, left:&Box, right:&Box, op:&Box<[u8]>)-> L } // 不是赋值行为再去正常计算 - let mut left = this.calc_ref(&left); + let left = this.calc_ref(&left); let right = this.calc_ref(&right); /// 二元运算中普通数字的戏份 macro_rules! impl_num { diff --git a/src/runtime/call.rs b/src/runtime/call.rs index e93bcdd..e26dd83 100644 --- a/src/runtime/call.rs +++ b/src/runtime/call.rs @@ -4,12 +4,38 @@ use self::calc::CalcRef; use super::*; +pub struct CallStackElem { + pub file: &'static str, + pub line: usize, + pub fname: Interned +} +/// 报错时打印调用栈 +pub static mut CALL_STACK: Vec = Vec::new(); +const MAX_CALL_COUNT: usize = 0x1000; +fn push_stack(fname: Interned) { + unsafe{ + let file = crate::FILE_PATH; + if CALL_STACK.len()>MAX_CALL_COUNT { + panic!("递归过多, 超出最大调用限制{}", MAX_CALL_COUNT) + } + CALL_STACK.push(CallStackElem{file, line:LINE, fname}) + } +} +fn pop_stack() { + unsafe{CALL_STACK.pop();} +} + impl Scope { /// 解析Expr的调用 - pub fn call(mut self, args:Vec, targ:&Function)-> Litr { + pub fn call(self, args:Vec, targ:&Function)-> Litr { use Function::*; match targ { - Native(f)=> f(args, self), + Native(f)=> { + push_stack(intern(b"@native")); + let r = f(args, self); + pop_stack(); + r + }, Local(f)=> { let args = args.into_iter().map(|e|e.own()).collect(); self.call_local(&f, args) @@ -22,8 +48,9 @@ impl Scope { } /// 为a.b()的行为匹配对应方法并调用 - pub fn call_method(mut self, mut args:Vec, mut targ:CalcRef, name:Interned)-> Litr { - match &mut *targ { + pub fn call_method(self, mut args:Vec, mut targ:CalcRef, name:Interned)-> Litr { + push_stack(name); + let r = match &mut *targ { Litr::Bool(v)=> match name.vec() { b"rev"=> Litr::Bool(!*v), b"then"=> { @@ -57,11 +84,11 @@ impl Scope { let methods = &cls.methods; for mthd in methods.iter() { - if mthd.name == name { + if mthd.f.name == name { if !mthd.public && cannot_access_private { panic!("'{}'类型的成员方法'{}'是私有的", cls.name, name) } - let mut f = LocalFunc::new(&mthd.f, cls.cx); + let f = LocalFunc::new(&mthd.f, cls.cx); let args = args.into_iter().map(|e|e.own()).collect(); return Scope::call_local_with_self(&f, args, &mut *targ); } @@ -75,7 +102,9 @@ impl Scope { .find(|(find,_)|name==*find).unwrap_or_else(||panic!("'{}'原生类型中没有'{}'方法\n 你需要用(x.{})()的写法吗?", cls.name, name, name)); (*f)(inst, args, self) } - } + }; + pop_stack(); + r } /// 实际调用一个local function @@ -87,7 +116,7 @@ impl Scope { pub fn call_local_with_self(f:&LocalFunc, args:Vec, kself:*mut Litr)-> Litr { // 将传入参数按定义参数数量放入作用域 let init_vars = match &f.argdecl { - /// 正常传参 + // 正常传参 LocalFuncRawArg::Normal(argdecl)=> { // 将传入参数按定义参数数量放入作用域 let mut vars = Vec::with_capacity(f.stmts.vars + argdecl.len()); @@ -104,7 +133,7 @@ impl Scope { } vars } - /// List传参 + // List传参 LocalFuncRawArg::Custom(name)=> { let mut vars = Vec::with_capacity(f.stmts.vars + 1); vars.push(Variant {name:*name, v:Litr::List(args), locked:false}); @@ -117,7 +146,20 @@ impl Scope { scope.return_to = &mut ret; scope.vars = init_vars; scope.kself = kself; - scope.run(&f.stmts); + + unsafe { + // 模块外函数报错时知道在模块外 + let mut file_path = std::mem::take(&mut crate::FILE_PATH); + crate::FILE_PATH = (*scope.exports).modpath; + + // 调用栈推一份记录 + push_stack(f.name); + + scope.run(&f.stmts); + + crate::FILE_PATH = std::mem::take(&mut file_path); + pop_stack(); + } ret } } diff --git a/src/runtime/evil.rs b/src/runtime/evil.rs index 8d46394..d920e92 100644 --- a/src/runtime/evil.rs +++ b/src/runtime/evil.rs @@ -21,7 +21,7 @@ impl Scope { Stmt::Let(asn)=> assign(*self, asn, false), // const语句 Stmt::Const(asn)=> assign(*self, asn, true), - /// 锁定语句 + // 锁定语句 Stmt::Lock(id)=> self.lock(*id), // 块语句 @@ -63,9 +63,7 @@ impl Scope { // 导出函数 mod. Stmt::ExportFn(id, f)=> { - // 将函数本体生命周期拉为static - let func_raw = Box::into_raw(Box::new(f.clone())); - let f = LocalFunc::new(func_raw, *self); + let f = LocalFunc::new(*f, *self); // 将函数定义处的作用域生命周期永久延长 outlive::increase_scope_count(f.scope); self.vars.push(Variant { @@ -124,7 +122,7 @@ impl Scope { use primitive::iter::LitrIterator; let mut iter_ = self.calc_ref(iter); - let mut iter = LitrIterator::new(&mut iter_); + let iter = LitrIterator::new(&mut iter_); let mut breaked = false; match &**exec { @@ -150,8 +148,8 @@ impl Scope { // 单语句运行 _=> if let None = id { - let mut scope = self.subscope(); - for v in iter { + let scope = self.subscope(); + for _ in iter { self.evil(exec); } outlive::scope_end(scope); @@ -238,7 +236,7 @@ impl Scope { /// let和const fn assign(mut s:Scope, asn:&AssignDef, locked: bool) { // 如果用的是<而不是=, 则直接夺取右侧值所有权 - let mut v = if asn.take { + let v = if asn.take { std::mem::take(&mut *s.calc_ref(&asn.val)) } else { s.calc(&asn.val) @@ -366,7 +364,7 @@ fn loop_run(mut scope:Scope,breaked:&mut bool,exec:&Statements) { Stmt::Break=> return *breaked = true, Stmt::Continue=> return, // 把直属该for下的块拦截,检测break和continue - Stmt::Block(v)=> loop_run(scope, breaked, exec), + Stmt::Block(_)=> loop_run(scope, breaked, exec), Stmt::If { condition, exec, els }=> { if cond(scope.calc(condition)) { loop_run_stmt!(&**exec) diff --git a/src/runtime/externer.rs b/src/runtime/externer.rs index 6b6ba65..204dab5 100644 --- a/src/runtime/externer.rs +++ b/src/runtime/externer.rs @@ -1,9 +1,6 @@ //! 提供Ks数据和C交互的转换 use std::mem::transmute; -use std::slice::from_raw_parts as raw; -use crate::intern::Interned; -use crate::c::{dlopen,dlsym}; use crate::primitive::litr::*; static mut EXEC:Option = None; @@ -22,7 +19,7 @@ macro_rules! translate_local_impl {{ $( extern fn $fname($($arg:usize,)*)-> usize { let exec = unsafe {EXEC.as_mut().expect("未找到extern函数,这是bug")}; - let mut scope = exec.scope; + let scope = exec.scope; let args = [$($arg,)*].into_iter().map(|n|Litr::Uint(n)).collect(); let ret = scope.call_local(exec, args); match translate(&ret) { @@ -50,7 +47,7 @@ pub fn translate(arg:&Litr)-> Result { Bool(n)=> Ok(*n as usize), Int(n)=> unsafe{Ok(transmute(*n))}, Uint(n)=> Ok(*n), - Float(n)=> (unsafe{Ok(transmute(*n))}), + Float(n)=> unsafe{Ok(transmute(*n))}, Str(p)=> Ok((*p).as_ptr() as usize), Buf(v)=> Ok(v.as_ptr() as usize), Func(exec)=> { @@ -78,7 +75,7 @@ pub fn translate(arg:&Litr)-> Result { } -use super::{ExternFunc, Scope}; +use super::ExternFunc; pub fn call_extern(f:&ExternFunc, args:Vec)-> Litr { let len = f.argdecl.len(); let mut args = args.into_iter(); diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index 26522d6..a1d1b0b 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -6,16 +6,14 @@ pub mod outlive; mod evil; pub mod calc; -mod call; +pub mod call; mod externer; use crate::intern::{intern, Interned}; use crate::LINE; use std::collections::HashMap; -use std::sync::atomic::{AtomicUsize,self}; -use std::ptr::NonNull; +use std::sync::atomic::AtomicUsize; use crate::scan::{ - literal::*, stmt::*, expr::* }; @@ -99,22 +97,6 @@ impl Scope { Scope {ptr} } - /// 确认此作用域是否为一个作用域的子作用域 - pub fn subscope_of(&self,upper:Scope)-> bool { - let mut scope = *self; - let upper = upper.ptr; - if scope.ptr == upper { - return true; - } - while let Some(parent) = scope.parent { - if parent.ptr == upper { - return true; - } - scope = parent; - } - false - } - /// 生成一个子作用域 pub fn subscope(&self)-> Scope { Scope::new(ScopeInner { @@ -237,12 +219,12 @@ pub struct RunResult { } /// 创建顶级作用域并运行一段程序 -pub fn run(s:&Statements)-> RunResult { +pub fn run(s:&Statements, modpath:&'static str)-> RunResult { let mut top_ret = Litr::Uninit; - let mut imports = Vec::new(); - let mut exports = Box::into_raw(Box::new(LocalMod { funcs: Vec::new(), classes: Vec::new() })); + let imports = Box::into_raw(Box::new(Vec::new())); + let exports = Box::into_raw(Box::new(LocalMod { funcs: Vec::new(), classes: Vec::new(), modpath })); let mut kself = Litr::Uninit; - let mut top = top_scope(&mut top_ret, &mut imports, exports,&mut kself); + let top = top_scope(&mut top_ret, imports, exports,&mut kself); top.run(s); RunResult { returned: top_ret, exports, kself } } @@ -252,7 +234,7 @@ pub fn run(s:&Statements)-> RunResult { /// 自定义此函数可添加初始函数和变量 pub fn top_scope(return_to:*mut Litr, imports:*mut Vec<(Interned, Module)>, exports:*mut LocalMod, kself:*mut Litr)-> Scope { let vars = crate::primitive::kstd::prelude(); - let mut class_uses = crate::primitive::classes(); + let class_uses = crate::primitive::classes(); Scope::new(ScopeInner { parent: None, diff --git a/src/runtime/outlive.rs b/src/runtime/outlive.rs index 37c0cb9..064a864 100644 --- a/src/runtime/outlive.rs +++ b/src/runtime/outlive.rs @@ -8,9 +8,8 @@ use super::LocalFuncRaw; use std::sync::atomic::Ordering; -use std::sync::atomic::AtomicUsize; use super::Scope; -fn ln()->usize{unsafe{crate::LINE}} +// fn ln()->usize{unsafe{crate::LINE}} /// 本地函数指针 #[derive(Debug)] @@ -58,7 +57,7 @@ impl Clone for LocalFunc { // 或者a=||{};a=0的时候,此函数会直接原地drop impl Drop for LocalFunc { fn drop(&mut self) { - let count = &self.scope.outlives; + // let count = &self.scope.outlives; // println!("{:02}: func drop inplace : {:?}",ln(), self.ptr); decrease_scope_count(self.scope); } diff --git a/src/scan/expr.rs b/src/scan/expr.rs index 035a010..4d189f7 100644 --- a/src/scan/expr.rs +++ b/src/scan/expr.rs @@ -1,6 +1,6 @@ use super::{Scanner, charts}; use crate::primitive::litr::{ - KsType, Litr, LocalFuncRaw + Litr, LocalFuncRaw }; use crate::intern::{intern, Interned}; @@ -16,7 +16,7 @@ pub enum Expr { Kself, /// 未绑定作用域的本地函数 - LocalDecl (LocalFuncRaw), + LocalDecl (*mut LocalFuncRaw), /// -.运算符 module-.func ModFuncAcc(Interned, Interned), @@ -102,7 +102,6 @@ impl Scanner<'_> { let mut expr_stack = vec![left]; let mut op_stack = Vec::<&[u8]>::new(); - let len = self.src.len(); loop { // 向后检索二元运算符 self.spaces(); @@ -193,7 +192,7 @@ impl Scanner<'_> { self.next(); self.spaces(); let targ = Box::new(expr_stack.pop().unwrap()); - let mut args = parse_input_args(self); + let args = parse_input_args(self); expr_stack.push(Expr::Call { args, targ }); continue; } diff --git a/src/scan/literal.rs b/src/scan/literal.rs index fb19bf0..e79ea99 100644 --- a/src/scan/literal.rs +++ b/src/scan/literal.rs @@ -1,9 +1,6 @@ use super::*; use crate::{ - native::NativeInstance, - runtime::{calc::CalcRef, Module, Scope}, intern::Interned, - scan::stmt::ClassDef, primitive::litr::{Litr, LocalFuncRaw} }; @@ -356,7 +353,7 @@ impl Scanner<'_> { // 解析闭包内容 let stmt = self.stmt(); - let mut stmts = if let super::Stmt::Block(b) = stmt { + let stmts = if let super::Stmt::Block(b) = stmt { b }else { Statements { @@ -365,7 +362,7 @@ impl Scanner<'_> { } }; - Expr::LocalDecl(LocalFuncRaw { argdecl: args, stmts }) + Expr::LocalDecl(Box::into_raw(Box::new(LocalFuncRaw { argdecl: args, stmts, name: intern(b"unnamed") }))) } // 解析字面量或变量 diff --git a/src/scan/mod.rs b/src/scan/mod.rs index c899ada..fb01f88 100644 --- a/src/scan/mod.rs +++ b/src/scan/mod.rs @@ -1,13 +1,7 @@ //! 将源码扫描为 AST的过程 -use std::collections::HashMap; - -use crate::intern::{ - intern, - Interned -}; +use crate::intern::intern; use crate::primitive::litr::{ArgDecl, KsType, Litr, LocalFuncRawArg}; -use crate::runtime::Scope; use crate::LINE; pub mod charts; @@ -20,29 +14,26 @@ use expr::Expr; /// 将字符扫描为ast pub fn scan(src: &[u8])-> Statements { - // 已知此处所有变量未泄露 - // 为了规避&mut所有权检查,将引用改为指针 let mut i = 0; - let mut sttms = Statements::default(); - let mut scanner = Scanner { - src, i:&mut i, - sttms:&mut sttms as *mut Statements + let mut stmts = Statements::default(); + let scanner = Scanner { + src, i:&mut i, stmts:&mut stmts }; scanner.scan(); - sttms + stmts } struct Scanner<'a> { src: &'a [u8], i: *mut usize, - sttms: *mut Statements, + stmts: *mut Statements, } /// 通用方法 impl Scanner<'_> { /// 启动扫描 - fn scan(mut self) { + fn scan(self) { let len = self.src.len(); while self.i() < len { let s = self.stmt(); @@ -55,7 +46,7 @@ impl Scanner<'_> { #[inline] fn push(&self, s:Stmt) { - unsafe{(*self.sttms).v.push((LINE, s));} + unsafe{(*self.stmts).v.push((LINE, s));} } /// 获取当前字符(ascii u8) #[inline] diff --git a/src/scan/stmt.rs b/src/scan/stmt.rs index 6894887..07cd2ee 100644 --- a/src/scan/stmt.rs +++ b/src/scan/stmt.rs @@ -1,7 +1,7 @@ use super::{Scanner, scan}; use crate::intern::{Interned,intern}; -use crate::native::{NativeClassDef, NativeMod}; -use crate::runtime::{Scope, ScopeInner, Module}; +use crate::native::NativeMod; +use crate::runtime::Scope; use crate::LINE; use crate::primitive::litr::{ Litr, Function, LocalFuncRaw, LocalFunc, ExternFunc, KsType @@ -34,7 +34,7 @@ pub enum Stmt { Mod (Interned, *const LocalMod), NativeMod (Interned, *const NativeMod), - ExportFn (Interned, LocalFuncRaw), + ExportFn (Interned, *mut LocalFuncRaw), ExportCls (*const ClassDefRaw), Match { @@ -99,7 +99,8 @@ pub enum AssignTo { #[derive(Debug, Clone)] pub struct LocalMod { pub funcs: Vec<(Interned, LocalFunc)>, - pub classes: Vec<(Interned, *mut ClassDef)> + pub classes: Vec<(Interned, *mut ClassDef)>, + pub modpath: &'static str } /// 未绑定作用域的类声明 @@ -138,7 +139,6 @@ pub struct ClassProp { /// 类中的未绑定作用域的函数声明 #[derive(Debug,Clone)] pub struct ClassFuncRaw { - pub name: Interned, pub f: LocalFuncRaw, pub public: bool } @@ -316,7 +316,7 @@ impl Scanner<'_> { self.next(); let stmt = self.stmt(); - let mut stmts = if let Stmt::Block(b) = stmt { + let stmts = if let Stmt::Block(b) = stmt { b }else { Statements { @@ -325,12 +325,16 @@ impl Scanner<'_> { } }; + let fname = match id { + AssignTo::One(n)=>n, + AssignTo::Destr(_)=>intern(b"unnamed") + }; // scan过程产生的LocalFunc是没绑定作用域的,因此不能由运行时来控制其内存释放 // 其生命周期应当和Statements相同,绑定作用域时将被复制 // 绑定作用域行为发生在runtime::Scope::calc AssignDef { id, take:false, - val: Expr::LocalDecl(LocalFuncRaw { argdecl: args, stmts }) + val: Expr::LocalDecl(Box::into_raw(Box::new(LocalFuncRaw { argdecl: args, stmts, name:fname }))) } } _ => AssignDef { @@ -462,7 +466,7 @@ impl Scanner<'_> { }else {false}; let id = match self.ident() { - Some(id)=> id, + Some(id)=> intern(id), None=> break }; @@ -476,7 +480,7 @@ impl Scanner<'_> { // 函数体 let stmt = self.stmt(); - let mut stmts = if let Stmt::Block(b) = stmt { + let stmts = if let Stmt::Block(b) = stmt { b }else { Statements { @@ -485,7 +489,7 @@ impl Scanner<'_> { } }; - let v = ClassFuncRaw {name: intern(id), f:LocalFuncRaw{argdecl:args,stmts}, public}; + let v = ClassFuncRaw {f:LocalFuncRaw{argdecl:args,stmts,name:id}, public}; if is_method { methods.push(v); }else { @@ -495,7 +499,7 @@ impl Scanner<'_> { }else { let typ = self.typ(); let v = ClassProp { - name: intern(id), typ, public + name: id, typ, public }; props.push(v); } @@ -547,53 +551,51 @@ impl Scanner<'_> { self.spaces(); let mut i = self.i(); let len = self.src.len(); - let mut dot = 0; loop { assert!(i 符号"); let cur = self.src[i]; if cur == b'>' { break; } - if cur == b'.' { - dot = i; - } i += 1; } let path = String::from_utf8_lossy(&self.src[self.i()..i]).into_owned(); let path = crate::utils::to_absolute_path(path); + let path_path = std::path::Path::new(&path); self.set_i(i + 1); self.spaces(); - let name = intern(&self.ident().unwrap_or_else(||panic!("需要为模块命名"))); + let name = intern(&self.ident().expect("需要为模块命名")); self.spaces(); - assert!(dot!=0, "未知模块类型"); - let suffix = &self.src[dot..i]; - match suffix { - b".ksm"|b".dll"=> unsafe{ - /// 让mod过程出错时知道是原生模块的锅 - let mut place = std::mem::take(&mut crate::PLACE); - crate::PLACE = format!("'{}'中:\n 解析原生模块'{}'时出现错误", place, path); + let ext = path_path.extension().expect("未知模块类型\n 原生模块应有ksm|dll|so|dylib后缀").as_encoded_bytes(); + match ext { + b"ksm"|b"dll"|b"so"|b"dylib"=> unsafe{ + // 让mod过程出错时知道是原生模块的锅 + let mut file_dir = std::mem::take(&mut crate::FILE_PATH); + crate::FILE_PATH = path_path.to_string_lossy().into_owned().leak(); + let module = crate::native::parse(path.as_bytes()); - crate::PLACE = std::mem::take(&mut place); + + crate::FILE_PATH = std::mem::take(&mut file_dir); Stmt::NativeMod(name, module) } - b".ks"=> { - let file = std::fs::read(&*path).unwrap_or_else(|e|panic!( + b"ks"=> { + let file = std::fs::read(&*path).unwrap_or_else(|_|panic!( "无法找到模块'{}'", path )); unsafe { // 将报错位置写为该模块 并保存原先的报错数据 - let mut place = std::mem::take(&mut crate::PLACE); - crate::PLACE = path.clone(); + let mut file_dir = std::mem::take(&mut crate::FILE_PATH); + crate::FILE_PATH = path_path.to_string_lossy().into_owned().leak(); let line = crate::LINE; crate::LINE = 1; - let mut module = crate::runtime::run(&scan(&file)).exports; + let module = crate::runtime::run(&scan(&file), crate::FILE_PATH).exports; // 还原报错信息 - crate::PLACE = std::mem::take(&mut place); + crate::FILE_PATH = std::mem::take(&mut file_dir); crate::LINE = line; Stmt::Mod(name, module) diff --git a/src/utils.rs b/src/utils.rs index 49f70b7..cc8b0b9 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -37,15 +37,36 @@ pub fn date()-> String { format!("{year}/{mon:02}/{t:02} {hour:02}:{min:02}:{sec:02}") } + +// pub static mut PATH_SEARCH_DIRS: Vec = Vec::new(); + #[inline] +/// 寻找一个ks文件 pub fn to_absolute_path(s:String)-> String { let p = std::path::Path::new(&s); if p.is_absolute() { s }else { let mut buf = std::path::PathBuf::new(); - buf.push(std::env::current_dir().expect("无法获取当前文件夹, 请尝试传入绝对路径")); - buf.push(s); - buf.into_os_string().to_string_lossy().into_owned() + unsafe{if crate::FILE_PATH!=""{ + buf.push(&crate::FILE_PATH); + buf.pop(); + }else { + buf.push(&std::env::current_dir().expect("无法获取当前文件夹, 请尝试传入绝对路径")) + }} + buf.push(&s); + + if let None = buf.extension() { + match buf.metadata() { + // 对文件夹自动加mod.ks文件名 + Ok(meta)=> if meta.is_dir() { + buf.push("mod.ks") + } + // 对文件名自动加.ks后缀 + Err(_)=> buf.as_mut_os_string().push(".ks") + } + } + + buf.to_string_lossy().into_owned() } } \ No newline at end of file