diff --git a/Cargo.toml b/Cargo.toml index 124b5dd..511e1c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,9 +9,14 @@ license = "MIT" readme = "README.md" description = "" edition = "2018" +build = "build.rs" [dependencies] nom = "5.0.0" nom_locate = { git = "https://github.com/fflorent/nom_locate" } str-concat = "*" node_derive = { path = "./node_derive" } + +[build-dependencies] +walkdir = "2" +regex = "1" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..6cb26d0 --- /dev/null +++ b/build.rs @@ -0,0 +1,40 @@ +use regex::Regex; +use std::env; +use std::fs::File; +use std::io::{BufRead, BufReader, Write}; +use std::path::Path; +use walkdir::WalkDir; + +fn main() { + let out_dir = env::var("OUT_DIR").unwrap(); + let dest = Path::new(&out_dir).join("any_node.rs"); + let mut out = File::create(&dest).unwrap(); + + let _ = write!(out, "#[derive(Debug, Clone, AnyNode)]\n"); + let _ = write!(out, "pub enum AnyNode<'a> {{\n"); + let _ = write!(out, " Span(&'a Span<'a>),\n"); + + let re_node = Regex::new(r"#\[derive.*Node.*\]").unwrap(); + + for entry in WalkDir::new("src/parser") { + let entry = entry.unwrap(); + if entry.file_type().is_file() { + let f = File::open(entry.path()).unwrap(); + let f = BufReader::new(f); + let mut hit_node = false; + for line in f.lines() { + let line = line.unwrap(); + if hit_node { + let name = line.split_whitespace().nth(2).unwrap().replace("<'a>", ""); + let _ = write!(out, " {}(&'a {}<'a>),\n", name, name); + hit_node = false; + } + if re_node.is_match(&line) { + hit_node = true; + } + } + } + } + + let _ = write!(out, "}}\n"); +} diff --git a/src/ast.rs b/src/ast.rs new file mode 100644 index 0000000..5bc9d66 --- /dev/null +++ b/src/ast.rs @@ -0,0 +1,5 @@ +pub mod any_node; +pub mod node; +pub use any_node::*; +pub use node::*; +pub use node_derive::*; diff --git a/src/ast/any_node.rs b/src/ast/any_node.rs new file mode 100644 index 0000000..dd7b29d --- /dev/null +++ b/src/ast/any_node.rs @@ -0,0 +1,28 @@ +use crate::ast::*; +use crate::parser::*; + +impl<'a> From<&'a Span<'a>> for AnyNode<'a> { + fn from(x: &'a Span<'a>) -> Self { + AnyNode::Span(x) + } +} + +include!(concat!(env!("OUT_DIR"), "/any_node.rs")); + +pub struct Iter<'a> { + pub 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(); + x.reverse(); + self.next.append(&mut x); + } + ret + } +} diff --git a/src/ast/node.rs b/src/ast/node.rs new file mode 100644 index 0000000..ef9f02e --- /dev/null +++ b/src/ast/node.rs @@ -0,0 +1,16 @@ +use crate::ast::*; +use crate::parser::*; + +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![] + } +} diff --git a/src/lib.rs b/src/lib.rs index af359b8..f751626 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,3 @@ #![recursion_limit = "128"] -pub mod node; +pub mod ast; pub mod parser; diff --git a/src/node.rs b/src/node.rs deleted file mode 100644 index d1b2cb5..0000000 --- a/src/node.rs +++ /dev/null @@ -1,74 +0,0 @@ -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/expressions/numbers.rs b/src/parser/expressions/numbers.rs index b634d73..e1b8712 100644 --- a/src/parser/expressions/numbers.rs +++ b/src/parser/expressions/numbers.rs @@ -1,6 +1,5 @@ -use crate::node::*; +use crate::ast::*; use crate::parser::*; -use node_derive::Node; use nom::branch::*; use nom::bytes::complete::*; use nom::character::complete::*; diff --git a/src/parser/general/comments.rs b/src/parser/general/comments.rs index 937ed79..c89836c 100644 --- a/src/parser/general/comments.rs +++ b/src/parser/general/comments.rs @@ -1,6 +1,5 @@ -use crate::node::*; +use crate::ast::*; use crate::parser::*; -use node_derive::Node; use nom::branch::*; use nom::bytes::complete::*; use nom::IResult; diff --git a/src/parser/utils.rs b/src/parser/utils.rs index 70f135a..daa8521 100644 --- a/src/parser/utils.rs +++ b/src/parser/utils.rs @@ -1,6 +1,5 @@ -use crate::node::*; +use crate::ast::*; use crate::parser::*; -use node_derive::Node; use nom::branch::*; use nom::bytes::complete::*; use nom::character::complete::*;