Add custom derive
This commit is contained in:
parent
07265d153e
commit
fe008b3bad
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
/target
|
||||
/node_derive/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
|
@ -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" }
|
||||
|
@ -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 | | | |
|
||||
|
14
node_derive/Cargo.toml
Normal file
14
node_derive/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "node_derive"
|
||||
version = "0.1.0"
|
||||
authors = ["dalance <dalance@gmail.com>"]
|
||||
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"
|
110
node_derive/src/lib.rs
Normal file
110
node_derive/src/lib.rs
Normal file
@ -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<AnyNode<'a>> {
|
||||
#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<AnyNode<'a>> {
|
||||
match self {
|
||||
#items
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
gen.into()
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
#![recursion_limit = "128"]
|
||||
pub mod node;
|
||||
pub mod parser;
|
||||
|
74
src/node.rs
Normal file
74
src/node.rs
Normal file
@ -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<AnyNode<'a>>;
|
||||
}
|
||||
|
||||
impl<'a> Node<'a> for Span<'a> {
|
||||
fn test(&'a self) -> String {
|
||||
String::from("")
|
||||
}
|
||||
fn next(&'a self) -> Vec<AnyNode<'a>> {
|
||||
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<AnyNode<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Iter<'a> {
|
||||
type Item = AnyNode<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let ret = self.next.pop();
|
||||
if let Some(x) = ret.clone() {
|
||||
let mut x = x.next();
|
||||
self.next.append(&mut x);
|
||||
}
|
||||
ret
|
||||
}
|
||||
}
|
@ -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<Span, SubroutineCallStatement> {
|
||||
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<Span, SubroutineCallStatement> {
|
||||
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),
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -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<Size<'a>>, DecimalBase<'a>, UnsignedNumber<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct DecimalNumberBaseXNumber<'a> {
|
||||
pub nodes: (Option<Size<'a>>, DecimalBase<'a>, XNumber<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct DecimalNumberBaseZNumber<'a> {
|
||||
pub nodes: (Option<Size<'a>>, DecimalBase<'a>, ZNumber<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct BinaryNumber<'a> {
|
||||
pub nodes: (Option<Size<'a>>, BinaryBase<'a>, BinaryValue<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct OctalNumber<'a> {
|
||||
pub nodes: (Option<Size<'a>>, OctalBase<'a>, OctalValue<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct HexNumber<'a> {
|
||||
pub nodes: (Option<Size<'a>>, 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<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[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<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct BinaryValue<'a> {
|
||||
pub nodes: (Span<'a>, Vec<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct OctalValue<'a> {
|
||||
pub nodes: (Span<'a>, Vec<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct HexValue<'a> {
|
||||
pub nodes: (Span<'a>, Vec<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct DecimalBase<'a> {
|
||||
pub nodes: (Span<'a>, Vec<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct BinaryBase<'a> {
|
||||
pub nodes: (Span<'a>, Vec<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct OctalBase<'a> {
|
||||
pub nodes: (Span<'a>, Vec<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct HexBase<'a> {
|
||||
pub nodes: (Span<'a>, Vec<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct XNumber<'a> {
|
||||
pub nodes: (Span<'a>, Vec<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub struct ZNumber<'a> {
|
||||
pub nodes: (Span<'a>, Vec<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>,),
|
||||
}
|
||||
|
@ -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<WhiteSpace<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Node)]
|
||||
pub enum WhiteSpace<'a> {
|
||||
Space(Span<'a>),
|
||||
Comment(Comment<'a>),
|
||||
|
Loading…
x
Reference in New Issue
Block a user