From e2e32ec01afb7c954c7fc7b8a2a02a9229e95a3e Mon Sep 17 00:00:00 2001 From: limuy Date: Tue, 9 Apr 2024 17:44:22 +0800 Subject: [PATCH] fix(compiler):make compiler extern function id become global --- derive/src/lib.rs | 3 +- libcore/src/codegen.rs | 6 ++ libcore/src/error.rs | 4 +- libcore/src/libbasic.rs | 2 +- libcore/src/types.rs | 22 +++--- libcore/src/types/trcstr.rs | 4 +- src/compiler.rs | 4 +- src/compiler/ast.rs | 58 ++++++++++----- src/compiler/ast/ast_base.rs | 6 ++ src/compiler/scope.rs | 134 ++++++++++++++++++++++++++--------- src/compiler/token.rs | 14 ++-- src/tools/compile_tool.rs | 2 +- src/tools/dis.rs | 2 +- src/tools/run.rs | 2 +- src/tools/tshell.rs | 2 +- src/tvm.rs | 76 ++++++++++++++++---- tests/test_compiler.rs | 5 ++ 17 files changed, 253 insertions(+), 93 deletions(-) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 8808a789..966d045f 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -80,7 +80,8 @@ pub fn trc_function(attr: TokenStream, input: TokenStream) -> TokenStream { } } } - input.sig.output = parse_str::("-> RuntimeResult<()>").expect("err1"); + input.sig.output = + parse_str::("-> libcore::ErrorInfoResult<()>").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() { diff --git a/libcore/src/codegen.rs b/libcore/src/codegen.rs index 554735f7..b27a800a 100644 --- a/libcore/src/codegen.rs +++ b/libcore/src/codegen.rs @@ -219,6 +219,7 @@ pub struct StaticData { pub line_table: Vec, pub type_list: Vec>, pub function_split: Option, + pub dll_module_should_loaded: Vec, } impl StaticData { @@ -242,4 +243,9 @@ impl StaticData { pub fn get_next_opcode_id(&self) -> usize { self.inst.len() } + + #[inline] + pub fn add_dll_module(&mut self, module_name: String) { + self.dll_module_should_loaded.push(module_name); + } } diff --git a/libcore/src/error.rs b/libcore/src/error.rs index 6acf852e..7e1993bf 100644 --- a/libcore/src/error.rs +++ b/libcore/src/error.rs @@ -153,5 +153,5 @@ impl From for RuntimeError { } } -pub type RunResult = Result; -pub type RuntimeResult = Result; +pub type RuntimeResult = Result; +pub type ErrorInfoResult = Result; diff --git a/libcore/src/libbasic.rs b/libcore/src/libbasic.rs index 6c5d972d..70fd2b00 100644 --- a/libcore/src/libbasic.rs +++ b/libcore/src/libbasic.rs @@ -7,7 +7,7 @@ use std::{ use super::{codegen::Opcode, error::*}; -pub type RustlibFunc = fn(&mut DynaData) -> RuntimeResult<()>; +pub type RustlibFunc = fn(&mut DynaData) -> ErrorInfoResult<()>; pub type ScopeAllocIdTy = usize; pub type TypeAllowNull = Option; diff --git a/libcore/src/types.rs b/libcore/src/types.rs index a3c765c4..7ab553d2 100644 --- a/libcore/src/types.rs +++ b/libcore/src/types.rs @@ -21,7 +21,7 @@ pub use trcstr::*; macro_rules! batch_unsupported_operators { ($($traie_name:ident => $oper_name:expr),*) => { $( - fn $traie_name(&self, _:*mut dyn TrcObj, _: &mut $crate::gc::GcMgr) -> RuntimeResult<*mut dyn TrcObj> { + fn $traie_name(&self, _:*mut dyn TrcObj, _: &mut $crate::gc::GcMgr) -> ErrorInfoResult<*mut dyn TrcObj> { return Err(ErrorInfo::new( t!( OPERATOR_IS_NOT_SUPPORT, @@ -39,7 +39,7 @@ 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) => { #[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> { + fn $trait_oper_fn_name(&self, other:*mut dyn TrcObj, gc: &mut $crate::gc::GcMgr) -> $crate::error::ErrorInfoResult<*mut dyn TrcObj> { unsafe { match (*other).downcast_ref::<$self_type>() { Some(v) => { @@ -55,7 +55,7 @@ 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) => { #[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> { + fn $trait_oper_fn_name(&self, other:*mut dyn TrcObj, gc: &mut $crate::gc::GcMgr) -> $crate::error::ErrorInfoResult<*mut dyn TrcObj> { unsafe { match (*other).downcast_ref::<$self_type>() { Some(v) => { @@ -82,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 $crate::gc::GcMgr) -> $crate::error::RuntimeResult<*mut dyn TrcObj> { + fn $trait_oper_fn_name(&self, gc: &mut $crate::gc::GcMgr) -> $crate::error::ErrorInfoResult<*mut dyn TrcObj> { return Ok(gc.alloc($newtype::new($oper self._value))); } }; @@ -90,7 +90,7 @@ macro_rules! impl_single_oper { macro_rules! gen_interface { ($funcname:ident, 2) => { - pub fn $funcname(dydata: &mut DynaData) -> RuntimeResult<()> { + pub fn $funcname(dydata: &mut DynaData) -> ErrorInfoResult<()> { let t2 = dydata.pop_data::<*mut dyn TrcObj>(); let t1 = dydata.pop_data::<*mut dyn TrcObj>(); let tmp = unsafe { (*t1).$funcname(t2, dydata.get_gc())? }; @@ -98,7 +98,7 @@ macro_rules! gen_interface { Ok(()) } paste::paste!( - pub fn [<$funcname _without_pop>](dydata: &mut DynaData) -> RuntimeResult<()> { + pub fn [<$funcname _without_pop>](dydata: &mut DynaData) -> ErrorInfoResult<()> { let t2 = dydata.pop_data::<*mut dyn TrcObj>(); let t1 = dydata.read_top_data::<*mut dyn TrcObj>(); let tmp = unsafe { (*t1).$funcname(t2, dydata.get_gc())? }; @@ -108,14 +108,14 @@ macro_rules! gen_interface { ); }; ($funcname:ident, 1) => { - pub fn $funcname(dydata: &mut DynaData) -> RuntimeResult<()> { + pub fn $funcname(dydata: &mut DynaData) -> ErrorInfoResult<()> { let t1 = dydata.pop_data::<*mut dyn TrcObj>(); let tmp = unsafe { (*t1).$funcname(dydata.get_gc())? }; dydata.push_data(tmp); Ok(()) } paste::paste!( - pub fn [<$funcname _without_pop>](dydata: &mut DynaData) -> RuntimeResult<()> { + pub fn [<$funcname _without_pop>](dydata: &mut DynaData) -> ErrorInfoResult<()> { let t1 = dydata.read_top_data::<*mut dyn TrcObj>(); let tmp = unsafe { (*t1).$funcname(dydata.get_gc())? }; dydata.push_data(tmp); @@ -168,7 +168,7 @@ pub trait TrcObj: Downcast + std::fmt::Display + Debug + TrcObjClone { bit_right_shift => ">>" ); - fn not(&self, _: &mut GcMgr) -> RuntimeResult<*mut dyn TrcObj> { + fn not(&self, _: &mut GcMgr) -> ErrorInfoResult<*mut dyn TrcObj> { Err(ErrorInfo::new( t!( OPERATOR_IS_NOT_SUPPORT, @@ -179,7 +179,7 @@ pub trait TrcObj: Downcast + std::fmt::Display + Debug + TrcObjClone { )) } - fn bit_not(&self, _: &mut GcMgr) -> RuntimeResult<*mut dyn TrcObj> { + fn bit_not(&self, _: &mut GcMgr) -> ErrorInfoResult<*mut dyn TrcObj> { Err(ErrorInfo::new( t!( OPERATOR_IS_NOT_SUPPORT, @@ -190,7 +190,7 @@ pub trait TrcObj: Downcast + std::fmt::Display + Debug + TrcObjClone { )) } - fn self_negative(&self, _: &mut GcMgr) -> RuntimeResult<*mut dyn TrcObj> { + fn self_negative(&self, _: &mut GcMgr) -> ErrorInfoResult<*mut dyn TrcObj> { Err(ErrorInfo::new( t!( OPERATOR_IS_NOT_SUPPORT, diff --git a/libcore/src/types/trcstr.rs b/libcore/src/types/trcstr.rs index 84ca7e79..aa3598f3 100644 --- a/libcore/src/types/trcstr.rs +++ b/libcore/src/types/trcstr.rs @@ -27,7 +27,7 @@ impl TrcObj for TrcStr { } #[allow(clippy::not_unsafe_ptr_arg_deref)] - fn add(&self, other: *mut dyn TrcObj, gc: &mut GcMgr) -> RuntimeResult<*mut dyn TrcObj> { + fn add(&self, other: *mut dyn TrcObj, gc: &mut GcMgr) -> ErrorInfoResult<*mut dyn TrcObj> { unsafe { self.add_impl(other, gc) } } } @@ -53,7 +53,7 @@ impl TrcStr { &self, other: *mut dyn TrcObj, gc: &mut GcMgr, - ) -> RuntimeResult<*mut dyn TrcObj> { + ) -> ErrorInfoResult<*mut dyn TrcObj> { unsafe { match (*other).downcast_ref::() { Some(v) => { diff --git a/src/compiler.rs b/src/compiler.rs index 402fa2ec..f14b3a75 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -382,7 +382,7 @@ impl Compiler { self.input = input; } - pub fn lex(&mut self) -> RunResult { + pub fn lex(&mut self) -> RuntimeResult { let token_lexer = TokenLex::new(self); let mut ast_builder = AstBuilder::new(token_lexer); ast_builder.generate_code()?; @@ -395,7 +395,7 @@ impl Compiler { } #[inline] - pub fn report_compiler_error(&self, info: ErrorInfo) -> RunResult { + pub fn report_compiler_error(&self, info: ErrorInfo) -> RuntimeResult { Err(RuntimeError::new(Box::new(self.context.clone()), info)) } } diff --git a/src/compiler/ast.rs b/src/compiler/ast.rs index f3bdefb9..2dff0f69 100644 --- a/src/compiler/ast.rs +++ b/src/compiler/ast.rs @@ -7,9 +7,10 @@ use super::{ InputSource, TokenLex, }; use crate::{base::dll::load_module_storage, compiler::token::TokenType::RightBigBrace}; +use collection_literals::collection; use libcore::*; use rust_i18n::t; -use std::{cell::RefCell, mem::swap, path::PathBuf, rc::Rc}; +use std::{cell::RefCell, collections::HashSet, mem::swap, path::PathBuf, rc::Rc}; #[derive(Default)] struct Cache { @@ -36,9 +37,11 @@ pub struct AstBuilder<'a> { cache: Cache, // record if the fisrt func is defined first_func: bool, + modules_dll_dup: HashSet, + modules_dll: Vec, } -type AstError = RunResult; +type AstError = RuntimeResult; macro_rules! tmp_expe_function_gen { ($tmpfuncname:ident, $next_item_func:ident, $($accepted_token:path),*) => { @@ -111,11 +114,10 @@ macro_rules! expr_gen { impl<'a> AstBuilder<'a> { pub fn new(mut token_lexer: TokenLex<'a>) -> Self { - let root_scope = Rc::new(RefCell::new(SymScope::new(None))); - let stdlib_dll = unsafe { - libloading::Library::new(libloading::library_filename("stdlib")) - .expect("without stdlib") - }; + let root_scope = Rc::new(RefCell::new(SymScope::new(SymScopePrev::Root))); + let stdlib_dll_name = libloading::library_filename("stdlib"); + let stdlib_dll = + unsafe { libloading::Library::new(stdlib_dll_name.clone()).expect("without stdlib") }; let (stdlib, stdstorage) = load_module_storage(&stdlib_dll); let prelude = stdlib.sub_modules().get("prelude").unwrap(); for i in prelude.functions() { @@ -159,6 +161,7 @@ impl<'a> AstBuilder<'a> { // "{} {} {} {} {}", // cache.intty_id, cache.floatty_id, cache.charty_id, cache.strty_id, cache.boolty_id // ); + let name_str = stdlib_dll_name.to_str().unwrap().to_owned(); AstBuilder { token_lexer, staticdata: StaticData::new(), @@ -166,6 +169,8 @@ impl<'a> AstBuilder<'a> { process_info: lexprocess::LexProcess::new(), cache, first_func: false, + modules_dll_dup: collection! {name_str.clone()}, + modules_dll: vec![name_str.clone()], } } @@ -206,6 +211,11 @@ impl<'a> AstBuilder<'a> { pub fn prepare_get_static(&mut self) -> &StaticData { self.staticdata.constpool = self.token_lexer.const_pool.store_val_to_vm(); + self.staticdata.dll_module_should_loaded.clear(); + std::mem::swap( + &mut self.staticdata.dll_module_should_loaded, + &mut self.modules_dll, + ); &self.staticdata } @@ -823,7 +833,9 @@ 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 = Rc::new(RefCell::new(SymScope::new(SymScopePrev::Prev( + self.self_scope.clone(), + )))); 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)?; @@ -846,7 +858,9 @@ impl<'a> AstBuilder<'a> { .get_token_checked(TokenType::StringValue)? .data .unwrap(); + // import的路径 let mut path_with_dot = self.token_lexer.const_pool.id_str[tok].clone(); + // 具体文件的路径 let mut import_file_path = String::new(); let mut is_dll = false; if path_with_dot.starts_with("std") { @@ -872,12 +886,15 @@ impl<'a> AstBuilder<'a> { // 优先判断dll now_module_path.set_file_name(file_name_dll); if now_module_path.exists() { + // 是dll is_dll = true; now_module_path .to_str() .unwrap() .clone_into(&mut import_file_path); + self.add_module(import_file_path.clone()) } else { + // 不是dll,尝试判断trc文件 let file_name_trc = format!("{}{}", file_name.to_str().unwrap(), ".trc"); now_module_path.set_file_name(file_name_trc); // now_module_path.ex @@ -953,8 +970,9 @@ 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); - let sub_module = - Rc::new(RefCell::new(SymScope::new(Some(self.self_scope.clone())))); + let sub_module = Rc::new(RefCell::new(SymScope::new(SymScopePrev::Prev( + self.self_scope.clone(), + )))); self.self_scope .borrow_mut() .add_imported_module(module_sym_idx, sub_module.clone()); @@ -1012,7 +1030,7 @@ impl<'a> AstBuilder<'a> { Ok(()) } - fn store_var(&mut self, name: usize) -> RunResult<()> { + fn store_var(&mut self, name: usize) -> RuntimeResult<()> { self.expr(false)?; let var_type = match self.process_info.pop_last_ty() { Some(v) => v, @@ -1024,7 +1042,7 @@ impl<'a> AstBuilder<'a> { Ok(()) } - fn assign_var(&mut self, name: usize) -> RunResult<()> { + fn assign_var(&mut self, name: usize) -> RuntimeResult<()> { self.expr(false)?; let var_type = match self.process_info.pop_last_ty() { Some(v) => v, @@ -1063,7 +1081,7 @@ impl<'a> AstBuilder<'a> { Ok(()) } - fn lex_condit(&mut self) -> RunResult<()> { + fn lex_condit(&mut self) -> RuntimeResult<()> { self.expr(false)?; match self.process_info.pop_last_ty() { None => { @@ -1078,7 +1096,7 @@ impl<'a> AstBuilder<'a> { Ok(()) } - fn if_lex(&mut self) -> RunResult<()> { + fn if_lex(&mut self) -> RuntimeResult<()> { self.lex_condit()?; self.get_token_checked(TokenType::LeftBigBrace)?; // 最后需要跳转地址 @@ -1115,7 +1133,7 @@ impl<'a> AstBuilder<'a> { Ok(()) } - fn statement(&mut self) -> RunResult<()> { + fn statement(&mut self) -> RuntimeResult<()> { let t = self.token_lexer.next_token()?; match t.tp { TokenType::Continue => { @@ -1245,7 +1263,7 @@ impl<'a> AstBuilder<'a> { /// # Return /// 返回函数的首地址 - fn lex_function(&mut self, funcid: usize, body: &FuncBodyTy) -> RunResult<(usize, usize)> { + fn lex_function(&mut self, funcid: usize, body: &FuncBodyTy) -> RuntimeResult<(usize, usize)> { if !self.first_func { // 如果不是第一个函数,在末尾加上结束主程序的指令 self.first_func = true; @@ -1263,7 +1281,7 @@ impl<'a> AstBuilder<'a> { 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 = Rc::new(RefCell::new(SymScope::new(SymScopePrev::Prev(tmp.clone())))); 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 @@ -1309,7 +1327,7 @@ impl<'a> AstBuilder<'a> { Ok(()) } - pub fn generate_code(&mut self) -> RunResult<()> { + pub fn generate_code(&mut self) -> RuntimeResult<()> { self.process_info.is_global = true; self.lex_until(TokenType::EndOfFile)?; // 结束一个作用域的代码解析后再解析这里面的函数 @@ -1317,6 +1335,10 @@ impl<'a> AstBuilder<'a> { self.generate_func_in_scope()?; Ok(()) } + + pub fn modules_dll(&self) -> &[String] { + &self.modules_dll + } } #[cfg(test)] diff --git a/src/compiler/ast/ast_base.rs b/src/compiler/ast/ast_base.rs index 77739c5d..ff67985b 100644 --- a/src/compiler/ast/ast_base.rs +++ b/src/compiler/ast/ast_base.rs @@ -193,4 +193,10 @@ impl<'a> AstBuilder<'a> { pub fn get_scope(&self) -> Rc> { self.self_scope.clone() } + + pub fn add_module(&mut self, module_name: String) { + if self.modules_dll_dup.insert(module_name.clone()) { + self.modules_dll.push(module_name); + } + } } diff --git a/src/compiler/scope.rs b/src/compiler/scope.rs index 68ed138a..e0abb372 100644 --- a/src/compiler/scope.rs +++ b/src/compiler/scope.rs @@ -3,7 +3,12 @@ use super::{ ValuePool, }; use libcore::*; -use std::{cell::RefCell, collections::HashMap, fmt::Display, rc::Rc}; +use std::{ + cell::RefCell, + collections::HashMap, + fmt::Display, + rc::{Rc, Weak}, +}; /// Manager of function #[derive(Clone, Debug)] @@ -132,10 +137,44 @@ impl VarInfo { } } +#[derive(Clone, Debug, Default)] +pub struct RootInfo { + // 该id不会减少,在所有作用域共同使用 + funcs_extern_id: FuncIdxTy, +} + +#[derive(Debug, Clone)] +pub enum RootOnlyInfo { + NonRoot(T), + Root(RootInfo), +} + +impl Default for RootOnlyInfo { + fn default() -> Self { + Self::Root(RootInfo::default()) + } +} + +impl RootOnlyInfo { + pub fn get_info(&mut self) -> &mut RootInfo { + match self { + RootOnlyInfo::NonRoot(_) => panic!("without root info"), + RootOnlyInfo::Root(v) => v, + } + } + + pub fn unwrap(self) -> T { + match self { + RootOnlyInfo::NonRoot(v) => v, + RootOnlyInfo::Root(_) => panic!("without root info"), + } + } +} + #[derive(Default)] pub struct SymScope { // 父作用域 - pub prev_scope: Option>>, + pub prev_scope: RootOnlyInfo>>, // 管理符号之间的映射,由token在name pool中的id映射到符号表中的id sym_map: HashMap, // 当前作用域要分配的下一个ID,也就是当前作用域的最大id+1 @@ -152,7 +191,6 @@ pub struct SymScope { types_id: ClassIdxId, vars_id: ScopeAllocIdTy, funcs_custom_id: FuncIdxTy, - funcs_extern_id: FuncIdxTy, // 用户自定义的类型储存位置 types_custom_store: HashMap>, // 作用域暂时储存的函数token @@ -170,21 +208,38 @@ pub struct SymScope { pub is_pub: bool, imported_modules: HashMap>>, imported_native: HashMap>, + root_scope: Option>>, +} + +pub enum SymScopePrev { + Prev(Rc>), + Root, } impl SymScope { - pub fn new(prev_scope: Option>>) -> Self { - let mut ret = Self { - prev_scope: prev_scope.clone(), - ..Default::default() - }; - 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.funcs_extern_id = prev_scope.borrow().funcs_extern_id; + pub fn new(prev_scope: SymScopePrev) -> Self { + match prev_scope { + SymScopePrev::Prev(prev_scope) => { + let mut ret = Self { + prev_scope: RootOnlyInfo::NonRoot(prev_scope.clone()), + ..Default::default() + }; + match prev_scope.borrow().root_scope.clone() { + Some(v) => ret.root_scope = Some(v), + None => ret.root_scope = Some(Rc::downgrade(&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.root_scope.clone_from(&prev_scope.borrow().root_scope); + ret + } + SymScopePrev::Root => Self { + root_scope: None, + prev_scope: RootOnlyInfo::Root(Default::default()), + ..Default::default() + }, } - ret } pub fn add_custom_function( @@ -280,8 +335,8 @@ impl SymScope { let t = self.imported_modules.get(&id); match t { None => match self.prev_scope { - Some(ref prev_scope) => prev_scope.borrow().get_module(id), - None => None, + RootOnlyInfo::NonRoot(ref prev_scope) => prev_scope.borrow().get_module(id), + RootOnlyInfo::Root(_) => None, }, Some(v) => Some(v.clone()), } @@ -291,8 +346,8 @@ impl SymScope { match self.funcs.get(&id) { Some(f) => Some(f.clone()), None => match self.prev_scope { - Some(ref prev) => prev.borrow().get_function(id), - None => None, + RootOnlyInfo::NonRoot(ref prev) => prev.borrow().get_function(id), + RootOnlyInfo::Root(_) => None, }, } } @@ -302,8 +357,8 @@ impl SymScope { return true; } match self.prev_scope { - Some(ref prev_scope) => prev_scope.borrow().has_sym(id), - None => false, + RootOnlyInfo::NonRoot(ref prev_scope) => prev_scope.borrow().has_sym(id), + RootOnlyInfo::Root(_) => false, } } @@ -328,8 +383,8 @@ impl SymScope { match self.vars.get(&id) { Some(v) => Some(*v), None => match self.prev_scope { - Some(ref prev_scope) => prev_scope.borrow().get_var(id), - None => None, + RootOnlyInfo::NonRoot(ref prev_scope) => prev_scope.borrow().get_var(id), + RootOnlyInfo::Root(_) => None, }, } } @@ -338,8 +393,8 @@ impl SymScope { let t = self.sym_map.get(&id); match t { None => match self.prev_scope { - Some(ref prev_scope) => prev_scope.borrow().get_sym(id), - None => None, + RootOnlyInfo::NonRoot(ref prev_scope) => prev_scope.borrow().get_sym(id), + RootOnlyInfo::Root(_) => None, }, Some(t) => Some(*t), } @@ -356,9 +411,22 @@ impl SymScope { } pub fn alloc_extern_func_id(&mut self) -> FuncIdxTy { - let ret = self.funcs_extern_id; - self.funcs_extern_id += 1; - ret + match self.root_scope { + Some(ref root_scope) => { + let tmp = root_scope.upgrade().unwrap(); + let mut tmp = tmp.borrow_mut(); + let refer = tmp.prev_scope.get_info(); + let ret = refer.funcs_extern_id; + refer.funcs_extern_id += 1; + ret + } + None => { + let refer = self.prev_scope.get_info(); + let ret = refer.funcs_extern_id; + refer.funcs_extern_id += 1; + ret + } + } } /// 返回变量的索引和内存地址 @@ -379,8 +447,8 @@ impl SymScope { 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.borrow().get_type_id(id), - None => None, + RootOnlyInfo::NonRoot(ref prev_scope) => prev_scope.borrow().get_type_id(id), + RootOnlyInfo::Root(_) => None, }, Some(t) => Some(*t), } @@ -407,8 +475,8 @@ impl SymScope { match t { Some(t) => self.get_class_by_class_id(*t), None => match self.prev_scope { - Some(ref prev_scope) => prev_scope.borrow().get_class(classid_idx), - None => None, + RootOnlyInfo::NonRoot(ref prev_scope) => prev_scope.borrow().get_class(classid_idx), + RootOnlyInfo::Root(_) => None, }, } } @@ -457,9 +525,9 @@ mod tests { #[test] fn test_scope() { - let root_scope = Rc::new(RefCell::new(SymScope::new(None))); + let root_scope = Rc::new(RefCell::new(SymScope::new(SymScopePrev::Root))); root_scope.borrow_mut().insert_sym(1); - let mut son_scope = SymScope::new(Some(root_scope.clone())); + let mut son_scope = SymScope::new(SymScopePrev::Prev(root_scope.clone())); son_scope.insert_sym(2); assert_eq!(son_scope.get_sym(2), Some(1)); drop(son_scope); diff --git a/src/compiler/token.rs b/src/compiler/token.rs index 7f954cb6..8cf2253a 100644 --- a/src/compiler/token.rs +++ b/src/compiler/token.rs @@ -388,7 +388,7 @@ impl<'a> TokenLex<'a> { self.compiler_data.input = source; } - fn lex_id(&mut self, c: char) -> RunResult { + fn lex_id(&mut self, c: char) -> RuntimeResult { Ok({ let mut retname: String = String::from(c); loop { @@ -458,7 +458,7 @@ impl<'a> TokenLex<'a> { || Self::is_useless_char(c)) } - fn lex_symbol(&mut self, c: char) -> RunResult { + fn lex_symbol(&mut self, c: char) -> RuntimeResult { Ok(match c { '.' => Token::new(TokenType::Dot, None), ',' => Token::new(TokenType::Comma, None), @@ -609,7 +609,7 @@ impl<'a> TokenLex<'a> { s } - fn lex_int_float(&mut self, mut c: char) -> RunResult { + fn lex_int_float(&mut self, mut c: char) -> RuntimeResult { // the radix of result let mut radix = 10; if c == '0' { @@ -689,7 +689,7 @@ impl<'a> TokenLex<'a> { zero } - fn lex_num(&mut self, mut c: char) -> RunResult { + fn lex_num(&mut self, mut c: char) -> RuntimeResult { let tmp = self.lex_int_float(c)?; c = self.compiler_data.input.read(); if c == 'e' || c == 'E' { @@ -784,7 +784,7 @@ impl<'a> TokenLex<'a> { } } - fn lex_str(&mut self) -> RunResult { + fn lex_str(&mut self) -> RuntimeResult { let mut s = String::new(); let mut c = self.compiler_data.input.read(); while c != '"' { @@ -815,7 +815,7 @@ impl<'a> TokenLex<'a> { )) } - fn lex_char(&mut self) -> RunResult { + fn lex_char(&mut self) -> RuntimeResult { let c = self.compiler_data.input.read(); let end = self.compiler_data.input.read(); if end != '\'' { @@ -839,7 +839,7 @@ impl<'a> TokenLex<'a> { self.unget_token.clear(); } - pub fn next_token(&mut self) -> RunResult { + pub fn next_token(&mut self) -> RuntimeResult { if !self.unget_token.is_empty() { let tmp = self.unget_token.pop().unwrap(); self.compiler_data.context.set_line(tmp.1); diff --git a/src/tools/compile_tool.rs b/src/tools/compile_tool.rs index 7e03e99d..940b0ab3 100644 --- a/src/tools/compile_tool.rs +++ b/src/tools/compile_tool.rs @@ -1,7 +1,7 @@ use crate::compiler; use libcore::*; -pub fn compile(opt: compiler::CompileOption) -> RunResult<()> { +pub fn compile(opt: compiler::CompileOption) -> RuntimeResult<()> { let mut compiler = compiler::Compiler::new(opt); compiler.lex()?; Ok(()) diff --git a/src/tools/dis.rs b/src/tools/dis.rs index f738fe57..6ba05913 100644 --- a/src/tools/dis.rs +++ b/src/tools/dis.rs @@ -1,6 +1,6 @@ use libcore::*; -pub fn dis(opt: crate::compiler::CompileOption, rustcode: bool) -> RunResult<()> { +pub fn dis(opt: crate::compiler::CompileOption, rustcode: bool) -> RuntimeResult<()> { let mut compiler = crate::compiler::Compiler::new(opt); let mut ast = compiler.lex()?; let static_data = ast.prepare_get_static(); diff --git a/src/tools/run.rs b/src/tools/run.rs index 4c2a8ae0..ccb86228 100644 --- a/src/tools/run.rs +++ b/src/tools/run.rs @@ -4,7 +4,7 @@ use crate::{ }; use libcore::*; -pub fn run(opt: compiler::CompileOption) -> RunResult<()> { +pub fn run(opt: compiler::CompileOption) -> RuntimeResult<()> { let mut compiler = Compiler::new(opt); let static_data = compiler.lex()?; let tmp = static_data.return_static_data(); diff --git a/src/tools/tshell.rs b/src/tools/tshell.rs index b1641145..f0bfcbb5 100644 --- a/src/tools/tshell.rs +++ b/src/tools/tshell.rs @@ -10,7 +10,7 @@ use rust_i18n::t; use rustyline::{config::Configurer, history::FileHistory, Editor}; use std::io::{self, Write}; -pub fn tshell() -> RunResult<()> { +pub fn tshell() -> RuntimeResult<()> { println!("{}\n", t!("tshell.welcome").bold()); let config = rustyline::config::Config::builder() .check_cursor_position(true) diff --git a/src/tvm.rs b/src/tvm.rs index 44ed1bb8..2a217f69 100644 --- a/src/tvm.rs +++ b/src/tvm.rs @@ -10,6 +10,7 @@ pub struct Vm<'a> { run_context: Context, dynadata: DydataWrap, static_data: &'a libcore::codegen::StaticData, + imported_modules: Vec, } #[derive(Debug, Clone)] @@ -125,6 +126,7 @@ impl<'a> Vm<'a> { dynadata: DydataWrap::new(), run_context: Context::new(cfg::MAIN_MODULE_NAME), static_data, + imported_modules: Vec::new(), } } @@ -132,17 +134,50 @@ impl<'a> Vm<'a> { self.static_data = static_data; } - fn throw_err_info(&self, info: RuntimeResult) -> RunResult { + fn convert_err_info(&self, info: ErrorInfoResult) -> RuntimeResult { match info { Ok(data) => Ok(data), - Err(e) => Err(RuntimeError::new(Box::new(self.run_context.clone()), e)), + Err(e) => self.report_err(e), } } - pub fn reset(&mut self) { + fn report_err(&self, info: ErrorInfo) -> RuntimeResult { + Err(RuntimeError::new(Box::new(self.run_context.clone()), info)) + } + + pub fn reset(&mut self) -> RuntimeResult<()> { self.dynadata .dydata .init_global_var_store(self.static_data.sym_table_sz); + let mut should_be_reloaded = false; + for (i, j) in self.static_data.dll_module_should_loaded.iter().enumerate() { + if i >= self.imported_modules.len() { + break; + } + if *j != self.imported_modules[i] { + should_be_reloaded = true; + break; + } + } + // 导入未导入的模块 + if !should_be_reloaded { + for i in self + .static_data + .dll_module_should_loaded + .iter() + .skip(self.imported_modules.len()) + { + self.imported_modules.push(i.clone()); + self.import_module(i.clone())?; + } + } else { + self.imported_modules.clear(); + for i in &self.static_data.dll_module_should_loaded { + self.imported_modules.push(i.clone()); + self.import_module(i.clone())?; + } + } + Ok(()) } #[inline] @@ -170,8 +205,10 @@ impl<'a> Vm<'a> { Opcode::PopFrame => { let ret = match self.dynadata.frames_stack.pop() { None => { - return self - .throw_err_info(Err(ErrorInfo::new(t!(VM_FRAME_EMPTY), t!(VM_ERROR)))) + return self.convert_err_info(Err(ErrorInfo::new( + t!(VM_FRAME_EMPTY), + t!(VM_ERROR), + ))) } Some(v) => v, }; @@ -254,31 +291,31 @@ impl<'a> Vm<'a> { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); self.dynadata .dydata - .push_data(self.throw_err_info(div_int(first, second))?); + .push_data(self.convert_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))?); + .push_data(self.convert_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))?); + .push_data(self.convert_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))?); + .push_data(self.convert_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))?); + .push_data(self.convert_err_info(mod_int(first, second))?); } Opcode::PowerInt => { let (first, second) = impl_opcode!(TrcIntInternal, self, 2); @@ -604,8 +641,8 @@ impl<'a> Vm<'a> { Ok(()) } - pub fn run(&mut self) -> Result<(), RuntimeError> { - self.reset(); + pub fn run(&mut self) -> RuntimeResult<()> { + self.reset()?; let mut pc = 0; if !self.static_data.line_table.is_empty() { while pc < self.static_data.inst.len() { @@ -619,6 +656,21 @@ impl<'a> Vm<'a> { } Ok(()) } + + /// 导入一个dll模块 + fn import_module(&mut self, i: String) -> Result<(), RuntimeError> { + let lib = unsafe { + match libloading::Library::new(i.clone()) { + Ok(lib) => lib, + Err(_) => { + return self.report_err(module_not_found(&i)); + } + } + }; + let (module, storage) = crate::base::dll::load_module_storage(&lib); + for i in &storage.func_table {} + Ok(()) + } } #[cfg(test)] diff --git a/tests/test_compiler.rs b/tests/test_compiler.rs index 3b2b5619..7cd123ac 100644 --- a/tests/test_compiler.rs +++ b/tests/test_compiler.rs @@ -1,4 +1,5 @@ use libcore::*; +use libloading::library_filename; use std::mem::size_of; use trc::compiler::{ast::AstBuilder, *}; @@ -612,6 +613,10 @@ print("{}", math::sin(9.8)) ); t.generate_code().unwrap(); let fid = get_func_id(&mut t, "print"); + assert_eq!( + t.modules_dll(), + vec![library_filename("stdlib").to_str().unwrap().to_string()] + ); opcode_assert_eq( t.staticdata.inst, vec![