Skip to content

Commit

Permalink
add static type check
Browse files Browse the repository at this point in the history
  • Loading branch information
limuy2022 committed Feb 6, 2024
1 parent e98c232 commit 7f9d095
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 23 deletions.
1 change: 0 additions & 1 deletion rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ num-bigint = "0.4.4"
reqwest = { version = "0.11.24", features = ["json", "multipart"] }
tokio = { version = "1.36.0", features = ["full"] }
llvm-sys = "170.0.1"
once_cell = "1.19.0"
derive = { path = "./derive" }

[profile.release]
Expand Down
4 changes: 2 additions & 2 deletions rust/derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub fn trc_class(_: TokenStream, input: TokenStream) -> TokenStream {
// 因为很可能某个函数的参数就是标准库中的某个类型,所以我们需要先将类型导入到class_table中
let ret = quote!(#input
use crate::base::stdlib::{RustClass, new_class_id, STD_CLASS_TABLE};
use once_cell::sync::OnceCell;
use std::sync::OnceLock;
impl #name {
pub fn init_info() -> usize {
use std::collections::hash_map::HashMap;
Expand Down Expand Up @@ -144,7 +144,7 @@ pub fn trc_class(_: TokenStream, input: TokenStream) -> TokenStream {
}

pub fn export_info() -> usize {
static ID: OnceCell<usize> = OnceCell::new();
static ID: OnceLock<usize> = OnceLock::new();
*ID.get_or_init(|| {
let id = Self::init_info();
id
Expand Down
4 changes: 2 additions & 2 deletions rust/examples/expr.trc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
test expr
*/
print(1+1)
print(1.0+9.0)
print("hello")
#print("ppp"+1)
#print(1+"ppp")
19 changes: 19 additions & 0 deletions rust/src/base/stdlib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
};
use downcast_rs::{impl_downcast, Downcast};
use lazy_static::lazy_static;
use std::sync::OnceLock;
use std::{
cell::RefCell,
collections::HashMap,
Expand Down Expand Up @@ -103,6 +104,8 @@ pub trait ClassInterface: Downcast + Sync + Send + ClassClone + Debug + Display
fn is_any(&self) -> bool {
self.get_id() == 0
}

fn get_override_func(&self, oper_token: TokenType) -> Option<&IOType>;
}

impl<T> ClassClone for T
Expand Down Expand Up @@ -197,6 +200,13 @@ impl ClassInterface for RustClass {
fn get_id(&self) -> usize {
self.id
}

fn get_override_func(&self, oper_token: TokenType) -> Option<&IOType> {
match self.overrides.get(&oper_token) {
Some(i) => Some(i),
None => None,
}
}
}

impl Display for RustClass {
Expand Down Expand Up @@ -276,3 +286,12 @@ lazy_static! {
RustClass::new("any", HashMap::new(), None, HashMap::new(), new_class_id());
pub static ref STDLIB_ROOT: Stdlib = crate::tvm::stdlib::init();
}

/// 获取到标准库的类的个数,从而区分标准库和用户自定义的类
pub fn get_stdclass_end() -> usize {
static STD_NUM: OnceLock<usize> = OnceLock::new();
*STD_NUM.get_or_init(|| {
let mut num = STD_CLASS_TABLE.with(|std| std.borrow().len());
num
})
}
42 changes: 30 additions & 12 deletions rust/src/compiler/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,40 @@ macro_rules! tmp_expe_function_gen {
let next_sym = self.token_lexer.next_token()?;
match next_sym.tp {
$($accepted_token => {
let ty_now = self.$next_item_func(istry)?;
let tya = self.$next_item_func(istry)?;
self.add_bycode($add_opcode, NO_ARG);
let ty_after = self.$tmpfuncname(istry)?;
if let TypeAllowNull::No = ty_after {
return Ok(ty_now);
let tyb = self.$tmpfuncname(istry)?;
if let TypeAllowNull::No = tyb {
return Ok(tya);
}
if let TypeAllowNull::No = ty_now {
return Ok(ty_now)
if let TypeAllowNull::No = tya {
return Ok(tya)
}
if(ty_now.unwrap() == ty_after.unwrap()) {
return Ok(ty_now);
}
return try_err!(istry,
// 读取IOType检查
let tya = tya.unwrap();
let tyb = tyb.unwrap();
let func_obj = self.self_scope.as_ref().borrow().get_class(tya).unwrap();
let io_check = func_obj.get_override_func($accepted_token);
match io_check {
None => return try_err!(istry,
Box::new(self.token_lexer.compiler_data.content.clone()),
ErrorInfo::new(gettext!(TYPE_NOT_THE_SAME, ty_now,
ty_after), gettextrs::gettext(TYPE_ERROR)))
ErrorInfo::new(
gettext!(OPERATOR_IS_NOT_SUPPORT, $accepted_token, func_obj.get_name()),
gettext(OPERATOR_ERROR),
)
),
Some(v) => {
if let Ok(_) = v.check_argvs(vec![tyb]) {
return Ok(v.return_type.clone());
}
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)))

}
}
})*
_ => {
self.token_lexer.next_back(next_sym);
Expand Down
30 changes: 29 additions & 1 deletion rust/src/compiler/scope.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::ValuePool;
use crate::base::stdlib::{
ClassInterface, FunctionInterface, IOType, Stdlib, STDLIB_ROOT, STD_CLASS_TABLE,
get_stdclass_end, ClassInterface, FunctionInterface, IOType, Stdlib, STDLIB_ROOT,
STD_CLASS_TABLE,
};
use lazy_static::lazy_static;
use std::{borrow::Borrow, cell::RefCell, collections::HashMap, fmt::Display, rc::Rc};
Expand Down Expand Up @@ -143,6 +144,10 @@ impl ClassInterface for CommonType {
fn get_id(&self) -> usize {
self.name
}

fn get_override_func(&self, oper_token: super::token::TokenType) -> Option<&IOType> {
None
}
}

pub struct SymScope {
Expand All @@ -154,6 +159,7 @@ pub struct SymScope {
vars: HashMap<usize, Var>,
modules: HashMap<usize, &'static Stdlib>,
types_id: usize,
types_custom_store: HashMap<usize, CommonType>,
}

impl SymScope {
Expand All @@ -166,6 +172,7 @@ impl SymScope {
funcs: HashMap::new(),
vars: HashMap::new(),
modules: HashMap::new(),
types_custom_store: HashMap::new(),
types_id: 0,
};
match prev_scope {
Expand Down Expand Up @@ -262,6 +269,27 @@ impl SymScope {
pub fn get_scope_last_idx(&self) -> usize {
self.scope_sym_id
}

pub fn get_class(&self, classid: usize) -> Option<Type> {
// 在标准库界限内
if classid < get_stdclass_end() {
return Some(Box::new(
STD_CLASS_TABLE.with(|std| std.borrow()[classid].clone()),
));
}
// 不存在的类
if classid >= self.types_id {
return None;
}
let t = self.types.get(&classid);
return match t {
Some(t) => Some(Box::new(self.types_custom_store.get(t).unwrap().clone())),
None => match self.prev_scope {
Some(ref prev_scope) => prev_scope.as_ref().borrow().get_class(classid),
None => None,
},
};
}
}

#[cfg(test)]
Expand Down
5 changes: 4 additions & 1 deletion rust/src/compiler/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use gettextrs::gettext;
use lazy_static::lazy_static;
use std::{collections::HashMap, fmt::Display, process::exit};

#[derive(PartialEq, Debug, Clone)]
#[derive(PartialEq, Debug, Clone, Hash, Eq)]
pub enum TokenType {
// ->
Arrow,
Expand Down Expand Up @@ -424,11 +424,14 @@ impl TokenLex<'_> {
if c == '/' {
return self.next_token();
}
self.compiler_data.input.unread(c);
} else if c == '\0' {
return Err(RuntimeError::new(
Box::new(self.compiler_data.content.clone()),
ErrorInfo::new(gettext(UNCLODED_COMMENT), gettext(SYNTAX_ERROR)),
));
} else if c == '\n' {
self.compiler_data.content.add_line();
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions rust/src/tvm/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,21 +141,21 @@ pub trait TrcObj: Downcast + std::fmt::Display + Debug {
fn not(&self) -> RuntimeResult<Box<dyn TrcObj>> {
return Err(ErrorInfo::new(
gettext!(OPERATOR_IS_NOT_SUPPORT, "!", self.get_type_name()),
gettext(SYNTAX_ERROR),
gettext(OPERATOR_ERROR),
));
}

fn bit_not(&self) -> RuntimeResult<Box<dyn TrcObj>> {
return Err(ErrorInfo::new(
gettext!(OPERATOR_IS_NOT_SUPPORT, "~", self.get_type_name()),
gettext(SYNTAX_ERROR),
gettext(OPERATOR_ERROR),
));
}

fn self_negative(&self) -> RuntimeResult<Box<dyn TrcObj>> {
return Err(ErrorInfo::new(
gettext!(OPERATOR_IS_NOT_SUPPORT, "-", self.get_type_name()),
gettext(SYNTAX_ERROR),
gettext(OPERATOR_ERROR),
));
}

Expand Down

0 comments on commit 7f9d095

Please sign in to comment.