diff --git a/sv-parser-macros/src/lib.rs b/sv-parser-macros/src/lib.rs index d73dafe..263f86c 100644 --- a/sv-parser-macros/src/lib.rs +++ b/sv-parser-macros/src/lib.rs @@ -92,10 +92,13 @@ fn impl_any_node(ast: &DeriveInput) -> TokenStream { _ => unreachable!(), }; - let mut items = quote! {}; + let mut try_froms = quote! {}; + let mut from_items = quote! {}; for v in &data.variants { let ident = &v.ident; - let item = quote! { + + try_froms = quote! { + #try_froms impl TryFrom for #ident { type Error = (); fn try_from(x: AnyNode) -> Result { @@ -106,14 +109,23 @@ fn impl_any_node(ast: &DeriveInput) -> TokenStream { } } }; - items = quote! { - #items - #item + + from_items = quote! { + #from_items + AnyNode::#ident(x) => RefNode::#ident(&x), }; } let gen = quote! { - #items + #try_froms + + impl<'a> From<&'a AnyNode> for RefNode<'a> { + fn from(x: &'a AnyNode) -> Self { + match x { + #from_items + } + } + } }; gen.into() } @@ -130,15 +142,17 @@ fn impl_ref_node(ast: &DeriveInput) -> TokenStream { _ => unreachable!(), }; - let mut items = quote! {}; + let mut next_items = quote! {}; + let mut into_iter_items = quote! {}; for v in &data.variants { let ident = &v.ident; - let item = quote! { + next_items = quote! { + #next_items RefNode::#ident(x) => x.next(), }; - items = quote! { - #items - #item + into_iter_items = quote! { + #into_iter_items + RefNode::#ident(x) => x.into_iter(), }; } @@ -147,7 +161,18 @@ fn impl_ref_node(ast: &DeriveInput) -> TokenStream { impl<'a> #name<'a> { fn next(&self) -> RefNodes<'a> { match self { - #items + #next_items + } + } + } + + impl<'a> IntoIterator for #name<'a> { + type Item = RefNode<'a>; + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Self::IntoIter { + match self { + #into_iter_items } } } diff --git a/sv-parser-parser/src/lib.rs b/sv-parser-parser/src/lib.rs index f041680..bcfd140 100644 --- a/sv-parser-parser/src/lib.rs +++ b/sv-parser-parser/src/lib.rs @@ -84,18 +84,10 @@ impl HasExtraState<()> for SpanInfo { nom_packrat::storage!(AnyNode); -pub fn parse_sv(s: &str) -> Result { - let s = Span::new_extra(s, SpanInfo::default()); - match source_text(s) { - Ok((_, x)) => Ok(x), - Err(_) => Err(()), - } +pub fn sv_parser(s: Span) -> IResult { + source_text(s) } -pub fn parse_lib(s: &str) -> Result { - let s = Span::new_extra(s, SpanInfo::default()); - match library_text(s) { - Ok((_, x)) => Ok(x), - Err(_) => Err(()), - } +pub fn lib_parser(s: Span) -> IResult { + library_text(s) } diff --git a/sv-parser-syntaxtree/src/lib.rs b/sv-parser-syntaxtree/src/lib.rs index b5deb25..312a5e0 100644 --- a/sv-parser-syntaxtree/src/lib.rs +++ b/sv-parser-syntaxtree/src/lib.rs @@ -45,3 +45,13 @@ impl<'a> Node<'a> for Locate { vec![].into() } } + +impl<'a> IntoIterator for &'a Locate { + type Item = RefNode<'a>; + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Self::IntoIter { + let nodes: RefNodes = self.into(); + Iter { next: nodes } + } +} diff --git a/sv-parser/Cargo.toml b/sv-parser/Cargo.toml index 9203b9a..b3e1ed3 100644 --- a/sv-parser/Cargo.toml +++ b/sv-parser/Cargo.toml @@ -15,5 +15,6 @@ default = [] trace = ["sv-parser-parser/trace"] [dependencies] +nom = "5.0.0" sv-parser-parser = { path = "../sv-parser-parser" } sv-parser-syntaxtree = { path = "../sv-parser-syntaxtree" } diff --git a/sv-parser/src/lib.rs b/sv-parser/src/lib.rs index ab05c5d..4cb1d6e 100644 --- a/sv-parser/src/lib.rs +++ b/sv-parser/src/lib.rs @@ -1,4 +1,51 @@ #![recursion_limit = "256"] -pub use sv_parser_parser::{parse_lib, parse_sv}; +use nom::combinator::all_consuming; +use sv_parser_parser::{lib_parser, sv_parser, Span, SpanInfo}; pub use sv_parser_syntaxtree::*; + +pub struct SyntaxTree<'a> { + node: AnyNode, + buf: &'a str, +} + +impl<'a> SyntaxTree<'a> { + pub fn get_str(&self, locate: &Locate) -> &'a str { + unsafe { + self.buf + .get_unchecked(locate.offset..locate.offset + locate.len) + } + } +} + +impl<'a> IntoIterator for &'a SyntaxTree<'a> { + type Item = RefNode<'a>; + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Self::IntoIter { + let ref_node: RefNode = (&self.node).into(); + ref_node.into_iter() + } +} + +pub fn parse_sv(s: &str) -> Result { + let span = Span::new_extra(s, SpanInfo::default()); + match all_consuming(sv_parser)(span) { + Ok((_, x)) => Ok(SyntaxTree { + node: AnyNode::SourceText(x), + buf: s, + }), + Err(_) => Err(()), + } +} + +pub fn parse_lib(s: &str) -> Result { + let span = Span::new_extra(s, SpanInfo::default()); + match all_consuming(lib_parser)(span) { + Ok((_, x)) => Ok(SyntaxTree { + node: AnyNode::LibraryText(x), + buf: s, + }), + Err(_) => Err(()), + } +}