1#![feature(
2 custom_inner_attributes,
3 proc_macro_span,
4 proc_macro_diagnostic,
5 proc_macro_def_site
6)]
7use rhythmc_compiler::utils::syn::resolve_module_path;
8
9#[macro_use]
10extern crate lazy_static;
11
12use glsl::syntax::TranslationUnit;
13use proc_macro::{Delimiter, Span, TokenStream, TokenTree};
14
15use std::collections::HashMap;
16use std::str::FromStr;
17
18lazy_static! {
19 static ref IR_MAP: HashMap<String, TranslationUnit> = HashMap::new();
22}
23
24fn compile_error(message: &str) -> TokenStream {
25 TokenStream::from_str(message).unwrap()
26}
27
28#[proc_macro_attribute]
29pub fn shader(_attr: TokenStream, item: TokenStream) -> TokenStream {
30 let module_path = if let Some(path) = resolve_module_path(
31 Span::call_site().into(),
32 Span::call_site().source_file().path(),
33 ) {
34 path
35 } else {
36 return compile_error("rhythmc failed to resolve this module path");
37 };
38
39 let mut result = Vec::new();
40 let mut iter = item.into_iter();
41 loop {
42 let token = iter.next();
43 if token.is_none() {
44 return compile_error(
45 "invalid usage of 'rhythmc::shader', expected module",
46 );
47 }
48 result.push(TokenStream::from(token.clone().unwrap()));
49 if let TokenTree::Group(group) = token.clone().unwrap() {
50 if group.delimiter() == Delimiter::Brace {
51 return compile_error(
52 "invalid usage of 'rhythmc::shader', expected module",
53 );
54 }
55 }
56 if token.unwrap().to_string() == "mod" {
57 break;
58 }
59 }
60 result.push(TokenStream::from(iter.next().unwrap()));
61 if let TokenTree::Group(group) = iter.next().unwrap() {
62 assert_eq!(group.delimiter(), Delimiter::Brace);
63 result.push(
64 TokenStream::from_str(
65 format!(
66 "{{
67 pub static RHYTHMC_SHADER_MODULE_NAME: &str = \"{}\";
68 pub static RHYTHMC_SHADER_MODULE_IMPORTS: Vec<String> = vec![];
69 {}
70 }}",
71 module_path,
72 group.stream()
73 )
74 .as_str(),
75 )
76 .unwrap(),
77 );
78 } else {
79 return compile_error(
80 "invalid usage of 'rhythmc::shader', failed to parse",
81 );
82 }
83 assert!(iter.next().is_none());
84 let result = result.iter().cloned().collect();
85 result
86}
87
88#[proc_macro_attribute]
89pub fn import(_attr: TokenStream, item: TokenStream) -> TokenStream {
90 item
92}
93
94