Refactoring

This commit is contained in:
dalance 2019-07-17 12:14:21 +09:00
parent 6d2f7e729a
commit 9b8b90eb63
3 changed files with 47 additions and 125 deletions

View File

@ -126,22 +126,22 @@ fn impl_trace(item: &syn::ItemFn) -> TokenStream {
let tracer = quote! { let tracer = quote! {
if cfg!(feature = "trace") { 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: TokenStream = tracer.into();
let tracer = parse_macro_input!(tracer as syn::Stmt); let tracer = parse_macro_input!(tracer as syn::Stmt);
let checker = quote! { let checker = quote! {
if thread_context::TABLE.with(|t| { if thread_context::PARSER_INDEX.with(|p| {
if let Some(i) = t.borrow_mut().get_or_allocate(stringify!(#ident)) { if let Some(i) = p.borrow_mut().get(stringify!(#ident)) {
return check_bit(s, i); return check_bit(s, i);
} else { } else {
return false return false
} }
}) { }) {
if cfg!(feature = "trace") { 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))); 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 checker = parse_macro_input!(checker as syn::Stmt);
let before = quote! { let before = quote! {
let s = thread_context::TABLE.with(|t| { let s = thread_context::PARSER_INDEX.with(|p| {
if let Some(i) = t.borrow_mut().get_or_allocate(stringify!(#ident)) { if let Some(i) = p.borrow_mut().get(stringify!(#ident)) {
//println!("{}:{} set", stringify!(#ident), i);
set_bit(s, i, true) set_bit(s, i, true)
} else { } else {
if cfg!(feature = "trace") { if cfg!(feature = "trace") {
println!("{:<48} : allocate failed", stringify!(#ident)); println!("{:<64} : allocate failed", stringify!(#ident));
} }
s s
} }
@ -197,35 +196,3 @@ fn impl_trace(item: &syn::ItemFn) -> TokenStream {
}; };
gen.into() 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()
}

View File

@ -21,48 +21,30 @@ pub use source_text::*;
pub use specify_section::*; pub use specify_section::*;
pub use udp_declaration_and_instantiation::*; pub use udp_declaration_and_instantiation::*;
pub type Span<'a> = nom_locate::LocatedSpanEx<&'a str, u128>; pub type Span<'a> = nom_locate::LocatedSpanEx<&'a str, [u128; 10]>;
// IDs for left recursion detection
//static REC_PRIMARY: u32 = 0;
mod thread_context { mod thread_context {
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
thread_local!( pub struct ParserIndex {
pub static MAP_MUT: RefCell<HashMap<(&'static str, &'static str, u32, u32), usize>> = {
RefCell::new(HashMap::new())
}
);
#[derive(Debug)]
pub struct Table {
index: HashMap<&'static str, u32>, index: HashMap<&'static str, u32>,
offset: HashMap<&'static str, usize>, allocated: [u128; 10],
allocated: u128,
} }
impl Table { impl ParserIndex {
pub fn get(&self, key: &'static str) -> Option<u32> { pub fn get(&mut self, key: &'static str) -> Option<u32> {
if let Some(x) = self.index.get(key) { if let Some(x) = self.index.get(key) {
Some(*x) Some(*x)
} else { } else {
None for i in 0..1280u32 {
} let upper = (i / 128) as usize;
} let lower = i % 128;
if ((self.allocated[upper] >> lower) & 1) == 0 {
pub fn get_or_allocate(&mut self, key: &'static str) -> Option<u32> { let val = 1u128 << lower;
if let Some(x) = self.index.get(key) { let mask = !(1u128 << lower);
Some(*x) self.allocated[upper] = (self.allocated[upper] & mask) | val;
} 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;
self.index.insert(key, i); self.index.insert(key, i);
return Some(i); return Some(i);
} }
@ -70,19 +52,11 @@ mod thread_context {
None 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!( thread_local!(
pub static TABLE: RefCell<Table> = { pub static PARSER_INDEX: RefCell<ParserIndex> = {
RefCell::new(Table{index: HashMap::new(), offset: HashMap::new(), allocated: 0}) RefCell::new(ParserIndex{index: HashMap::new(), allocated: [0;10]})
} }
); );
} }

View File

@ -4,9 +4,8 @@ use nom::branch::*;
use nom::bytes::complete::*; use nom::bytes::complete::*;
use nom::character::complete::*; use nom::character::complete::*;
use nom::combinator::*; use nom::combinator::*;
use nom::error::*;
use nom::multi::*; 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<Span<'a>, Symbol<'
move |s: Span<'a>| { move |s: Span<'a>| {
if cfg!(feature = "trace") { if cfg!(feature = "trace") {
println!( println!(
"{:<48} : {:<4},{:>032x} : {}", "{:<64} : {:<4},{:>032x} : {}",
format!("symbol(\"{}\")", t), format!("symbol(\"{}\")", t),
s.offset, s.offset,
s.extra, s.extra[0],
s.fragment s.fragment
); );
} }
@ -82,8 +81,8 @@ where
move |s: Span<'a>| { move |s: Span<'a>| {
if cfg!(feature = "trace") { if cfg!(feature = "trace") {
println!( println!(
"{:<48} : {:<4},{:>032x} : {}", "{:<64} : {:<4},{:>032x} : {}",
"paren", s.offset, s.extra, s.fragment "paren", s.offset, s.extra[0], s.fragment
); );
} }
let (s, a) = symbol("(")(s)?; let (s, a) = symbol("(")(s)?;
@ -100,8 +99,8 @@ where
move |s: Span<'a>| { move |s: Span<'a>| {
if cfg!(feature = "trace") { if cfg!(feature = "trace") {
println!( println!(
"{:<48} : {:<4},{:>032x} : {}", "{:<64} : {:<4},{:>032x} : {}",
"bracket", s.offset, s.extra, s.fragment "bracket", s.offset, s.extra[0], s.fragment
); );
} }
let (s, a) = symbol("[")(s)?; let (s, a) = symbol("[")(s)?;
@ -118,8 +117,8 @@ where
move |s: Span<'a>| { move |s: Span<'a>| {
if cfg!(feature = "trace") { if cfg!(feature = "trace") {
println!( println!(
"{:<48} : {:<4},{:>032x} : {}", "{:<64} : {:<4},{:>032x} : {}",
"brace", s.offset, s.extra, s.fragment "brace", s.offset, s.extra[0], s.fragment
); );
} }
let (s, a) = symbol("{")(s)?; let (s, a) = symbol("{")(s)?;
@ -138,8 +137,8 @@ where
move |s: Span<'a>| { move |s: Span<'a>| {
if cfg!(feature = "trace") { if cfg!(feature = "trace") {
println!( println!(
"{:<48} : {:<4},{:>032x} : {}", "{:<64} : {:<4},{:>032x} : {}",
"apostrophe_brace", s.offset, s.extra, s.fragment "apostrophe_brace", s.offset, s.extra[0], s.fragment
); );
} }
let (s, a) = symbol("'{")(s)?; 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<Span<'a>, O>
//where
// F: Fn(Span<'a>) -> IResult<Span<'a>, 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>( pub fn triple<'a, O1, O2, O3, F, G, H>(
f: F, f: F,
g: G, g: G,
@ -231,18 +215,26 @@ pub fn concat<'a>(a: Span<'a>, b: Span<'a>) -> Option<Span<'a>> {
} }
pub fn check_bit(s: Span, id: u32) -> bool { 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 { pub fn set_bit(s: Span, id: u32, bit: bool) -> Span {
let val = if bit { 1u128 << id } else { 0u128 }; let upper = (id / 128) as usize;
let mask = !(1u128 << id); let lower = id % 128;
let val = (s.extra & mask) | val;
let val = if bit { 1u128 << lower } else { 0u128 };
let mask = !(1u128 << lower);
let mut extra = s.extra;
extra[upper] = (extra[upper] & mask) | val;
Span { Span {
offset: s.offset, offset: s.offset,
line: s.line, line: s.line,
fragment: s.fragment, fragment: s.fragment,
extra: val, extra,
} }
} }
@ -251,7 +243,7 @@ pub fn clear_bit(s: Span) -> Span {
offset: s.offset, offset: s.offset,
line: s.line, line: s.line,
fragment: s.fragment, fragment: s.fragment,
extra: 0, extra: [0; 10],
} }
} }
@ -260,21 +252,10 @@ pub fn clear_bit(s: Span) -> Span {
#[cfg(test)] #[cfg(test)]
macro_rules! parser_test { macro_rules! parser_test {
( $x:expr, $y:expr, $z:pat ) => { ( $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 { if let $z = ret {
} else { } else {
assert!(false, "{:?}", ret) assert!(false, "{:?}", ret)
} }
}; };
} }
//macro_rules! s {
// ( $x:expr ) => {
// Span {
// offset: $x.offset,
// line: $x.line,
// fragment: $x.fragment,
// extra: (file!(), line!(), column!()),
// }
// };
//}