extern crate proc_macro;
use std::io::Read;
use syn::parse_macro_input;
use proc_macro::TokenStream;
mod stack;
mod numeric_type;
mod evaluator;
mod recurrence;
use recurrence::RecurrencyConstraint;
mod synthesis;
mod macro_core;
mod netcrate_invocation;
use netcrate_invocation::NetcrateInvocation;
#[macro_use] mod invocation_parser;
#[proc_macro_attribute]
pub fn network(attr: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
macro_core::core(parse_invocation!(attr, item, RecurrencyConstraint::DontCare))
}
#[proc_macro_attribute]
pub fn recurrent(attr: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
macro_core::core(parse_invocation!(attr, item, RecurrencyConstraint::Required))
}
#[proc_macro_attribute]
pub fn nonrecurrent(attr: TokenStream, item: TokenStream) -> proc_macro::TokenStream {
macro_core::core(parse_invocation!(attr, item, RecurrencyConstraint::Forbidden))
}
#[proc_macro]
pub fn netcrate(input: TokenStream) -> proc_macro::TokenStream {
let NetcrateInvocation { name, path } = parse_macro_input!(input as NetcrateInvocation);
let manifest_path = std::env::var("CARGO_MANIFEST_DIR").expect("Failed to discover crate manifest directory!");
let cge_path = std::path::Path::new(&manifest_path).join(path);
let cge_data = {
let mut file = std::fs::File::open(cge_path).expect("Failed to open CGE file");
let mut contents = String::new();
file.read_to_string(&mut contents).expect("Failed to read CGE file");
contents
};
quote::quote! {
#[allow(unused_macros)] #[macro_export] macro_rules! #name { (
$invocation: ident,
$item: item,
$($rest:stmt),*
) => {
#[const_cge::$invocation(#cge_data, $($rest),*)]
$item
}
}
}.into()
}