diff --git a/node_derive/src/lib.rs b/node_derive/src/lib.rs index 34ce38b..69378c9 100644 --- a/node_derive/src/lib.rs +++ b/node_derive/src/lib.rs @@ -126,22 +126,22 @@ fn impl_trace(item: &syn::ItemFn) -> TokenStream { let tracer = quote! { if cfg!(feature = "trace") { - println!("{:<48} : {:<4},{:>032x} : {}", stringify!(#ident), s.offset, s.extra, s.fragment); + println!("{:<64} : {:<4},{:>032x} : {}", stringify!(#ident), s.offset, s.extra[0], s.fragment); } }; let tracer: TokenStream = tracer.into(); let tracer = parse_macro_input!(tracer as syn::Stmt); let checker = quote! { - if thread_context::TABLE.with(|t| { - if let Some(i) = t.borrow_mut().get_or_allocate(stringify!(#ident)) { + if thread_context::PARSER_INDEX.with(|p| { + if let Some(i) = p.borrow_mut().get(stringify!(#ident)) { return check_bit(s, i); } else { return false } }) { if cfg!(feature = "trace") { - println!("{:<48} : loop detect", stringify!(#ident)); + println!("{:<64} : loop detect", stringify!(#ident)); } return Err(nom::Err::Error(nom::error::make_error(s, nom::error::ErrorKind::Fix))); } @@ -150,13 +150,12 @@ fn impl_trace(item: &syn::ItemFn) -> TokenStream { let checker = parse_macro_input!(checker as syn::Stmt); let before = quote! { - let s = thread_context::TABLE.with(|t| { - if let Some(i) = t.borrow_mut().get_or_allocate(stringify!(#ident)) { - //println!("{}:{} set", stringify!(#ident), i); + let s = thread_context::PARSER_INDEX.with(|p| { + if let Some(i) = p.borrow_mut().get(stringify!(#ident)) { set_bit(s, i, true) } else { if cfg!(feature = "trace") { - println!("{:<48} : allocate failed", stringify!(#ident)); + println!("{:<64} : allocate failed", stringify!(#ident)); } s } @@ -197,35 +196,3 @@ fn impl_trace(item: &syn::ItemFn) -> TokenStream { }; gen.into() } - -#[proc_macro_attribute] -pub fn rec(_attr: TokenStream, item: TokenStream) -> TokenStream { - let item = parse_macro_input!(item as ItemFn); - impl_rec(&item) -} - -fn impl_rec(item: &syn::ItemFn) -> TokenStream { - let ident = &item.ident; - let mut item = item.clone(); - let tracer = quote! { - if thread_context::MAP_MUT.with(|m| { - if let Some(x) = m.borrow().get(stringify!(#ident)) { - if *x == s.offset { - return true; - } - } - m.borrow_mut().insert(stringify!(#ident), s.offset); - false - }) { - return Err(nom::Err::Error(nom::error::make_error(s, nom::error::ErrorKind::Fix))); - } - }; - let tracer: TokenStream = tracer.into(); - let tracer = parse_macro_input!(tracer as syn::Stmt); - item.block.stmts.insert(0, tracer); - - let gen = quote! { - #item - }; - gen.into() -} diff --git a/src/parser.rs b/src/parser.rs index 51ef869..b5a8454 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -21,48 +21,30 @@ pub use source_text::*; pub use specify_section::*; pub use udp_declaration_and_instantiation::*; -pub type Span<'a> = nom_locate::LocatedSpanEx<&'a str, u128>; - -// IDs for left recursion detection -//static REC_PRIMARY: u32 = 0; +pub type Span<'a> = nom_locate::LocatedSpanEx<&'a str, [u128; 10]>; mod thread_context { use std::cell::RefCell; use std::collections::HashMap; - thread_local!( - pub static MAP_MUT: RefCell> = { - RefCell::new(HashMap::new()) - } - ); - - #[derive(Debug)] - pub struct Table { + pub struct ParserIndex { index: HashMap<&'static str, u32>, - offset: HashMap<&'static str, usize>, - allocated: u128, + allocated: [u128; 10], } - impl Table { - pub fn get(&self, key: &'static str) -> Option { + impl ParserIndex { + pub fn get(&mut self, key: &'static str) -> Option { if let Some(x) = self.index.get(key) { Some(*x) } else { - None - } - } - - pub fn get_or_allocate(&mut self, key: &'static str) -> Option { - if let Some(x) = self.index.get(key) { - Some(*x) - } else { - let allocated = self.allocated; - for i in 0..128 { - if ((allocated >> i) & 1) == 0 { - let val = 1u128 << i; - let mask = !(1u128 << i); - self.allocated = (allocated & mask) | val; + for i in 0..1280u32 { + let upper = (i / 128) as usize; + let lower = i % 128; + if ((self.allocated[upper] >> lower) & 1) == 0 { + let val = 1u128 << lower; + let mask = !(1u128 << lower); + self.allocated[upper] = (self.allocated[upper] & mask) | val; self.index.insert(key, i); return Some(i); } @@ -70,19 +52,11 @@ mod thread_context { None } } - - pub fn release(&mut self, key: &'static str) { - if let Some(x) = self.index.get(key) { - let mask = !(1u128 << *x); - self.allocated = self.allocated & mask; - self.index.remove(key); - } - } } thread_local!( - pub static TABLE: RefCell = { - RefCell::new(Table{index: HashMap::new(), offset: HashMap::new(), allocated: 0}) + pub static PARSER_INDEX: RefCell = { + RefCell::new(ParserIndex{index: HashMap::new(), allocated: [0;10]}) } ); } diff --git a/src/parser/utils.rs b/src/parser/utils.rs index 6c8a7b2..e10eca1 100644 --- a/src/parser/utils.rs +++ b/src/parser/utils.rs @@ -4,9 +4,8 @@ use nom::branch::*; use nom::bytes::complete::*; use nom::character::complete::*; use nom::combinator::*; -use nom::error::*; use nom::multi::*; -use nom::{Err, IResult}; +use nom::IResult; // ----------------------------------------------------------------------------- @@ -63,10 +62,10 @@ pub fn symbol<'a>(t: &'a str) -> impl Fn(Span<'a>) -> IResult, Symbol<' move |s: Span<'a>| { if cfg!(feature = "trace") { println!( - "{:<48} : {:<4},{:>032x} : {}", + "{:<64} : {:<4},{:>032x} : {}", format!("symbol(\"{}\")", t), s.offset, - s.extra, + s.extra[0], s.fragment ); } @@ -82,8 +81,8 @@ where move |s: Span<'a>| { if cfg!(feature = "trace") { println!( - "{:<48} : {:<4},{:>032x} : {}", - "paren", s.offset, s.extra, s.fragment + "{:<64} : {:<4},{:>032x} : {}", + "paren", s.offset, s.extra[0], s.fragment ); } let (s, a) = symbol("(")(s)?; @@ -100,8 +99,8 @@ where move |s: Span<'a>| { if cfg!(feature = "trace") { println!( - "{:<48} : {:<4},{:>032x} : {}", - "bracket", s.offset, s.extra, s.fragment + "{:<64} : {:<4},{:>032x} : {}", + "bracket", s.offset, s.extra[0], s.fragment ); } let (s, a) = symbol("[")(s)?; @@ -118,8 +117,8 @@ where move |s: Span<'a>| { if cfg!(feature = "trace") { println!( - "{:<48} : {:<4},{:>032x} : {}", - "brace", s.offset, s.extra, s.fragment + "{:<64} : {:<4},{:>032x} : {}", + "brace", s.offset, s.extra[0], s.fragment ); } let (s, a) = symbol("{")(s)?; @@ -138,8 +137,8 @@ where move |s: Span<'a>| { if cfg!(feature = "trace") { println!( - "{:<48} : {:<4},{:>032x} : {}", - "apostrophe_brace", s.offset, s.extra, s.fragment + "{:<64} : {:<4},{:>032x} : {}", + "apostrophe_brace", s.offset, s.extra[0], s.fragment ); } let (s, a) = symbol("'{")(s)?; @@ -171,21 +170,6 @@ where } } -//pub fn rec<'a, O, F>(f: F, id: u32) -> impl Fn(Span<'a>) -> IResult, O> -//where -// F: Fn(Span<'a>) -> IResult, O>, -//{ -// move |s: Span<'a>| { -// if check_bit(s, id) { -// return Err(Err::Error(make_error(s, ErrorKind::Fix))); -// } -// let s = set_bit(s, id, true); -// let (s, x) = f(s)?; -// let s = set_bit(s, id, false); -// Ok((s, x)) -// } -//} - pub fn triple<'a, O1, O2, O3, F, G, H>( f: F, g: G, @@ -231,18 +215,26 @@ pub fn concat<'a>(a: Span<'a>, b: Span<'a>) -> Option> { } pub fn check_bit(s: Span, id: u32) -> bool { - ((s.extra >> id) & 1) == 1 + let upper = (id / 128) as usize; + let lower = id % 128; + + ((s.extra[upper] >> lower) & 1) == 1 } pub fn set_bit(s: Span, id: u32, bit: bool) -> Span { - let val = if bit { 1u128 << id } else { 0u128 }; - let mask = !(1u128 << id); - let val = (s.extra & mask) | val; + let upper = (id / 128) as usize; + let lower = id % 128; + + let val = if bit { 1u128 << lower } else { 0u128 }; + let mask = !(1u128 << lower); + + let mut extra = s.extra; + extra[upper] = (extra[upper] & mask) | val; Span { offset: s.offset, line: s.line, fragment: s.fragment, - extra: val, + extra, } } @@ -251,7 +243,7 @@ pub fn clear_bit(s: Span) -> Span { offset: s.offset, line: s.line, fragment: s.fragment, - extra: 0, + extra: [0; 10], } } @@ -260,21 +252,10 @@ pub fn clear_bit(s: Span) -> Span { #[cfg(test)] macro_rules! parser_test { ( $x:expr, $y:expr, $z:pat ) => { - let ret = all_consuming($x)(Span::new_extra($y, 0)); + let ret = all_consuming($x)(Span::new_extra($y, [0; 10])); if let $z = ret { } else { assert!(false, "{:?}", ret) } }; } - -//macro_rules! s { -// ( $x:expr ) => { -// Span { -// offset: $x.offset, -// line: $x.line, -// fragment: $x.fragment, -// extra: (file!(), line!(), column!()), -// } -// }; -//}