diff --git a/Cargo.lock b/Cargo.lock index 8a6b867d..b30731eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -189,6 +189,12 @@ dependencies = [ "error-code", ] +[[package]] +name = "collection_literals" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271" + [[package]] name = "colorchoice" version = "1.0.0" @@ -526,6 +532,18 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libcore" +version = "0.1.0" +dependencies = [ + "collection_literals", + "colored", + "derive", + "downcast-rs", + "paste", + "rust-i18n", +] + [[package]] name = "libgit2-sys" version = "0.16.2+1.7.2" @@ -971,12 +989,19 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "stdlib" version = "0.1.0" +dependencies = [ + "collection_literals", + "derive", + "downcast-rs", + "libcore", + "rust-i18n", +] [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "suffix_array" @@ -989,9 +1014,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.57" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -1007,6 +1032,26 @@ dependencies = [ "libc", ] +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.3.34" @@ -1094,9 +1139,11 @@ name = "trc" version = "0.0.1" dependencies = [ "clap", + "collection_literals", "colored", "derive", "downcast-rs", + "libcore", "libloading", "num-bigint", "paste", @@ -1107,6 +1154,7 @@ dependencies = [ "stdlib", "suffix_array", "sys-locale", + "thiserror", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b01f58f2..606730c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,18 +26,20 @@ rustyline = { version = "14.0", features = ["with-file-history"] } suffix_array = "0.5.0" paste = "1" shadow-rs = "0" +libcore = { path = "./libcore" } +collection_literals = "1" +thiserror = "1" [build-dependencies] shadow-rs = "0" [profile.release] -panic = "abort" lto = true codegen-units = 1 strip = true [workspace] -members = ["derive", ".", "stdlib"] +members = ["derive", ".", "stdlib", "libcore"] [package.metadata.i18n] # The available locales for your application, default: ["en"]. diff --git a/derive/src/def_module.rs b/derive/src/def_module.rs index eb95f702..715e4f07 100644 --- a/derive/src/def_module.rs +++ b/derive/src/def_module.rs @@ -154,29 +154,31 @@ pub fn def_impl(context: TokenStream) -> TokenStream { .expect("name error"); } let ret = quote!( - pub fn init() -> crate::base::stdlib::Stdlib { - use crate::base::stdlib::Stdlib; + pub fn module_init(storage: &mut ModuleStorage) -> libcore::libbasic::Module { + use libcore::libbasic::Module; use std::collections::hash_map::HashMap; let mut functions = HashMap::new(); let mut classes = HashMap::new(); let mut submodules = HashMap::new(); let mut consts_info = HashMap::new(); #( - functions.insert(stringify!(#right_func).to_string(), #left_func()); + classes.insert(stringify!(#right_class).to_string(), #left_class::init_info(Some(storage))); )* #( - classes.insert(stringify!(#right_class).to_string(), #left_class::export_info()); - #left_class::gen_funcs_info(); - #left_class::gen_overrides_info(); - #left_class::modify_shadow_name(stringify!(#right_class)); + #left_class::gen_funcs_info(storage); + #left_class::gen_overrides_info(storage); + #left_class::modify_shadow_name(storage, stringify!(#right_class)); )* #( - submodules.insert(stringify!(#submodules).to_string(), #submodules::init()); + consts_info.insert(stringify!(#consts).to_string(), #consts.to_string()); )* #( - consts_info.insert(stringify!(#consts).to_string(), #consts.to_string()); + functions.insert(stringify!(#right_func).to_string(), #left_func(storage)); + )* + #( + submodules.insert(stringify!(#submodules).to_string(), #submodules::module_init(storage)); )* - Stdlib::new( + Module::new( stringify!(#module_ident), submodules, functions, diff --git a/derive/src/function.rs b/derive/src/function.rs index aa94d785..2841fffc 100644 --- a/derive/src/function.rs +++ b/derive/src/function.rs @@ -7,29 +7,24 @@ use syn::{ pub fn process_function_def(sig: &mut Signature) -> (Vec, Vec, syn::Expr) { let output = sig.output.clone(); let output: syn::Expr = match output { - ReturnType::Default => parse_str("TypeAllowNull::None").unwrap(), + ReturnType::Default => parse_str("None").unwrap(), ReturnType::Type(_, ty) => { if let Type::Path(name) = (*ty).clone() { let tyname = name.path.segments[0].ident.to_string(); if tyname == "void" { - parse_str("TypeAllowNull::None").unwrap() + parse_str("None").unwrap() } else if tyname == "any" { parse_str("ANY_TYPE").unwrap() } else if tyname.ends_with("str") { - parse_str(r#"TypeAllowNull::Some(crate::tvm::types::TrcStr::export_info())"#) - .unwrap() + parse_str(r#"TypeAllowNull::Some(libcore::TrcStr::export_info())"#).unwrap() } else if tyname.ends_with("int") { - parse_str("TypeAllowNull::Some(crate::tvm::types::TrcInt::export_info())") - .unwrap() + parse_str("TypeAllowNull::Some(libcore::TrcInt::export_info())").unwrap() } else if tyname.ends_with("bool") { - parse_str("TypeAllowNull::Some(crate::tvm::types::TrcBool::export_info())") - .unwrap() + parse_str("TypeAllowNull::Some(libcore::TrcBool::export_info())").unwrap() } else if tyname.ends_with("char") { - parse_str("TypeAllowNull::Some(crate::tvm::types::TrcChar::export_info())") - .unwrap() + parse_str("TypeAllowNull::Some(libcore::TrcChar::export_info())").unwrap() } else if tyname.ends_with("float") { - parse_str("TypeAllowNull::Some(crate::tvm::types::TrcFloat::export_info())") - .unwrap() + parse_str("TypeAllowNull::Some(libcore::TrcFloat::export_info())").unwrap() } else { panic!("error"); } @@ -49,7 +44,7 @@ pub fn process_function_def(sig: &mut Signature) -> (Vec, Vec, s } let mut args_type_required = vec![]; - new_args.push(parse_str::("dydata: &mut crate::tvm::DynaData").unwrap()); + new_args.push(parse_str::("dydata: &mut libcore::DynaData").unwrap()); sig.inputs = new_args; for i in &input_args { if let FnArg::Typed(PatType { pat, ty, .. }, ..) = i { @@ -70,25 +65,25 @@ pub fn process_function_def(sig: &mut Signature) -> (Vec, Vec, s .unwrap(), ); } else if typename.ends_with("str") { - args_type_required.push(parse_str("crate::tvm::TrcStr").unwrap()); + args_type_required.push(parse_str("libcore::TrcStr").unwrap()); new_stmts.push( parse_str(&format!( - r#"let mut {} = dydata.pop_data::();"#, + r#"let mut {} = dydata.pop_data::();"#, arg_name )) .unwrap(), ); } else if typename.ends_with("int") { - args_type_required.push(parse_str("crate::tvm::TrcInt").unwrap()); + args_type_required.push(parse_str("libcore::TrcInt").unwrap()); new_stmts.push( parse_str(&format!( - r#"let mut {} = dydata.pop_data::();"#, + r#"let mut {} = dydata.pop_data::();"#, arg_name )) .unwrap(), ); } else if typename.ends_with("bool") { - args_type_required.push(parse_str("crate::tvm::TrcBool").unwrap()); + args_type_required.push(parse_str("libcore::TrcBool").unwrap()); new_stmts.push( parse_str(&format!( r#"let mut {} = dydata.pop_data::();"#, @@ -97,19 +92,19 @@ pub fn process_function_def(sig: &mut Signature) -> (Vec, Vec, s .unwrap(), ); } else if typename.ends_with("char") { - args_type_required.push(parse_str("crate::tvm::TrcChar").unwrap()); + args_type_required.push(parse_str("libcore::TrcChar").unwrap()); new_stmts.push( parse_str(&format!( - r#"let mut {} = dydata.pop_data::();"#, + r#"let mut {} = dydata.pop_data::();"#, arg_name )) .unwrap(), ); } else if typename.ends_with("float") { - args_type_required.push(parse_str("crate::tvm::TrcFloat").unwrap()); + args_type_required.push(parse_str("libcore::TrcFloat").unwrap()); new_stmts.push( parse_str(&format!( - r#"let mut {} = dydata.pop_data::();"#, + r#"let mut {} = dydata.pop_data::();"#, arg_name )) .unwrap(), diff --git a/derive/src/lib.rs b/derive/src/lib.rs index ca247946..1f07ea8b 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -47,7 +47,7 @@ pub fn trc_function(attr: TokenStream, input: TokenStream) -> TokenStream { let mut var_lex_tmp: Vec = vec![ parse_str("let mut va_list = vec![];").unwrap(), parse_str( - "let args_num = dydata.pop_data::() as usize;", + "let args_num = dydata.pop_data::() as usize;", ) .unwrap(), parse_str("va_list.reserve(args_num);").unwrap(), @@ -80,8 +80,7 @@ pub fn trc_function(attr: TokenStream, input: TokenStream) -> TokenStream { } } } - input.sig.output = - parse_str::("-> crate::base::error::RuntimeResult<()>").expect("err1"); + input.sig.output = parse_str::("-> RuntimeResult<()>").expect("err1"); let return_stmt = parse_str::("return Ok(());").expect("err2"); for i in input.block.stmts { if let Stmt::Expr(Expr::Return(reexpr), ..) = i.clone() { @@ -115,11 +114,9 @@ pub fn trc_function(attr: TokenStream, input: TokenStream) -> TokenStream { // println!("{}{:#?}", name.to_string(), info_function_self); let rettmp = quote!(#input - fn #info_func_name() -> crate::base::stdlib::RustFunction { - use crate::base::stdlib::*; - use crate::compiler::scope::TypeAllowNull; + fn #info_func_name(storage: &mut ModuleStorage) -> RustFunction { let ret_classes = vec![#(#args_type_required::export_info()),*]; - return RustFunction::new(stringify!(#name), #function_path, IOType::new(ret_classes, #output, #if_enable_var_params)); + return RustFunction::new(stringify!(#name), #function_path, IOType::new(ret_classes, #output, #if_enable_var_params), storage); } ); // println!("{}", rettmp.to_token_stream()); @@ -163,53 +160,42 @@ pub fn trc_class(_: TokenStream, input: TokenStream) -> TokenStream { // 目前的实现策略是先提供一个由once_cell储存的usize数,表示在类型表中的索引,里面储存该类型的Rc指针 // 因为很可能某个函数的参数就是标准库中的某个类型,所以我们需要先将类型导入到class_table中 let ret = quote!(#input - use crate::base::stdlib::{RustClass, new_class_id, STD_CLASS_TABLE}; use std::sync::OnceLock; impl #name { - pub fn init_info() -> usize { + pub fn init_info(storage: Option<&mut ModuleStorage>) -> usize { use std::collections::hash_map::HashMap; - let mut members = HashMap::new(); - #( - members.insert(stringify!(#members_ty), stringify!(#members_ident)); - )* - let classid = new_class_id(); - let mut ret = RustClass::new( - "", - members, - None, - None, - classid - ); - unsafe { - STD_CLASS_TABLE.push(ret); - } - classid + static CLASS_ID: OnceLock = OnceLock::new(); + *CLASS_ID.get_or_init(|| { + let mut members = HashMap::new(); + #( + members.insert(stringify!(#members_ty), stringify!(#members_ident)); + )* + let tmp = RustClass::new_in_storage( + "", + members, + None, + None, + storage.expect("class info is called without initing") + ); + //println!("init id"); + tmp + }) } - pub fn gen_funcs_info() { - unsafe { - STD_CLASS_TABLE[Self::export_info()].functions = Self::function_export(); - } + pub fn gen_funcs_info(storage: &mut ModuleStorage) { + storage.class_table[Self::export_info()].functions = Self::function_export(storage); } - pub fn gen_overrides_info() { - unsafe { - STD_CLASS_TABLE[Self::export_info()].overrides = Self::override_export(); - } + pub fn gen_overrides_info(storage: &mut ModuleStorage) { + storage.class_table[Self::export_info()].overrides = Self::override_export(); } - pub fn modify_shadow_name(name: &'static str) { - unsafe { - STD_CLASS_TABLE[Self::export_info()].name = name; - } + pub fn modify_shadow_name(storage: &mut ModuleStorage, name: &'static str) { + storage.class_table[Self::export_info()].name = name; } pub fn export_info() -> usize { - static ID: OnceLock = OnceLock::new(); - *ID.get_or_init(|| { - let id = Self::init_info(); - id - }) + Self::init_info(None) } } ); @@ -240,10 +226,10 @@ pub fn trc_method(_: TokenStream, input: TokenStream) -> TokenStream { let ret = quote!( #input impl #name { - fn function_export() -> HashMap { + fn function_export(storage: &mut ModuleStorage) -> HashMap { let mut ret = HashMap::new(); #( - ret.insert(stringify!(#funcs).to_string(), Self::#funcs()); + ret.insert(stringify!(#funcs).to_string(), Self::#funcs(storage)); )* ret } diff --git a/libcore/Cargo.toml b/libcore/Cargo.toml new file mode 100644 index 00000000..ffa83238 --- /dev/null +++ b/libcore/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "libcore" +version = "0.1.0" +edition = "2021" + +[dependencies] +rust-i18n = "3" +colored = "2" +downcast-rs = "1" +paste = "1" +collection_literals = "1" +derive = { path = "../derive" } + +[lib] +name = "libcore" +crate-type = ["dylib"] diff --git a/src/base/codegen.rs b/libcore/src/codegen.rs similarity index 92% rename from src/base/codegen.rs rename to libcore/src/codegen.rs index 01548611..1763b9ba 100644 --- a/src/base/codegen.rs +++ b/libcore/src/codegen.rs @@ -1,8 +1,22 @@ -use super::func; use core::{cmp::max, fmt}; use std::{fmt::Display, usize}; -#[derive(Debug, PartialEq, Clone)] +#[derive(Clone)] +pub struct FuncStorage { + pub func_addr: usize, + pub var_table_sz: usize, +} + +impl FuncStorage { + pub fn new(name: usize, var_table_sz: usize) -> Self { + Self { + func_addr: name, + var_table_sz, + } + } +} + +#[derive(Debug, PartialEq, Clone, Copy)] pub enum Opcode { Add, AddInt, @@ -198,7 +212,7 @@ pub struct StaticData { pub constpool: ConstPool, pub inst: InstSet, // 储存函数的位置 - pub funcs: Vec, + pub funcs: Vec, // 符号表需要的长度 pub sym_table_sz: usize, pub line_table: Vec, diff --git a/libcore/src/dynadata.rs b/libcore/src/dynadata.rs new file mode 100644 index 00000000..d02930ab --- /dev/null +++ b/libcore/src/dynadata.rs @@ -0,0 +1,155 @@ +use std::{any::TypeId, mem::size_of, sync::OnceLock}; + +use crate::gc::GcMgr; + +pub type Byte = u64; + +pub fn get_max_stack_sz() -> usize { + static T: OnceLock = OnceLock::new(); + *T.get_or_init(|| 1024 * 1024 * 2 / size_of::()) +} + +pub fn get_trcobj_sz() -> usize { + static T: OnceLock = OnceLock::new(); + *T.get_or_init(size_of::<*mut dyn crate::types::TrcObj>) +} + +#[derive(Default)] +pub struct DynaData { + pub gc: GcMgr, + run_stack: Vec, + pub var_store: Vec, + stack_ptr: usize, + // 变量已经使用的内存空间大小 + var_used: usize, + #[cfg(debug_assertions)] + type_used: Vec<(TypeId, &'static str)>, +} + +impl DynaData { + pub fn new() -> Self { + let mut ret = Self { + run_stack: Vec::with_capacity(get_max_stack_sz()), + var_store: Vec::with_capacity(get_max_stack_sz()), + stack_ptr: 0, + ..Default::default() + }; + unsafe { + ret.run_stack.set_len(get_max_stack_sz()); + ret.var_store.set_len(get_max_stack_sz()); + } + ret + } + + pub fn init_global_var_store(&mut self, cap: usize) { + self.var_used = cap; + if self.var_store.len() > cap { + return; + } + self.var_store.resize(cap, Byte::default()); + } + + /// Push data of this [`DynaData`]. + pub fn push_data(&mut self, data: T) { + unsafe { + (self + .run_stack + .as_mut_ptr() + .byte_offset(self.stack_ptr as isize) as *mut T) + .write(data); + } + self.stack_ptr += size_of::(); + #[cfg(debug_assertions)] + { + self.type_used + .push((TypeId::of::(), std::any::type_name::())); + } + } + + /// Pop data of the data stack + /// + /// # Panics + /// + /// Panics if in debug mode and the type of `T` is wrong. + pub fn pop_data(&mut self) -> T { + let sz = size_of::(); + #[cfg(debug_assertions)] + { + let info = TypeId::of::(); + let info_stack = self.type_used.pop().unwrap(); + if info_stack.0 != info { + panic!( + "pop data type error.Expected get {}.Actually has {}", + std::any::type_name::(), + info_stack.1 + ); + } + debug_assert!(self.stack_ptr >= sz); + } + self.stack_ptr -= sz; + unsafe { *(self.run_stack.as_ptr().byte_offset(self.stack_ptr as isize) as *const T) } + } + + /// Returns the top data of the data stack. + /// + /// # Panics + /// + /// Panics if . + pub fn read_top_data(&self) -> T { + let sz = size_of::(); + #[cfg(debug_assertions)] + { + let info = TypeId::of::(); + let info_stack = self.type_used.last().unwrap(); + if info_stack.0 != info { + panic!( + "pop data type error.Expected get {}.Actually has {}", + std::any::type_name::(), + info_stack.1 + ); + } + debug_assert!(self.stack_ptr >= sz); + } + unsafe { + *(self + .run_stack + .as_ptr() + .byte_offset((self.stack_ptr - sz) as isize) as *const T) + } + } + + pub fn set_var(&mut self, addr: usize, data: T) { + unsafe { + *(self.var_store.as_mut_ptr().byte_offset(addr as isize) as *mut T) = data; + } + } + + pub fn get_var(&self, addr: usize) -> T { + debug_assert!(addr < self.var_used); + unsafe { *(self.var_store.as_ptr().byte_offset(addr as isize) as *const T) } + } + + pub fn alloc_var_space(&mut self, need_sz: usize) -> *mut Byte { + self.var_used += need_sz; + if self.var_used > self.var_store.len() { + self.var_store.resize(self.var_used, Byte::default()); + } + unsafe { + self.var_store + .as_mut_ptr() + .byte_offset((self.var_used - need_sz) as isize) + } + } + + pub fn dealloc_var_space(&mut self, need_sz: usize) { + self.var_used -= need_sz; + } + + pub fn get_var_used(&self) -> usize { + self.var_used + } + + pub fn get_gc(&mut self) -> &mut GcMgr { + &mut self.gc + } +} diff --git a/src/base/error.rs b/libcore/src/error.rs similarity index 95% rename from src/base/error.rs rename to libcore/src/error.rs index 7d25e33d..e3329f59 100644 --- a/src/base/error.rs +++ b/libcore/src/error.rs @@ -43,6 +43,10 @@ pub const CANNOT_IMPORT_MODULE_WITHOUT_FILE: &str = "compiler.symbolerror.cannot_import_not_in_file"; pub const MODULE_NOT_FOUND: &str = "compiler.modulenotfounderror.module_not_found"; +pub fn symbol_redefined(name: &str) -> ErrorInfo { + ErrorInfo::new(t!(SYMBOL_REDEFINED, "0" = name), t!(SYMBOL_ERROR)) +} + #[derive(Debug)] pub struct ErrorInfo { pub message: String, @@ -96,9 +100,7 @@ impl Display for RuntimeError { impl RuntimeError { pub fn new(context: Box, info: ErrorInfo) -> RuntimeError { - // if info.message != "" { - // panic!("develop debug use"); - // } + debug_assert!(!info.message.is_empty()); RuntimeError { context, info } } } @@ -109,7 +111,7 @@ pub struct LightFakeError {} impl Error for LightFakeError {} impl Display for LightFakeError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { panic!("Error calling lightfakeerror"); } } diff --git a/src/tvm/gc.rs b/libcore/src/gc.rs similarity index 80% rename from src/tvm/gc.rs rename to libcore/src/gc.rs index 2df09487..b0b863be 100644 --- a/src/tvm/gc.rs +++ b/libcore/src/gc.rs @@ -10,7 +10,6 @@ impl GcMgr { pub fn alloc(&mut self, obj: T) -> *mut T { // unsafe { alloc(Layout::new::()) as *mut T } - let mem = Box::into_raw(Box::new(obj)); - mem + Box::into_raw(Box::new(obj)) } } diff --git a/libcore/src/lib.rs b/libcore/src/lib.rs new file mode 100644 index 00000000..a65f90f3 --- /dev/null +++ b/libcore/src/lib.rs @@ -0,0 +1,14 @@ +pub mod codegen; +pub mod dynadata; +pub mod error; +pub mod gc; +pub mod libbasic; +pub mod types; + +pub use codegen::*; +pub use dynadata::*; +pub use error::*; +pub use libbasic::*; +pub use types::*; + +rust_i18n::i18n!("locales"); diff --git a/src/base/stdlib.rs b/libcore/src/libbasic.rs similarity index 64% rename from src/base/stdlib.rs rename to libcore/src/libbasic.rs index 3554fa93..63c1e3ca 100644 --- a/src/base/stdlib.rs +++ b/libcore/src/libbasic.rs @@ -1,23 +1,18 @@ -use std::sync::OnceLock; +use crate::dynadata::DynaData; +use downcast_rs::{impl_downcast, Downcast}; use std::{ collections::HashMap, fmt::{Debug, Display}, }; -use downcast_rs::{impl_downcast, Downcast}; - -use crate::{ - compiler::{ - scope::{TyIdxTy, TypeAllowNull}, - token::{ConstPoolIndexTy, TokenType}, - }, - tvm::DynaData, -}; - use super::{codegen::Opcode, error::*}; type StdlibFunc = fn(&mut DynaData) -> RuntimeResult<()>; -const ANY_TYPE_ID: usize = 0; + +pub type ScopeAllocIdTy = usize; +pub type TypeAllowNull = Option; +pub type TyIdxTy = ScopeAllocIdTy; +type ConstPoolIndexTy = usize; #[derive(Clone, Debug)] pub struct IOType { @@ -27,6 +22,33 @@ pub struct IOType { pub return_type: TypeAllowNull, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum OverrideOperations { + Add, + Not, + And, + Or, + Sub, + SelfNegative, + GreaterEqual, + Greater, + LessEqual, + Less, + Equal, + NotEqual, + Mul, + Div, + ExactDiv, + Mod, + BitNot, + BitRightShift, + BitLeftShift, + BitAnd, + BitOr, + Xor, + Power, +} + pub type ArgsNameTy = Vec; #[derive(Clone, Debug)] @@ -70,9 +92,9 @@ impl IOType { ))); } for i in argvs.iter().enumerate().take(self.argvs_type.len()) { - if self.argvs_type[i.0] == 0 { - continue; - } + // if self.argvs_type[i.0] == 0 { + // continue; + // } if self.argvs_type[i.0] != *i.1 { return Err(ArguError::TypeNotMatch(ArgumentError::new( self.argvs_type[i.0], @@ -84,37 +106,15 @@ impl IOType { } } -pub trait FunctionClone { - fn clone_box(&self) -> Box; -} - -impl FunctionClone for T -where - T: 'static + FunctionInterface + Clone, -{ - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } -} - -pub trait FunctionInterface: Downcast + FunctionClone + Debug { +pub trait FunctionInterface: Downcast + Debug { fn get_io(&self) -> &IOType; fn get_name(&self) -> &str; -} - -impl Clone for Box { - fn clone(&self) -> Self { - self.clone_box() - } + fn get_io_mut(&mut self) -> &mut IOType; } impl_downcast!(FunctionInterface); -pub trait ClassClone { - fn clone_box(&self) -> Box; -} - -pub trait ClassInterface: Downcast + Sync + Send + ClassClone + Debug + Display { +pub trait ClassInterface: Downcast + Sync + Send + Debug + Display { fn has_func(&self, funcname: &str) -> Option>; fn has_attr(&self, attrname: usize) -> bool; @@ -127,22 +127,7 @@ pub trait ClassInterface: Downcast + Sync + Send + ClassClone + Debug + Display self.get_id() == 0 } - fn get_override_func(&self, oper_token: TokenType) -> Option<&OverrideWrapper>; -} - -impl ClassClone for T -where - T: 'static + ClassInterface + Clone, -{ - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } -} - -impl Clone for Box { - fn clone(&self) -> Self { - self.clone_box() - } + fn get_override_func(&self, oper_token: OverrideOperations) -> Option<&OverrideWrapper>; } impl_downcast!(ClassInterface); @@ -152,6 +137,10 @@ impl FunctionInterface for RustFunction { &self.io } + fn get_io_mut(&mut self) -> &mut IOType { + &mut self.io + } + fn get_name(&self) -> &str { &self.name } @@ -173,7 +162,7 @@ impl OverrideWrapper { pub struct RustClass { pub members: HashMap, pub functions: HashMap, - pub overrides: HashMap, + pub overrides: HashMap, pub id: usize, pub name: &'static str, pub id_to_var: HashMap, @@ -181,21 +170,22 @@ pub struct RustClass { /// 约定,0号id是any类型 impl RustClass { - pub fn new( + pub fn new_in_storage( name: &'static str, members: HashMap, functions: Option>, - overrides: Option>, - id: usize, - ) -> RustClass { - RustClass { + overrides: Option>, + storage: &mut ModuleStorage, + ) -> usize { + let ret = RustClass { members, functions: functions.unwrap_or_default(), overrides: overrides.unwrap_or_default(), - id, + id: storage.class_table.len(), name, ..Default::default() - } + }; + storage.add_class(ret) } pub fn add_function(&mut self, name: impl Into, func: RustFunction) { @@ -229,7 +219,7 @@ impl ClassInterface for RustClass { self.name } - fn get_override_func(&self, oper_token: TokenType) -> Option<&OverrideWrapper> { + fn get_override_func(&self, oper_token: OverrideOperations) -> Option<&OverrideWrapper> { match self.overrides.get(&oper_token) { Some(i) => Some(i), None => None, @@ -243,24 +233,45 @@ impl Display for RustClass { } } -pub static mut STD_FUNC_TABLE: Vec = vec![]; -pub static mut STD_CLASS_TABLE: Vec = vec![]; - -pub fn get_stdlib() -> &'static Stdlib { - static INIT: OnceLock = OnceLock::new(); - INIT.get_or_init(crate::tvm::stdlib::import_stdlib) +/// 最基础的储存一个动态链接库中的函数和类的地方 +#[derive(Default)] +pub struct ModuleStorage { + pub func_table: Vec, + pub class_table: Vec, } -pub fn new_class_id() -> usize { - unsafe { STD_CLASS_TABLE.len() } +impl ModuleStorage { + pub fn new() -> Self { + Self { + func_table: Vec::new(), + class_table: Vec::new(), + } + } + + pub fn add_func(&mut self, f: StdlibFunc) -> usize { + self.func_table.push(f); + self.func_table.len() - 1 + } + + /// 获取类的个数 + pub fn get_class_end(&self) -> usize { + self.class_table.len() + } + + pub fn add_class(&mut self, c: RustClass) -> usize { + self.class_table.push(c); + self.class_table.len() - 1 + } } impl RustFunction { - pub fn new(name: impl Into, ptr: StdlibFunc, io: IOType) -> RustFunction { - let buildin_id = unsafe { - STD_FUNC_TABLE.push(ptr); - STD_FUNC_TABLE.len() - } - 1; + pub fn new( + name: impl Into, + ptr: StdlibFunc, + io: IOType, + storage: &mut ModuleStorage, + ) -> RustFunction { + let buildin_id = storage.add_func(ptr); Self { name: name.into(), buildin_id, @@ -271,24 +282,24 @@ impl RustFunction { } #[derive(Debug, Clone)] -pub struct Stdlib { +pub struct Module { pub name: String, - pub sub_modules: HashMap, + pub sub_modules: HashMap, pub functions: HashMap, // class name 和class id pub classes: HashMap, pub consts: HashMap, } -impl Stdlib { +impl Module { pub fn new( name: impl Into, - sub_modules: HashMap, + sub_modules: HashMap, functions: HashMap, classes: HashMap, consts: HashMap, - ) -> Stdlib { - Stdlib { + ) -> Module { + Module { name: name.into(), sub_modules, functions, @@ -297,7 +308,7 @@ impl Stdlib { } } - pub fn add_module(&mut self, name: String, module: Stdlib) { + pub fn add_module(&mut self, name: String, module: Module) { let ret = self.sub_modules.insert(name, module); debug_assert!(ret.is_none()); } @@ -307,7 +318,7 @@ impl Stdlib { debug_assert!(ret.is_none()); } - pub fn get_module>>(&self, mut path: T) -> Option { + pub fn get_module>>(&self, mut path: T) -> Option { let item = path.next(); if item.is_none() { return Some(self.clone()); @@ -318,34 +329,6 @@ impl Stdlib { } } -pub fn get_any_type() -> &'static RustClass { - static ANY_TYPE: OnceLock = OnceLock::new(); - ANY_TYPE.get_or_init(|| RustClass::new("any", HashMap::new(), None, None, ANY_TYPE_ID)) -} - -pub struct AnyType {} - -impl AnyType { - pub fn export_info() -> usize { - ANY_TYPE_ID - } -} - -/// 获取到标准库的类的个数,从而区分标准库和用户自定义的类,其实也相当于获取第一个用户可以定义的类的ID -pub fn get_stdclass_end() -> usize { - static STD_NUM: OnceLock = OnceLock::new(); - *STD_NUM.get_or_init(|| unsafe { STD_CLASS_TABLE.len() }) -} - -pub fn get_prelude_function(func_name: &str) -> Option<&'static RustFunction> { - get_stdlib() - .sub_modules - .get("prelude") - .unwrap() - .functions - .get(func_name) -} - pub const INT: &str = "int"; pub const FLOAT: &str = "float"; pub const BOOL: &str = "bool"; diff --git a/src/tvm/types.rs b/libcore/src/types.rs similarity index 81% rename from src/tvm/types.rs rename to libcore/src/types.rs index 0630318b..a3c765c4 100644 --- a/src/tvm/types.rs +++ b/libcore/src/types.rs @@ -1,30 +1,27 @@ -use crate::base::error::*; -use crate::tvm::DynaData; +use crate::dynadata::DynaData; +use crate::error::*; use downcast_rs::{impl_downcast, Downcast}; use rust_i18n::t; use std::fmt::Debug; -pub mod data_structure; -pub mod trcbigint; pub mod trcbool; pub mod trcchar; pub mod trcfloat; pub mod trcint; pub mod trcstr; -pub use trcbool::TrcBool; -pub use trcchar::TrcChar; -pub use trcfloat::TrcFloat; -pub use trcint::TrcInt; -pub use trcstr::TrcStr; - use super::gc::GcMgr; +pub use trcbool::*; +pub use trcchar::*; +pub use trcfloat::*; +pub use trcint::*; +pub use trcstr::*; /// help to generate the same error reporter functions macro_rules! batch_unsupported_operators { ($($traie_name:ident => $oper_name:expr),*) => { $( - fn $traie_name(&self, _:*mut dyn TrcObj, _: &mut crate::tvm::GcMgr) -> RuntimeResult<*mut dyn TrcObj> { + fn $traie_name(&self, _:*mut dyn TrcObj, _: &mut $crate::gc::GcMgr) -> RuntimeResult<*mut dyn TrcObj> { return Err(ErrorInfo::new( t!( OPERATOR_IS_NOT_SUPPORT, @@ -41,14 +38,15 @@ macro_rules! batch_unsupported_operators { macro_rules! impl_oper { // for unsupported operator in rust ($trait_oper_fn_name:ident, $oper:ident, $error_oper_name:expr, $self_type:ident, $newtype:ident, $whether_throw_error:tt) => { - fn $trait_oper_fn_name(&self, other:*mut dyn TrcObj, gc: &mut GcMgr) -> RuntimeResult<*mut dyn TrcObj> { + #[allow(clippy::not_unsafe_ptr_arg_deref)] + fn $trait_oper_fn_name(&self, other:*mut dyn TrcObj, gc: &mut $crate::gc::GcMgr) -> $crate::error::RuntimeResult<*mut dyn TrcObj> { unsafe { match (*other).downcast_ref::<$self_type>() { Some(v) => { return Ok(gc.alloc($newtype::new($oper(self._value, v._value)$whether_throw_error))); }, None => { - return Err(ErrorInfo::new(t!(OPERATOR_IS_NOT_SUPPORT, "0"=$error_oper_name, "1"=(*other).get_type_name()), t!(OPERATOR_ERROR))) + return Err($crate::error::ErrorInfo::new(t!($crate::error::OPERATOR_IS_NOT_SUPPORT, "0"=$error_oper_name, "1"=(*other).get_type_name()), t!($crate::error::OPERATOR_ERROR))) } } } @@ -56,14 +54,15 @@ macro_rules! impl_oper { }; // for supported operator in rust ($trait_oper_fn_name:ident, $oper:tt, $error_oper_name:expr, $self_type:ident, $newtype:ident) => { - fn $trait_oper_fn_name(&self, other:*mut dyn TrcObj, gc: &mut GcMgr) -> RuntimeResult<*mut dyn TrcObj> { + #[allow(clippy::not_unsafe_ptr_arg_deref)] + fn $trait_oper_fn_name(&self, other:*mut dyn TrcObj, gc: &mut $crate::gc::GcMgr) -> $crate::error::RuntimeResult<*mut dyn TrcObj> { unsafe { match (*other).downcast_ref::<$self_type>() { Some(v) => { return Ok(gc.alloc($newtype::new(self._value $oper v._value))); }, None => { - return Err(ErrorInfo::new(t!(OPERATOR_IS_NOT_SUPPORT, "0"=$error_oper_name, "1"=(*other).get_type_name()), t!(OPERATOR_ERROR))) + return Err($crate::error::ErrorInfo::new(t!($crate::error::OPERATOR_IS_NOT_SUPPORT, "0"=$error_oper_name, "1"=(*other).get_type_name()), t!($crate::error::OPERATOR_ERROR))) } } } @@ -83,7 +82,7 @@ macro_rules! batch_impl_opers { #[macro_export] macro_rules! impl_single_oper { ($trait_oper_fn_name:ident, $oper:tt, $error_oper_name:expr, $self_type:ident, $newtype:ident) => { - fn $trait_oper_fn_name(&self, gc: &mut GcMgr) -> RuntimeResult<*mut dyn TrcObj> { + fn $trait_oper_fn_name(&self, gc: &mut $crate::gc::GcMgr) -> $crate::error::RuntimeResult<*mut dyn TrcObj> { return Ok(gc.alloc($newtype::new($oper self._value))); } }; @@ -94,7 +93,7 @@ macro_rules! gen_interface { pub fn $funcname(dydata: &mut DynaData) -> RuntimeResult<()> { let t2 = dydata.pop_data::<*mut dyn TrcObj>(); let t1 = dydata.pop_data::<*mut dyn TrcObj>(); - let tmp = unsafe { (*t1).$funcname(t2, &mut dydata.gc)? }; + let tmp = unsafe { (*t1).$funcname(t2, dydata.get_gc())? }; dydata.push_data(tmp); Ok(()) } @@ -102,7 +101,7 @@ macro_rules! gen_interface { pub fn [<$funcname _without_pop>](dydata: &mut DynaData) -> RuntimeResult<()> { let t2 = dydata.pop_data::<*mut dyn TrcObj>(); let t1 = dydata.read_top_data::<*mut dyn TrcObj>(); - let tmp = unsafe { (*t1).$funcname(t2, &mut dydata.gc)? }; + let tmp = unsafe { (*t1).$funcname(t2, dydata.get_gc())? }; dydata.push_data(tmp); Ok(()) } @@ -111,14 +110,14 @@ macro_rules! gen_interface { ($funcname:ident, 1) => { pub fn $funcname(dydata: &mut DynaData) -> RuntimeResult<()> { let t1 = dydata.pop_data::<*mut dyn TrcObj>(); - let tmp = unsafe { (*t1).$funcname(&mut dydata.gc)? }; + let tmp = unsafe { (*t1).$funcname(dydata.get_gc())? }; dydata.push_data(tmp); Ok(()) } paste::paste!( pub fn [<$funcname _without_pop>](dydata: &mut DynaData) -> RuntimeResult<()> { let t1 = dydata.read_top_data::<*mut dyn TrcObj>(); - let tmp = unsafe { (*t1).$funcname(&mut dydata.gc)? }; + let tmp = unsafe { (*t1).$funcname(dydata.get_gc())? }; dydata.push_data(tmp); Ok(()) } diff --git a/libcore/src/types/trcbool.rs b/libcore/src/types/trcbool.rs new file mode 100644 index 00000000..ae316fa7 --- /dev/null +++ b/libcore/src/types/trcbool.rs @@ -0,0 +1,50 @@ +use super::TrcObj; +use crate::libbasic::*; +use crate::{batch_impl_opers, impl_oper, impl_single_oper}; +use derive::{trc_class, trc_method}; +use rust_i18n::t; +use std::collections::hash_map::HashMap; +use std::fmt::Display; + +#[trc_class] +#[derive(Debug, Clone)] +pub struct TrcBool { + pub _value: bool, +} + +#[trc_method] +impl TrcObj for TrcBool { + fn get_type_name(&self) -> &str { + "bool" + } + + impl_single_oper!(not, !, "!", TrcBool, TrcBool); + batch_impl_opers!( + and => &&, "&&", TrcBool, TrcBool, + or => ||, "||", TrcBool, TrcBool + ); +} + +impl Display for TrcBool { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self._value { + write!(f, "true") + } else { + write!(f, "false") + } + } +} + +impl TrcBool { + pub fn new(value: bool) -> TrcBool { + Self { _value: value } + } + + fn override_export() -> HashMap { + collection_literals::hash![ + OverrideOperations::And => OverrideWrapper::new(crate::codegen::Opcode::AndBool, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Or => OverrideWrapper::new(crate::codegen::Opcode::OrBool, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Not => OverrideWrapper::new(crate::codegen::Opcode::NotBool, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)) + ] + } +} diff --git a/src/tvm/types/trcchar.rs b/libcore/src/types/trcchar.rs similarity index 77% rename from src/tvm/types/trcchar.rs rename to libcore/src/types/trcchar.rs index 45a42f9e..a43e463f 100644 --- a/src/tvm/types/trcchar.rs +++ b/libcore/src/types/trcchar.rs @@ -1,7 +1,6 @@ use super::TrcObj; -use crate::base::stdlib::*; -use crate::compiler::token::TokenType; -use crate::hash_map; +use crate::libbasic::*; +use collection_literals::collection; use derive::{trc_class, trc_method}; use std::collections::hash_map::HashMap; use std::fmt::Display; @@ -32,7 +31,7 @@ impl TrcChar { Self { _value: value } } - fn override_export() -> HashMap { - hash_map![] + fn override_export() -> HashMap { + collection_literals::hash![] } } diff --git a/libcore/src/types/trcfloat.rs b/libcore/src/types/trcfloat.rs new file mode 100644 index 00000000..af012cbb --- /dev/null +++ b/libcore/src/types/trcfloat.rs @@ -0,0 +1,91 @@ +use super::trcbool::TrcBool; +use super::TrcInt; +use super::TrcObj; +use crate::codegen::Opcode; +use crate::error::*; +use crate::impl_single_oper; +use crate::libbasic::*; +use crate::{batch_impl_opers, impl_oper}; +use derive::trc_class; +use derive::trc_method; +use rust_i18n::t; +use std::collections::hash_map::HashMap; +use std::fmt::Display; + +pub type TrcFloatInternal = f64; + +#[trc_class] +#[derive(Debug, Clone)] +pub struct TrcFloat { + pub _value: TrcFloatInternal, +} + +impl TrcFloat { + pub fn new(value: f64) -> TrcFloat { + Self { _value: value } + } + + fn override_export() -> HashMap { + collection_literals::hash![ + OverrideOperations::Add => OverrideWrapper::new(Opcode::AddFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Sub => OverrideWrapper::new(Opcode::SubFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Mul => OverrideWrapper::new(Opcode::MulFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Div => OverrideWrapper::new(Opcode::DivFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::ExactDiv => OverrideWrapper::new(Opcode::ExtraDivFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcInt::export_info()), false)), + OverrideOperations::Equal => OverrideWrapper::new(Opcode::EqFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::NotEqual => OverrideWrapper::new(Opcode::NeFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::Less => OverrideWrapper::new(Opcode::LtFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::LessEqual => OverrideWrapper::new(Opcode::LeFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::Greater => OverrideWrapper::new(Opcode::GtFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::GreaterEqual => OverrideWrapper::new(Opcode::GeFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::SelfNegative => OverrideWrapper::new(Opcode::SelfNegativeFloat, IOType::new(vec![], TypeAllowNull::Some(Self::export_info()), false)) + ] + } +} + +pub fn div_float(a: f64, b: f64) -> Result { + if b == 0.0 { + return Err(ErrorInfo::new( + t!(ZERO_DIV, "0" = a), + t!(ZERO_DIVSION_ERROR), + )); + } + Ok(a / b) +} + +pub fn exact_div_float(a: f64, b: f64) -> Result { + if b == 0.0 { + return Err(ErrorInfo::new( + t!(ZERO_DIV, "0" = a), + t!(ZERO_DIVSION_ERROR), + )); + } + Ok((a / b).floor() as i64) +} + +#[trc_method] +impl TrcObj for TrcFloat { + fn get_type_name(&self) -> &str { + "float" + } + batch_impl_opers! { + add => +, "+", TrcFloat, TrcFloat, + sub => -, "-", TrcFloat, TrcFloat, + mul => *, "*", TrcFloat, TrcFloat, + gt => >, ">", TrcFloat, TrcBool, + lt => <, "<", TrcFloat, TrcBool, + eq => ==, "==", TrcFloat, TrcBool, + ne => !=, "!=",TrcFloat, TrcBool, + ge => >=, ">=",TrcFloat, TrcBool, + le => <=, "<=",TrcFloat, TrcBool + } + impl_oper!(div, div_float, "/", TrcFloat, TrcFloat, ?); + impl_oper!(extra_div, exact_div_float, "//", TrcFloat, TrcInt, ?); + impl_single_oper!(self_negative, -, "-", TrcFloat, TrcFloat); +} + +impl Display for TrcFloat { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self._value) + } +} diff --git a/libcore/src/types/trcint.rs b/libcore/src/types/trcint.rs new file mode 100644 index 00000000..ab5ecf78 --- /dev/null +++ b/libcore/src/types/trcint.rs @@ -0,0 +1,130 @@ +use super::trcbool::TrcBool; +use super::trcfloat::TrcFloat; +use super::TrcObj; +use crate::codegen::Opcode; +use crate::impl_single_oper; +use crate::libbasic::*; +use crate::{batch_impl_opers, error::*, impl_oper}; +use derive::trc_class; +use derive::trc_method; +use rust_i18n::t; +use std::collections::hash_map::HashMap; +use std::fmt::Display; + +pub type TrcIntInternal = i64; + +#[trc_class] +#[derive(Debug, Clone)] +pub struct TrcInt { + pub _value: TrcIntInternal, +} + +impl TrcInt { + pub fn new(value: TrcIntInternal) -> TrcInt { + TrcInt { _value: value } + } + + fn override_export() -> HashMap { + collection_literals::hash![OverrideOperations::Add => OverrideWrapper::new(Opcode::AddInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Sub => OverrideWrapper::new(Opcode::SubInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Mul => OverrideWrapper::new(Opcode::MulInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Div => OverrideWrapper::new(Opcode::DivInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcFloat::export_info()), false)), + OverrideOperations::Mod => OverrideWrapper::new(Opcode::ModInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Power => OverrideWrapper::new(Opcode::PowerInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::BitAnd => OverrideWrapper::new(Opcode::BitAndInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::BitOr => OverrideWrapper::new(Opcode::BitOrInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Xor => OverrideWrapper::new(Opcode::XorInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::ExactDiv => OverrideWrapper::new(Opcode::ExactDivInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::BitLeftShift => OverrideWrapper::new(Opcode::BitLeftShiftInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::BitRightShift => OverrideWrapper::new(Opcode::BitRightShiftInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::BitNot => OverrideWrapper::new(Opcode::BitNotInt,IOType::new(vec![], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::SelfNegative => OverrideWrapper::new(Opcode::SelfNegativeInt,IOType::new(vec![], TypeAllowNull::Some(Self::export_info()), false)), + OverrideOperations::Equal => OverrideWrapper::new(Opcode::EqInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::NotEqual => OverrideWrapper::new(Opcode::NeInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::Less => OverrideWrapper::new(Opcode::LtInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::LessEqual => OverrideWrapper::new(Opcode::LeInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::Greater => OverrideWrapper::new(Opcode::GtInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), + OverrideOperations::GreaterEqual => OverrideWrapper::new(Opcode::GeInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)) + ] + } +} + +pub fn exact_div_int(a: TrcIntInternal, b: TrcIntInternal) -> Result { + if b == 0 { + return Err(ErrorInfo::new( + t!(ZERO_DIV, "0" = a), + t!(ZERO_DIVSION_ERROR), + )); + } + Ok(a / b) +} + +pub fn div_int(a: i64, b: i64) -> Result { + if b == 0 { + return Err(ErrorInfo::new( + t!(ZERO_DIV, "0" = a), + t!(ZERO_DIVSION_ERROR), + )); + } + Ok(a as f64 / b as f64) +} + +pub fn mod_int(a: i64, b: i64) -> Result { + if b == 0 { + return Err(ErrorInfo::new( + t!(ZERO_DIV, "0" = a), + t!(ZERO_DIVSION_ERROR), + )); + } + Ok(a % b) +} + +/// won't throw error,although 0^0 is undefined,but to be more convenient to use, so we return 1 +pub fn power_int(a: i64, b: i64) -> i64 { + if b == 0 { + return 1; + } + let mut t = power_int(a, b / 2); + t *= t; + if b % 2 == 1 { + t *= a; + } + t +} + +impl Display for TrcInt { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self._value) + } +} + +#[trc_method] +impl TrcObj for TrcInt { + fn get_type_name(&self) -> &str { + "int" + } + + batch_impl_opers!( + add => +, "+", TrcInt, TrcInt, + sub => -, "-", TrcInt, TrcInt, + mul => *, "*", TrcInt, TrcInt, + bit_and => &, "&", TrcInt, TrcInt, + bit_or => |, "|", TrcInt, TrcInt, + bit_left_shift => <<, "<<", TrcInt, TrcInt, + bit_right_shift => >>, ">>", TrcInt, TrcInt, + xor => ^, "^", TrcInt, TrcInt, + gt => >, ">", TrcInt, TrcBool, + lt => <, "<", TrcInt, TrcBool, + eq => ==, "==", TrcInt, TrcBool, + ne => !=, "!=",TrcInt, TrcBool, + ge => >=, ">=",TrcInt, TrcBool, + le => <=, "<=",TrcInt, TrcBool + ); + + impl_oper!(div, div_int, "/", TrcInt, TrcFloat, ?); + impl_oper!(extra_div, exact_div_int, "//", TrcInt, TrcInt, ?); + impl_oper!(modd, mod_int, "%", TrcInt, TrcInt, ?); + impl_oper!(power, power_int, "**", TrcInt, TrcInt,,); + impl_single_oper!(bit_not, !, "~", TrcInt, TrcInt); + impl_single_oper!(self_negative, -, "-", TrcInt, TrcInt); +} diff --git a/src/tvm/types/trcstr.rs b/libcore/src/types/trcstr.rs similarity index 68% rename from src/tvm/types/trcstr.rs rename to libcore/src/types/trcstr.rs index 42a043e6..84ca7e79 100644 --- a/src/tvm/types/trcstr.rs +++ b/libcore/src/types/trcstr.rs @@ -1,19 +1,13 @@ +use super::TrcObj; +use crate::codegen::Opcode; +use crate::error::*; +use crate::gc::GcMgr; +use crate::libbasic::*; +use derive::{trc_class, trc_method}; +use rust_i18n::t; use std::collections::hash_map::HashMap; use std::fmt::Display; -use rust_i18n::t; - -use derive::{trc_class, trc_method}; - -use crate::base::error::*; -use crate::base::stdlib::*; -use crate::compiler::scope::TypeAllowNull; -use crate::compiler::token::TokenType; -use crate::hash_map; -use crate::tvm::GcMgr; - -use super::TrcObj; - pub type TrcStrInternal = *mut String; #[trc_class] @@ -32,23 +26,9 @@ impl TrcObj for TrcStr { "str" } + #[allow(clippy::not_unsafe_ptr_arg_deref)] fn add(&self, other: *mut dyn TrcObj, gc: &mut GcMgr) -> RuntimeResult<*mut dyn TrcObj> { - return unsafe { - match (*other).downcast_ref::() { - Some(v) => { - let val = gc.alloc(cat_string(&*self._value, &*(v._value))); - Ok(gc.alloc(TrcStr::new(val))) - } - None => Err(ErrorInfo::new( - t!( - OPERATOR_IS_NOT_SUPPORT, - "0" = "+", - "1" = (*other).get_type_name() - ), - t!(OPERATOR_ERROR), - )), - } - }; + unsafe { self.add_impl(other, gc) } } } @@ -63,9 +43,32 @@ impl TrcStr { Self { _value: value } } - fn override_export() -> HashMap { - hash_map![ - TokenType::Add => OverrideWrapper::new(crate::base::codegen::Opcode::AddStr, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)) + fn override_export() -> HashMap { + collection_literals::hash![ + OverrideOperations::Add => OverrideWrapper::new(Opcode::AddStr, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)) ] } + + unsafe fn add_impl( + &self, + other: *mut dyn TrcObj, + gc: &mut GcMgr, + ) -> RuntimeResult<*mut dyn TrcObj> { + unsafe { + match (*other).downcast_ref::() { + Some(v) => { + let val = gc.alloc(cat_string(&*self._value, &*(v._value))); + Ok(gc.alloc(TrcStr::new(val))) + } + None => Err(ErrorInfo::new( + t!( + OPERATOR_IS_NOT_SUPPORT, + "0" = "+", + "1" = (*other).get_type_name() + ), + t!(OPERATOR_ERROR), + )), + } + } + } } diff --git a/src/base.rs b/src/base.rs index 704b6f68..6fe177f1 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1,6 +1,2 @@ -pub mod codegen; pub mod ctrc; -pub mod error; -pub mod func; -pub mod stdlib; pub mod utils; diff --git a/src/base/func.rs b/src/base/func.rs deleted file mode 100644 index d62188a8..00000000 --- a/src/base/func.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[derive(Clone)] -pub struct Func { - pub func_addr: usize, - pub var_table_sz: usize, -} - -impl Func { - pub fn new(name: usize, var_table_sz: usize) -> Self { - Self { - func_addr: name, - var_table_sz, - } - } -} diff --git a/src/base/utils.rs b/src/base/utils.rs index fce0cb76..cca53e1f 100644 --- a/src/base/utils.rs +++ b/src/base/utils.rs @@ -1,25 +1,5 @@ use std::ops::DivAssign; -#[macro_export] -macro_rules! hash_map { - [] => { - { - use std::collections::hash_map::HashMap; - HashMap::new() - } - }; - [$($key:expr => $val:expr),*] => { - { - use std::collections::hash_map::HashMap; - let mut ret = HashMap::new(); - $( - ret.insert($key, $val); - )* - ret - } - }; -} - pub fn get_bit_num + DivAssign>(mut val: T) -> usize { if val == 0 { return 1; diff --git a/src/compiler.rs b/src/compiler.rs index 855a4f6a..1f5fb5f6 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -1,13 +1,12 @@ pub mod ast; +pub mod linker; pub mod llvm_convent; pub mod scope; pub mod token; use self::{ast::AstBuilder, token::TokenLex}; -use crate::{ - base::{codegen::ConstPool, error::*}, - cfg, -}; +use crate::cfg; +use libcore::*; use rust_i18n::t; use std::{ collections::HashMap, diff --git a/src/compiler/ast.rs b/src/compiler/ast.rs index 86630370..95bbb99e 100644 --- a/src/compiler/ast.rs +++ b/src/compiler/ast.rs @@ -1,24 +1,16 @@ mod ast_base; mod lexprocess; -use crate::{ - base::{ - codegen::{Opcode, StaticData, VmStackType, ARG_WRONG, NO_ARG}, - error::*, - func, - stdlib::{get_stdlib, ArgsNameTy, IOType, RustFunction, BOOL, CHAR, FLOAT, INT, STR}, - }, - compiler::token::TokenType::RightBigBrace, -}; +use crate::compiler::token::TokenType::RightBigBrace; +use libcore::*; use rust_i18n::t; use std::{cell::RefCell, mem::swap, rc::Rc}; use super::{ scope::*, token::{ConstPoolIndexTy, TokenType}, - CompileOption, Compiler, InputSource, TokenLex, + InputSource, TokenLex, }; -use crate::base::stdlib::FunctionInterface; #[derive(Default)] struct Cache { @@ -57,9 +49,14 @@ macro_rules! tmp_expe_function_gen { $($accepted_token => { self.$next_item_func(istry)?; // 读取IOType检查 - let func_obj = self.self_scope.as_ref().borrow().get_class(extend).unwrap(); - let io_check = func_obj.get_override_func($accepted_token); - match io_check { + let func_obj = self.self_scope.borrow().get_class_by_class_id(extend).expect("Class empty"); + let io_check = func_obj.get_override_func(match $accepted_token.convert_to_override() { + Some(v) => v, + None => { + panic!("error token {}", $accepted_token); + } + }); + let io_check = match io_check { None => self.try_err(istry, ErrorInfo::new( t!(OPERATOR_IS_NOT_SUPPORT, "0"=$accepted_token, "1"=func_obj.get_name()), @@ -67,15 +64,14 @@ macro_rules! tmp_expe_function_gen { ) )?, Some(v) => { - if let Ok(_) = v.io.check_argvs(vec![self.process_info.get_last_ty().unwrap()]) {} - else { + if v.io.check_argvs(vec![self.process_info.get_last_ty().expect("type stack is empty")]).is_err() { self.try_err(istry, ErrorInfo::new(t!(OPERATOR_IS_NOT_SUPPORT, "0"=$accepted_token, "1"=func_obj.get_name()), t!(OPERATOR_ERROR)))? } + v } - } - let io_check = io_check.unwrap(); - self.add_bycode(io_check.opcode.clone(), NO_ARG); + }; + self.add_bycode(io_check.opcode, NO_ARG); let stage_ty = io_check.io.return_type.unwrap(); self.$tmpfuncname(istry, stage_ty)?; self.process_info.cal_val(stage_ty); @@ -116,7 +112,7 @@ macro_rules! expr_gen { impl<'a> AstBuilder<'a> { pub fn new(mut token_lexer: TokenLex<'a>) -> Self { - let prelude = get_stdlib().sub_modules.get("prelude").unwrap(); + let prelude = stdlib::get_stdlib().sub_modules.get("prelude").unwrap(); for i in &prelude.functions { token_lexer.const_pool.add_id(i.0.clone()); } @@ -127,19 +123,35 @@ impl<'a> AstBuilder<'a> { // 为root scope添加prelude let _optimize = token_lexer.compiler_data.option.optimize; root_scope - .as_ref() .borrow_mut() - .import_prelude(&token_lexer.const_pool); + .import_prelude(&token_lexer.const_pool) + .expect("Import prelude but failed"); let mut cache = Cache::new(); let val_pool_ref = &token_lexer.const_pool; - cache.intty_id = Self::get_type_id_internel(root_scope.clone(), val_pool_ref, INT).unwrap(); - cache.floatty_id = - Self::get_type_id_internel(root_scope.clone(), val_pool_ref, FLOAT).unwrap(); - cache.charty_id = - Self::get_type_id_internel(root_scope.clone(), val_pool_ref, CHAR).unwrap(); - cache.strty_id = Self::get_type_id_internel(root_scope.clone(), val_pool_ref, STR).unwrap(); - cache.boolty_id = - Self::get_type_id_internel(root_scope.clone(), val_pool_ref, BOOL).unwrap(); + cache.intty_id = root_scope + .borrow() + .get_type_id_by_token(val_pool_ref.name_pool[INT]) + .unwrap(); + cache.floatty_id = root_scope + .borrow() + .get_type_id_by_token(val_pool_ref.name_pool[FLOAT]) + .unwrap(); + cache.charty_id = root_scope + .borrow() + .get_type_id_by_token(val_pool_ref.name_pool[CHAR]) + .unwrap(); + cache.strty_id = root_scope + .borrow() + .get_type_id_by_token(val_pool_ref.name_pool[STR]) + .unwrap(); + cache.boolty_id = root_scope + .borrow() + .get_type_id_by_token(val_pool_ref.name_pool[BOOL]) + .unwrap(); + println!( + "{} {} {} {} {}", + cache.intty_id, cache.floatty_id, cache.charty_id, cache.strty_id, cache.boolty_id + ); AstBuilder { token_lexer, staticdata: StaticData::new(), @@ -199,7 +211,7 @@ impl<'a> AstBuilder<'a> { let mut prev_loop_state = true; swap( &mut prev_loop_state, - &mut self.self_scope.as_ref().borrow_mut().in_loop, + &mut self.self_scope.borrow_mut().in_loop, ); let condit_id = self.staticdata.get_next_opcode_id(); self.lex_condit()?; @@ -213,7 +225,7 @@ impl<'a> AstBuilder<'a> { let mut break_record = vec![]; swap( &mut break_record, - &mut self.self_scope.as_ref().borrow_mut().for_break, + &mut self.self_scope.borrow_mut().for_break, ); for i in break_record { self.staticdata.inst[i].operand = opcode_after_while; @@ -221,14 +233,14 @@ impl<'a> AstBuilder<'a> { let mut continue_record = vec![]; swap( &mut continue_record, - &mut self.self_scope.as_ref().borrow_mut().for_continue, + &mut self.self_scope.borrow_mut().for_continue, ); for i in continue_record { self.staticdata.inst[i].operand = condit_id; } swap( &mut prev_loop_state, - &mut self.self_scope.as_ref().borrow_mut().in_loop, + &mut self.self_scope.borrow_mut().in_loop, ); Ok(()) } @@ -238,7 +250,7 @@ impl<'a> AstBuilder<'a> { let mut prev_loop_state = true; swap( &mut prev_loop_state, - &mut self.self_scope.as_ref().borrow_mut().in_loop, + &mut self.self_scope.borrow_mut().in_loop, ); self.statement()?; self.get_token_checked(TokenType::Semicolon)?; @@ -286,7 +298,7 @@ impl<'a> AstBuilder<'a> { let mut break_record = vec![]; swap( &mut break_record, - &mut self.self_scope.as_ref().borrow_mut().for_break, + &mut self.self_scope.borrow_mut().for_break, ); for i in break_record { self.staticdata.inst[i].operand = next_opcode_after_for; @@ -294,7 +306,7 @@ impl<'a> AstBuilder<'a> { let mut continue_record = vec![]; swap( &mut continue_record, - &mut self.self_scope.as_ref().borrow_mut().for_continue, + &mut self.self_scope.borrow_mut().for_continue, ); for i in continue_record { self.staticdata.inst[i].operand = opcode_goto; @@ -302,7 +314,7 @@ impl<'a> AstBuilder<'a> { // 重置循环状态 swap( &mut prev_loop_state, - &mut self.self_scope.as_ref().borrow_mut().in_loop, + &mut self.self_scope.borrow_mut().in_loop, ); Ok(()) } @@ -313,7 +325,7 @@ impl<'a> AstBuilder<'a> { } /// 解析出函数参数 - fn opt_args(&mut self, lex_func_obj: &Func) -> AstError> { + fn opt_args(&mut self, lex_func_obj: &Rc) -> AstError> { let mut ret = vec![]; let mut var_params_num = 0; let io_tmp = lex_func_obj.get_io(); @@ -394,7 +406,7 @@ impl<'a> AstBuilder<'a> { name_token: ConstPoolIndexTy, istry: bool, ) -> AstError<()> { - let var = match self.self_scope.as_ref().borrow().get_var(idx) { + let var = match self.self_scope.borrow().get_var(idx) { None => self.try_err( istry, ErrorInfo::new( @@ -418,7 +430,7 @@ impl<'a> AstBuilder<'a> { let t = self.token_lexer.next_token()?; if t.tp == TokenType::ID { let token_data = t.data.unwrap(); - let idx = self.self_scope.as_ref().borrow().get_sym(token_data); + let idx = self.self_scope.borrow().get_sym(token_data); if idx.is_none() { self.try_err( istry, @@ -435,7 +447,7 @@ impl<'a> AstBuilder<'a> { let nxt = self.token_lexer.next_token()?; match nxt.tp { TokenType::LeftSmallBrace => { - let func_obj = self.self_scope.as_ref().borrow().get_function(idx).unwrap(); + let func_obj = self.self_scope.borrow().get_function(idx).unwrap(); let argv_list = self.opt_args(&func_obj)?; // match ) self.get_token_checked(TokenType::RightSmallBrace)?; @@ -467,7 +479,7 @@ impl<'a> AstBuilder<'a> { return Ok(()); } TokenType::DoubleColon => { - let mut module = match self.self_scope.as_ref().borrow().get_module(idx) { + let mut module = match self.self_scope.borrow().get_module(idx) { Some(m) => m, None => self.try_err( istry, @@ -487,7 +499,7 @@ impl<'a> AstBuilder<'a> { } TokenType::LeftBigBrace => { // 定义类 - match self.self_scope.as_ref().borrow().get_class(idx) { + match self.self_scope.borrow().get_class(idx) { None => {} Some(_v) => return Ok(()), } @@ -543,17 +555,16 @@ impl<'a> AstBuilder<'a> { fn unary_opcode_impl(&mut self, istry: bool, optoken: TokenType) -> AstError<()> { let class_obj = self .self_scope - .as_ref() .borrow() - .get_class(self.process_info.pop_last_ty().unwrap()) + .get_class_by_class_id(self.process_info.pop_last_ty().unwrap()) .unwrap(); - let oride = class_obj.get_override_func(optoken); + let oride = class_obj.get_override_func(optoken.convert_to_override().unwrap()); match oride { Some(v) => { let tmp = v.io.check_argvs(vec![]); match tmp { Ok(_) => { - self.add_bycode(v.opcode.clone(), NO_ARG); + self.add_bycode(v.opcode, NO_ARG); self.process_info.new_type(v.io.return_type.unwrap()) } Err(e) => { @@ -747,7 +758,7 @@ impl<'a> AstBuilder<'a> { } } // self.self_scope = tmp.clone(); - self.self_scope.as_ref().borrow_mut().add_custom_function( + self.self_scope.borrow_mut().add_custom_function( name_id, CustomFunction::new( io, @@ -784,17 +795,11 @@ impl<'a> AstBuilder<'a> { } TokenType::Pub => { let mut is_in_pub = true; - swap( - &mut self.self_scope.as_ref().borrow_mut().is_pub, - &mut is_in_pub, - ); + swap(&mut self.self_scope.borrow_mut().is_pub, &mut is_in_pub); self.get_token_checked(TokenType::LeftBigBrace)?; self.lex_class_item_loop(class_obj)?; self.get_token_checked(RightBigBrace)?; - swap( - &mut self.self_scope.as_ref().borrow_mut().is_pub, - &mut is_in_pub, - ); + swap(&mut self.self_scope.borrow_mut().is_pub, &mut is_in_pub); } TokenType::Func => { self.def_func()?; @@ -812,7 +817,7 @@ impl<'a> AstBuilder<'a> { fn def_class(&mut self) -> AstError<()> { // new scope self.self_scope = Rc::new(RefCell::new(SymScope::new(Some(self.self_scope.clone())))); - self.self_scope.as_ref().borrow_mut().in_class = true; + self.self_scope.borrow_mut().in_class = true; let name = self.get_token_checked(TokenType::ID)?.data.unwrap(); let name_id = self.insert_sym_with_error(name)?; let mut class_obj = @@ -821,16 +826,10 @@ impl<'a> AstBuilder<'a> { self.lex_class_item_loop(&mut class_obj)?; // 将作用域中剩下的函数加入作用域 self.self_scope - .as_ref() .borrow_mut() - .add_custom_type(name_id, class_obj); - let prev_scope = self - .self_scope - .as_ref() - .borrow() - .prev_scope - .clone() + .add_type(name_id, Rc::new(class_obj)) .unwrap(); + let prev_scope = self.self_scope.borrow().prev_scope.clone().unwrap(); self.self_scope = prev_scope; Ok(()) } @@ -855,7 +854,7 @@ impl<'a> AstBuilder<'a> { let mut items = path.split('.'); // 删除std items.next(); - let now = match get_stdlib().get_module(items) { + let now = match stdlib::get_stdlib().get_module(items) { Some(d) => d, None => { return self.try_err( @@ -880,9 +879,8 @@ impl<'a> AstBuilder<'a> { // println!("{}", func_item.get_name()); let func_id = self.insert_sym_with_error(token_idx)?; self.self_scope - .as_ref() .borrow_mut() - .add_func(func_id, Box::new(func_item.clone())); + .add_func(func_id, Rc::new(func_item.clone())); } } } @@ -890,21 +888,22 @@ impl<'a> AstBuilder<'a> { let tmp = self.token_lexer.add_id_token(&import_item_name); let module_sym_idx: ScopeAllocIdTy = self.insert_sym_with_error(tmp)?; self.import_module_sym(module); - match self.self_scope.as_ref().borrow_mut().import_native_module( - module_sym_idx, + let sub_module = + Rc::new(RefCell::new(SymScope::new(Some(self.self_scope.clone())))); + self.self_scope + .borrow_mut() + .add_imported_module(module_sym_idx, sub_module.clone()); + if let Err(e) = sub_module.borrow_mut().import_native_module( module, + stdlib::get_storage(), &self.token_lexer.const_pool, ) { - Err(e) => { - return self.try_err(istry, e); - } - Ok(sp) => { - sp.as_ref().borrow_mut().prev_scope = Some(self.self_scope.clone()); - } - } + return self.try_err(istry, e); + }; } } } else { + // custom module match self.token_lexer.compiler_data.option.inputsource.clone() { InputSource::File(now_module_path) => { let path = std::path::PathBuf::from(path.replace('.', "/")); @@ -914,6 +913,7 @@ impl<'a> AstBuilder<'a> { now_module_path = now_module_path.join(path.clone()); if now_module_path.exists() { // 创建新的compiler来编译模块 + // self.self_scope.as_any().borrow_mut().import_module(); } else { return self.try_err( istry, @@ -966,12 +966,11 @@ impl<'a> AstBuilder<'a> { let sym_idx = self.insert_sym_with_error(name)?; let (_var_sym, var_addr) = self.self_scope - .as_ref() .borrow_mut() .add_var(sym_idx, varty, self.get_ty_sz(varty)); self.modify_var(varty, var_addr, self.process_info.is_global); self.staticdata - .update_var_table_mem_sz(self.self_scope.as_ref().borrow().get_var_table_sz()); + .update_var_table_mem_sz(self.self_scope.borrow().get_var_table_sz()); Ok(()) } @@ -995,7 +994,7 @@ impl<'a> AstBuilder<'a> { return self.gen_error(ErrorInfo::new(t!(EXPECTED_EXPR), t!(SYNTAX_ERROR))); } }; - let var = match self.self_scope.as_ref().borrow().get_var(name) { + let var = match self.self_scope.borrow().get_var(name) { Some(v) => v, None => { return self.gen_error(ErrorInfo::new( @@ -1082,7 +1081,7 @@ impl<'a> AstBuilder<'a> { let t = self.token_lexer.next_token()?; match t.tp { TokenType::Continue => { - if !self.self_scope.as_ref().borrow().in_loop { + if !self.self_scope.borrow().in_loop { return self.gen_error(ErrorInfo::new( t!(SHOULD_IN_LOOP, "0" = "continue"), t!(SYNTAX_ERROR), @@ -1090,14 +1089,13 @@ impl<'a> AstBuilder<'a> { } self.add_bycode(Opcode::Jump, ARG_WRONG); self.self_scope - .as_ref() .borrow_mut() .for_continue .push(self.staticdata.get_last_opcode_id()); return Ok(()); } TokenType::Break => { - if !self.self_scope.as_ref().borrow().in_loop { + if !self.self_scope.borrow().in_loop { return self.gen_error(ErrorInfo::new( t!(SHOULD_IN_LOOP, "0" = "break"), t!(SYNTAX_ERROR), @@ -1105,7 +1103,6 @@ impl<'a> AstBuilder<'a> { } self.add_bycode(Opcode::Jump, ARG_WRONG); self.self_scope - .as_ref() .borrow_mut() .for_break .push(self.staticdata.get_last_opcode_id()); @@ -1120,7 +1117,7 @@ impl<'a> AstBuilder<'a> { } // ignore the result // for return and return expr both - let ret_type = self.self_scope.as_ref().borrow().func_io.unwrap(); + let ret_type = self.self_scope.borrow().func_io.unwrap(); match ret_type { Some(ty) => { self.expr(true)?; @@ -1204,6 +1201,7 @@ impl<'a> AstBuilder<'a> { } self.token_lexer.next_back(t); self.expr(false)?; + self.process_info.clear(); Ok(()) } @@ -1219,17 +1217,16 @@ impl<'a> AstBuilder<'a> { let begin_inst_idx = self.staticdata.get_next_opcode_id(); let func_obj = self .self_scope - .as_ref() .borrow() .get_function(funcid) .unwrap() - .downcast::() + .downcast_rc::() .expect("Expect Custom Function"); let io = func_obj.get_io(); let tmp = self.self_scope.clone(); // 解析参数 self.self_scope = Rc::new(RefCell::new(SymScope::new(Some(tmp.clone())))); - self.self_scope.as_ref().borrow_mut().func_io = Some(io.return_type); + self.self_scope.borrow_mut().func_io = Some(io.return_type); debug_assert_eq!(io.argvs_type.len(), func_obj.args_names.len()); for (argty, argname) in io .argvs_type @@ -1257,22 +1254,19 @@ impl<'a> AstBuilder<'a> { self.add_bycode(Opcode::PopFrame, NO_ARG); } self.generate_func_in_scope()?; - let mem_sz = self.self_scope.as_ref().borrow().get_var_table_sz(); + let mem_sz = self.self_scope.borrow().get_var_table_sz(); self.self_scope = tmp.clone(); Ok((begin_inst_idx, mem_sz)) } fn generate_func_in_scope(&mut self) -> AstError<()> { let mut tmp = vec![]; - swap( - &mut tmp, - &mut self.self_scope.as_ref().borrow_mut().funcs_temp_store, - ); + swap(&mut tmp, &mut self.self_scope.borrow_mut().funcs_temp_store); for i in tmp { let (code_begin, var_mem_sz) = self.lex_function(i.0, &i.1)?; self.staticdata .funcs - .push(func::Func::new(code_begin, var_mem_sz)) + .push(libcore::FuncStorage::new(code_begin, var_mem_sz)) } Ok(()) } diff --git a/src/compiler/ast/ast_base.rs b/src/compiler/ast/ast_base.rs index a2876309..1e56d8c1 100644 --- a/src/compiler/ast/ast_base.rs +++ b/src/compiler/ast/ast_base.rs @@ -1,25 +1,11 @@ use super::AstBuilder; use super::AstError; -use super::ScopeAllocIdTy; -use super::SymScope; -use crate::base::codegen::Inst; -use crate::base::codegen::Opcode; -use crate::base::codegen::VmStackType; -use crate::base::error::*; -use crate::base::stdlib::ArguError; -use crate::base::stdlib::ArgumentError; -use crate::base::stdlib::Stdlib; -use crate::compiler::scope::TyIdxTy; use crate::compiler::token::ConstPoolIndexTy; use crate::compiler::token::Token; use crate::compiler::token::TokenType; -use crate::compiler::ValuePool; -use crate::tvm::get_trcobj_sz; -use core::panic; +use libcore::*; use rust_i18n::t; -use std::cell::RefCell; use std::mem::size_of; -use std::rc::Rc; impl<'a> AstBuilder<'a> { pub fn clear_inst(&mut self) { @@ -80,28 +66,19 @@ impl<'a> AstBuilder<'a> { VmStackType::Object } - pub fn get_type_id_internel( - scope: Rc>, - const_pool: &ValuePool, - ty_name: &str, - ) -> Option { - scope - .as_ref() - .borrow() - .get_type(*const_pool.name_pool.get(ty_name).unwrap()) - } - pub fn get_type_id(&self, ty_name: &str) -> Option { - Self::get_type_id_internel( - self.self_scope.clone(), - &self.token_lexer.const_pool, - ty_name, - ) + self.self_scope + .borrow() + .get_type_id_by_token(self.token_lexer.const_pool.name_pool[ty_name]) } pub fn get_ty(&mut self, istry: bool) -> AstError { let t = self.get_token_checked(TokenType::ID)?; - let ty = match self.self_scope.as_ref().borrow().get_type(t.data.unwrap()) { + let ty = match self + .self_scope + .borrow() + .get_type_id_by_token(t.data.unwrap()) + { None => self.try_err( istry, ErrorInfo::new( @@ -137,10 +114,10 @@ impl<'a> AstBuilder<'a> { Ok(t) } - pub fn del_opcode(&mut self) -> Result<(), ()> { + pub fn del_opcode(&mut self) -> Result<(), &'static str> { match self.staticdata.inst.pop() { Some(_) => Ok(()), - None => Err(()), + None => Err("stack empty"), } } @@ -173,7 +150,6 @@ impl<'a> AstBuilder<'a> { pub fn get_ty_name(&mut self, type_name: TyIdxTy) -> String { self.self_scope - .as_ref() .borrow() .get_class(type_name) .unwrap() @@ -181,7 +157,7 @@ impl<'a> AstBuilder<'a> { .to_string() } - pub fn import_module_sym(&mut self, lib: &Stdlib) { + pub fn import_module_sym(&mut self, lib: &Module) { for i in &lib.functions { self.token_lexer.const_pool.add_id(i.0.clone()); } @@ -191,7 +167,7 @@ impl<'a> AstBuilder<'a> { } pub fn insert_sym_with_error(&mut self, name: ConstPoolIndexTy) -> AstError { - match self.self_scope.as_ref().borrow_mut().insert_sym(name) { + match self.self_scope.borrow_mut().insert_sym(name) { Some(v) => Ok(v), None => self.gen_error(ErrorInfo::new( t!( diff --git a/src/compiler/ast/lexprocess.rs b/src/compiler/ast/lexprocess.rs index 35c9f931..784f526f 100644 --- a/src/compiler/ast/lexprocess.rs +++ b/src/compiler/ast/lexprocess.rs @@ -1,4 +1,4 @@ -use crate::compiler::scope::TyIdxTy; +use libcore::*; /// 过程间分析用的结构 #[derive(Default)] diff --git a/src/compiler/linker.rs b/src/compiler/linker.rs new file mode 100644 index 00000000..a123f3e2 --- /dev/null +++ b/src/compiler/linker.rs @@ -0,0 +1,6 @@ +/// link different modules +use libcore::*; + +pub fn link(data_iter: impl Iterator) -> StaticData { + todo!() +} diff --git a/src/compiler/llvm_convent.rs b/src/compiler/llvm_convent.rs index 65bbc098..622e939b 100644 --- a/src/compiler/llvm_convent.rs +++ b/src/compiler/llvm_convent.rs @@ -1,4 +1,4 @@ -use crate::base::codegen::StaticData; +use libcore::*; // use llvm_sys::core::{ // LLVMAddFunction, LLVMContextCreate, LLVMCreateBuilderInContext, LLVMFunctionType, diff --git a/src/compiler/scope.rs b/src/compiler/scope.rs index d2682b17..45e0622f 100644 --- a/src/compiler/scope.rs +++ b/src/compiler/scope.rs @@ -1,21 +1,10 @@ -use rust_i18n::t; - use super::{ token::{ConstPoolIndexTy, Token}, - ErrorInfo, ValuePool, SYMBOL_ERROR, -}; -use crate::base::{ - error::SYMBOL_REDEFINED, - stdlib::{ - get_stdclass_end, get_stdlib, ArgsNameTy, ClassInterface, FunctionInterface, IOType, - OverrideWrapper, Stdlib, STD_CLASS_TABLE, - }, + ValuePool, }; +use libcore::*; use std::{cell::RefCell, collections::HashMap, fmt::Display, rc::Rc}; -pub type ScopeAllocIdTy = usize; -pub type TypeAllowNull = Option; - /// Manager of function #[derive(Clone, Debug)] pub struct CustomFunction { @@ -25,6 +14,12 @@ pub struct CustomFunction { name: String, } +#[derive(thiserror::Error, Debug)] +pub enum ScopeError { + #[error("key redefine")] + Redefine, +} + impl CustomFunction { pub fn new(io: IOType, args_names: ArgsNameTy, name: impl Into) -> Self { Self { @@ -46,12 +41,11 @@ impl FunctionInterface for CustomFunction { fn get_name(&self) -> &str { &self.name } -} - -pub type Type = Box; -pub type Func = Box; -pub type TyIdxTy = ScopeAllocIdTy; + fn get_io_mut(&mut self) -> &mut IOType { + &mut self.io + } +} /// Manager of type #[derive(Clone, Debug, Default)] @@ -108,7 +102,10 @@ impl ClassInterface for CustomType { &self.origin_name } - fn get_override_func(&self, _oper_token: super::token::TokenType) -> Option<&OverrideWrapper> { + fn get_override_func( + &self, + _oper_token: libcore::OverrideOperations, + ) -> Option<&OverrideWrapper> { None } } @@ -142,7 +139,7 @@ pub struct SymScope { // ID到class id的映射 types: HashMap, // ID到函数的映射 - funcs: HashMap>, + funcs: HashMap>, // id到变量类型的映射 vars: HashMap, // 由token id到模块的映射 @@ -152,7 +149,7 @@ pub struct SymScope { vars_id: ScopeAllocIdTy, funcs_custom_id: ScopeAllocIdTy, // 用户自定义的类型储存位置 - types_custom_store: HashMap, + types_custom_store: HashMap>, // 作用域暂时储存的函数token pub funcs_temp_store: Vec<(ScopeAllocIdTy, Vec<(Token, usize)>)>, // 计算当前需要最少多大的空间来保存变量 @@ -175,16 +172,10 @@ impl SymScope { prev_scope: prev_scope.clone(), ..Default::default() }; - match prev_scope { - Some(prev_scope) => { - ret.scope_sym_id = prev_scope.as_ref().borrow().scope_sym_id; - ret.types_id = prev_scope.as_ref().borrow().types_id; - ret.funcs_custom_id = prev_scope.as_ref().borrow().funcs_custom_id; - } - None => { - ret.types_id = get_stdclass_end(); - ret.funcs_custom_id = 0; - } + if let Some(prev_scope) = prev_scope { + ret.scope_sym_id = prev_scope.borrow().scope_sym_id; + ret.types_id = prev_scope.borrow().types_id; + ret.funcs_custom_id = prev_scope.borrow().funcs_custom_id; } ret } @@ -198,7 +189,7 @@ impl SymScope { let ret = self.funcs_custom_id; self.funcs_temp_store.push((id, body)); f.custom_id = ret; - self.add_func(id, Box::new(f)); + self.add_func(id, Rc::new(f)); self.funcs_custom_id += 1; ret } @@ -210,80 +201,105 @@ impl SymScope { ) -> Result { match self.insert_sym(sym_name) { Some(v) => Ok(v), - None => Err(ErrorInfo::new( - t!(SYMBOL_REDEFINED, "0" = str_name), - t!(SYMBOL_ERROR), - )), + None => Err(symbol_redefined(str_name)), + } + } + + pub fn add_imported_module(&mut self, id: ScopeAllocIdTy, son_modules: Rc>) { + self.imported_modules.insert(id, son_modules); + } + + fn fix_func(&self, io: &mut IOType, storage: &ModuleStorage, pool: &ValuePool) { + for i in &mut io.argvs_type { + *i = self + .get_type_id_by_token(pool.name_pool[storage.class_table[*i].name]) + .unwrap(); + } + match io.return_type { + None => {} + Some(t) => { + io.return_type = Some( + self.get_type_id_by_token(pool.name_pool[storage.class_table[t].name]) + .unwrap(), + ); + } } } /// import the module defined in rust pub fn import_native_module( &mut self, - id: ScopeAllocIdTy, - stdlib: &Stdlib, + stdlib: &Module, + libstorage: &ModuleStorage, const_pool: &ValuePool, - ) -> Result>, ErrorInfo> { - let module_scope = Rc::new(RefCell::new(SymScope::new(None))); - let funcs = &stdlib.functions; - for i in funcs { - let idx = module_scope - .as_ref() - .borrow_mut() - .insert_sym_with_error(const_pool.name_pool[i.0], i.0)?; - module_scope - .as_ref() - .borrow_mut() - .add_func(idx, Box::new(i.1.clone())); - } + ) -> Result<(), ErrorInfo> { let types = &stdlib.classes; + // println!("{:?}", types); + let mut obj_vec = vec![]; for i in types { - let idx = module_scope - .as_ref() - .borrow_mut() - .insert_sym_with_error(const_pool.name_pool[i.0], i.0)?; - module_scope - .as_ref() - .borrow_mut() - .add_native_type(idx, *i.1); + let idx = self.insert_sym_with_error(const_pool.name_pool[i.0], i.0)?; + let obj_rc = libstorage.class_table[*i.1].clone(); + let classid = match self.alloc_type_id(idx) { + Err(_) => return Err(symbol_redefined(i.0)), + Ok(t) => t, + }; + obj_vec.push((classid, obj_rc)); } - self.imported_modules.insert(id, module_scope.clone()); - Ok(module_scope) - } - - pub fn add_custom_type(&mut self, id: ScopeAllocIdTy, f: CustomType) { - self.types_custom_store.insert(id, f); - } - - pub fn import_prelude(&mut self, const_pool: &ValuePool) { - let funcs = &get_stdlib().sub_modules.get("prelude").unwrap().functions; - for i in funcs { - let idx = self.insert_sym(const_pool.name_pool[i.0]).unwrap(); - self.add_func(idx, Box::new(i.1.clone())); + for i in &mut obj_vec { + for j in &mut i.1.functions { + self.fix_func(j.1.get_io_mut(), libstorage, const_pool); + } + for j in &mut i.1.overrides { + self.fix_func(&mut j.1.io, libstorage, const_pool) + } } - let types = &get_stdlib().sub_modules.get("prelude").unwrap().classes; - for i in types { - let idx = self.insert_sym(const_pool.name_pool[i.0]).unwrap(); - self.add_native_type(idx, *i.1); + for i in obj_vec { + self.insert_type(i.0, Rc::new(i.1)) + .expect("type symbol conflict"); + } + let funcs = &stdlib.functions; + for i in funcs { + let idx = self.insert_sym_with_error(const_pool.name_pool[i.0], i.0)?; + // 在将类型全部添加进去之后,需要重新改写函数和类的输入和输出参数 + let mut fobj = i.1.clone(); + self.fix_func(fobj.get_io_mut(), libstorage, const_pool); + let fobj = Rc::new(fobj); + self.add_func(idx, fobj.clone()); } + // 改写类的重载方法 + Ok(()) + } + + /// import the prelude of stdlib + /// + /// # Errors + /// + /// This function will return an error if can insert the symbol to scope. + /// + /// # Panics + /// When submodule prelude is not here + pub fn import_prelude(&mut self, const_pool: &ValuePool) -> Result<(), ErrorInfo> { + let lib = &stdlib::get_stdlib().sub_modules["prelude"]; + self.import_native_module(lib, stdlib::get_storage(), const_pool)?; + Ok(()) } pub fn get_module(&self, id: ScopeAllocIdTy) -> Option>> { let t = self.imported_modules.get(&id); match t { None => match self.prev_scope { - Some(ref prev_scope) => prev_scope.as_ref().borrow().get_module(id), + Some(ref prev_scope) => prev_scope.borrow().get_module(id), None => None, }, Some(v) => Some(v.clone()), } } - pub fn get_function(&self, id: usize) -> Option> { + pub fn get_function(&self, id: usize) -> Option> { match self.funcs.get(&id) { Some(f) => Some(f.clone()), None => match self.prev_scope { - Some(ref prev) => prev.as_ref().borrow().get_function(id), + Some(ref prev) => prev.borrow().get_function(id), None => None, }, } @@ -294,7 +310,7 @@ impl SymScope { return true; } match self.prev_scope { - Some(ref prev_scope) => prev_scope.as_ref().borrow().has_sym(id), + Some(ref prev_scope) => prev_scope.borrow().has_sym(id), None => false, } } @@ -320,7 +336,7 @@ impl SymScope { match self.vars.get(&id) { Some(v) => Some(*v), None => match self.prev_scope { - Some(ref prev_scope) => prev_scope.as_ref().borrow().get_var(id), + Some(ref prev_scope) => prev_scope.borrow().get_var(id), None => None, }, } @@ -330,14 +346,14 @@ impl SymScope { let t = self.sym_map.get(&id); match t { None => match self.prev_scope { - Some(ref prev_scope) => prev_scope.as_ref().borrow().get_sym(id), + Some(ref prev_scope) => prev_scope.borrow().get_sym(id), None => None, }, Some(t) => Some(*t), } } - pub fn add_func(&mut self, id: usize, f: Box) { + pub fn add_func(&mut self, id: usize, f: Rc) { self.funcs.insert(id, f); } @@ -356,14 +372,10 @@ impl SymScope { self.var_sz } - pub fn add_native_type(&mut self, id: ScopeAllocIdTy, t: usize) { - self.types.insert(id, t); - } - - pub fn get_type(&self, id: usize) -> Option { + pub fn get_type_id(&self, id: ScopeAllocIdTy) -> Option { match self.types.get(&id) { None => match self.prev_scope { - Some(ref prev_scope) => prev_scope.as_ref().borrow().get_type(id), + Some(ref prev_scope) => prev_scope.borrow().get_type_id(id), None => None, }, Some(t) => Some(*t), @@ -378,26 +390,60 @@ impl SymScope { self.vars_id } - pub fn get_class(&self, classid: usize) -> Option { - // 在标准库界限内 - if classid < get_stdclass_end() { - unsafe { - return Some(Box::new(STD_CLASS_TABLE[classid].clone())); - } - } + pub fn get_class_by_class_id( + &self, + classid: ScopeAllocClassId, + ) -> Option> { // 不存在的类 if classid >= self.types_id { return None; } - let t = self.types.get(&classid); + self.types_custom_store.get(&classid).cloned() + } + + pub fn get_class(&self, classid_idx: ScopeAllocIdTy) -> Option> { + let t = self.types.get(&classid_idx); match t { - Some(t) => Some(Box::new(self.types_custom_store.get(t).unwrap().clone())), + Some(t) => self.get_class_by_class_id(*t), None => match self.prev_scope { - Some(ref prev_scope) => prev_scope.as_ref().borrow().get_class(classid), + Some(ref prev_scope) => prev_scope.borrow().get_class(classid_idx), None => None, }, } } + + fn alloc_type_id(&mut self, idx: ScopeAllocIdTy) -> Result { + if self.types.insert(idx, self.types_id).is_some() { + return Err(ScopeError::Redefine); + } + let ret = self.types_id; + self.types_id += 1; + Ok(ret) + } + + fn insert_type( + &mut self, + id: ScopeAllocClassId, + f: Rc, + ) -> Result<(), ScopeError> { + self.types_custom_store.insert(id, f); + Ok(()) + } + + pub fn add_type( + &mut self, + idx: ScopeAllocIdTy, + obj: Rc, + ) -> Result { + let ret = self.alloc_type_id(idx)?; + self.insert_type(ret, obj)?; + Ok(ret) + } + + pub fn get_type_id_by_token(&self, ty_name: ConstPoolIndexTy) -> Option { + let ty_idx_id = self.get_sym(ty_name).unwrap(); + self.get_type_id(ty_idx_id) + } } #[cfg(test)] @@ -407,11 +453,11 @@ mod tests { #[test] fn test_scope() { let root_scope = Rc::new(RefCell::new(SymScope::new(None))); - root_scope.as_ref().borrow_mut().insert_sym(1); + root_scope.borrow_mut().insert_sym(1); let mut son_scope = SymScope::new(Some(root_scope.clone())); son_scope.insert_sym(2); assert_eq!(son_scope.get_sym(2), Some(1)); drop(son_scope); - assert_eq!(root_scope.as_ref().borrow().get_sym(1), Some(0)); + assert_eq!(root_scope.borrow().get_sym(1), Some(0)); } } diff --git a/src/compiler/token.rs b/src/compiler/token.rs index df8990ce..7f954cb6 100644 --- a/src/compiler/token.rs +++ b/src/compiler/token.rs @@ -1,5 +1,6 @@ use super::{Compiler, Context, Float, TokenIo, ValuePool}; -use crate::{base::error::*, cfg::FLOAT_OVER_FLOW_LIMIT, hash_map}; +use crate::cfg::FLOAT_OVER_FLOW_LIMIT; +use libcore::*; use rust_i18n::t; use std::{collections::HashMap, fmt::Display, sync::OnceLock}; @@ -130,6 +131,37 @@ pub enum TokenType { DoubleColon, } +impl TokenType { + pub fn convert_to_override(&self) -> Option { + Some(match *self { + TokenType::Add => libcore::OverrideOperations::Add, + TokenType::Sub => libcore::OverrideOperations::Sub, + TokenType::Mul => libcore::OverrideOperations::Mul, + TokenType::Div => libcore::OverrideOperations::Div, + TokenType::Mod => libcore::OverrideOperations::Mod, + TokenType::ExactDiv => libcore::OverrideOperations::ExactDiv, + TokenType::Power => libcore::OverrideOperations::Power, + TokenType::Not => libcore::OverrideOperations::Not, + TokenType::And => libcore::OverrideOperations::And, + TokenType::Or => libcore::OverrideOperations::Or, + TokenType::SelfNegative => libcore::OverrideOperations::SelfNegative, + TokenType::GreaterEqual => libcore::OverrideOperations::GreaterEqual, + TokenType::Greater => libcore::OverrideOperations::Greater, + TokenType::LessEqual => libcore::OverrideOperations::LessEqual, + TokenType::Less => libcore::OverrideOperations::Less, + TokenType::Equal => libcore::OverrideOperations::Equal, + TokenType::NotEqual => libcore::OverrideOperations::NotEqual, + TokenType::BitNot => libcore::OverrideOperations::BitNot, + TokenType::BitRightShift => libcore::OverrideOperations::BitRightShift, + TokenType::BitLeftShift => libcore::OverrideOperations::BitLeftShift, + TokenType::BitAnd => libcore::OverrideOperations::BitAnd, + TokenType::BitOr => libcore::OverrideOperations::BitOr, + TokenType::Xor => libcore::OverrideOperations::Xor, + _ => return None, + }) + } +} + pub type ConstPoolIndexTy = usize; impl Display for TokenType { @@ -269,7 +301,7 @@ macro_rules! check_braces_match { fn get_keywords() -> &'static HashMap { static KEYWORDS: OnceLock> = OnceLock::new(); KEYWORDS.get_or_init(|| { - hash_map![ + collection_literals::hash![ "while".to_string() => TokenType::While, "for".to_string() => TokenType::For, "if".to_string() => TokenType::If, @@ -290,7 +322,7 @@ fn get_keywords() -> &'static HashMap { fn get_redix_to_prefix() -> &'static HashMap { static RADIX_TO_PREFIX: OnceLock> = OnceLock::new(); RADIX_TO_PREFIX.get_or_init(|| { - hash_map![ + collection_literals::hash![ 2 => "0b", 8 => "0o", 16 => "0x" diff --git a/src/main.rs b/src/main.rs index 2c59ebf3..84985c9a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -use shadow_rs::shadow; use trc::run; fn main() -> Result<(), Box> { diff --git a/src/tools/compile_tool.rs b/src/tools/compile_tool.rs index 8081ba9f..7e03e99d 100644 --- a/src/tools/compile_tool.rs +++ b/src/tools/compile_tool.rs @@ -1,4 +1,5 @@ -use crate::{base::error::RunResult, compiler}; +use crate::compiler; +use libcore::*; pub fn compile(opt: compiler::CompileOption) -> RunResult<()> { let mut compiler = compiler::Compiler::new(opt); diff --git a/src/tools/dis.rs b/src/tools/dis.rs index 7e483c6e..f738fe57 100644 --- a/src/tools/dis.rs +++ b/src/tools/dis.rs @@ -1,5 +1,4 @@ -use crate::base::codegen::Opcode::*; -use crate::base::error::RunResult; +use libcore::*; pub fn dis(opt: crate::compiler::CompileOption, rustcode: bool) -> RunResult<()> { let mut compiler = crate::compiler::Compiler::new(opt); @@ -11,9 +10,9 @@ pub fn dis(opt: crate::compiler::CompileOption, rustcode: bool) -> RunResult<()> } else { print!("{} {}", i.0, i.1); match i.1.opcode { - LoadInt => print!("({})", static_data.constpool.intpool[i.1.operand]), - LoadString => print!("({})", static_data.constpool.stringpool[i.1.operand]), - LoadFloat => print!("({})", static_data.constpool.floatpool[i.1.operand]), + Opcode::LoadInt => print!("({})", static_data.constpool.intpool[i.1.operand]), + Opcode::LoadString => print!("({})", static_data.constpool.stringpool[i.1.operand]), + Opcode::LoadFloat => print!("({})", static_data.constpool.floatpool[i.1.operand]), _ => {} } println!(); diff --git a/src/tools/run.rs b/src/tools/run.rs index b5a385fa..4c2a8ae0 100644 --- a/src/tools/run.rs +++ b/src/tools/run.rs @@ -1,8 +1,8 @@ use crate::{ - base::error::RunResult, compiler::{self, Compiler}, tvm::Vm, }; +use libcore::*; pub fn run(opt: compiler::CompileOption) -> RunResult<()> { let mut compiler = Compiler::new(opt); diff --git a/src/tools/tshell.rs b/src/tools/tshell.rs index dc9afcef..b1641145 100644 --- a/src/tools/tshell.rs +++ b/src/tools/tshell.rs @@ -1,17 +1,14 @@ //! the read execute print loop for trc -use std::io::{self, Write}; - -use colored::*; -use rust_i18n::t; -use rustyline::{config::Configurer, history::FileHistory, Editor}; - -use crate::base::codegen::{Opcode, NO_ARG}; use crate::{ - base::{codegen::StaticData, error::RunResult}, compiler::{self, token::TokenType}, tvm::Vm, }; +use colored::*; +use libcore::{codegen::StaticData, *}; +use rust_i18n::t; +use rustyline::{config::Configurer, history::FileHistory, Editor}; +use std::io::{self, Write}; pub fn tshell() -> RunResult<()> { println!("{}\n", t!("tshell.welcome").bold()); diff --git a/src/tvm.rs b/src/tvm.rs index 3256579d..eac028f7 100644 --- a/src/tvm.rs +++ b/src/tvm.rs @@ -1,187 +1,17 @@ mod def; mod function; -mod gc; -pub mod stdlib; -mod types; -use core::panic; -use std::{any::TypeId, mem::size_of, sync::OnceLock}; - -use self::{ - function::Frame, - gc::GcMgr, - types::{ - trcchar::TrcCharInternal, - trcfloat::{div_float, exact_div_float, TrcFloat, TrcFloatInternal}, - trcint::{div_int, exact_div_int, mod_int, power_int, TrcInt, TrcIntInternal}, - trcstr::{TrcStr, TrcStrInternal}, - TrcBool, TrcChar, TrcObj, - }, -}; -use crate::{ - base::{ - codegen::{Opcode, StaticData}, - error::*, - stdlib::STD_FUNC_TABLE, - }, - cfg, -}; +use self::function::Frame; +use crate::cfg; +use libcore::*; use libloading::Library; use rust_i18n::t; - -pub fn get_max_stack_sz() -> usize { - static T: OnceLock = OnceLock::new(); - *T.get_or_init(|| 1024 * 1024 * 2 / size_of::()) -} - -pub fn get_trcobj_sz() -> usize { - static T: OnceLock = OnceLock::new(); - *T.get_or_init(size_of::<*mut dyn TrcObj>) -} - -type Byte = u64; - -#[derive(Default)] -pub struct DynaData { - gc: GcMgr, - run_stack: Vec, - frames_stack: Vec, - var_store: Vec, - stack_ptr: usize, - // 变量已经使用的内存空间大小 - var_used: usize, - #[cfg(debug_assertions)] - type_used: Vec<(TypeId, &'static str)>, -} - -impl DynaData { - pub fn new() -> Self { - let mut ret = Self { - run_stack: Vec::with_capacity(get_max_stack_sz()), - var_store: Vec::with_capacity(get_max_stack_sz()), - stack_ptr: 0, - ..Default::default() - }; - unsafe { - ret.run_stack.set_len(get_max_stack_sz()); - ret.var_store.set_len(get_max_stack_sz()); - } - ret - } - - pub fn init_global_var_store(&mut self, cap: usize) { - self.var_used = cap; - if self.var_store.len() > cap { - return; - } - self.var_store.resize(cap, Byte::default()); - } - - /// Push data of this [`DynaData`]. - pub fn push_data(&mut self, data: T) { - unsafe { - (self - .run_stack - .as_mut_ptr() - .byte_offset(self.stack_ptr as isize) as *mut T) - .write(data); - } - self.stack_ptr += size_of::(); - #[cfg(debug_assertions)] - { - self.type_used - .push((TypeId::of::(), std::any::type_name::())); - } - } - - /// Pop data of the data stack - /// - /// # Panics - /// - /// Panics if in debug mode and the type of `T` is wrong. - pub fn pop_data(&mut self) -> T { - let sz = size_of::(); - #[cfg(debug_assertions)] - { - let info = TypeId::of::(); - let info_stack = self.type_used.pop().unwrap(); - if info_stack.0 != info { - panic!( - "pop data type error.Expected get {}.Actually has {}", - std::any::type_name::(), - info_stack.1 - ); - } - debug_assert!(self.stack_ptr >= sz); - } - self.stack_ptr -= sz; - unsafe { *(self.run_stack.as_ptr().byte_offset(self.stack_ptr as isize) as *const T) } - } - - /// Returns the top data of the data stack. - /// - /// # Panics - /// - /// Panics if . - pub fn read_top_data(&self) -> T { - let sz = size_of::(); - #[cfg(debug_assertions)] - { - let info = TypeId::of::(); - let info_stack = self.type_used.last().unwrap(); - if info_stack.0 != info { - panic!( - "pop data type error.Expected get {}.Actually has {}", - std::any::type_name::(), - info_stack.1 - ); - } - debug_assert!(self.stack_ptr >= sz); - } - unsafe { - *(self - .run_stack - .as_ptr() - .byte_offset((self.stack_ptr - sz) as isize) as *const T) - } - } - - pub fn set_var(&mut self, addr: usize, data: T) { - unsafe { - *(self.var_store.as_mut_ptr().byte_offset(addr as isize) as *mut T) = data; - } - } - - pub fn get_var(&self, addr: usize) -> T { - debug_assert!(addr < self.var_used); - unsafe { *(self.var_store.as_ptr().byte_offset(addr as isize) as *const T) } - } - - pub fn alloc_var_space(&mut self, need_sz: usize) -> *mut Byte { - self.var_used += need_sz; - if self.var_used > self.var_store.len() { - self.var_store.resize(self.var_used, Byte::default()); - } - unsafe { - self.var_store - .as_mut_ptr() - .byte_offset((self.var_used - need_sz) as isize) - } - } - - pub fn dealloc_var_space(&mut self, need_sz: usize) { - self.var_used -= need_sz; - } - - pub fn get_var_used(&self) -> usize { - self.var_used - } -} +use std::sync::OnceLock; pub struct Vm<'a> { run_context: Context, - dynadata: DynaData, - static_data: &'a StaticData, + dynadata: DydataWrap, + static_data: &'a libcore::codegen::StaticData, } #[derive(Debug, Clone)] @@ -260,13 +90,30 @@ fn load_libc() -> Option<&'static Library> { } } +pub struct DydataWrap { + frames_stack: Vec, + dydata: DynaData, +} + +impl DydataWrap { + fn new() -> Self { + Self { + frames_stack: Vec::new(), + dydata: DynaData::new(), + } + } +} + /// reduce the duplicate code to solve the operator running macro_rules! operator_opcode { ($trait_used:ident, $sself:expr) => {{ - let ret = types::$trait_used(&mut $sself.dynadata); + let ret = libcore::types::$trait_used(&mut $sself.dynadata.dydata); match ret { Err(e) => { - return Err(RuntimeError::new(Box::new($sself.run_context.clone()), e)); + return Err(libcore::error::RuntimeError::new( + Box::new($sself.run_context.clone()), + e, + )); } Ok(_) => {} } @@ -275,12 +122,12 @@ macro_rules! operator_opcode { macro_rules! impl_opcode { ($obj_ty:path, $sself:expr, 2) => {{ - let second = $sself.dynadata.pop_data::<$obj_ty>(); - let first = $sself.dynadata.pop_data::<$obj_ty>(); + let second = $sself.dynadata.dydata.pop_data::<$obj_ty>(); + let first = $sself.dynadata.dydata.pop_data::<$obj_ty>(); (first, second) }}; ($obj_ty:path, $sself:expr, 1) => {{ - let first = $sself.dynadata.pop_data::<$obj_ty>(); + let first = $sself.dynadata.dydata.pop_data::<$obj_ty>(); (first) }}; } @@ -288,15 +135,15 @@ macro_rules! impl_opcode { /// 生成不会pop数据的运算指令 macro_rules! impl_opcode_without_pop_first_data { ($obj_ty:path, $sself:expr) => {{ - let second = $sself.dynadata.pop_data::<$obj_ty>(); - let first = $sself.dynadata.read_top_data::<$obj_ty>(); + let second = $sself.dynadata.dydata.pop_data::<$obj_ty>(); + let first = $sself.dynadata.dydata.read_top_data::<$obj_ty>(); (first, second) }}; } macro_rules! impl_store_local_var { ($ty:path, $pc:expr, $sself:expr) => {{ - let data = $sself.dynadata.pop_data::<$ty>(); + let data = $sself.dynadata.dydata.pop_data::<$ty>(); let addr = $sself.static_data.inst[$pc].operand; $sself .dynadata @@ -315,14 +162,14 @@ macro_rules! impl_load_local_var { .last() .unwrap() .get_var::<$ty>($sself.static_data.inst[$pc].operand); - $sself.dynadata.push_data(data); + $sself.dynadata.dydata.push_data(data); }; } impl<'a> Vm<'a> { pub fn new(static_data: &'a StaticData) -> Self { Self { - dynadata: DynaData::new(), + dynadata: DydataWrap::new(), run_context: Context::new(cfg::MAIN_MODULE_NAME), static_data, } @@ -341,6 +188,7 @@ impl<'a> Vm<'a> { pub fn reset(&mut self) { self.dynadata + .dydata .init_global_var_store(self.static_data.sym_table_sz); } @@ -377,7 +225,7 @@ impl<'a> Vm<'a> { *pc = ret.prev_addr; } Opcode::LoadInt => { - self.dynadata.push_data( + self.dynadata.dydata.push_data( self.static_data.constpool.intpool[self.static_data.inst[*pc].operand], ); } @@ -388,20 +236,21 @@ impl<'a> Vm<'a> { Opcode::BitRightShift => operator_opcode!(bit_right_shift, self), Opcode::LoadLocalVarObj => { self.dynadata - .push_data(self.dynadata.var_store[self.static_data.inst[*pc].operand]); + .dydata + .push_data(self.dynadata.dydata.var_store[self.static_data.inst[*pc].operand]); } Opcode::StoreLocalObj => { - self.dynadata.var_store[self.static_data.inst[*pc].operand] = - self.dynadata.pop_data(); + self.dynadata.dydata.var_store[self.static_data.inst[*pc].operand] = + self.dynadata.dydata.pop_data(); } Opcode::LoadString => { let tmp = self.static_data.inst[*pc].operand; let tmp = self.static_data.constpool.stringpool[tmp].clone(); - let tmp = self.dynadata.gc.alloc(tmp); - self.dynadata.push_data(tmp); + let tmp = self.dynadata.dydata.gc.alloc(tmp); + self.dynadata.dydata.push_data(tmp); } Opcode::LoadFloat => { - self.dynadata.push_data( + self.dynadata.dydata.push_data( self.static_data.constpool.floatpool[self.static_data.inst[*pc].operand], ); } @@ -411,185 +260,192 @@ impl<'a> Vm<'a> { operator_opcode!(self_negative, self); } Opcode::CallNative => unsafe { - let tmp = STD_FUNC_TABLE[self.static_data.inst[*pc].operand](&mut self.dynadata); - self.throw_err_info(tmp)?; + // let tmp = + // STD_FUNC_TABLE[self.static_data.inst[*pc].operand](&mut self.dynadata.dydata); + // self.throw_err_info(tmp)?; }, Opcode::AddInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first + second); + self.dynadata.dydata.push_data(first + second); } Opcode::AddFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); - self.dynadata.push_data(first + second); + self.dynadata.dydata.push_data(first + second); } Opcode::AddStr => { let (first, second) = impl_opcode!(TrcStrInternal, self, 2); let tmp = self .dynadata + .dydata .gc .alloc(unsafe { format!("{}{}", *first, *second) }); - self.dynadata.push_data(tmp); + self.dynadata.dydata.push_data(tmp); } Opcode::SubInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first - second); + self.dynadata.dydata.push_data(first - second); } Opcode::SubFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); - self.dynadata.push_data(first - second); + self.dynadata.dydata.push_data(first - second); } Opcode::MulInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first * second); + self.dynadata.dydata.push_data(first * second); } Opcode::MulFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); - self.dynadata.push_data(first * second); + self.dynadata.dydata.push_data(first * second); } Opcode::DivInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); self.dynadata + .dydata .push_data(self.throw_err_info(div_int(first, second))?); } Opcode::DivFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); self.dynadata + .dydata .push_data(self.throw_err_info(div_float(first, second))?); } Opcode::ExactDivInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); self.dynadata + .dydata .push_data(self.throw_err_info(exact_div_int(first, second))?); } Opcode::ExtraDivFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); self.dynadata + .dydata .push_data(self.throw_err_info(exact_div_float(first, second))?); } Opcode::ModInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); self.dynadata + .dydata .push_data(self.throw_err_info(mod_int(first, second))?); } Opcode::PowerInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(power_int(first, second)); + self.dynadata.dydata.push_data(power_int(first, second)); } Opcode::EqInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first == second); + self.dynadata.dydata.push_data(first == second); } Opcode::EqFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); - self.dynadata.push_data(first == second); + self.dynadata.dydata.push_data(first == second); } Opcode::EqStr => { let (first, second) = impl_opcode!(TrcStrInternal, self, 2); - self.dynadata.push_data(unsafe { *first == *second }); + self.dynadata.dydata.push_data(unsafe { *first == *second }); } Opcode::EqChar => { let (first, second) = impl_opcode!(TrcCharInternal, self, 2); - self.dynadata.push_data(first == second); + self.dynadata.dydata.push_data(first == second); } Opcode::EqBool => { let (first, second) = impl_opcode!(bool, self, 2); - self.dynadata.push_data(first == second); + self.dynadata.dydata.push_data(first == second); } Opcode::NeInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first != second); + self.dynadata.dydata.push_data(first != second); } Opcode::NeFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); - self.dynadata.push_data(first != second); + self.dynadata.dydata.push_data(first != second); } Opcode::NeStr => { let (first, second) = impl_opcode!(TrcStrInternal, self, 2); - self.dynadata.push_data(unsafe { *first != *second }); + self.dynadata.dydata.push_data(unsafe { *first != *second }); } Opcode::NeChar => { let (first, second) = impl_opcode!(TrcCharInternal, self, 2); - self.dynadata.push_data(first != second); + self.dynadata.dydata.push_data(first != second); } Opcode::NeBool => { let (first, second) = impl_opcode!(bool, self, 2); - self.dynadata.push_data(first != second); + self.dynadata.dydata.push_data(first != second); } Opcode::LtInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first < second); + self.dynadata.dydata.push_data(first < second); } Opcode::LtFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); - self.dynadata.push_data(first < second); + self.dynadata.dydata.push_data(first < second); } Opcode::LeInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first <= second); + self.dynadata.dydata.push_data(first <= second); } Opcode::LeFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); - self.dynadata.push_data(first <= second); + self.dynadata.dydata.push_data(first <= second); } Opcode::GtInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first > second); + self.dynadata.dydata.push_data(first > second); } Opcode::GtFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); - self.dynadata.push_data(first > second); + self.dynadata.dydata.push_data(first > second); } Opcode::GeInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first >= second); + self.dynadata.dydata.push_data(first >= second); } Opcode::GeFloat => { let (first, second) = impl_opcode!(TrcFloatInternal, self, 2); - self.dynadata.push_data(first >= second); + self.dynadata.dydata.push_data(first >= second); } Opcode::AndBool => { let (first, second) = impl_opcode!(bool, self, 2); - self.dynadata.push_data(first && second); + self.dynadata.dydata.push_data(first && second); } Opcode::OrBool => { let (first, second) = impl_opcode!(bool, self, 2); - self.dynadata.push_data(first || second); + self.dynadata.dydata.push_data(first || second); } Opcode::NotBool => { let first = impl_opcode!(bool, self, 1); - self.dynadata.push_data(!first); + self.dynadata.dydata.push_data(!first); } Opcode::XorInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first ^ second); + self.dynadata.dydata.push_data(first ^ second); } Opcode::BitNotInt => { let first = impl_opcode!(TrcIntInternal, self, 1); - self.dynadata.push_data(!first); + self.dynadata.dydata.push_data(!first); } Opcode::BitAndInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first & second); + self.dynadata.dydata.push_data(first & second); } Opcode::BitOrInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first | second); + self.dynadata.dydata.push_data(first | second); } Opcode::BitLeftShiftInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first << second); + self.dynadata.dydata.push_data(first << second); } Opcode::BitRightShiftInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); - self.dynadata.push_data(first >> second); + self.dynadata.dydata.push_data(first >> second); } Opcode::SelfNegativeInt => { let first = impl_opcode!(TrcIntInternal, self, 1); - self.dynadata.push_data(-first); + self.dynadata.dydata.push_data(-first); } Opcode::SelfNegativeFloat => { let first = impl_opcode!(TrcFloatInternal, self, 1); - self.dynadata.push_data(-first); + self.dynadata.dydata.push_data(-first); } Opcode::JumpIfFalse => { let condit = impl_opcode!(bool, self, 1); @@ -603,39 +459,40 @@ impl<'a> Vm<'a> { return Ok(()); } Opcode::LoadChar => unsafe { - self.dynadata.push_data(char::from_u32_unchecked( + self.dynadata.dydata.push_data(char::from_u32_unchecked( self.static_data.inst[*pc].operand as u32, )); }, Opcode::LoadBool => { self.dynadata + .dydata .push_data(self.static_data.inst[*pc].operand != 0); } Opcode::MoveInt => { - let tmp = TrcInt::new(self.dynadata.pop_data()); - let ptr = self.dynadata.gc.alloc(tmp); - self.dynadata.push_data(ptr as *mut dyn TrcObj); + let tmp = TrcInt::new(self.dynadata.dydata.pop_data()); + let ptr = self.dynadata.dydata.gc.alloc(tmp); + self.dynadata.dydata.push_data(ptr as *mut dyn TrcObj); } Opcode::MoveFloat => { - let tmp = TrcFloat::new(self.dynadata.pop_data()); - let ptr = self.dynadata.gc.alloc(tmp); - self.dynadata.push_data(ptr as *mut dyn TrcObj); + let tmp = TrcFloat::new(self.dynadata.dydata.pop_data()); + let ptr = self.dynadata.dydata.gc.alloc(tmp); + self.dynadata.dydata.push_data(ptr as *mut dyn TrcObj); } Opcode::MoveChar => { - let tmp = TrcChar::new(self.dynadata.pop_data()); - let ptr = self.dynadata.gc.alloc(tmp); - self.dynadata.push_data(ptr as *mut dyn TrcObj); + let tmp = TrcChar::new(self.dynadata.dydata.pop_data()); + let ptr = self.dynadata.dydata.gc.alloc(tmp); + self.dynadata.dydata.push_data(ptr as *mut dyn TrcObj); } Opcode::MoveBool => { - let tmp = TrcBool::new(self.dynadata.pop_data()); - let ptr = self.dynadata.gc.alloc(tmp); - self.dynadata.push_data(ptr as *mut dyn TrcObj); + let tmp = TrcBool::new(self.dynadata.dydata.pop_data()); + let ptr = self.dynadata.dydata.gc.alloc(tmp); + self.dynadata.dydata.push_data(ptr as *mut dyn TrcObj); } Opcode::MoveStr => { // todo:inmprove performance - let tmp = TrcStr::new(self.dynadata.pop_data()); - let ptr = self.dynadata.gc.alloc(tmp); - self.dynadata.push_data(ptr as *mut dyn TrcObj); + let tmp = TrcStr::new(self.dynadata.dydata.pop_data()); + let ptr = self.dynadata.dydata.gc.alloc(tmp); + self.dynadata.dydata.push_data(ptr as *mut dyn TrcObj); } Opcode::StoreLocalInt => { impl_store_local_var!(TrcIntInternal, *pc, self); @@ -674,112 +531,112 @@ impl<'a> Vm<'a> { Opcode::CallCustom => { let var_table_mem_sz = self.static_data.funcs[self.static_data.inst[*pc].operand].var_table_sz; - let space = self.dynadata.alloc_var_space(var_table_mem_sz); + let space = self.dynadata.dydata.alloc_var_space(var_table_mem_sz); self.dynadata.frames_stack.push(Frame::new(*pc, space)); *pc = self.static_data.funcs[self.static_data.inst[*pc].operand].func_addr; return Ok(()); } Opcode::StoreGlobalObj => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.pop_data::<*mut dyn TrcObj>(); - self.dynadata.set_var(addr, data); + let data = self.dynadata.dydata.pop_data::<*mut dyn TrcObj>(); + self.dynadata.dydata.set_var(addr, data); } Opcode::StoreGlobalInt => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.pop_data::(); - self.dynadata.set_var(addr, data); + let data = self.dynadata.dydata.pop_data::(); + self.dynadata.dydata.set_var(addr, data); } Opcode::StoreGlobalFloat => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.pop_data::(); - self.dynadata.set_var(addr, data); + let data = self.dynadata.dydata.pop_data::(); + self.dynadata.dydata.set_var(addr, data); } Opcode::StoreGlobalChar => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.pop_data::(); - self.dynadata.set_var(addr, data); + let data = self.dynadata.dydata.pop_data::(); + self.dynadata.dydata.set_var(addr, data); } Opcode::StoreGlobalBool => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.pop_data::(); - self.dynadata.set_var(addr, data); + let data = self.dynadata.dydata.pop_data::(); + self.dynadata.dydata.set_var(addr, data); } Opcode::StoreGlobalStr => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.pop_data::(); - self.dynadata.set_var(addr, data); + let data = self.dynadata.dydata.pop_data::(); + self.dynadata.dydata.set_var(addr, data); } Opcode::LoadGlobalVarObj => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.get_var::<*mut dyn TrcObj>(addr); - self.dynadata.push_data(data); + let data = self.dynadata.dydata.get_var::<*mut dyn TrcObj>(addr); + self.dynadata.dydata.push_data(data); } Opcode::LoadGlobalVarBool => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.get_var::(addr); - self.dynadata.push_data(data); + let data = self.dynadata.dydata.get_var::(addr); + self.dynadata.dydata.push_data(data); } Opcode::LoadGlobalVarInt => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.get_var::(addr); - self.dynadata.push_data(data); + let data = self.dynadata.dydata.get_var::(addr); + self.dynadata.dydata.push_data(data); } Opcode::LoadGlobalVarFloat => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.get_var::(addr); - self.dynadata.push_data(data); + let data = self.dynadata.dydata.get_var::(addr); + self.dynadata.dydata.push_data(data); } Opcode::LoadGlobalVarStr => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.get_var::(addr); - self.dynadata.push_data(data); + let data = self.dynadata.dydata.get_var::(addr); + self.dynadata.dydata.push_data(data); } Opcode::LoadGlobalVarChar => { let addr = self.static_data.inst[*pc].operand; - let data = self.dynadata.get_var::(addr); - self.dynadata.push_data(data); + let data = self.dynadata.dydata.get_var::(addr); + self.dynadata.dydata.push_data(data); } Opcode::EqWithoutPop => { // let (first, second) = impl_opcode_without_pop_first_data!(*mut dyn TrcObj, self); - // self.dynadata.push_data(first == second); + // self.dynadata.dydata.push_data(first == second); } Opcode::EqIntWithoutPop => { let (first, second) = impl_opcode_without_pop_first_data!(TrcIntInternal, self); - self.dynadata.push_data(first == second); + self.dynadata.dydata.push_data(first == second); } Opcode::EqFloatWithoutPop => { let (first, second) = impl_opcode_without_pop_first_data!(TrcFloatInternal, self); - self.dynadata.push_data(first == second); + self.dynadata.dydata.push_data(first == second); } Opcode::EqStrWithoutPop => { let (first, second) = impl_opcode_without_pop_first_data!(TrcStrInternal, self); - self.dynadata.push_data(unsafe { *first == *second }); + self.dynadata.dydata.push_data(unsafe { *first == *second }); } Opcode::EqCharWithoutPop => { let (first, second) = impl_opcode_without_pop_first_data!(TrcCharInternal, self); - self.dynadata.push_data(first == second); + self.dynadata.dydata.push_data(first == second); } Opcode::EqBoolWithoutPop => { let (first, second) = impl_opcode_without_pop_first_data!(bool, self); - self.dynadata.push_data(first == second); + self.dynadata.dydata.push_data(first == second); } Opcode::PopData => { - self.dynadata.pop_data::<*mut dyn TrcObj>(); + self.dynadata.dydata.pop_data::<*mut dyn TrcObj>(); } Opcode::PopDataInt => { - self.dynadata.pop_data::(); + self.dynadata.dydata.pop_data::(); } Opcode::PopDataFloat => { - self.dynadata.pop_data::(); + self.dynadata.dydata.pop_data::(); } Opcode::PopDataStr => { - self.dynadata.pop_data::(); + self.dynadata.dydata.pop_data::(); } Opcode::PopDataChar => { - self.dynadata.pop_data::(); + self.dynadata.dydata.pop_data::(); } Opcode::PopDataBool => { - self.dynadata.pop_data::(); + self.dynadata.dydata.pop_data::(); } Opcode::JumpIfTrue => { let condit = impl_opcode!(bool, self, 1); diff --git a/src/tvm/stdlib.rs b/src/tvm/stdlib.rs deleted file mode 100644 index 573e6cf2..00000000 --- a/src/tvm/stdlib.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::base::stdlib::{get_any_type, new_class_id, Stdlib, STD_CLASS_TABLE}; -use derive::def_module; - -pub mod algo; -pub mod ds; -pub mod math; -pub mod prelude; -pub mod sys; - -def_module!( - module_name = std, - submodules = [prelude, ds, algo, math, sys] -); - -/// 导入标准库 -/// # Warning -/// 这个函数在整个程序中只被调用一次,不能调用第二次 -pub fn import_stdlib() -> Stdlib { - // this is for any type - let _newid = new_class_id(); - // 该函数不会并行调用,所以这里是safe的 - unsafe { - STD_CLASS_TABLE.push(get_any_type().clone()); - } - init() -} diff --git a/src/tvm/stdlib/ds.rs b/src/tvm/stdlib/ds.rs deleted file mode 100644 index a400f9b7..00000000 --- a/src/tvm/stdlib/ds.rs +++ /dev/null @@ -1,4 +0,0 @@ -use super::super::types::data_structure::sam::Sam; -use derive::def_module; - -def_module!(module_name=ds, classes=[Sam => sam]); diff --git a/src/tvm/types/trcbool.rs b/src/tvm/types/trcbool.rs deleted file mode 100644 index 05f0e4be..00000000 --- a/src/tvm/types/trcbool.rs +++ /dev/null @@ -1,54 +0,0 @@ -use super::TrcObj; -use crate::base::error::*; -use crate::base::stdlib::*; -use crate::compiler::scope::TypeAllowNull; -use crate::compiler::token::TokenType; -use crate::tvm::GcMgr; -use crate::{batch_impl_opers, hash_map, impl_oper, impl_single_oper}; -use derive::{trc_class, trc_method}; -use rust_i18n::t; -use std::collections::hash_map::HashMap; -use std::fmt::Display; - -#[trc_class] -#[derive(Debug, Clone)] -pub struct TrcBool { - pub _value: bool, -} - -#[trc_method] -impl TrcObj for TrcBool { - fn get_type_name(&self) -> &str { - "bool" - } - - impl_single_oper!(not, !, "!", TrcBool, TrcBool); - batch_impl_opers!( - and => &&, "&&", TrcBool, TrcBool, - or => ||, "||", TrcBool, TrcBool - ); -} - -impl Display for TrcBool { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if self._value { - write!(f, "true") - } else { - write!(f, "false") - } - } -} - -impl TrcBool { - pub fn new(value: bool) -> TrcBool { - Self { _value: value } - } - - fn override_export() -> HashMap { - hash_map![ - TokenType::And => OverrideWrapper::new(crate::base::codegen::Opcode::AndBool, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Or => OverrideWrapper::new(crate::base::codegen::Opcode::OrBool, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Not => OverrideWrapper::new(crate::base::codegen::Opcode::NotBool, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)) - ] - } -} diff --git a/src/tvm/types/trcfloat.rs b/src/tvm/types/trcfloat.rs deleted file mode 100644 index 300e72b2..00000000 --- a/src/tvm/types/trcfloat.rs +++ /dev/null @@ -1,95 +0,0 @@ -use super::trcbool::TrcBool; -use super::TrcInt; -use super::TrcObj; -use crate::base::codegen::Opcode; -use crate::base::error::*; -use crate::base::stdlib::*; -use crate::compiler::scope::TypeAllowNull; -use crate::compiler::token::TokenType; -use crate::hash_map; -use crate::impl_single_oper; -use crate::tvm::GcMgr; -use crate::{batch_impl_opers, impl_oper}; -use derive::trc_class; -use derive::trc_method; -use rust_i18n::t; -use std::collections::hash_map::HashMap; -use std::fmt::Display; - -pub type TrcFloatInternal = f64; - -#[trc_class] -#[derive(Debug, Clone)] -pub struct TrcFloat { - pub _value: TrcFloatInternal, -} - -impl TrcFloat { - pub fn new(value: f64) -> TrcFloat { - Self { _value: value } - } - - fn override_export() -> HashMap { - hash_map![ - TokenType::Add => OverrideWrapper::new(Opcode::AddFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Sub => OverrideWrapper::new(Opcode::SubFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Mul => OverrideWrapper::new(Opcode::MulFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Div => OverrideWrapper::new(Opcode::DivFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::ExactDiv => OverrideWrapper::new(Opcode::ExtraDivFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcInt::export_info()), false)), - TokenType::Equal => OverrideWrapper::new(Opcode::EqFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::NotEqual => OverrideWrapper::new(Opcode::NeFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::Less => OverrideWrapper::new(Opcode::LtFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::LessEqual => OverrideWrapper::new(Opcode::LeFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::Greater => OverrideWrapper::new(Opcode::GtFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::GreaterEqual => OverrideWrapper::new(Opcode::GeFloat, IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::SelfNegative => OverrideWrapper::new(Opcode::SelfNegativeFloat, IOType::new(vec![], TypeAllowNull::Some(Self::export_info()), false)) - ] - } -} - -pub fn div_float(a: f64, b: f64) -> Result { - if b == 0.0 { - return Err(ErrorInfo::new( - t!(ZERO_DIV, "0" = a), - t!(ZERO_DIVSION_ERROR), - )); - } - Ok(a / b) -} - -pub fn exact_div_float(a: f64, b: f64) -> Result { - if b == 0.0 { - return Err(ErrorInfo::new( - t!(ZERO_DIV, "0" = a), - t!(ZERO_DIVSION_ERROR), - )); - } - Ok((a / b).floor() as i64) -} - -#[trc_method] -impl TrcObj for TrcFloat { - fn get_type_name(&self) -> &str { - "float" - } - batch_impl_opers! { - add => +, "+", TrcFloat, TrcFloat, - sub => -, "-", TrcFloat, TrcFloat, - mul => *, "*", TrcFloat, TrcFloat, - gt => >, ">", TrcFloat, TrcBool, - lt => <, "<", TrcFloat, TrcBool, - eq => ==, "==", TrcFloat, TrcBool, - ne => !=, "!=",TrcFloat, TrcBool, - ge => >=, ">=",TrcFloat, TrcBool, - le => <=, "<=",TrcFloat, TrcBool - } - impl_oper!(div, div_float, "/", TrcFloat, TrcFloat, ?); - impl_oper!(extra_div, exact_div_float, "//", TrcFloat, TrcInt, ?); - impl_single_oper!(self_negative, -, "-", TrcFloat, TrcFloat); -} - -impl Display for TrcFloat { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self._value) - } -} diff --git a/src/tvm/types/trcint.rs b/src/tvm/types/trcint.rs deleted file mode 100644 index 1decf692..00000000 --- a/src/tvm/types/trcint.rs +++ /dev/null @@ -1,134 +0,0 @@ -use super::trcbool::TrcBool; -use super::trcfloat::TrcFloat; -use super::TrcObj; -use crate::base::codegen::Opcode; -use crate::base::stdlib::*; -use crate::compiler::scope::TypeAllowNull; -use crate::compiler::token::TokenType; -use crate::hash_map; -use crate::impl_single_oper; -use crate::tvm::gc::*; -use crate::{base::error::*, batch_impl_opers, impl_oper}; -use derive::trc_class; -use derive::trc_method; -use rust_i18n::t; -use std::collections::hash_map::HashMap; -use std::fmt::Display; - -pub type TrcIntInternal = i64; - -#[trc_class] -#[derive(Debug, Clone)] -pub struct TrcInt { - pub _value: TrcIntInternal, -} - -impl TrcInt { - pub fn new(value: TrcIntInternal) -> TrcInt { - TrcInt { _value: value } - } - - fn override_export() -> HashMap { - hash_map![TokenType::Add => OverrideWrapper::new(Opcode::AddInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Sub => OverrideWrapper::new(Opcode::SubInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Mul => OverrideWrapper::new(Opcode::MulInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Div => OverrideWrapper::new(Opcode::DivInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcFloat::export_info()), false)), - TokenType::Mod => OverrideWrapper::new(Opcode::ModInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Power => OverrideWrapper::new(Opcode::PowerInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::BitAnd => OverrideWrapper::new(Opcode::BitAndInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::BitOr => OverrideWrapper::new(Opcode::BitOrInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Xor => OverrideWrapper::new(Opcode::XorInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::ExactDiv => OverrideWrapper::new(Opcode::ExactDivInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::BitLeftShift => OverrideWrapper::new(Opcode::BitLeftShiftInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::BitRightShift => OverrideWrapper::new(Opcode::BitRightShiftInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::BitNot => OverrideWrapper::new(Opcode::BitNotInt,IOType::new(vec![], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::SelfNegative => OverrideWrapper::new(Opcode::SelfNegativeInt,IOType::new(vec![], TypeAllowNull::Some(Self::export_info()), false)), - TokenType::Equal => OverrideWrapper::new(Opcode::EqInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::NotEqual => OverrideWrapper::new(Opcode::NeInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::Less => OverrideWrapper::new(Opcode::LtInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::LessEqual => OverrideWrapper::new(Opcode::LeInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::Greater => OverrideWrapper::new(Opcode::GtInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)), - TokenType::GreaterEqual => OverrideWrapper::new(Opcode::GeInt,IOType::new(vec![Self::export_info()], TypeAllowNull::Some(TrcBool::export_info()), false)) - ] - } -} - -pub fn exact_div_int(a: TrcIntInternal, b: TrcIntInternal) -> Result { - if b == 0 { - return Err(ErrorInfo::new( - t!(ZERO_DIV, "0" = a), - t!(ZERO_DIVSION_ERROR), - )); - } - Ok(a / b) -} - -pub fn div_int(a: i64, b: i64) -> Result { - if b == 0 { - return Err(ErrorInfo::new( - t!(ZERO_DIV, "0" = a), - t!(ZERO_DIVSION_ERROR), - )); - } - Ok(a as f64 / b as f64) -} - -pub fn mod_int(a: i64, b: i64) -> Result { - if b == 0 { - return Err(ErrorInfo::new( - t!(ZERO_DIV, "0" = a), - t!(ZERO_DIVSION_ERROR), - )); - } - Ok(a % b) -} - -/// won't throw error,although 0^0 is undefined,but to be more convenient to use, so we return 1 -pub fn power_int(a: i64, b: i64) -> i64 { - if b == 0 { - return 1; - } - let mut t = power_int(a, b / 2); - t *= t; - if b % 2 == 1 { - t *= a; - } - t -} - -impl Display for TrcInt { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self._value) - } -} - -#[trc_method] -impl TrcObj for TrcInt { - fn get_type_name(&self) -> &str { - "int" - } - - batch_impl_opers!( - add => +, "+", TrcInt, TrcInt, - sub => -, "-", TrcInt, TrcInt, - mul => *, "*", TrcInt, TrcInt, - bit_and => &, "&", TrcInt, TrcInt, - bit_or => |, "|", TrcInt, TrcInt, - bit_left_shift => <<, "<<", TrcInt, TrcInt, - bit_right_shift => >>, ">>", TrcInt, TrcInt, - xor => ^, "^", TrcInt, TrcInt, - gt => >, ">", TrcInt, TrcBool, - lt => <, "<", TrcInt, TrcBool, - eq => ==, "==", TrcInt, TrcBool, - ne => !=, "!=",TrcInt, TrcBool, - ge => >=, ">=",TrcInt, TrcBool, - le => <=, "<=",TrcInt, TrcBool - ); - - impl_oper!(div, div_int, "/", TrcInt, TrcFloat, ?); - impl_oper!(extra_div, exact_div_int, "//", TrcInt, TrcInt, ?); - impl_oper!(modd, mod_int, "%", TrcInt, TrcInt, ?); - impl_oper!(power, power_int, "**", TrcInt, TrcInt,,); - impl_single_oper!(bit_not, !, "~", TrcInt, TrcInt); - impl_single_oper!(self_negative, -, "-", TrcInt, TrcInt); -} diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml index 41bf08c9..fd5d0bf7 100644 --- a/stdlib/Cargo.toml +++ b/stdlib/Cargo.toml @@ -4,6 +4,12 @@ version = "0.1.0" edition = "2021" [dependencies] +derive = { path = "../derive" } +downcast-rs = "1" +libcore = { path = "../libcore" } +collection_literals = "1" +rust-i18n = "3" [lib] name = "stdlib" +crate-type = ["dylib"] diff --git a/src/tvm/stdlib/algo.rs b/stdlib/src/algo.rs similarity index 85% rename from src/tvm/stdlib/algo.rs rename to stdlib/src/algo.rs index 04520d57..557267f4 100644 --- a/src/tvm/stdlib/algo.rs +++ b/stdlib/src/algo.rs @@ -1,4 +1,5 @@ pub mod string; use derive::def_module; +use libcore::*; def_module!(module_name = algo, submodules = [string]); diff --git a/src/tvm/stdlib/algo/string.rs b/stdlib/src/algo/string.rs similarity index 97% rename from src/tvm/stdlib/algo/string.rs rename to stdlib/src/algo/string.rs index 552bf4f0..fcce2e3b 100644 --- a/src/tvm/stdlib/algo/string.rs +++ b/stdlib/src/algo/string.rs @@ -1,8 +1,6 @@ -use std::usize; - use derive::{def_module, trc_function}; - -use crate::tvm::types::trcint::TrcIntInternal; +use libcore::*; +use std::usize; pub fn kmp_impl(main_string: &str, pattern: &str) -> usize { // 首先对模式串构建next数组 diff --git a/src/tvm/types/data_structure.rs b/stdlib/src/ds.rs similarity index 71% rename from src/tvm/types/data_structure.rs rename to stdlib/src/ds.rs index a26668da..192cbd6c 100644 --- a/src/tvm/types/data_structure.rs +++ b/stdlib/src/ds.rs @@ -16,3 +16,9 @@ pub mod stack; pub mod trie; pub mod union; pub mod vec; + +use derive::def_module; +use libcore::*; +use sam::Sam; + +def_module!(module_name=ds, classes=[Sam => sam]); diff --git a/src/tvm/types/data_structure/ac.rs b/stdlib/src/ds/ac.rs similarity index 100% rename from src/tvm/types/data_structure/ac.rs rename to stdlib/src/ds/ac.rs diff --git a/src/tvm/types/data_structure/deque.rs b/stdlib/src/ds/deque.rs similarity index 100% rename from src/tvm/types/data_structure/deque.rs rename to stdlib/src/ds/deque.rs diff --git a/src/tvm/types/data_structure/fenwick.rs b/stdlib/src/ds/fenwick.rs similarity index 100% rename from src/tvm/types/data_structure/fenwick.rs rename to stdlib/src/ds/fenwick.rs diff --git a/src/tvm/types/data_structure/forward_list.rs b/stdlib/src/ds/forward_list.rs similarity index 100% rename from src/tvm/types/data_structure/forward_list.rs rename to stdlib/src/ds/forward_list.rs diff --git a/src/tvm/types/data_structure/hash_map.rs b/stdlib/src/ds/hash_map.rs similarity index 100% rename from src/tvm/types/data_structure/hash_map.rs rename to stdlib/src/ds/hash_map.rs diff --git a/src/tvm/types/data_structure/heap.rs b/stdlib/src/ds/heap.rs similarity index 100% rename from src/tvm/types/data_structure/heap.rs rename to stdlib/src/ds/heap.rs diff --git a/src/tvm/types/data_structure/list.rs b/stdlib/src/ds/list.rs similarity index 100% rename from src/tvm/types/data_structure/list.rs rename to stdlib/src/ds/list.rs diff --git a/src/tvm/types/data_structure/map.rs b/stdlib/src/ds/map.rs similarity index 100% rename from src/tvm/types/data_structure/map.rs rename to stdlib/src/ds/map.rs diff --git a/src/tvm/types/data_structure/priority_queue.rs b/stdlib/src/ds/priority_queue.rs similarity index 100% rename from src/tvm/types/data_structure/priority_queue.rs rename to stdlib/src/ds/priority_queue.rs diff --git a/src/tvm/types/data_structure/queue.rs b/stdlib/src/ds/queue.rs similarity index 100% rename from src/tvm/types/data_structure/queue.rs rename to stdlib/src/ds/queue.rs diff --git a/src/tvm/types/data_structure/sam.rs b/stdlib/src/ds/sam.rs similarity index 93% rename from src/tvm/types/data_structure/sam.rs rename to stdlib/src/ds/sam.rs index 32e186b1..1d189bd0 100644 --- a/src/tvm/types/data_structure/sam.rs +++ b/stdlib/src/ds/sam.rs @@ -1,11 +1,11 @@ -use crate::base::stdlib::{OverrideWrapper, RustFunction}; -use crate::tvm::types::trcchar::TrcChar; -use crate::tvm::types::TrcObj; -use crate::{compiler::token::TokenType, hash_map}; +use collection_literals::collection; use derive::{trc_class, trc_function, trc_method}; +use libcore::error::*; +use libcore::libbasic::*; +use libcore::types::trcchar::TrcChar; +use libcore::types::TrcObj; use std::collections::HashMap; use std::fmt::Display; -use std::usize; #[derive(Debug, Clone)] pub struct Node { @@ -32,8 +32,8 @@ pub struct Sam { } impl Sam { - fn override_export() -> HashMap { - hash_map![] + fn override_export() -> HashMap { + collection_literals::hash![] } pub fn new() -> Sam { diff --git a/src/tvm/types/data_structure/set.rs b/stdlib/src/ds/set.rs similarity index 100% rename from src/tvm/types/data_structure/set.rs rename to stdlib/src/ds/set.rs diff --git a/src/tvm/types/data_structure/splay.rs b/stdlib/src/ds/splay.rs similarity index 100% rename from src/tvm/types/data_structure/splay.rs rename to stdlib/src/ds/splay.rs diff --git a/src/tvm/types/data_structure/st.rs b/stdlib/src/ds/st.rs similarity index 100% rename from src/tvm/types/data_structure/st.rs rename to stdlib/src/ds/st.rs diff --git a/src/tvm/types/data_structure/stack.rs b/stdlib/src/ds/stack.rs similarity index 100% rename from src/tvm/types/data_structure/stack.rs rename to stdlib/src/ds/stack.rs diff --git a/src/tvm/types/data_structure/trie.rs b/stdlib/src/ds/trie.rs similarity index 100% rename from src/tvm/types/data_structure/trie.rs rename to stdlib/src/ds/trie.rs diff --git a/src/tvm/types/data_structure/union.rs b/stdlib/src/ds/union.rs similarity index 100% rename from src/tvm/types/data_structure/union.rs rename to stdlib/src/ds/union.rs diff --git a/src/tvm/types/data_structure/vec.rs b/stdlib/src/ds/vec.rs similarity index 100% rename from src/tvm/types/data_structure/vec.rs rename to stdlib/src/ds/vec.rs diff --git a/stdlib/src/lib.rs b/stdlib/src/lib.rs index 8b137891..ca0386d2 100644 --- a/stdlib/src/lib.rs +++ b/stdlib/src/lib.rs @@ -1 +1,49 @@ +use derive::def_module; +pub use libcore; +use libcore::libbasic::*; +use std::{collections::HashMap, sync::OnceLock}; +pub mod algo; +pub mod ds; +pub mod math; +pub mod prelude; +pub mod sys; + +rust_i18n::i18n!("locales"); + +def_module!( + module_name = std, + submodules = [prelude, ds, algo, math, sys] +); + +/// 导入标准库 +fn import_stdlib() -> (&'static Module, &'static ModuleStorage) { + // this is for any type + static STDLIB_STORAGE: OnceLock = OnceLock::new(); + static RETURN_VAL: OnceLock = OnceLock::new(); + let stro = STDLIB_STORAGE.get_or_init(|| { + let mut storage = ModuleStorage::new(); + // any + RustClass::new_in_storage("any", HashMap::new(), None, None, &mut storage); + RETURN_VAL.get_or_init(|| module_init(&mut storage)); + storage + }); + (RETURN_VAL.get().unwrap(), stro) +} + +pub fn get_stdlib() -> &'static Module { + import_stdlib().0 +} + +pub fn get_storage() -> &'static ModuleStorage { + import_stdlib().1 +} + +pub fn get_prelude_function(func_name: &str) -> Option<&'static RustFunction> { + get_stdlib() + .sub_modules + .get("prelude") + .unwrap() + .functions + .get(func_name) +} diff --git a/src/tvm/stdlib/math.rs b/stdlib/src/math.rs similarity index 97% rename from src/tvm/stdlib/math.rs rename to stdlib/src/math.rs index 9cc7846d..5f259899 100644 --- a/src/tvm/stdlib/math.rs +++ b/stdlib/src/math.rs @@ -1,5 +1,6 @@ use derive::trc_const; use derive::{def_module, trc_function}; +use libcore::*; #[trc_function] pub fn sin(x: float) -> float { diff --git a/src/tvm/stdlib/prelude.rs b/stdlib/src/prelude.rs similarity index 96% rename from src/tvm/stdlib/prelude.rs rename to stdlib/src/prelude.rs index 23f82659..a0b2621a 100644 --- a/src/tvm/stdlib/prelude.rs +++ b/stdlib/src/prelude.rs @@ -1,6 +1,5 @@ -use super::super::types::*; -use crate::base::error::*; use derive::{def_module, trc_function}; +use libcore::*; use rust_i18n::t; use std::io::{self, Write}; diff --git a/src/tvm/stdlib/sys.rs b/stdlib/src/sys.rs similarity index 92% rename from src/tvm/stdlib/sys.rs rename to stdlib/src/sys.rs index df9b1c56..f84a5eb9 100644 --- a/src/tvm/stdlib/sys.rs +++ b/stdlib/src/sys.rs @@ -1,4 +1,5 @@ use derive::{def_module, trc_function}; +use libcore::*; #[trc_function] pub fn exit(val: int) -> void { diff --git a/src/tvm/types/trcbigint.rs b/stdlib/src/types/trcbigint.rs similarity index 100% rename from src/tvm/types/trcbigint.rs rename to stdlib/src/types/trcbigint.rs diff --git a/tests/test_compiler.rs b/tests/test_compiler.rs index 3a71b3ba..991bae8d 100644 --- a/tests/test_compiler.rs +++ b/tests/test_compiler.rs @@ -1,6 +1,6 @@ +use libcore::*; use std::mem::size_of; -use trc::base::stdlib::*; -use trc::{base::codegen::*, compiler::*}; +use trc::compiler::*; macro_rules! gen_test_env { ($test_code:expr, $env_name:ident) => { @@ -47,7 +47,7 @@ fn test_assign() { Inst::new(Opcode::LoadInt, 4), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), ], ) @@ -183,7 +183,7 @@ print("{}", a+90)"#, Inst::new(Opcode::LoadInt, INT_VAL_POOL_ONE), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), ] ) @@ -200,7 +200,7 @@ fn test_call_builtin_function() { Inst::new(Opcode::LoadInt, INT_VAL_POOL_ZERO), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), ] ) @@ -219,6 +219,7 @@ fn test_wrong_type() { fn test_wrong_type2() { gen_test_env!(r#"1+"90""#, t); t.generate_code().unwrap(); + println!("{:?}", t.staticdata.inst); } #[test] @@ -226,6 +227,7 @@ fn test_wrong_type2() { fn test_wrong_type3() { gen_test_env!(r#""90"+28"#, t); t.generate_code().unwrap(); + println!("{:?}", t.staticdata.inst); } #[test] @@ -243,7 +245,7 @@ fn test_if_easy() { Inst::new(Opcode::LoadInt, INT_VAL_POOL_ZERO), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), ] ) @@ -325,7 +327,7 @@ fn test_var_params() { Inst::new(Opcode::LoadInt, 3), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), ] ) @@ -346,7 +348,7 @@ fn test_while_1() { Inst::new(Opcode::LoadInt, INT_VAL_POOL_ZERO), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), Inst::new(Opcode::Jump, 0) ] @@ -370,7 +372,7 @@ fn test_for_1() { Inst::new(Opcode::LoadInt, INT_VAL_POOL_ZERO), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), Inst::new(Opcode::LoadGlobalVarInt, get_offset(0)), Inst::new(Opcode::LoadInt, 1), @@ -403,14 +405,14 @@ func f() { Inst::new(Opcode::LoadInt, INT_VAL_POOL_ZERO), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), Inst::new(Opcode::PopFrame, NO_ARG), Inst::new(Opcode::LoadString, 1), Inst::new(Opcode::LoadInt, INT_VAL_POOL_ZERO), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), Inst::new(Opcode::CallCustom, 0), Inst::new(Opcode::PopFrame, NO_ARG) @@ -438,7 +440,7 @@ f()"#, Inst::new(Opcode::LoadInt, INT_VAL_POOL_ZERO), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), Inst::new(Opcode::PopFrame, NO_ARG) ] @@ -478,7 +480,7 @@ print("{}{}", a, b) Inst::new(Opcode::LoadInt, 2), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), Inst::new(Opcode::Stop, NO_ARG), Inst::new(Opcode::StoreLocalInt, get_offset(0)), @@ -491,7 +493,7 @@ print("{}{}", a, b) Inst::new(Opcode::LoadInt, 2), Inst::new( Opcode::CallNative, - get_prelude_function("print").unwrap().buildin_id + stdlib::get_prelude_function("print").unwrap().buildin_id ), Inst::new(Opcode::PopFrame, NO_ARG) ] @@ -600,7 +602,7 @@ print("{}", math::sin(9.8)) Inst::new(Opcode::LoadFloat, 0), Inst::new( Opcode::CallNative, - get_stdlib().sub_modules["math"].functions["sin"].buildin_id + stdlib::get_stdlib().sub_modules["math"].functions["sin"].buildin_id ), Inst::new(Opcode::MoveFloat, 0), Inst::new(Opcode::LoadInt, 1), diff --git a/tests/test_tvm.rs b/tests/test_tvm.rs index cb4b1a5e..bf65a5c0 100644 --- a/tests/test_tvm.rs +++ b/tests/test_tvm.rs @@ -1,3 +1,4 @@ +use libcore::*; use std::ptr::null_mut; use trc::compiler::*; use trc::tvm::*;