ekege-macros 0.1.0

Procedural macros for Ekege: An E-graph library that's built like a database
Documentation
use quote::ToTokens;
use syn::{
    parse::{Parse, ParseStream},
    Token,
};

use crate::rule::{TreeQuery, TreeRule, TreeRulePayload, TreeTermPatternInput};

#[derive(Clone)]
pub(crate) struct TreeTermPatternInputSeries {
    inputs: Vec<TreeTermPatternInput>,
}

impl Parse for TreeTermPatternInputSeries {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let mut inputs = Vec::new();

        while input.peek(syn::Ident) || input.peek(syn::Lifetime) {
            inputs.push(input.parse::<TreeTermPatternInput>()?);

            let _ = input.parse::<Token![,]>();
        }

        Ok(Self { inputs })
    }
}

pub(crate) fn create_rewrite_tree_rule(
    inputs: TreeTermPatternInputSeries,
    rewrites: TreeTermPatternInputSeries,
) -> TreeRule {
    TreeRule {
        payloads: inputs
            .inputs
            .iter()
            .cloned()
            .zip(rewrites.inputs)
            .map(|(before_pattern, after_pattern)| {
                TreeRulePayload::Union(before_pattern, after_pattern)
            })
            .collect(),
        query: TreeQuery {
            term_patterns: inputs
                .inputs
                .into_iter()
                .filter_map(|input| {
                    if let TreeTermPatternInput::TreeTermPattern(map_pattern) = input {
                        Some(map_pattern)
                    } else {
                        None
                    }
                })
                .collect(),
        },
    }
}

pub(crate) struct Rewrite {
    tree_rule: TreeRule,
}

impl ToTokens for Rewrite {
    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
        self.tree_rule.to_tokens(tokens);
    }
}

impl Parse for Rewrite {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let rule_terms = input.parse::<TreeTermPatternInputSeries>()?;

        let _ = input.parse::<Token![->]>()?;

        let rewrites = input.parse::<TreeTermPatternInputSeries>()?;

        Ok(Self {
            tree_rule: create_rewrite_tree_rule(rule_terms, rewrites),
        })
    }
}