diff --git a/.gitignore b/.gitignore index 6936990..c3919e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target +/node_derive/target **/*.rs.bk Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index f5ab2a6..124b5dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,4 @@ edition = "2018" nom = "5.0.0" nom_locate = { git = "https://github.com/fflorent/nom_locate" } str-concat = "*" +node_derive = { path = "./node_derive" } diff --git a/README.md b/README.md index 3a494e0..d200e8c 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ A parser library for System Verilog. | behavioral_statements | case_statements | | | | | behavioral_statements | patterns | | | | | behavioral_statements | looping_statements | | | | -| behavioral_statements | subroutine_call_statements | | | | +| behavioral_statements | subroutine_call_statements | x | x | | | behavioral_statements | assertion_statements | | | | | behavioral_statements | clocking_block | | | | | behavioral_statements | randsequence | | | | diff --git a/node_derive/Cargo.toml b/node_derive/Cargo.toml new file mode 100644 index 0000000..052b31f --- /dev/null +++ b/node_derive/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "node_derive" +version = "0.1.0" +authors = ["dalance "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +proc-macro = true + +[dependencies] +syn = "0.14.4" +quote = "0.6.3" diff --git a/node_derive/src/lib.rs b/node_derive/src/lib.rs new file mode 100644 index 0000000..61c1871 --- /dev/null +++ b/node_derive/src/lib.rs @@ -0,0 +1,110 @@ +#![recursion_limit = "128"] + +extern crate proc_macro; + +use crate::proc_macro::TokenStream; +use quote::quote; +use syn; + +#[proc_macro_derive(Node)] +pub fn node_derive(input: TokenStream) -> TokenStream { + let ast = syn::parse(input).unwrap(); + impl_node(&ast) +} + +fn impl_node(ast: &syn::DeriveInput) -> TokenStream { + let name = &ast.ident; + + let next = match ast.data { + syn::Data::Enum(ref data) => { + let mut items = quote! {}; + for v in &data.variants { + let ident = &v.ident; + let item = quote! { + #name::#ident(x) => { let ret: AnyNode<'a> = x.into(); vec![ret] }, + }; + items = quote! { + #items + #item + }; + } + + quote! { + match self { + #items + } + } + } + _ => { + quote! { + vec![] + } + } + }; + + let gen = quote! { + impl<'a> Node<'a> for #name<'a> { + fn test(&'a self) -> String { + format!("{}", stringify!(#name)) + } + + fn next(&'a self) -> Vec> { + #next + } + } + + impl<'a> From<&'a #name<'a>> for AnyNode<'a> { + fn from(x: &'a #name<'a>) -> Self { + AnyNode::#name(x) + } + } + + impl<'a> IntoIterator for &'a #name<'a> { + type Item = AnyNode<'a>; + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Self::IntoIter { + let node: AnyNode<'a> = self.into(); + Iter { next: vec![node] } + } + } + }; + gen.into() +} + +#[proc_macro_derive(AnyNode)] +pub fn any_node_derive(input: TokenStream) -> TokenStream { + let ast = syn::parse(input).unwrap(); + impl_any_node(&ast) +} + +fn impl_any_node(ast: &syn::DeriveInput) -> TokenStream { + let ref data = match ast.data { + syn::Data::Enum(ref data) => data, + _ => unreachable!(), + }; + + let mut items = quote! {}; + for v in &data.variants { + let ident = &v.ident; + let item = quote! { + AnyNode::#ident(x) => x.next(), + }; + items = quote! { + #items + #item + }; + } + + let name = &ast.ident; + let gen = quote! { + impl<'a> #name<'a> { + fn next(&self) -> Vec> { + match self { + #items + } + } + } + }; + gen.into() +} diff --git a/src/lib.rs b/src/lib.rs index f757266..af359b8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ #![recursion_limit = "128"] +pub mod node; pub mod parser; diff --git a/src/node.rs b/src/node.rs new file mode 100644 index 0000000..d1b2cb5 --- /dev/null +++ b/src/node.rs @@ -0,0 +1,74 @@ +use crate::parser::*; +use node_derive::AnyNode; + +pub trait Node<'a> { + fn test(&'a self) -> String; + fn next(&'a self) -> Vec>; +} + +impl<'a> Node<'a> for Span<'a> { + fn test(&'a self) -> String { + String::from("") + } + fn next(&'a self) -> Vec> { + vec![] + } +} + +impl<'a> From<&'a Span<'a>> for AnyNode<'a> { + fn from(x: &'a Span<'a>) -> Self { + AnyNode::Span(x) + } +} + +#[derive(Debug, Clone, AnyNode)] +pub enum AnyNode<'a> { + Span(&'a Span<'a>), + Symbol(&'a Symbol<'a>), + WhiteSpace(&'a WhiteSpace<'a>), + Comment(&'a Comment<'a>), + Number(&'a Number<'a>), + IntegralNumber(&'a IntegralNumber<'a>), + DecimalNumber(&'a DecimalNumber<'a>), + DecimalNumberBaseUnsigned(&'a DecimalNumberBaseUnsigned<'a>), + DecimalNumberBaseXNumber(&'a DecimalNumberBaseXNumber<'a>), + DecimalNumberBaseZNumber(&'a DecimalNumberBaseZNumber<'a>), + BinaryNumber(&'a BinaryNumber<'a>), + OctalNumber(&'a OctalNumber<'a>), + HexNumber(&'a HexNumber<'a>), + Sign(&'a Sign<'a>), + Size(&'a Size<'a>), + NonZeroUnsignedNumber(&'a NonZeroUnsignedNumber<'a>), + RealNumber(&'a RealNumber<'a>), + RealNumberFloating(&'a RealNumberFloating<'a>), + FixedPointNumber(&'a FixedPointNumber<'a>), + Exp(&'a Exp<'a>), + UnsignedNumber(&'a UnsignedNumber<'a>), + BinaryValue(&'a BinaryValue<'a>), + OctalValue(&'a OctalValue<'a>), + HexValue(&'a HexValue<'a>), + DecimalBase(&'a DecimalBase<'a>), + BinaryBase(&'a BinaryBase<'a>), + OctalBase(&'a OctalBase<'a>), + HexBase(&'a HexBase<'a>), + XNumber(&'a XNumber<'a>), + ZNumber(&'a ZNumber<'a>), + UnbasedUnsizedLiteral(&'a UnbasedUnsizedLiteral<'a>), +} + +pub struct Iter<'a> { + pub(crate) next: Vec>, +} + +impl<'a> Iterator for Iter<'a> { + type Item = AnyNode<'a>; + + fn next(&mut self) -> Option { + let ret = self.next.pop(); + if let Some(x) = ret.clone() { + let mut x = x.next(); + self.next.append(&mut x); + } + ret + } +} diff --git a/src/parser/behavioral_statements/subroutine_call_statements.rs b/src/parser/behavioral_statements/subroutine_call_statements.rs index e051dfe..7e926e3 100644 --- a/src/parser/behavioral_statements/subroutine_call_statements.rs +++ b/src/parser/behavioral_statements/subroutine_call_statements.rs @@ -8,26 +8,42 @@ use nom::IResult; #[derive(Debug)] pub enum SubroutineCallStatement<'a> { - SubroutineCall(SubroutineCall<'a>), - FunctionSubroutineCall(FunctionSubroutineCall<'a>), + SubroutineCall((SubroutineCall<'a>, Symbol<'a>)), + Function(SubroutineCallStatementFunction<'a>), +} + +#[derive(Debug)] +pub struct SubroutineCallStatementFunction<'a> { + pub nodes: ( + Symbol<'a>, + Symbol<'a>, + Paren<'a, FunctionSubroutineCall<'a>>, + Symbol<'a>, + ), } // ----------------------------------------------------------------------------- pub fn subroutine_call_statement(s: Span) -> IResult { alt(( - map(terminated(subroutine_call, symbol(";")), |x| { + map(pair(subroutine_call, symbol(";")), |x| { SubroutineCallStatement::SubroutineCall(x) }), - map( - delimited( - triple(symbol("void"), symbol("'"), symbol("(")), - function_subroutine_call, - pair(symbol(")"), symbol(";")), - ), - |x| SubroutineCallStatement::FunctionSubroutineCall(x), - ), + subroutine_call_statement_function, ))(s) } +pub fn subroutine_call_statement_function(s: Span) -> IResult { + let (s, a) = symbol("void")(s)?; + let (s, b) = symbol("'")(s)?; + let (s, c) = paren2(function_subroutine_call)(s)?; + let (s, d) = symbol(";")(s)?; + Ok(( + s, + SubroutineCallStatement::Function(SubroutineCallStatementFunction { + nodes: (a, b, c, d), + }), + )) +} + // ----------------------------------------------------------------------------- diff --git a/src/parser/expressions/numbers.rs b/src/parser/expressions/numbers.rs index d68077d..b634d73 100644 --- a/src/parser/expressions/numbers.rs +++ b/src/parser/expressions/numbers.rs @@ -1,4 +1,6 @@ +use crate::node::*; use crate::parser::*; +use node_derive::Node; use nom::branch::*; use nom::bytes::complete::*; use nom::character::complete::*; @@ -9,13 +11,13 @@ use nom::IResult; // ----------------------------------------------------------------------------- -#[derive(Debug)] +#[derive(Debug, Node)] pub enum Number<'a> { IntegralNumber(IntegralNumber<'a>), RealNumber(RealNumber<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub enum IntegralNumber<'a> { DecimalNumber(DecimalNumber<'a>), OctalNumber(OctalNumber<'a>), @@ -23,7 +25,7 @@ pub enum IntegralNumber<'a> { HexNumber(HexNumber<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub enum DecimalNumber<'a> { UnsignedNumber(UnsignedNumber<'a>), BaseUnsigned(DecimalNumberBaseUnsigned<'a>), @@ -31,59 +33,59 @@ pub enum DecimalNumber<'a> { BaseZNumber(DecimalNumberBaseZNumber<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct DecimalNumberBaseUnsigned<'a> { pub nodes: (Option>, DecimalBase<'a>, UnsignedNumber<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct DecimalNumberBaseXNumber<'a> { pub nodes: (Option>, DecimalBase<'a>, XNumber<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct DecimalNumberBaseZNumber<'a> { pub nodes: (Option>, DecimalBase<'a>, ZNumber<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct BinaryNumber<'a> { pub nodes: (Option>, BinaryBase<'a>, BinaryValue<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct OctalNumber<'a> { pub nodes: (Option>, OctalBase<'a>, OctalValue<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct HexNumber<'a> { pub nodes: (Option>, HexBase<'a>, HexValue<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub enum Sign<'a> { Plus(Symbol<'a>), Minus(Symbol<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct Size<'a> { pub nodes: (NonZeroUnsignedNumber<'a>,), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct NonZeroUnsignedNumber<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub enum RealNumber<'a> { FixedPointNumber(FixedPointNumber<'a>), Floating(RealNumberFloating<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct RealNumberFloating<'a> { pub nodes: ( UnsignedNumber<'a>, @@ -94,67 +96,67 @@ pub struct RealNumberFloating<'a> { ), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct FixedPointNumber<'a> { pub nodes: (UnsignedNumber<'a>, Symbol<'a>, UnsignedNumber<'a>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct Exp<'a> { pub nodes: (Symbol<'a>,), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct UnsignedNumber<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct BinaryValue<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct OctalValue<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct HexValue<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct DecimalBase<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct BinaryBase<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct OctalBase<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct HexBase<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct XNumber<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct ZNumber<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub struct UnbasedUnsizedLiteral<'a> { pub nodes: (Symbol<'a>,), } @@ -547,4 +549,16 @@ mod tests { parser_test!(unbased_unsized_literal, "'x", Ok((_, _))); parser_test!(unbased_unsized_literal, "'z", Ok((_, _))); } + + #[test] + fn test_node() { + if let Ok((_, x)) = all_consuming(number)(Span::new_extra("10", 0)) { + //assert_eq!(x.test(), "aaaa"); + //let y: AnyNode = (&x).into(); + for a in &x { + dbg!(a); + //assert_eq!(format!("{:?}", a), "aaa"); + } + } + } } diff --git a/src/parser/general/comments.rs b/src/parser/general/comments.rs index ce7e5f0..937ed79 100644 --- a/src/parser/general/comments.rs +++ b/src/parser/general/comments.rs @@ -1,11 +1,13 @@ +use crate::node::*; use crate::parser::*; +use node_derive::Node; use nom::branch::*; use nom::bytes::complete::*; use nom::IResult; // ----------------------------------------------------------------------------- -#[derive(Debug)] +#[derive(Debug, Node)] pub struct Comment<'a> { nodes: (Span<'a>,), } diff --git a/src/parser/utils.rs b/src/parser/utils.rs index e9d0e60..70f135a 100644 --- a/src/parser/utils.rs +++ b/src/parser/utils.rs @@ -1,4 +1,6 @@ +use crate::node::*; use crate::parser::*; +use node_derive::Node; use nom::branch::*; use nom::bytes::complete::*; use nom::character::complete::*; @@ -9,12 +11,12 @@ use nom::{Err, IResult}; // ----------------------------------------------------------------------------- -#[derive(Debug)] +#[derive(Debug, Node)] pub struct Symbol<'a> { pub nodes: (Span<'a>, Vec>), } -#[derive(Debug)] +#[derive(Debug, Node)] pub enum WhiteSpace<'a> { Space(Span<'a>), Comment(Comment<'a>),