diff --git a/locales/en.toml b/locales/en.toml index 628d5b1c..fb981142 100644 --- a/locales/en.toml +++ b/locales/en.toml @@ -14,6 +14,7 @@ TypeError = "TypeError" OperatorError = "OperatorError" VmError = "VmError" SyntaxError = "SyntaxError" +ModuleNotFoundError = "ModuleNotFoundError" [compiler.syntaxerror] str_error = "this string should be ended with \"" @@ -24,11 +25,15 @@ unclosed_comment = "unclosed comment" char_error = "char should be the format like 'x'." expected_expr = "expected expression" return_should_in_function = "return should in function" -should_in_loop = "%{0}必须在循环内部" +should_in_loop = "%{0} must inside loop" [compiler.symbolerror] not_found_sym = "Symbol %{0} not found" redefined_sym = "Symbol %{0} redefined" +cannot_import_not_in_file = "Cannot import module when not running as file" + +[compiler.modulenotfounderror] +module_not_found = "Module %{0} not found" [compiler.argumenterror] argu_num = "expect %{0}.But given %{1}" diff --git a/locales/zh-CN.toml b/locales/zh-CN.toml index 5d8b57bd..0b7b357d 100644 --- a/locales/zh-CN.toml +++ b/locales/zh-CN.toml @@ -14,6 +14,7 @@ VmError = "虚拟机错误" ArgumentError = "参数错误" SyntaxError = "语法错误" OperatorError = "操作符错误" +ModuleNotFoundError = "模块未找到错误" [compiler.syntaxerror] unmatched = "%{0}未匹配" @@ -29,6 +30,10 @@ should_in_loop = "%{0}必须在循环内部" [compiler.symbolerror] not_found_sym = "未找到符号%{0}" redefined_sym = "符号%{0}重定义" +cannot_import_not_in_file = "在非文件模式下运行,不能导入模块" + +[compiler.modulenotfounderror] +module_not_found = "模块%{0}未找到" [compiler.argumenterror] void_argu = "参数不能为void" diff --git a/src/base/error.rs b/src/base/error.rs index 78d3f656..7d25e33d 100644 --- a/src/base/error.rs +++ b/src/base/error.rs @@ -12,6 +12,7 @@ pub const SYMBOL_ERROR: &str = "compiler.SymbolError"; pub const TYPE_ERROR: &str = "compiler.TypeError"; pub const ARGUMENT_ERROR: &str = "compiler.ArgumentError"; pub const FORMAT_STR_ERROR: &str = "compiler.FormatStringError"; +pub const MODULE_NOT_FOUND_ERROR: &str = "compiler.ModuleNotFoundError"; pub const STRING_WITHOUT_END: &str = "compiler.syntaxerror.str_error"; pub const CHAR_FORMAT: &str = "compiler.syntaxerror.char_error"; @@ -38,6 +39,9 @@ pub const JUST_ACCEPT_BOOL: &str = "compiler.typerror.if_while_accept_bool"; pub const RETURN_SHOULD_IN_FUNCTION: &str = "compiler.syntaxerror.return_should_in_function"; pub const RETURN_TYPE_ERROR: &str = "compiler.typerror.return_type"; pub const SHOULD_IN_LOOP: &str = "compiler.syntaxerror.should_in_loop"; +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"; #[derive(Debug)] pub struct ErrorInfo { diff --git a/src/compiler.rs b/src/compiler.rs index f623d000..855a4f6a 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -1,6 +1,3 @@ -//! reference iterator: -//! reference float hash map: - pub mod ast; pub mod llvm_convent; pub mod scope; @@ -22,12 +19,14 @@ use std::{ }; #[derive(Debug, Clone)] +/// 不同的输入源 pub enum InputSource { File(String), StringInternal, } -pub struct Option { +/// 编译器的参数控制 +pub struct CompileOption { optimize: bool, inputsource: InputSource, } @@ -76,9 +75,9 @@ impl Context { } } -impl Option { +impl CompileOption { pub fn new(optimize: bool, source: InputSource) -> Self { - Option { + CompileOption { optimize, inputsource: source, } @@ -86,6 +85,8 @@ impl Option { } #[derive(Hash, Eq, PartialEq, Clone, Debug)] +/// # Reference +/// float hash map: pub struct Float { // 小数点前的部分 front: i64, @@ -201,6 +202,8 @@ impl ValuePool { } #[derive(Debug)] +/// # Reference +/// reference iterator: pub struct StringSource { text: String, pos: usize, @@ -332,12 +335,12 @@ impl TokenIo for FileSource { pub struct Compiler { // to support read from stdin and file input: Box>, - option: Option, + option: CompileOption, context: Context, } impl Compiler { - pub fn new(option: Option) -> Self { + pub fn new(option: CompileOption) -> Self { match option.inputsource { InputSource::File(ref filename) => { let f = match fs::File::open(filename) { @@ -363,7 +366,7 @@ impl Compiler { } } - pub fn new_string_compiler(option: Option, source: &str) -> Self { + pub fn new_string_compiler(option: CompileOption, source: &str) -> Self { Compiler { input: Box::new(StringSource::new(String::from(source))), option, diff --git a/src/compiler/ast.rs b/src/compiler/ast.rs index d647fdec..ae31dfa5 100644 --- a/src/compiler/ast.rs +++ b/src/compiler/ast.rs @@ -16,7 +16,7 @@ use std::{cell::RefCell, mem::swap, rc::Rc}; use super::{ scope::*, token::{ConstPoolIndexTy, TokenType}, - InputSource, TokenLex, + CompileOption, Compiler, InputSource, TokenLex, }; use crate::base::stdlib::FunctionInterface; @@ -904,15 +904,34 @@ impl<'a> AstBuilder<'a> { } } } - } else if let InputSource::File(now_module_path) = - self.token_lexer.compiler_data.option.inputsource.clone() - { - let path = std::path::PathBuf::from(path.replace('.', "/")); - - let mut now_module_path = std::path::PathBuf::from(now_module_path); - now_module_path.pop(); - now_module_path = now_module_path.join(path); - if now_module_path.exists() {} + } else { + match self.token_lexer.compiler_data.option.inputsource.clone() { + InputSource::File(now_module_path) => { + let path = std::path::PathBuf::from(path.replace('.', "/")); + let mut now_module_path = std::path::PathBuf::from(now_module_path); + now_module_path.pop(); + // 找到想找到的文件 + now_module_path = now_module_path.join(path.clone()); + if now_module_path.exists() { + // 创建新的compiler来编译模块 + // let mut new_compiler = Compiler::new(Option::new()); + } else { + return self.try_err( + istry, + ErrorInfo::new( + t!(MODULE_NOT_FOUND, "0" = path.to_str().unwrap()), + t!(MODULE_NOT_FOUND_ERROR), + ), + ); + } + } + _ => { + return self.try_err( + istry, + ErrorInfo::new(t!(CANNOT_IMPORT_MODULE_WITHOUT_FILE), t!(SYMBOL_ERROR)), + ); + } + } } Ok(()) } diff --git a/src/compiler/token.rs b/src/compiler/token.rs index a8b28270..df8990ce 100644 --- a/src/compiler/token.rs +++ b/src/compiler/token.rs @@ -916,14 +916,14 @@ impl<'a> TokenLex<'a> { mod tests { use std::{collections::HashSet, fmt::Debug, hash::Hash}; - use crate::compiler::{InputSource, Option, Pool, INT_VAL_POOL_ONE, INT_VAL_POOL_ZERO}; + use crate::compiler::{CompileOption, InputSource, Pool, INT_VAL_POOL_ONE, INT_VAL_POOL_ZERO}; use super::*; macro_rules! gen_test_token_env { ($test_string:expr, $env_name:ident) => { let mut env = Compiler::new_string_compiler( - Option::new(false, InputSource::StringInternal), + CompileOption::new(false, InputSource::StringInternal), $test_string, ); let mut $env_name = TokenLex::new(&mut env); diff --git a/src/lib.rs b/src/lib.rs index 0453a30b..55d9c73b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,7 +53,7 @@ pub fn run() -> Result<(), Box> { match cli.mode { Commands::Build { optimize, files } => { for i in files { - match tools::compile(compiler::Option::new( + match tools::compile(compiler::CompileOption::new( optimize, compiler::InputSource::File(i), )) { @@ -74,7 +74,7 @@ pub fn run() -> Result<(), Box> { } Commands::Run { optimize, files } => { for i in files { - match tools::run::run(compiler::Option::new( + match tools::run::run(compiler::CompileOption::new( optimize, compiler::InputSource::File(i), )) { @@ -92,7 +92,7 @@ pub fn run() -> Result<(), Box> { } => { for i in files { match tools::dis::dis( - compiler::Option::new(optimize, compiler::InputSource::File(i)), + compiler::CompileOption::new(optimize, compiler::InputSource::File(i)), rustcode, ) { Ok(_) => {} diff --git a/src/tools/compile_tool.rs b/src/tools/compile_tool.rs index 1eb849ee..8081ba9f 100644 --- a/src/tools/compile_tool.rs +++ b/src/tools/compile_tool.rs @@ -1,6 +1,6 @@ use crate::{base::error::RunResult, compiler}; -pub fn compile(opt: compiler::Option) -> RunResult<()> { +pub fn compile(opt: compiler::CompileOption) -> RunResult<()> { let mut compiler = compiler::Compiler::new(opt); compiler.lex()?; Ok(()) diff --git a/src/tools/dis.rs b/src/tools/dis.rs index 2ebed9c1..7e483c6e 100644 --- a/src/tools/dis.rs +++ b/src/tools/dis.rs @@ -1,7 +1,7 @@ use crate::base::codegen::Opcode::*; use crate::base::error::RunResult; -pub fn dis(opt: crate::compiler::Option, rustcode: bool) -> RunResult<()> { +pub fn dis(opt: crate::compiler::CompileOption, rustcode: bool) -> RunResult<()> { 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 a2a51372..b5a385fa 100644 --- a/src/tools/run.rs +++ b/src/tools/run.rs @@ -4,7 +4,7 @@ use crate::{ tvm::Vm, }; -pub fn run(opt: compiler::Option) -> RunResult<()> { +pub fn run(opt: compiler::CompileOption) -> RunResult<()> { 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 7a423112..dc9afcef 100644 --- a/src/tools/tshell.rs +++ b/src/tools/tshell.rs @@ -21,7 +21,7 @@ pub fn tshell() -> RunResult<()> { let mut rl: Editor<(), FileHistory> = rustyline::Editor::with_config(config).unwrap(); rl.set_max_history_size(1000).unwrap(); let mut compiler = compiler::Compiler::new_string_compiler( - compiler::Option::new(false, compiler::InputSource::StringInternal), + compiler::CompileOption::new(false, compiler::InputSource::StringInternal), "", ); let mut ast = compiler.lex()?; @@ -34,7 +34,7 @@ pub fn tshell() -> RunResult<()> { let mut cnt = 0; // 此处要引入compiler的词法分析器来解析大括号和小括号 let mut braces_lexer = compiler::Compiler::new_string_compiler( - compiler::Option::new(false, compiler::InputSource::StringInternal), + compiler::CompileOption::new(false, compiler::InputSource::StringInternal), "", ); let mut check_lexer = braces_lexer.get_token_lex(); diff --git a/tests/test_compiler.rs b/tests/test_compiler.rs index b9c6c703..3a71b3ba 100644 --- a/tests/test_compiler.rs +++ b/tests/test_compiler.rs @@ -4,10 +4,10 @@ use trc::{base::codegen::*, compiler::*}; macro_rules! gen_test_env { ($test_code:expr, $env_name:ident) => { + use trc::compiler::CompileOption; use trc::compiler::InputSource; - use trc::compiler::Option; let mut compiler = Compiler::new_string_compiler( - Option::new(false, InputSource::StringInternal), + CompileOption::new(false, InputSource::StringInternal), $test_code, ); let token_lexer = trc::compiler::token::TokenLex::new(&mut compiler); diff --git a/tests/test_tvm.rs b/tests/test_tvm.rs index a1b94f48..cb4b1a5e 100644 --- a/tests/test_tvm.rs +++ b/tests/test_tvm.rs @@ -16,7 +16,8 @@ fn test_dyna_data() { data.push_data(null_mut::()); data.push_data(50); data.push_data(false); - assert_eq!(data.pop_data::(), false); + // assert_eq == false + assert!(!data.pop_data::()); assert_eq!(data.pop_data::(), 50); assert_eq!(data.pop_data::<*mut i32>(), null_mut::()); assert_eq!(data.pop_data::(), 30); @@ -26,8 +27,10 @@ fn test_dyna_data() { macro_rules! gen_test_env { ($code:expr, $var:ident) => { - let mut compiler = - Compiler::new_string_compiler(Option::new(false, InputSource::StringInternal), $code); + let mut compiler = Compiler::new_string_compiler( + CompileOption::new(false, InputSource::StringInternal), + $code, + ); let com_tmp = compiler.lex().unwrap(); // println!("{:?}", com_tmp.inst); let tmp = com_tmp.return_static_data();