From 3863a330b8e046dc177f1fc4ee151cbebb4f961c Mon Sep 17 00:00:00 2001 From: limuy Date: Wed, 7 Feb 2024 00:18:32 +0800 Subject: [PATCH] add type system --- cpp/doc/developer/token.ll | 78 ----------------------------------- rust/Cargo.lock | 11 +++++ rust/Cargo.toml | 1 + rust/derive/src/def_module.rs | 1 + rust/derive/src/lib.rs | 10 +++-- rust/docs/developer/EBNF.md | 20 ++++----- rust/src/base/stdlib.rs | 6 +-- rust/src/compiler/ast.rs | 57 ++++++++++++------------- rust/src/compiler/token.rs | 3 ++ rust/src/tvm.rs | 48 +++++++++++++++++++++ rust/src/tvm/types.rs | 2 +- rust/src/tvm/types/trcbool.rs | 7 +++- rust/src/tvm/types/trcint.rs | 33 ++++++++++++++- 13 files changed, 148 insertions(+), 129 deletions(-) delete mode 100644 cpp/doc/developer/token.ll diff --git a/cpp/doc/developer/token.ll b/cpp/doc/developer/token.ll deleted file mode 100644 index 6be58180..00000000 --- a/cpp/doc/developer/token.ll +++ /dev/null @@ -1,78 +0,0 @@ -%{ -#include "compiler.hpp" -#include "parser.tab.hpp" - -// A number symbol corresponding to the value in S. - yy::parser::symbol_type - make_NUMBER (const std::string &s, const yy::parser::location_type& loc); -%} - -/* %option noyywrap nounput noinput batch debug */ -%option noyywrap batch debug - -string \"[^\n"]+\" - -blank [ \t\r] - -alpha [A-Za-z] -ids alpha|_ -dig [0-9] -name ({ids}|{dig}|\$)({ids}|{dig}|[_.\-/$])* -num1 [-+]?{dig}+\.?([eE][-+]?{dig}+)? -num2 [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)? -number {num1}|{num2} - -%{ - // Code run each time a pattern is matched. - # define YY_USER_ACTION loc.columns (yyleng); -%} - -%% -%{ - // A handy shortcut to the location held by the driver. - yy::location& loc = drv.location; - // Code run each time yylex is called. - loc.step (); -%} -{blank}+ loc.step (); - -"/*" { - int c; - while((c = yyinput()) != 0) { - if(c == '\n') { - loc.lines (yyleng); - loc.step (); - } else if(c == '*') { - if((c = yyinput()) == '/') { - break; - } else - unput(c); - } - } - } - -{number} - -\n+ loc.lines (yyleng); loc.step (); - -{name} - -{string} - -%% - -namesapce trc::compiler { - void compiler::scan_begin(const std::string&path) { - yy_flex_debug = trace_scanning; - yyin = open_file(file); - } - - void compiler::scan_begin(FILE* file) { - yy_flex_debug = trace_scanning; - yyin = file; - } - - void compiler::scan_end () { - fclose(yyin); - } -} diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 96695eb1..11f394e8 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -537,6 +537,16 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libloading" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -1291,6 +1301,7 @@ dependencies = [ "downcast-rs", "gettext-rs", "lazy_static", + "libloading", "llvm-sys", "num-bigint", "rand", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index cdb2b282..99b09ae9 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -21,6 +21,7 @@ reqwest = { version = "0.11.24", features = ["json", "multipart"] } tokio = { version = "1.36.0", features = ["full"] } llvm-sys = "170.0.1" derive = { path = "./derive" } +libloading = "0.8.1" [profile.release] panic = "abort" diff --git a/rust/derive/src/def_module.rs b/rust/derive/src/def_module.rs index a052e122..fc24daf7 100644 --- a/rust/derive/src/def_module.rs +++ b/rust/derive/src/def_module.rs @@ -152,6 +152,7 @@ pub fn def_impl(content: TokenStream) -> TokenStream { #( classes.insert(stringify!(#right_class).to_string(), #left_class::export_info()); #left_class::gen_funcs_info(); + #left_class::gen_overrides_info(); )* #( submodules.insert(stringify!(#submodules).to_string(), #submodules::init()); diff --git a/rust/derive/src/lib.rs b/rust/derive/src/lib.rs index 3cd79609..bb64e566 100644 --- a/rust/derive/src/lib.rs +++ b/rust/derive/src/lib.rs @@ -126,14 +126,12 @@ pub fn trc_class(_: TokenStream, input: TokenStream) -> TokenStream { stringify!(#name), members, None, - Self::override_export(), + None, classid ); STD_CLASS_TABLE.with(|std| { std.borrow_mut().push(ret); }); - // let funcs_info = Self::function_export() - // ret.functions = funcs_info; classid } @@ -143,6 +141,12 @@ pub fn trc_class(_: TokenStream, input: TokenStream) -> TokenStream { }); } + pub fn gen_overrides_info() { + STD_CLASS_TABLE.with(|std| { + std.borrow_mut()[Self::export_info()].overrides = Self::override_export(); + }); + } + pub fn export_info() -> usize { static ID: OnceLock = OnceLock::new(); *ID.get_or_init(|| { diff --git a/rust/docs/developer/EBNF.md b/rust/docs/developer/EBNF.md index 5413c304..b1bb6442 100644 --- a/rust/docs/developer/EBNF.md +++ b/rust/docs/developer/EBNF.md @@ -21,43 +21,43 @@ argv : expr expr : expr1 expr_ -expr_: || expr_ | empty +expr_: || expr1 expr_ | empty expr1 : expr2 expr1_ -expr1_: && expr1_ | empty +expr1_: && expr2 expr1_ | empty expr2 : expr3 expr2_ -expr2_: == expr2_| != expr2_| < expr2_| > expr2_| <= expr2_| >= expr2_ |empty +expr2_: == expr3 expr2_| != expr3 expr2_| < expr3 expr2_| > expr3 expr2_| <= expr3 expr2_| >= expr3 expr2_ | empty expr3 : expr4 expr3_ -expr3_: | expr3_ | empty +expr3_: | expr4 expr3_ | empty expr4 : expr5 expr4_ -expr4_: ^ expr4_ | empty +expr4_: ^ expr5 expr4_ | empty expr5 : expr6 expr5_ -expr5_: & expr5_ | empty +expr5_: & expr6 expr5_ | empty expr6: expr7 expr6_ -expr6_: << expr6_| >> expr6_ | empty +expr6_: << expr7 expr6_| >> expr7 expr6_ | empty expr7 : expr8 expr7_ -expr7_: + expr7_| - expr7_ | empty +expr7_: + expr8 expr7_| - expr8 expr7_ | empty expr8 : expr9 expr8_ -expr8_: * expr8_| / expr8_| % expr8_| // expr8_ | empty +expr8_: * expr9 expr8_| / expr9 expr8_| % expr8_| // expr9 expr8_ | empty expr9: factor expr9_ -expr9_: ** expr9_ | empty +expr9_: ** factor expr9_ | empty factor : (expr) | item | - factor | + factor | ! factor | ~ factor diff --git a/rust/src/base/stdlib.rs b/rust/src/base/stdlib.rs index cac9630f..6c1876e8 100644 --- a/rust/src/base/stdlib.rs +++ b/rust/src/base/stdlib.rs @@ -150,14 +150,14 @@ impl RustClass { name: impl Into, members: HashMap, functions: Option>, - overrides: HashMap, + overrides: Option>, id: usize, ) -> RustClass { RustClass { name: name.into(), members, functions: functions.unwrap_or_else(|| HashMap::new()), - overrides, + overrides: overrides.unwrap_or_else(|| HashMap::new()), id, } } @@ -283,7 +283,7 @@ impl Stdlib { lazy_static! { pub static ref ANY_TYPE: RustClass = - RustClass::new("any", HashMap::new(), None, HashMap::new(), new_class_id()); + RustClass::new("any", HashMap::new(), None, None, new_class_id()); pub static ref STDLIB_ROOT: Stdlib = crate::tvm::stdlib::init(); } diff --git a/rust/src/compiler/ast.rs b/rust/src/compiler/ast.rs index cd836ee4..b30de9c1 100644 --- a/rust/src/compiler/ast.rs +++ b/rust/src/compiler/ast.rs @@ -29,23 +29,13 @@ macro_rules! try_err { macro_rules! tmp_expe_function_gen { ($tmpfuncname:ident, $next_item_func:ident, $($accepted_token:path => $add_opcode:path),*) => { - fn $tmpfuncname(&mut self, istry: bool) -> AstError { + fn $tmpfuncname(&mut self, istry: bool, extend: usize) -> AstError { let next_sym = self.token_lexer.next_token()?; match next_sym.tp { $($accepted_token => { - let tya = self.$next_item_func(istry)?; - self.add_bycode($add_opcode, NO_ARG); - let tyb = self.$tmpfuncname(istry)?; - if let TypeAllowNull::No = tyb { - return Ok(tya); - } - if let TypeAllowNull::No = tya { - return Ok(tya) - } + let tya = self.$next_item_func(istry)?.unwrap(); // 读取IOType检查 - let tya = tya.unwrap(); - let tyb = tyb.unwrap(); - let func_obj = self.self_scope.as_ref().borrow().get_class(tya).unwrap(); + 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 { None => return try_err!(istry, @@ -56,15 +46,26 @@ macro_rules! tmp_expe_function_gen { ) ), Some(v) => { - if let Ok(_) = v.check_argvs(vec![tyb]) { - return Ok(v.return_type.clone()); + if let Ok(_) = v.check_argvs(vec![tya]) {} + else { + let func_obja = self.self_scope.as_ref().borrow().get_class(tya).unwrap(); + return try_err!(istry, + Box::new(self.token_lexer.compiler_data.content.clone()), + ErrorInfo::new(gettext!(TYPE_NOT_THE_SAME, func_obj.get_name(), + func_obja.get_name()), gettextrs::gettext(TYPE_ERROR))) } - let func_objb = self.self_scope.as_ref().borrow().get_class(tyb).unwrap(); - return try_err!(istry, - Box::new(self.token_lexer.compiler_data.content.clone()), - ErrorInfo::new(gettext!(TYPE_NOT_THE_SAME, func_obj.get_name(), - func_objb.get_name()), gettextrs::gettext(TYPE_ERROR))) - + } + } + let io_check = io_check.unwrap(); + self.add_bycode($add_opcode, NO_ARG); + let stage_ty = io_check.return_type.unwrap(); + let tyb = self.$tmpfuncname(istry, stage_ty)?; + match tyb { + TypeAllowNull::No => { + return Ok(TypeAllowNull::Yes(stage_ty)); + } + TypeAllowNull::Yes(_) => { + return Ok(tyb); } } })* @@ -83,20 +84,14 @@ macro_rules! expr_gen { tmp_expe_function_gen!($tmpfuncname, $next_item_func, $($accepted_token => $add_opcode),*); fn $funcname(&mut self, istry: bool) -> AstError { let t1 = self.$next_item_func(istry)?; - let t2 = self.$tmpfuncname(istry)?; - if let TypeAllowNull::No = t2 { - return Ok(t1); - } if let TypeAllowNull::No = t1 { return Ok(t1); } - if t1.unwrap() != t2.unwrap() { - return try_err!(istry, - Box::new(self.token_lexer.compiler_data.content.clone()), - ErrorInfo::new(gettext!(TYPE_NOT_THE_SAME, t1, - t2), gettextrs::gettext(TYPE_ERROR))) + let t2 = self.$tmpfuncname(istry, t1.unwrap())?; + if let TypeAllowNull::No = t2 { + return Ok(t1); } - Ok(t1) + Ok(t2) } }; } diff --git a/rust/src/compiler/token.rs b/rust/src/compiler/token.rs index 298043c7..bda72944 100644 --- a/rust/src/compiler/token.rs +++ b/rust/src/compiler/token.rs @@ -125,6 +125,8 @@ pub enum TokenType { Func, Import, Return, + // 不会被使用到的自反运算符,仅仅当标识重载运算符使用 + SelfNegative, EndOfFile, } @@ -195,6 +197,7 @@ impl Display for TokenType { TokenType::Return => "return", TokenType::SelfAnd => "&&=", TokenType::SelfOr => "||=", + TokenType::SelfNegative => "-", }; write!(f, "{}", res) } diff --git a/rust/src/tvm.rs b/rust/src/tvm.rs index de6719f5..7b48ebad 100644 --- a/rust/src/tvm.rs +++ b/rust/src/tvm.rs @@ -12,6 +12,7 @@ use crate::base::codegen::{self, StaticData}; use crate::base::stdlib::STD_FUNC_TABLE; use crate::{base::error::*, cfg}; use gettextrs::gettext; +use libloading::Library; pub struct DynaData<'a> { obj_stack: Vec>, @@ -63,6 +64,53 @@ impl Content { } } +/// Load libc +fn load_libc() -> Option<&'static Library> { + static LIBC: std::sync::OnceLock> = std::sync::OnceLock::new(); + #[cfg(target_os = "linux")] + { + let tmp = LIBC.get_or_init(|| unsafe { + let lib: Result = libloading::Library::new(""); + match lib { + Err(_) => None, + Ok(val) => Some(val), + } + }); + match tmp { + None => None, + Some(val) => Some(&val), + } + } + #[cfg(target_os = "windows")] + { + let tmp = LIBC.get_or_init(|| unsafe { + let lib: Result = libloading::Library::new("msvcrt.dll"); + match lib { + Err(_) => None, + Ok(val) => Some(val), + } + }); + match tmp { + None => None, + Some(val) => Some(&val), + } + } + #[cfg(target_os = "macos")] + { + let tmp = LIBC.get_or_init(|| unsafe { + let lib: Result = libloading::Library::new("libc.dylib"); + match lib { + Err(_) => None, + Ok(val) => Some(val), + } + }); + match tmp { + None => None, + Some(val) => Some(&val), + } + } +} + /// reduce the duplicate code to solve the operator running macro_rules! operator_opcode { ($trait_used:ident, $sself:expr) => {{ diff --git a/rust/src/tvm/types.rs b/rust/src/tvm/types.rs index d41ad726..006a7ec0 100644 --- a/rust/src/tvm/types.rs +++ b/rust/src/tvm/types.rs @@ -133,7 +133,7 @@ pub trait TrcObj: Downcast + std::fmt::Display + Debug { power => "**", bit_and => "&", bit_or => "|", - xor => "~", + xor => "^", bit_left_shift => "<<", bit_right_shift => ">>" ); diff --git a/rust/src/tvm/types/trcbool.rs b/rust/src/tvm/types/trcbool.rs index 917e85aa..8f2e0d9e 100644 --- a/rust/src/tvm/types/trcbool.rs +++ b/rust/src/tvm/types/trcbool.rs @@ -2,6 +2,7 @@ use super::TrcObj; use crate::base::error::*; use crate::base::error::{ErrorInfo, OPERATOR_ERROR, OPERATOR_IS_NOT_SUPPORT}; use crate::base::stdlib::*; +use crate::compiler::scope::TypeAllowNull; use crate::compiler::token::TokenType; use crate::{batch_impl_opers, hash_map, impl_oper, impl_single_oper}; use derive::{trc_class, trc_method}; @@ -44,6 +45,10 @@ impl TrcBool { } fn override_export() -> HashMap { - hash_map![] + hash_map![ + TokenType::And => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::Or => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::Not => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())) + ] } } diff --git a/rust/src/tvm/types/trcint.rs b/rust/src/tvm/types/trcint.rs index b0b54b55..3e1e98fe 100644 --- a/rust/src/tvm/types/trcint.rs +++ b/rust/src/tvm/types/trcint.rs @@ -1,6 +1,8 @@ +use super::trcbool::TrcBool; use super::trcfloat::TrcFloat; use super::TrcObj; use crate::base::stdlib::*; +use crate::compiler::scope::TypeAllowNull; use crate::compiler::token::TokenType; use crate::hash_map; use crate::impl_single_oper; @@ -23,7 +25,27 @@ impl TrcInt { } fn override_export() -> HashMap { - hash_map![] + hash_map![TokenType::Add => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::Sub => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::Mul => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::Div => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::Mod => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::Power => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::BitAnd => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::BitOr => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::Xor => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::ExactDiv => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::BitLeftShift => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::BitRightShift => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(Self::export_info())), + TokenType::BitNot => IOType::new(vec![], TypeAllowNull::Yes(Self::export_info())), + TokenType::SelfNegative => IOType::new(vec![], TypeAllowNull::Yes(Self::export_info())), + TokenType::Equal => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(TrcBool::export_info())), + TokenType::NotEqual => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(TrcBool::export_info())), + TokenType::Less => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(TrcBool::export_info())), + TokenType::LessEqual => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(TrcBool::export_info())), + TokenType::Greater => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(TrcBool::export_info())), + TokenType::GreaterEqual => IOType::new(vec![Self::export_info()], TypeAllowNull::Yes(TrcBool::export_info())) + ] } } @@ -89,7 +111,14 @@ impl TrcObj for TrcInt { bit_and => &, "&", TrcInt, TrcInt, bit_or => |, "|", TrcInt, TrcInt, bit_left_shift => <<, "<<", TrcInt, TrcInt, - bit_right_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, ?);