Skip to content

Commit

Permalink
feat(compiler):support custom module initially
Browse files Browse the repository at this point in the history
  • Loading branch information
limuy2022 committed Mar 31, 2024
1 parent ddab9da commit fecaddc
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 35 deletions.
7 changes: 6 additions & 1 deletion locales/en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ TypeError = "TypeError"
OperatorError = "OperatorError"
VmError = "VmError"
SyntaxError = "SyntaxError"
ModuleNotFoundError = "ModuleNotFoundError"

[compiler.syntaxerror]
str_error = "this string should be ended with \""
Expand All @@ -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}"
Expand Down
5 changes: 5 additions & 0 deletions locales/zh-CN.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ VmError = "虚拟机错误"
ArgumentError = "参数错误"
SyntaxError = "语法错误"
OperatorError = "操作符错误"
ModuleNotFoundError = "模块未找到错误"

[compiler.syntaxerror]
unmatched = "%{0}未匹配"
Expand All @@ -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"
Expand Down
4 changes: 4 additions & 0 deletions src/base/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 {
Expand Down
21 changes: 12 additions & 9 deletions src/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//! reference iterator:<https://stackoverflow.com/questions/43952104/how-can-i-store-a-chars-iterator-in-the-same-struct-as-the-string-it-is-iteratin>
//! reference float hash map:<https://www.soinside.com/question/tUJxYmevbVSHZYe2C2AK5o>
pub mod ast;
pub mod llvm_convent;
pub mod scope;
Expand All @@ -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,
}
Expand Down Expand Up @@ -76,16 +75,18 @@ impl Context {
}
}

impl Option {
impl CompileOption {
pub fn new(optimize: bool, source: InputSource) -> Self {
Option {
CompileOption {
optimize,
inputsource: source,
}
}
}

#[derive(Hash, Eq, PartialEq, Clone, Debug)]
/// # Reference
/// float hash map:<https://www.soinside.com/question/tUJxYmevbVSHZYe2C2AK5o>
pub struct Float {
// 小数点前的部分
front: i64,
Expand Down Expand Up @@ -201,6 +202,8 @@ impl ValuePool {
}

#[derive(Debug)]
/// # Reference
/// reference iterator:<https://stackoverflow.com/questions/43952104/how-can-i-store-a-chars-iterator-in-the-same-struct-as-the-string-it-is-iteratin>
pub struct StringSource {
text: String,
pos: usize,
Expand Down Expand Up @@ -332,12 +335,12 @@ impl TokenIo for FileSource {
pub struct Compiler {
// to support read from stdin and file
input: Box<dyn TokenIo<Item = char>>,
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) {
Expand All @@ -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,
Expand Down
39 changes: 29 additions & 10 deletions src/compiler/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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(())
}
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ pub fn run() -> Result<(), Box<dyn Error>> {
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),
)) {
Expand All @@ -74,7 +74,7 @@ pub fn run() -> Result<(), Box<dyn Error>> {
}
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),
)) {
Expand All @@ -92,7 +92,7 @@ pub fn run() -> Result<(), Box<dyn Error>> {
} => {
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(_) => {}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/compile_tool.rs
Original file line number Diff line number Diff line change
@@ -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(())
Expand Down
2 changes: 1 addition & 1 deletion src/tools/dis.rs
Original file line number Diff line number Diff line change
@@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/tools/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions src/tools/tshell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()?;
Expand All @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions tests/test_compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
9 changes: 6 additions & 3 deletions tests/test_tvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ fn test_dyna_data() {
data.push_data(null_mut::<i32>());
data.push_data(50);
data.push_data(false);
assert_eq!(data.pop_data::<bool>(), false);
// assert_eq == false
assert!(!data.pop_data::<bool>());
assert_eq!(data.pop_data::<i32>(), 50);
assert_eq!(data.pop_data::<*mut i32>(), null_mut::<i32>());
assert_eq!(data.pop_data::<i64>(), 30);
Expand All @@ -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();
Expand Down

0 comments on commit fecaddc

Please sign in to comment.