Refactoring
This commit is contained in:
parent
6d2f7e729a
commit
9b8b90eb63
@ -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()
|
|
||||||
}
|
|
||||||
|
@ -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]})
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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!()),
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
//}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user