summaryrefslogtreecommitdiff
path: root/dhall_proc_macros
diff options
context:
space:
mode:
Diffstat (limited to 'dhall_proc_macros')
-rw-r--r--dhall_proc_macros/src/lib.rs7
-rw-r--r--dhall_proc_macros/src/make_parser.rs90
-rw-r--r--dhall_proc_macros/src/parse_children.rs (renamed from dhall_proc_macros/src/parser.rs)88
3 files changed, 95 insertions, 90 deletions
diff --git a/dhall_proc_macros/src/lib.rs b/dhall_proc_macros/src/lib.rs
index 63dd29a..37e8f9f 100644
--- a/dhall_proc_macros/src/lib.rs
+++ b/dhall_proc_macros/src/lib.rs
@@ -7,7 +7,8 @@
extern crate proc_macro;
mod derive;
-mod parser;
+mod make_parser;
+mod parse_children;
use proc_macro::TokenStream;
@@ -18,7 +19,7 @@ pub fn derive_static_type(input: TokenStream) -> TokenStream {
#[proc_macro_attribute]
pub fn make_parser(attrs: TokenStream, input: TokenStream) -> TokenStream {
- TokenStream::from(match parser::make_parser(attrs, input) {
+ TokenStream::from(match make_parser::make_parser(attrs, input) {
Ok(tokens) => tokens,
Err(err) => err.to_compile_error(),
})
@@ -26,7 +27,7 @@ pub fn make_parser(attrs: TokenStream, input: TokenStream) -> TokenStream {
#[proc_macro]
pub fn parse_children(input: TokenStream) -> TokenStream {
- TokenStream::from(match parser::parse_children(input) {
+ TokenStream::from(match parse_children::parse_children(input) {
Ok(tokens) => tokens,
Err(err) => err.to_compile_error(),
})
diff --git a/dhall_proc_macros/src/make_parser.rs b/dhall_proc_macros/src/make_parser.rs
new file mode 100644
index 0000000..63ce779
--- /dev/null
+++ b/dhall_proc_macros/src/make_parser.rs
@@ -0,0 +1,90 @@
+use quote::quote;
+use syn::parse::{ParseStream, Result};
+use syn::spanned::Spanned;
+use syn::{
+ parse_quote, Error, Expr, Ident, ImplItem, ImplItemMethod, ItemImpl,
+ ReturnType, Token,
+};
+
+fn apply_special_attrs(
+ rule_enum: &Ident,
+ function: &mut ImplItemMethod,
+) -> Result<()> {
+ let recognized_attrs: Vec<_> = function
+ .attrs
+ .drain_filter(|attr| attr.path.is_ident("prec_climb"))
+ .collect();
+
+ let name = function.sig.ident.clone();
+ let output_type = match &function.sig.output {
+ ReturnType::Default => parse_quote!(()),
+ ReturnType::Type(_, t) => (**t).clone(),
+ };
+
+ if recognized_attrs.is_empty() {
+ } else if recognized_attrs.len() > 1 {
+ return Err(Error::new(
+ recognized_attrs[1].span(),
+ "expected a single prec_climb attribute",
+ ));
+ } else {
+ let attr = recognized_attrs.into_iter().next().unwrap();
+ let (child_rule, climber) =
+ attr.parse_args_with(|input: ParseStream| {
+ let child_rule: Ident = input.parse()?;
+ let _: Token![,] = input.parse()?;
+ let climber: Expr = input.parse()?;
+ Ok((child_rule, climber))
+ })?;
+
+ *function = parse_quote!(
+ fn #name<'a>(
+ input: ParseInput<'a, #rule_enum>,
+ ) -> #output_type {
+ #[allow(non_snake_case, dead_code)]
+ #function
+
+ #climber.climb(
+ input.pair.clone().into_inner(),
+ |p| Self::#child_rule(input.with_pair(p)),
+ |l, op, r| {
+ #name(input.clone(), l?, op, r?)
+ },
+ )
+ }
+ );
+ }
+
+ *function = parse_quote!(
+ #[allow(non_snake_case, dead_code)]
+ #function
+ );
+
+ Ok(())
+}
+
+pub fn make_parser(
+ attrs: proc_macro::TokenStream,
+ input: proc_macro::TokenStream,
+) -> Result<proc_macro2::TokenStream> {
+ let rule_enum: Ident = syn::parse(attrs)?;
+
+ let mut imp: ItemImpl = syn::parse(input)?;
+ imp.items
+ .iter_mut()
+ .map(|item| match item {
+ ImplItem::Method(m) => apply_special_attrs(&rule_enum, m),
+ _ => Ok(()),
+ })
+ .collect::<Result<()>>()?;
+
+ let ty = &imp.self_ty;
+ let (impl_generics, _, where_clause) = imp.generics.split_for_impl();
+ Ok(quote!(
+ impl #impl_generics PestConsumer for #ty #where_clause {
+ type RuleEnum = #rule_enum;
+ }
+
+ #imp
+ ))
+}
diff --git a/dhall_proc_macros/src/parser.rs b/dhall_proc_macros/src/parse_children.rs
index a440b16..ce6f66c 100644
--- a/dhall_proc_macros/src/parser.rs
+++ b/dhall_proc_macros/src/parse_children.rs
@@ -3,10 +3,7 @@ use quote::quote;
use syn::parse::{Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
-use syn::{
- bracketed, parenthesized, parse_quote, token, Error, Expr, Ident, ImplItem,
- ImplItemMethod, ItemImpl, Pat, ReturnType, Token,
-};
+use syn::{bracketed, parenthesized, token, Error, Expr, Ident, Pat, Token};
#[derive(Debug, Clone)]
struct ChildrenBranch {
@@ -76,89 +73,6 @@ impl Parse for ParseChildrenInput {
}
}
-fn apply_special_attrs(
- rule_enum: &Ident,
- function: &mut ImplItemMethod,
-) -> Result<()> {
- let recognized_attrs: Vec<_> = function
- .attrs
- .drain_filter(|attr| attr.path.is_ident("prec_climb"))
- .collect();
-
- let name = function.sig.ident.clone();
- let output_type = match &function.sig.output {
- ReturnType::Default => parse_quote!(()),
- ReturnType::Type(_, t) => (**t).clone(),
- };
-
- if recognized_attrs.is_empty() {
- } else if recognized_attrs.len() > 1 {
- return Err(Error::new(
- recognized_attrs[1].span(),
- "expected a single prec_climb attribute",
- ));
- } else {
- let attr = recognized_attrs.into_iter().next().unwrap();
- let (child_rule, climber) =
- attr.parse_args_with(|input: ParseStream| {
- let child_rule: Ident = input.parse()?;
- let _: Token![,] = input.parse()?;
- let climber: Expr = input.parse()?;
- Ok((child_rule, climber))
- })?;
-
- *function = parse_quote!(
- fn #name<'a>(
- input: ParseInput<'a, #rule_enum>,
- ) -> #output_type {
- #[allow(non_snake_case, dead_code)]
- #function
-
- #climber.climb(
- input.pair.clone().into_inner(),
- |p| Self::#child_rule(input.with_pair(p)),
- |l, op, r| {
- #name(input.clone(), l?, op, r?)
- },
- )
- }
- );
- }
-
- *function = parse_quote!(
- #[allow(non_snake_case, dead_code)]
- #function
- );
-
- Ok(())
-}
-
-pub fn make_parser(
- attrs: proc_macro::TokenStream,
- input: proc_macro::TokenStream,
-) -> Result<proc_macro2::TokenStream> {
- let rule_enum: Ident = syn::parse(attrs)?;
-
- let mut imp: ItemImpl = syn::parse(input)?;
- imp.items
- .iter_mut()
- .map(|item| match item {
- ImplItem::Method(m) => apply_special_attrs(&rule_enum, m),
- _ => Ok(()),
- })
- .collect::<Result<()>>()?;
-
- let ty = &imp.self_ty;
- let (impl_generics, _, where_clause) = imp.generics.split_for_impl();
- Ok(quote!(
- impl #impl_generics PestConsumer for #ty #where_clause {
- type RuleEnum = #rule_enum;
- }
-
- #imp
- ))
-}
-
fn make_parser_branch(branch: &ChildrenBranch) -> Result<TokenStream> {
use ChildrenBranchPatternItem::{Multiple, Single};