From 3a6ece3b8a4410b39f401217739837403da32b5a Mon Sep 17 00:00:00 2001 From: limuy Date: Mon, 5 Feb 2024 17:44:34 +0800 Subject: [PATCH] fix grammar lex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加行号表设置 add ds module and fix clippy warnings --- rust/derive/src/def_module.rs | 42 +++--- rust/derive/src/function.rs | 34 +++-- rust/derive/src/lib.rs | 34 ++++- rust/docs/usage.md | 92 ++++++------ rust/examples/expr.trc | 3 + rust/src/base/codegen.rs | 6 +- rust/src/base/ctrc.rs | 3 - rust/src/base/stdlib.rs | 20 +-- rust/src/base/utils.rs | 6 + rust/src/compiler.rs | 6 +- rust/src/compiler/ast.rs | 175 ++++++++++++----------- rust/src/compiler/scope.rs | 18 +-- rust/src/compiler/token.rs | 47 +++--- rust/src/lib.rs | 9 +- rust/src/tools/update.rs | 3 +- rust/src/tvm.rs | 14 +- rust/src/tvm/algo/string.rs | 22 +-- rust/src/tvm/stdlib.rs | 3 +- rust/src/tvm/stdlib/ds.rs | 5 + rust/src/tvm/stdlib/prelude.rs | 7 +- rust/src/tvm/types.rs | 11 +- rust/src/tvm/types/data_structure.rs | 36 ++--- rust/src/tvm/types/data_structure/sam.rs | 80 ++++++++--- rust/src/tvm/types/trcbool.rs | 7 +- rust/src/tvm/types/trcchar.rs | 36 +++++ rust/src/tvm/types/trcfloat.rs | 1 + rust/src/tvm/types/trcint.rs | 1 + rust/src/tvm/types/trcstr.rs | 4 +- 28 files changed, 432 insertions(+), 293 deletions(-) create mode 100644 rust/examples/expr.trc create mode 100644 rust/src/tvm/stdlib/ds.rs create mode 100644 rust/src/tvm/types/trcchar.rs diff --git a/rust/derive/src/def_module.rs b/rust/derive/src/def_module.rs index 4d6651a5..c0c9ddd5 100644 --- a/rust/derive/src/def_module.rs +++ b/rust/derive/src/def_module.rs @@ -11,14 +11,14 @@ pub fn lex_arrow( errormsg: &str, ) { match iter.next().unwrap() { - proc_macro::TokenTree::Group(x, ..) => { + TokenTree::Group(x, ..) => { let mut left_name = TokenStream::new(); let mut right_name = TokenStream::new(); let mut control_which_put = false; let mut iter = x.stream().into_iter(); while let Some(i) = iter.next() { // println!("{}", i); - if let proc_macro::TokenTree::Punct(x) = i { + if let TokenTree::Punct(x) = i { let x = x.to_string(); if x == "=" { check_next_iter(&mut iter, ">"); @@ -31,19 +31,17 @@ pub fn lex_arrow( left_name = TokenStream::new(); right_name = TokenStream::new(); control_which_put = false; - } else if x == "]" { - left_push.push(syn::parse(left_name).expect("left push break")); - right_push.push(syn::parse(right_name).expect("right push break")); - break; - } - } else { - if !control_which_put { - left_name.extend(std::iter::once(i)); } else { - right_name.extend(std::iter::once(i)); + panic!("{}", errormsg); } + } else if !control_which_put { + left_name.extend(std::iter::once(i)); + } else { + right_name.extend(std::iter::once(i)); } } + left_push.push(syn::parse(left_name).expect("left push break")); + right_push.push(syn::parse(right_name).expect("right push break")); } _ => { panic!("{}", errormsg); @@ -53,7 +51,7 @@ pub fn lex_arrow( fn check_next_iter(iter: &mut IntoIter, check_str: &str) { if let Some(i) = iter.next() { - if let proc_macro::TokenTree::Punct(x) = i { + if let TokenTree::Punct(x) = i { if x.to_string() != check_str { panic!("expected {}", check_str); } @@ -75,12 +73,12 @@ pub fn def_impl(content: TokenStream) -> TokenStream { let mut submodules = vec![]; while let Some(i) = iter.next() { match i { - proc_macro::TokenTree::Ident(x) => { + TokenTree::Ident(x) => { let x = x.to_string(); if x == "module_name" { check_next_iter(&mut iter, "="); if let TokenTree::Ident(tmp) = iter.next().expect("name is expected") { - if let Some(_) = module_ident { + if module_ident.is_some() { panic!("double defined"); } module_ident = @@ -106,14 +104,14 @@ pub fn def_impl(content: TokenStream) -> TokenStream { ); } else if x == "submodules" { check_next_iter(&mut iter, "="); - if let proc_macro::TokenTree::Group(x, ..) = iter.next().unwrap() { + if let TokenTree::Group(x, ..) = iter.next().unwrap() { // println!("{}", x); let mut iter = x.stream().into_iter(); - while let Some(i) = iter.next() { - if let proc_macro::TokenTree::Ident(x) = i { + for i in iter { + if let TokenTree::Ident(x) = i { submodules .push(syn::parse_str::(&(x.to_string())).unwrap()); - } else if let proc_macro::TokenTree::Ident(x) = i { + } else if let TokenTree::Ident(x) = i { let x = x.to_string(); if x != "," { panic!("expected ,.get {}", x); @@ -127,7 +125,7 @@ pub fn def_impl(content: TokenStream) -> TokenStream { } } } - proc_macro::TokenTree::Punct(x) => { + TokenTree::Punct(x) => { if x.to_string() != "," { panic!("expected ,"); } @@ -147,15 +145,19 @@ pub fn def_impl(content: TokenStream) -> TokenStream { use std::collections::hash_map::HashMap; let mut functions = HashMap::new(); let mut classes = HashMap::new(); + let mut submodules = HashMap::new(); #( functions.insert(stringify!(#right_func).to_string(), #left_func()); )* #( classes.insert(stringify!(#right_class).to_string(), #left_class::export_info()); )* + #( + submodules.insert(stringify!(#submodules).to_string(), #submodules::init()); + )* Stdlib::new( stringify!(#module_ident), - HashMap::new(), + submodules, functions, classes ) diff --git a/rust/derive/src/function.rs b/rust/derive/src/function.rs index ae525685..d08a2845 100644 --- a/rust/derive/src/function.rs +++ b/rust/derive/src/function.rs @@ -1,3 +1,6 @@ +use core::panic; + +use quote::ToTokens; use syn::{ parse_str, punctuated, token::Comma, FnArg, PatType, ReturnType, Signature, Stmt, Type, TypePath, @@ -24,11 +27,11 @@ pub fn process_function_def(sig: &mut Signature) -> (Vec, Vec, T }; let input_args = sig.inputs.clone(); let mut new_stmts = vec![]; - let mut new_args: punctuated::Punctuated = syn::punctuated::Punctuated::new(); + let mut new_args: punctuated::Punctuated = punctuated::Punctuated::new(); // 第一个参数是self - if input_args.len() >= 1 { + if !input_args.is_empty() { if let FnArg::Receiver(_) = &input_args[0] { - new_args.push(input_args[0].clone()); + panic!("don't use self, use fn(DynaData) instead.") } } let mut args_type_required = vec![]; @@ -43,18 +46,25 @@ pub fn process_function_def(sig: &mut Signature) -> (Vec, Vec, T _ => unreachable!(), }; // println!("argv:{:#?}", path); - if path.path.segments[0].ident.to_string() == "any" { - args_type_required.push(parse_str("ANY_TYPE").unwrap()); + if path.path.segments[0].ident == "any" { + args_type_required.push(parse_str("RustClass").unwrap()); + new_stmts.push( + parse_str::(&format!( + "let mut {} = dydata.obj_stack.pop().unwrap();", + arg_name + )) + .unwrap(), + ); } else { args_type_required.push(path.clone()); + new_stmts.push( + parse_str::(&format!( + "let mut {} = dydata.obj_stack.pop().unwrap().downcast::<{}>().unwrap();", + arg_name, path.to_token_stream() + )) + .unwrap(), + ); } - new_stmts.push( - parse_str::(&format!( - "let mut {} = dydata.obj_stack.pop().unwrap();", - arg_name - )) - .unwrap(), - ); } } } diff --git a/rust/derive/src/lib.rs b/rust/derive/src/lib.rs index 39f67c26..8956fe56 100644 --- a/rust/derive/src/lib.rs +++ b/rust/derive/src/lib.rs @@ -10,7 +10,7 @@ mod function; #[proc_macro_attribute] /// 返回值一定要加上return -pub fn trc_function(_: TokenStream, input: TokenStream) -> TokenStream { +pub fn trc_function(attr: TokenStream, input: TokenStream) -> TokenStream { let mut input = parse_macro_input!(input as ItemFn); let (mut new_stmts, args_type_required, output) = process_function_def(&mut input.sig); let name = input.sig.ident.clone(); @@ -51,15 +51,25 @@ pub fn trc_function(_: TokenStream, input: TokenStream) -> TokenStream { let info_func_name = parse_str::(&function::convent_to_info_func(name.to_string())).expect("name error"); // println!("{}{:#?}", name.to_string(), info_function_self); + let function_path: syn::Path; + if let Some(ty) = attr.into_iter().next() { + if ty.to_string() == "true" { + function_path = parse_str(&format!("Self::{}", name)).unwrap(); + } else { + function_path = parse_str(&name.to_string()).unwrap(); + } + } else { + function_path = parse_str(&name.to_string()).unwrap(); + } let rettmp = quote!(#input fn #info_func_name() -> RustFunction { use crate::base::stdlib::*; use crate::compiler::scope::TypeAllowNull; - let ret_classes = vec![#(#args_type_required.clone()),*]; - return RustFunction::new(stringify!(#name), #name, IOType::new(ret_classes, #output)); + let ret_classes = vec![#(#args_type_required::export_info()),*]; + return RustFunction::new(stringify!(#name), #function_path, IOType::new(ret_classes, #output)); } ); - // println!("{}", rettmp.to_token_stream()); + println!("{}", rettmp.to_token_stream()); rettmp.into() } @@ -83,6 +93,16 @@ pub fn trc_class(_: TokenStream, input: TokenStream) -> TokenStream { // 说明是要导出的成员 let varname = i.ident.clone().unwrap(); let vartype = i.ty.clone(); + if varname + .to_token_stream() + .into_iter() + .next() + .unwrap() + .to_string() + .starts_with('_') + { + continue; + } members_ident.push(varname); members_ty.push(vartype); } @@ -93,7 +113,7 @@ pub fn trc_class(_: TokenStream, input: TokenStream) -> TokenStream { impl #name { pub fn export_info() -> RustClass { use std::collections::hash_map::HashMap; - use crate::compiler::scope::{Var}; + use crate::compiler::scope::Var; let mut members = HashMap::new(); #( members.insert(Var::new(stringify!(#members_ty), #members_ident)); @@ -144,12 +164,12 @@ pub fn trc_method(_: TokenStream, input: TokenStream) -> TokenStream { fn function_export() -> HashMap { let mut ret = HashMap::new(); #( - ret.push(stringify!(#funcs).to_string(), self.#funcs()); + ret.insert(stringify!(#funcs).to_string(), Self::#funcs()); )* ret } } ); - // println!("{:#?}", ret.to_string()); + // println!("{}", ret); ret.into() } diff --git a/rust/docs/usage.md b/rust/docs/usage.md index bfba68dd..793f968f 100644 --- a/rust/docs/usage.md +++ b/rust/docs/usage.md @@ -30,22 +30,22 @@ Tip3:The form like 001 is supported The next is the string value. To make you to write strings more easily: -|Way|Explain| -|:---|:---| -|"hello world"|commom value| -|'hello_world'|another method that equals to "hello world"| -|"""hello world"""|this method is for code across multiple lines| +| Way | Explain | +|:------------------|:----------------------------------------------| +| "hello world" | commom value | +| 'hello_world' | another method that equals to "hello world" | +| """hello world""" | this method is for code across multiple lines | There are also many easape char in the string: -|escape char|meaning| -|:---|:---| -|\t|tab| -|\n|new line| -|\\\\|\| -|\'|'| -|\"|"| -|\0|the tick of the end of the string| +| escape char | meaning | +|:------------|:----------------------------------| +| \t | tab | +| \n | new line | +| \\\\|\| | | +| \' | ' | +| \" | " | +| \0 | the tick of the end of the string | If you add ```r``` or ```R``` in front of the string.Trc will treat it as a raw string. Yes.These rules are from Python.I love its grammar rules @@ -58,30 +58,30 @@ the operators for basic types of trc is like others language. Here are the operator support -|Operator|Explain| -|:---|:---| -|+|addition| -|-|subtraction| -|*|multiplication| -|/|division| -|//|divisible| -|%|mod| -|**|exponent| -|<|less than| -|>|greater than| -|<=|less than or equal to| -|>=|greater than or equal to| -|==|equal to| -|!=|not equal to| -|&&|and| -|\|\||or| -|\||bit or| -|&|bit and| -|^|bit xor| -|~|bit not| -|<<|bit left shift| -|>>|bit right shift| -|!|not| +| Operator | Explain | +|:---------|:-------------------------| +| + | addition | +| - | subtraction | +| * | multiplication | +| / | division | +| // | divisible | +| % | mod | +| ** | exponent | +| < | less than | +| > | greater than | +| <= | less than or equal to | +| >= | greater than or equal to | +| == | equal to | +| != | not equal to | +| && | and | +| \|\| | or | +| \| | bit or | +| & | bit and | +| ^ | bit xor | +| ~ | bit not | +| << | bit left shift | +| >> | bit right shift | +| ! | not | Obviously,operators like ```+=``` is supported,too. @@ -179,15 +179,15 @@ int a:=90 Std lib provide many kinds of data structures for Trc.Here is the list: -|Structure| -|:---| -|St table| -|suffix automaton| -|ac automaton| -|list| -|forward list| -|stack| -|deque| +| Structure | +|:-----------------| +| St table | +| suffix automaton | +| ac automaton | +| list | +| forward list | +| stack | +| deque | ## Function diff --git a/rust/examples/expr.trc b/rust/examples/expr.trc new file mode 100644 index 00000000..e43912c1 --- /dev/null +++ b/rust/examples/expr.trc @@ -0,0 +1,3 @@ +print(1+1) +print("hello") +print("ppp"+1) diff --git a/rust/src/base/codegen.rs b/rust/src/base/codegen.rs index 27f4340d..0c983343 100644 --- a/rust/src/base/codegen.rs +++ b/rust/src/base/codegen.rs @@ -93,15 +93,19 @@ pub struct StaticData { pub inst: Vec, pub funcs: Vec, pub sym_table_sz: usize, + pub line_table: Vec, + pub has_line_table: bool, } impl StaticData { - pub fn new() -> StaticData { + pub fn new(has_line_table: bool) -> StaticData { Self { constpool: ConstPool::new(), inst: vec![], funcs: vec![], sym_table_sz: 0, + line_table: vec![], + has_line_table, } } diff --git a/rust/src/base/ctrc.rs b/rust/src/base/ctrc.rs index 50e0ad70..26d5c684 100644 --- a/rust/src/base/ctrc.rs +++ b/rust/src/base/ctrc.rs @@ -1,7 +1,4 @@ //! generate ctrc file //! ctrc file is trc's compiled object //! can be loaded and runned by vm without compiling - -use super::codegen; - pub fn generate_ctrc() {} diff --git a/rust/src/base/stdlib.rs b/rust/src/base/stdlib.rs index 2754d738..7caf826a 100644 --- a/rust/src/base/stdlib.rs +++ b/rust/src/base/stdlib.rs @@ -165,6 +165,10 @@ impl RustClass { pub fn add_attr(&mut self, name: impl Into, attr: Var) { self.members.insert(name.into(), attr); } + + pub fn export_info() -> Self { + ANY_TYPE.clone() + } } impl ClassInterface for RustClass { @@ -177,14 +181,6 @@ impl ClassInterface for RustClass { None } - fn get_name(&self) -> &str { - &self.name - } - - fn get_id(&self) -> usize { - self.id - } - fn has_attr(&self, attrname: &str) -> Option { let ret = &self.members.get(attrname); match ret { @@ -192,6 +188,14 @@ impl ClassInterface for RustClass { None => None, } } + + fn get_name(&self) -> &str { + &self.name + } + + fn get_id(&self) -> usize { + self.id + } } impl Display for RustClass { diff --git a/rust/src/base/utils.rs b/rust/src/base/utils.rs index cb3440c6..fce0cb76 100644 --- a/rust/src/base/utils.rs +++ b/rust/src/base/utils.rs @@ -2,6 +2,12 @@ use std::ops::DivAssign; #[macro_export] macro_rules! hash_map { + [] => { + { + use std::collections::hash_map::HashMap; + HashMap::new() + } + }; [$($key:expr => $val:expr),*] => { { use std::collections::hash_map::HashMap; diff --git a/rust/src/compiler.rs b/rust/src/compiler.rs index c011aeda..f1eb2cd8 100644 --- a/rust/src/compiler.rs +++ b/rust/src/compiler.rs @@ -120,7 +120,7 @@ impl Display for Float { } } -type Pool = hash_map::HashMap; +type Pool = HashMap; pub struct ValuePool { const_ints: Pool, @@ -190,7 +190,7 @@ impl ValuePool { ret.stringpool .resize(self.const_strings.len(), "".to_string()); for i in &self.const_strings { - ret.stringpool[*i.1] = (i.0).clone(); + ret.stringpool[*i.1] = i.0.clone(); } ret } @@ -333,7 +333,7 @@ impl Compiler { pub fn new(option: Option) -> Self { match option.inputsource { InputSource::File(ref filename) => { - let f = std::fs::File::open(filename); + let f = fs::File::open(filename); Compiler { input: Box::new(FileSource::new(f.unwrap())), const_pool: ValuePool::new(), diff --git a/rust/src/compiler/ast.rs b/rust/src/compiler/ast.rs index cf1d8efe..5a6a3b73 100644 --- a/rust/src/compiler/ast.rs +++ b/rust/src/compiler/ast.rs @@ -5,7 +5,6 @@ use crate::base::codegen::{Inst, Opcode, NO_ARG}; use crate::base::stdlib::{RustFunction, STDLIB_ROOT}; use crate::base::{codegen::StaticData, error::*}; use gettextrs::gettext; -use std::borrow::Borrow; use std::cell::RefCell; use std::rc::Rc; @@ -17,7 +16,7 @@ pub struct AstBuilder<'a> { type AstError = RunResult; -macro_rules! TryErr { +macro_rules! try_err { ($istry: expr, $($argvs:expr),*) => { {if $istry { Err(LightFakeError::new().into()) @@ -28,14 +27,14 @@ macro_rules! TryErr { }; } -macro_rules! TmpExpeFunctionGen { +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 { let next_sym = self.token_lexer.next_token()?; match next_sym.tp { $($accepted_token => { let ty_now = self.$next_item_func(istry)?; - self.staticdata.inst.push(Inst::new($add_opcode, NO_ARG)); + self.add_bycode($add_opcode, NO_ARG); let ty_after = self.$tmpfuncname(istry)?; if let TypeAllowNull::No = ty_after { return Ok(ty_now); @@ -46,7 +45,7 @@ macro_rules! TmpExpeFunctionGen { if(ty_now.unwrap().get_id() == ty_after.unwrap().get_id()) { return Ok(ty_now); } - return TryErr!(istry, + 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))) @@ -61,9 +60,9 @@ macro_rules! TmpExpeFunctionGen { } /// there are a log of similar operators to be generated -macro_rules! ExprGen { +macro_rules! expr_gen { ($funcname:ident, $tmpfuncname:ident, $next_item_func:ident, $($accepted_token:path => $add_opcode:path),*) => { - TmpExpeFunctionGen!($tmpfuncname, $next_item_func, $($accepted_token => $add_opcode),*); + 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)?; @@ -74,7 +73,7 @@ macro_rules! ExprGen { return Ok(t1); } if t1.unwrap().get_id() != t2.unwrap().get_id() { - return TryErr!(istry, + 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))) @@ -95,9 +94,10 @@ impl<'a> AstBuilder<'a> { } let root_scope = Rc::new(RefCell::new(SymScope::new(None))); // 为root scope添加prelude - let mut ret = AstBuilder { + let optimize = token_lexer.compiler_data.option.optimize; + let ret = AstBuilder { token_lexer, - staticdata: StaticData::new(), + staticdata: StaticData::new(!optimize), self_scope: root_scope, }; ret.self_scope @@ -107,27 +107,27 @@ impl<'a> AstBuilder<'a> { ret } - ExprGen!(expr9, expr9_, factor, TokenType::Power => Opcode::Power); - ExprGen!(expr8, expr8_, expr9, TokenType::Mul => Opcode::Mul, + expr_gen!(expr9, expr9_, factor, TokenType::Power => Opcode::Power); + expr_gen!(expr8, expr8_, expr9, TokenType::Mul => Opcode::Mul, TokenType::Div => Opcode::Div, TokenType::Mod => Opcode::Mod, TokenType::ExactDiv => Opcode::ExtraDiv); - ExprGen!(expr7, expr7_, expr8, TokenType::Add => Opcode::Add, + expr_gen!(expr7, expr7_, expr8, TokenType::Add => Opcode::Add, TokenType::Sub => Opcode::Sub); - ExprGen!(expr6, expr6_, expr7, TokenType::BitLeftShift => Opcode::BitLeftShift, + expr_gen!(expr6, expr6_, expr7, TokenType::BitLeftShift => Opcode::BitLeftShift, TokenType::BitRightShift => Opcode::BitRightShift); - ExprGen!(expr5, expr5_, expr6, TokenType::BitAnd => Opcode::BitAnd); - ExprGen!(expr4, expr4_, expr5, TokenType::Xor => Opcode::Xor); - ExprGen!(expr3, expr3_, expr4, TokenType::BitOr => Opcode::BitOr); - ExprGen!(expr2, expr2_, expr3, TokenType::Equal => Opcode::Eq, + expr_gen!(expr5, expr5_, expr6, TokenType::BitAnd => Opcode::BitAnd); + expr_gen!(expr4, expr4_, expr5, TokenType::Xor => Opcode::Xor); + expr_gen!(expr3, expr3_, expr4, TokenType::BitOr => Opcode::BitOr); + expr_gen!(expr2, expr2_, expr3, TokenType::Equal => Opcode::Eq, TokenType::NotEqual => Opcode::Ne, TokenType::Less => Opcode::Lt, TokenType::LessEqual => Opcode::Le, TokenType::Greater => Opcode::Gt, TokenType::GreaterEqual => Opcode::Ge ); - ExprGen!(expr1, expr1_, expr2, TokenType::And => Opcode::And); - ExprGen!(expr, expr_, expr1, TokenType::Or => Opcode::Or); + expr_gen!(expr1, expr1_, expr2, TokenType::And => Opcode::And); + expr_gen!(expr, expr_, expr1, TokenType::Or => Opcode::Or); pub fn return_static_data(mut self) -> StaticData { self.staticdata.constpool = self.token_lexer.compiler_data.const_pool.store_val_to_vm(); @@ -180,11 +180,11 @@ impl<'a> AstBuilder<'a> { fn val(&mut self, istry: bool) -> AstError { let t = self.token_lexer.next_token()?; - if t.tp == TokenType::ID { + return if t.tp == TokenType::ID { let token_data = t.data.unwrap(); let idx = self.self_scope.as_ref().borrow().get_sym_idx(token_data); if let None = idx { - return TryErr!( + return try_err!( istry, Box::new(self.token_lexer.compiler_data.content.clone()), ErrorInfo::new( @@ -206,7 +206,7 @@ impl<'a> AstBuilder<'a> { let func_obj = tmp.get_function(idx).unwrap(); match func_obj.get_io().check_argvs(argv_list) { Err(e) => { - return TryErr!( + return try_err!( istry, Box::new(self.token_lexer.compiler_data.content.clone()), e @@ -214,32 +214,29 @@ impl<'a> AstBuilder<'a> { } Ok(_) => {} } + drop(tmp); if let Some(obj) = func_obj.downcast_ref::() { - self.staticdata - .inst - .push(Inst::new(Opcode::CallNative, obj.buildin_id)); + self.add_bycode(Opcode::CallNative, obj.buildin_id); } - return Ok((func_obj.get_io().return_type).clone()); + Ok(func_obj.get_io().return_type.clone()) } else { self.token_lexer.next_back(nxt); let varidx = self.self_scope.as_ref().borrow_mut().insert_sym(idx); - self.staticdata - .inst - .push(Inst::new(Opcode::LoadLocal, varidx)); + self.add_bycode(Opcode::LoadLocal, varidx); let tt = self.self_scope.as_ref().borrow().get_type(varidx); - return Ok(TypeAllowNull::Yes(tt)); + Ok(TypeAllowNull::Yes(tt)) } } else { self.token_lexer.next_back(t.clone()); - return TryErr!( + try_err!( istry, Box::new(self.token_lexer.compiler_data.content.clone()), ErrorInfo::new( gettext!(UNEXPECTED_TOKEN, t.tp), gettextrs::gettext(SYNTAX_ERROR), ) - ); - } + ) + }; } fn item(&mut self, istry: bool) -> AstError { @@ -247,12 +244,10 @@ impl<'a> AstBuilder<'a> { return Ok(v); } let t = self.token_lexer.next_token()?; - match t.tp { + return match t.tp { TokenType::IntValue => { - self.staticdata - .inst - .push(Inst::new(Opcode::LoadInt, t.data.unwrap())); - return Ok(TypeAllowNull::Yes( + self.add_bycode(Opcode::LoadInt, t.data.unwrap()); + Ok(TypeAllowNull::Yes( self.self_scope .as_ref() .borrow() @@ -266,13 +261,11 @@ impl<'a> AstBuilder<'a> { .unwrap(), ) .clone(), - )); + )) } TokenType::FloatValue => { - self.staticdata - .inst - .push(Inst::new(Opcode::LoadFloat, t.data.unwrap())); - return Ok(TypeAllowNull::Yes( + self.add_bycode(Opcode::LoadFloat, t.data.unwrap()); + Ok(TypeAllowNull::Yes( self.self_scope .as_ref() .borrow() @@ -286,13 +279,11 @@ impl<'a> AstBuilder<'a> { .unwrap(), ) .clone(), - )); + )) } TokenType::StringValue => { - self.staticdata - .inst - .push(Inst::new(Opcode::LoadString, t.data.unwrap())); - return Ok(TypeAllowNull::Yes( + self.add_bycode(Opcode::LoadString, t.data.unwrap()); + Ok(TypeAllowNull::Yes( self.self_scope .as_ref() .borrow() @@ -306,55 +297,51 @@ impl<'a> AstBuilder<'a> { .unwrap(), ) .clone(), - )); + )) } _ => { self.token_lexer.next_back(t.clone()); - return TryErr!( + try_err!( istry, Box::new(self.token_lexer.compiler_data.content.clone()), ErrorInfo::new( gettext!(UNEXPECTED_TOKEN, t.tp), gettextrs::gettext(SYNTAX_ERROR), ) - ); + ) } - } + }; } fn factor(&mut self, istry: bool) -> AstError { let next_token = self.token_lexer.next_token()?; - match next_token.tp { + return match next_token.tp { TokenType::Sub => { let ret = self.factor(istry)?; - self.staticdata - .inst - .push(Inst::new(Opcode::SelfNegative, NO_ARG)); - return Ok(ret); + self.add_bycode(Opcode::SelfNegative, NO_ARG); + Ok(ret) } TokenType::BitNot => { let ret = self.factor(istry)?; - self.staticdata.inst.push(Inst::new(Opcode::BitNot, NO_ARG)); - return Ok(ret); + self.add_bycode(Opcode::BitNot, NO_ARG); + Ok(ret) } TokenType::Not => { let ret = self.factor(istry)?; - self.staticdata.inst.push(Inst::new(Opcode::Not, NO_ARG)); - return Ok(ret); - } - TokenType::Add => { - return Ok(self.factor(istry)?); + self.add_bycode(Opcode::Not, NO_ARG); + Ok(ret) } + TokenType::Add => Ok(self.factor(istry)?), TokenType::LeftSmallBrace => { let ret = self.expr(istry)?; self.check_next_token(TokenType::RightSmallBrace)?; - return Ok(ret); + Ok(ret) } _ => { self.token_lexer.next_back(next_token); - return Ok(self.item(istry)?); + Ok(self.item(istry)?) } - } + }; } fn def_func(&mut self, istry: bool) -> AstError<()> { @@ -370,9 +357,9 @@ impl<'a> AstBuilder<'a> { } fn import_module(&mut self, istry: bool) -> AstError<()> { - let mut path = self.token_lexer.next_token()?; + let path = self.token_lexer.next_token()?; if path.tp != TokenType::StringValue { - return TryErr!( + return try_err!( istry, Box::new(self.token_lexer.compiler_data.content.clone()), ErrorInfo::new( @@ -405,23 +392,23 @@ impl<'a> AstBuilder<'a> { fn statement(&mut self) -> RunResult<()> { let t = self.token_lexer.next_token()?; match t.tp { - super::token::TokenType::Func => { + TokenType::Func => { self.def_func(false)?; } - super::token::TokenType::Class => { + TokenType::Class => { self.def_class(false)?; } - super::token::TokenType::While => { + TokenType::While => { self.while_lex(false)?; } - super::token::TokenType::For => { + TokenType::For => { self.for_lex(false)?; } - super::token::TokenType::ID => { + TokenType::ID => { let name = t.data.unwrap(); let tt = self.token_lexer.next_token()?; match tt.tp { - super::token::TokenType::Assign => { + TokenType::Assign => { let var = self.self_scope.as_ref().borrow().get_sym_idx(name); if let None = var { return Err(RuntimeError::new( @@ -437,11 +424,9 @@ impl<'a> AstBuilder<'a> { } self.expr(false)?; let var = var.unwrap(); - self.staticdata - .inst - .push(Inst::new(Opcode::StoreLocal, var)) + self.add_bycode(Opcode::StoreLocal, var) } - super::token::TokenType::Store => { + TokenType::Store => { if self.self_scope.as_ref().borrow().has_sym(name) { return Err(RuntimeError::new( Box::new(self.token_lexer.compiler_data.content.clone()), @@ -459,9 +444,7 @@ impl<'a> AstBuilder<'a> { self.staticdata.update_sym_table_sz( self.self_scope.as_ref().borrow().get_scope_last_idx(), ); - self.staticdata - .inst - .push(Inst::new(Opcode::StoreLocal, var_idx)) + self.add_bycode(Opcode::StoreLocal, var_idx) } _ => { self.token_lexer.next_back(tt); @@ -486,10 +469,10 @@ impl<'a> AstBuilder<'a> { pub fn generate_code(&mut self) -> RunResult<()> { loop { let token = self.token_lexer.next_token()?; - if token.tp == super::token::TokenType::EndOfLine { + if token.tp == TokenType::EndOfLine { continue; } - if token.tp == super::token::TokenType::EndOfFile { + if token.tp == TokenType::EndOfFile { break; } self.token_lexer.next_back(token); @@ -497,6 +480,16 @@ impl<'a> AstBuilder<'a> { } return Ok(()); } + + fn add_bycode(&mut self, opty: Opcode, opnum: usize) { + self.staticdata.inst.push(Inst::new(opty, opnum)); + if !self.token_lexer.compiler_data.option.optimize { + // 不生成行号表了 + self.staticdata + .line_table + .push(self.token_lexer.compiler_data.content.get_line()) + } + } } #[cfg(test)] @@ -638,7 +631,17 @@ mod tests { t.staticdata.inst, vec![ Inst::new(Opcode::LoadString, 0), - Inst::new(Opcode::CallNative, 0), + Inst::new( + Opcode::CallNative, + STDLIB_ROOT + .sub_modules + .get("prelude") + .unwrap() + .functions + .get("print") + .unwrap() + .buildin_id + ), ] ) } diff --git a/rust/src/compiler/scope.rs b/rust/src/compiler/scope.rs index ded8341c..a9d70e4d 100644 --- a/rust/src/compiler/scope.rs +++ b/rust/src/compiler/scope.rs @@ -229,17 +229,13 @@ impl SymScope { pub fn get_sym_idx(&self, id: usize) -> Option { let t = self.sym_map.get(&id); - match t { - None => { - return match self.prev_scope { - Some(ref prev_scope) => prev_scope.as_ref().borrow().get_sym_idx(id), - None => None, - } - } - Some(t) => { - return Some(*t); - } - } + return match t { + None => match self.prev_scope { + Some(ref prev_scope) => prev_scope.as_ref().borrow().get_sym_idx(id), + None => None, + }, + Some(t) => Some(*t), + }; } pub fn add_func(&mut self, id: usize, f: Box) { diff --git a/rust/src/compiler/token.rs b/rust/src/compiler/token.rs index 4b11374e..b697cced 100644 --- a/rust/src/compiler/token.rs +++ b/rust/src/compiler/token.rs @@ -279,7 +279,7 @@ enum NumValue { } impl TokenLex<'_> { - pub fn new<'a>(compiler_data: &'a mut Compiler) -> TokenLex<'a> { + pub fn new(compiler_data: &mut Compiler) -> TokenLex { TokenLex { compiler_data, braces_check: vec![], @@ -293,10 +293,7 @@ impl TokenLex<'_> { None => { return Err(RuntimeError::new( Box::new(self.compiler_data.content.clone()), - ErrorInfo::new( - gettext!(error::UNMATCHED_BRACE, c), - gettext(error::SYNTAX_ERROR), - ), + ErrorInfo::new(gettext!(error::UNMATCHED_BRACE, c), gettext(SYNTAX_ERROR)), )); } Some(cc) => { @@ -310,7 +307,7 @@ impl TokenLex<'_> { } } - fn lex_id(&mut self, c: char) -> error::RunResult { + fn lex_id(&mut self, c: char) -> RunResult { Ok({ let mut retname: String = String::from(c); loop { @@ -367,7 +364,7 @@ impl TokenLex<'_> { } } - fn lex_symbol(&mut self, c: char) -> error::RunResult { + fn lex_symbol(&mut self, c: char) -> RunResult { Ok(match c { '.' => Token::new(TokenType::Dot, None), ',' => Token::new(TokenType::Comma, None), @@ -572,7 +569,7 @@ impl TokenLex<'_> { fn lex_num(&mut self, mut c: char) -> RunResult { let tmp = self.lex_int_float(c)?; c = self.compiler_data.input.read(); - if c == 'e' || c == 'E' { + return if c == 'e' || c == 'E' { c = self.compiler_data.input.read(); let mut up_flag: i64 = 1; if c == '+' { @@ -590,10 +587,10 @@ impl TokenLex<'_> { for _ in 0..up { it *= 10; } - return Ok(Token::new( + Ok(Token::new( TokenType::IntValue, Some(self.compiler_data.const_pool.add_int(it)), - )); + )) } else { // 负数次,升级为float let mut float_part = String::new(); @@ -606,14 +603,14 @@ impl TokenLex<'_> { it /= 10; } } - return Ok(Token::new( + Ok(Token::new( TokenType::FloatValue, Some(self.compiler_data.const_pool.add_float(Float::new( it, float_part.parse().unwrap(), Self::cal_zero(&float_part), ))), - )); + )) } } NumValue::FloatVal(mut v) => { @@ -633,10 +630,10 @@ impl TokenLex<'_> { v.zero = Self::cal_zero(&s); v.back = s.parse().unwrap(); } - return Ok(Token::new( + Ok(Token::new( TokenType::FloatValue, Some(self.compiler_data.const_pool.add_float(v)), - )); + )) } else { up = -up; let mut s = String::new(); @@ -651,20 +648,20 @@ impl TokenLex<'_> { s += &v.back.to_string(); v.zero += Self::cal_zero(&s); v.back = s.parse().unwrap(); - return Ok(Token::new( + Ok(Token::new( TokenType::FloatValue, Some(self.compiler_data.const_pool.add_float(v)), - )); + )) } } } } else { self.compiler_data.input.unread(c); - return Ok(self.turn_to_token(tmp)); - } + Ok(self.turn_to_token(tmp)) + }; } - fn lex_str(&mut self, start_char: char) -> error::RunResult { + fn lex_str(&mut self, start_char: char) -> RunResult { let mut s = String::new(); let mut c = self.compiler_data.input.read(); while c != start_char { @@ -686,11 +683,11 @@ impl TokenLex<'_> { s.push(c); c = self.compiler_data.input.read(); if c == '\0' { - error::RuntimeError::new( + RuntimeError::new( Box::new(self.compiler_data.content.clone()), - error::ErrorInfo::new( + ErrorInfo::new( gettext!(error::STRING_WITHOUT_END, start_char), - gettext(error::SYNTAX_ERROR), + gettext(SYNTAX_ERROR), ), ); } @@ -701,7 +698,7 @@ impl TokenLex<'_> { )) } - pub fn next_token(&mut self) -> error::RunResult { + pub fn next_token(&mut self) -> RunResult { if !self.unget_token.is_empty() { let tmp = self.unget_token.pop().unwrap(); if tmp.tp == TokenType::EndOfLine { @@ -747,14 +744,14 @@ impl TokenLex<'_> { pub fn check(&mut self) -> Result<(), RuntimeError> { if !self.braces_check.is_empty() { let unmatch_char = self.braces_check.pop().unwrap(); - return Err(error::RuntimeError::new( + return Err(RuntimeError::new( Box::new(Content::new_line( &self.compiler_data.content.module_name, unmatch_char.line, )), ErrorInfo::new( gettext!(error::UNMATCHED_BRACE, unmatch_char.c), - gettext(error::SYNTAX_ERROR), + gettext(SYNTAX_ERROR), ), )); } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index cb66488d..482f6fe6 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -43,10 +43,10 @@ pub fn run() -> Result<(), Box> { match cli.mode { Commands::Build { optimize: opt, - files: files, + files, } => { for i in files { - tools::compile(compiler::Option::new(false, compiler::InputSource::File(i))); + tools::compile(compiler::Option::new(opt, compiler::InputSource::File(i))); } } Commands::Tshell {} => { @@ -60,11 +60,10 @@ pub fn run() -> Result<(), Box> { }, Commands::Run { optimize: opt, - files: files, + files, } => { for i in files { - match tools::run::run(compiler::Option::new(false, compiler::InputSource::File(i))) - { + match tools::run::run(compiler::Option::new(opt, compiler::InputSource::File(i))) { Ok(_) => {} Err(c) => { eprintln!("{}", c); diff --git a/rust/src/tools/update.rs b/rust/src/tools/update.rs index 508cce7f..ca5c9f1a 100644 --- a/rust/src/tools/update.rs +++ b/rust/src/tools/update.rs @@ -1,6 +1,5 @@ -use crate::cfg; use gettextrs::gettext; -use std::{collections::HashMap, error::Error, fmt::Display}; +use std::{error::Error, fmt::Display}; static GITHUB_API_URL: &str = "http://185.106.176.199/trc_version"; diff --git a/rust/src/tvm.rs b/rust/src/tvm.rs index 6b2672c6..de6719f5 100644 --- a/rust/src/tvm.rs +++ b/rust/src/tvm.rs @@ -58,12 +58,8 @@ impl Content { } } - fn add_line(&mut self) { - self.line_pos += 1; - } - - fn del_line(&mut self) { - self.line_pos -= 1; + fn set_line(&mut self, newline: usize) { + self.line_pos = newline; } } @@ -86,7 +82,7 @@ impl<'a> Vm<'a> { pc: 0, dynadata: DynaData::new(), run_contnet: Content::new(cfg::MAIN_MODULE_NAME), - static_data: StaticData::new(), + static_data: StaticData::new(false), } } @@ -105,6 +101,10 @@ impl<'a> Vm<'a> { pub fn run(&mut self) -> Result<(), RuntimeError> { while self.pc < self.static_data.inst.len() { + if self.static_data.has_line_table { + self.run_contnet + .set_line(self.static_data.line_table[self.pc]); + } match self.static_data.inst[self.pc].opcode { codegen::Opcode::Add => operator_opcode!(add, self), codegen::Opcode::Sub => operator_opcode!(sub, self), diff --git a/rust/src/tvm/algo/string.rs b/rust/src/tvm/algo/string.rs index f6bf81f2..352757dd 100644 --- a/rust/src/tvm/algo/string.rs +++ b/rust/src/tvm/algo/string.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; pub fn kmp(main_string: &str, pattern: &str) -> usize { // 首先对模式串构建next数组 @@ -9,14 +9,14 @@ pub fn kmp(main_string: &str, pattern: &str) -> usize { let mut ans = 0; for i in main_string.chars() { while j != -1 && pattern[(j + 1) as usize] != i { - j = next_arr[j as usize] as i64; + j = next_arr[j as usize]; } if pattern[(j + 1) as usize] == i { j += 1; } if j as usize == pattern.len() - 1 { ans += 1; - j = next_arr[j as usize] as i64; + j = next_arr[j as usize]; } } ans @@ -29,7 +29,7 @@ pub fn kmp_next(pattern: &str) -> Vec { // 从1开始匹配是因为第零个不需要匹配 for i in 1..pattern.len() { while j != -1 && pattern[(j + 1) as usize] != pattern[i] { - j = ret[j as usize] as i64; + j = ret[j as usize]; } if pattern[(j + 1) as usize] == pattern[i] { j += 1; @@ -41,18 +41,24 @@ pub fn kmp_next(pattern: &str) -> Vec { pub fn sa(s: &str) -> Vec { let mut sa: Vec = Vec::new(); - let mut t: HashMap = HashMap::new(); + let mut cntt: BTreeMap = BTreeMap::new(); + let mut rk: HashMap = HashMap::new(); + let mut cnt = 1; for i in s.chars() { - let tmp = t.entry(i).or_insert(0); + rk.insert(i, cnt); + cnt += 1; + let tmp = cntt.entry(i).or_insert(0); *tmp += 1; } - for i in &t { + + cnt = 1; + for i in &cntt { sa.push(*i.0 as usize); } let mut rk: Vec = Vec::new(); rk.resize(sa.len(), 0); for i in &sa { - let _tmp = t.entry(char::from_u32(*i as u32).unwrap()); + let _tmp = cntt.entry(char::from_u32(*i as u32).unwrap()); // rk[] } sa diff --git a/rust/src/tvm/stdlib.rs b/rust/src/tvm/stdlib.rs index ee6086c5..4428fdab 100644 --- a/rust/src/tvm/stdlib.rs +++ b/rust/src/tvm/stdlib.rs @@ -1,6 +1,7 @@ use crate::base::stdlib::Stdlib; use derive::def_module; +pub mod ds; pub mod prelude; -def_module!(module_name = std, submodules = [prelude]); +def_module!(module_name = std, submodules = [prelude, ds]); diff --git a/rust/src/tvm/stdlib/ds.rs b/rust/src/tvm/stdlib/ds.rs new file mode 100644 index 00000000..003f517a --- /dev/null +++ b/rust/src/tvm/stdlib/ds.rs @@ -0,0 +1,5 @@ +use super::super::types::data_structure::sam::Sam; +use crate::tvm::stdlib::Stdlib; +use derive::def_module; + +def_module!(module_name=ds, classes=[Sam => sam]); diff --git a/rust/src/tvm/stdlib/prelude.rs b/rust/src/tvm/stdlib/prelude.rs index 8c28c1b5..fd09db9c 100644 --- a/rust/src/tvm/stdlib/prelude.rs +++ b/rust/src/tvm/stdlib/prelude.rs @@ -1,3 +1,4 @@ +use super::super::types::*; use crate::base::stdlib::*; use crate::{base::error::*, tvm::DynaData}; use derive::{def_module, trc_function}; @@ -13,5 +14,9 @@ pub fn println(obj: any) -> void { } def_module!(module_name = prelude, functions = [print => print, println => print], classes = [ - Trcint => int + TrcInt => int, + TrcStr => str, + TrcBool => bool, + TrcFloat => float, + TrcChar => char ]); diff --git a/rust/src/tvm/types.rs b/rust/src/tvm/types.rs index 312a2cf3..fda2be7a 100644 --- a/rust/src/tvm/types.rs +++ b/rust/src/tvm/types.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use crate::base::error::*; use crate::tvm::DynaData; use downcast_rs::{impl_downcast, Downcast}; @@ -6,10 +8,17 @@ use gettextrs::gettext; pub mod data_structure; pub mod trcbigint; pub mod trcbool; +pub mod trcchar; pub mod trcfloat; pub mod trcint; pub mod trcstr; +pub use trcbool::TrcBool; +pub use trcchar::TrcChar; +pub use trcfloat::TrcFloat; +pub use trcint::TrcInt; +pub use trcstr::TrcStr; + /// help to generate the same error reporter functions macro_rules! batch_unsupported_operators { ($($traie_name:ident => $oper_name:expr),*) => { @@ -105,7 +114,7 @@ macro_rules! gen_interface { }; } -pub trait TrcObj: Downcast + std::fmt::Display { +pub trait TrcObj: Downcast + std::fmt::Display + Debug { batch_unsupported_operators!( sub => "-", mul => "*", diff --git a/rust/src/tvm/types/data_structure.rs b/rust/src/tvm/types/data_structure.rs index d830f380..a26668da 100644 --- a/rust/src/tvm/types/data_structure.rs +++ b/rust/src/tvm/types/data_structure.rs @@ -1,18 +1,18 @@ -mod ac; -mod deque; -mod fenwick; -mod forward_list; -mod hash_map; -mod heap; -mod list; -mod map; -mod priority_queue; -mod queue; -mod sam; -mod set; -mod splay; -mod st; -mod stack; -mod trie; -mod union; -mod vec; +pub mod ac; +pub mod deque; +pub mod fenwick; +pub mod forward_list; +pub mod hash_map; +pub mod heap; +pub mod list; +pub mod map; +pub mod priority_queue; +pub mod queue; +pub mod sam; +pub mod set; +pub mod splay; +pub mod st; +pub mod stack; +pub mod trie; +pub mod union; +pub mod vec; diff --git a/rust/src/tvm/types/data_structure/sam.rs b/rust/src/tvm/types/data_structure/sam.rs index a4266025..617a4c0b 100644 --- a/rust/src/tvm/types/data_structure/sam.rs +++ b/rust/src/tvm/types/data_structure/sam.rs @@ -1,5 +1,14 @@ +use crate::base::error::*; +use crate::base::stdlib::RustFunction; +use crate::tvm::types::trcchar::TrcChar; +use crate::tvm::types::TrcObj; +use crate::tvm::DynaData; +use crate::{base::stdlib::IOType, compiler::token::TokenType, hash_map}; +use derive::{trc_class, trc_function, trc_method}; use std::collections::HashMap; +use std::fmt::Display; +#[derive(Debug)] pub struct Node { link: Option, next: HashMap, @@ -16,28 +25,41 @@ impl Node { } } +#[trc_class] +#[derive(Debug)] pub struct Sam { - states: Vec, + pub _states: Vec, } impl Sam { + fn override_export() -> HashMap { + hash_map![] + } + pub fn new() -> Sam { Sam { - states: vec![Node::new(0)], + _states: vec![Node::new(0)], } } +} - pub fn extend(&mut self, c: char) { - let id: usize = self.states.len(); +#[trc_method] +impl Sam { + #[trc_function(true)] + pub fn extend(s: Sam, c: TrcChar) { + let id: usize = s._states.len(); + // 后缀自动机最后一个节点 let mut last = id - 1; - let mut u = Node::new(self.states[last].len + 1); + // 新节点,创造是因为包括最后一个字符串之后一定生成了一个新的等价类,也就是整个字符串,而它的长度一定等于上一个节点的长度加一 + let mut u = Node::new(s._states[last].len + 1); + loop { - if !self.states[last].next.contains_key(&c) { - self.states[last].next.insert(c, id); + if !s._states[last].next.contains_key(&c._value) { + s._states[last].next.insert(c._value, id); } else { break; } - match self.states[last].link { + match s._states[last].link { None => { break; } @@ -46,21 +68,21 @@ impl Sam { } } } - if let None = self.states[last].link { + if let None = s._states[last].link { u.link = Some(0); - self.states.push(u); + s._states.push(u); } else { - let q = self.states[last].next[&c]; - if self.states[q].len == self.states[last].len + 1 { + let q = s._states[last].next[&c._value]; + if s._states[q].len == s._states[last].len + 1 { u.link = Some(q); - self.states.push(u); + s._states.push(u); } else { - let mut clone = Node::new(self.states[last].len + 1); - clone.next = self.states[q].next.clone(); - clone.link = self.states[q].link; + let mut clone = Node::new(s._states[last].len + 1); + clone.next = s._states[q].next.clone(); + clone.link = s._states[q].link; let cloneid = id + 1; loop { - if let Some(tmp) = self.states[last].next.get_mut(&c) { + if let Some(tmp) = s._states[last].next.get_mut(&c._value) { if *tmp != q { break; } @@ -68,7 +90,7 @@ impl Sam { } else { break; } - match self.states[last].link { + match s._states[last].link { None => { break; } @@ -77,15 +99,27 @@ impl Sam { } } } - self.states[q].link = Some(cloneid); + s._states[q].link = Some(cloneid); u.link = Some(cloneid); - self.states.push(u); - self.states.push(clone); + s._states.push(u); + s._states.push(clone); } } } } +impl TrcObj for Sam { + fn get_type_name(&self) -> &str { + "sam" + } +} + +impl Display for Sam { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self._states) + } +} + #[cfg(test)] mod tests { use super::*; @@ -94,8 +128,8 @@ mod tests { let mut sam = Sam::new(); let str1 = "jdoasjdbasdhasjhdsjashdjsahshdhajdhsajkhdajshdsjadsjgfajshdasjfgjashdasjkdhudhwuidhsahsjkdhjadzxbjxbcnnxmbfdhbgsdahjkshdjbasjvahfghghgasjkdhasjdbdkhvfadhvfahdasjkhdasjkgdasjkbjkbchkdfgjhkasdghasjkdhasjdbfasjkgaskjdhadkjfgashk"; for c in str1.chars() { - sam.extend(c); + // sam.extend(c); } - assert_eq!(sam.states.len(), 334); + assert_eq!(sam._states.len(), 334); } } diff --git a/rust/src/tvm/types/trcbool.rs b/rust/src/tvm/types/trcbool.rs index d38e4495..917e85aa 100644 --- a/rust/src/tvm/types/trcbool.rs +++ b/rust/src/tvm/types/trcbool.rs @@ -10,6 +10,7 @@ use std::collections::hash_map::HashMap; use std::fmt::Display; #[trc_class] +#[derive(Debug)] pub struct TrcBool { _value: bool, } @@ -20,10 +21,10 @@ impl TrcObj for TrcBool { "bool" } - impl_single_oper!(not, !, "not", TrcBool, TrcBool); + impl_single_oper!(not, !, "!", TrcBool, TrcBool); batch_impl_opers!( - and => &&, "and", TrcBool, TrcBool, - or => ||, "or", TrcBool, TrcBool + and => &&, "&&", TrcBool, TrcBool, + or => ||, "||", TrcBool, TrcBool ); } diff --git a/rust/src/tvm/types/trcchar.rs b/rust/src/tvm/types/trcchar.rs new file mode 100644 index 00000000..41ec1c10 --- /dev/null +++ b/rust/src/tvm/types/trcchar.rs @@ -0,0 +1,36 @@ +use super::TrcObj; +use crate::base::stdlib::*; +use crate::compiler::token::TokenType; +use crate::hash_map; +use derive::{trc_class, trc_method}; +use std::collections::hash_map::HashMap; +use std::fmt::Display; + +#[trc_class] +#[derive(Debug)] +pub struct TrcChar { + pub _value: char, +} + +#[trc_method] +impl TrcObj for TrcChar { + fn get_type_name(&self) -> &str { + "char" + } +} + +impl Display for TrcChar { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self._value) + } +} + +impl TrcChar { + pub fn new(value: char) -> TrcChar { + Self { _value: value } + } + + fn override_export() -> HashMap { + hash_map![] + } +} diff --git a/rust/src/tvm/types/trcfloat.rs b/rust/src/tvm/types/trcfloat.rs index e439113e..03f47c51 100644 --- a/rust/src/tvm/types/trcfloat.rs +++ b/rust/src/tvm/types/trcfloat.rs @@ -12,6 +12,7 @@ use std::collections::hash_map::HashMap; use std::fmt::Display; #[trc_class] +#[derive(Debug)] pub struct TrcFloat { _value: f64, } diff --git a/rust/src/tvm/types/trcint.rs b/rust/src/tvm/types/trcint.rs index 62ae946b..b0b54b55 100644 --- a/rust/src/tvm/types/trcint.rs +++ b/rust/src/tvm/types/trcint.rs @@ -12,6 +12,7 @@ use std::collections::hash_map::HashMap; use std::fmt::Display; #[trc_class] +#[derive(Debug)] pub struct TrcInt { _value: i64, } diff --git a/rust/src/tvm/types/trcstr.rs b/rust/src/tvm/types/trcstr.rs index 4ee78804..5fffee87 100644 --- a/rust/src/tvm/types/trcstr.rs +++ b/rust/src/tvm/types/trcstr.rs @@ -2,14 +2,14 @@ use super::TrcObj; use crate::base::stdlib::*; use crate::compiler::token::TokenType; use crate::hash_map; -use crate::tvm::DynaData; use crate::{base::error::*, batch_impl_opers, impl_oper}; -use derive::{trc_class, trc_function, trc_method}; +use derive::{trc_class, trc_method}; use gettextrs::gettext; use std::collections::hash_map::HashMap; use std::fmt::Display; #[trc_class] +#[derive(Debug)] pub struct TrcStr { _value: String, }