aboutsummaryrefslogtreecommitdiff
path: root/azalea-block/block-macros/src
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-05-27 19:34:09 -0500
committermat <github@matdoes.dev>2022-05-27 19:34:09 -0500
commit88bc6d16602c163d122685997dc269d5d97a93a2 (patch)
tree959c68a4d21d7b832aaa04aebbf6e7412f620367 /azalea-block/block-macros/src
parentaac64d013546c8be3b992af63d70150155386c11 (diff)
downloadazalea-drasl-88bc6d16602c163d122685997dc269d5d97a93a2.tar.xz
Start making block macro
Diffstat (limited to 'azalea-block/block-macros/src')
-rw-r--r--azalea-block/block-macros/src/lib.rs157
1 files changed, 157 insertions, 0 deletions
diff --git a/azalea-block/block-macros/src/lib.rs b/azalea-block/block-macros/src/lib.rs
new file mode 100644
index 00000000..20ec5f3e
--- /dev/null
+++ b/azalea-block/block-macros/src/lib.rs
@@ -0,0 +1,157 @@
+use proc_macro::TokenStream;
+use quote::{quote, ToTokens};
+use std::fmt::Debug;
+use syn::{
+ self, braced,
+ parse::{Parse, ParseStream, Result},
+ parse_macro_input,
+ punctuated::Punctuated,
+ Data, DeriveInput, Expr, FieldsNamed, Ident, LitInt, Token,
+};
+
+struct PropertyDefinition {
+ name: Ident,
+ variants: Punctuated<Ident, Token![,]>,
+}
+struct PropertyDefinitions {
+ properties: Vec<PropertyDefinition>,
+}
+
+struct BlockDefinition {
+ name: Ident,
+ behavior: Expr,
+ properties: Punctuated<Ident, Token![,]>,
+}
+struct BlockDefinitions {
+ blocks: Vec<BlockDefinition>,
+}
+struct MakeBlockStates {
+ property_definitions: PropertyDefinitions,
+ block_definitions: BlockDefinitions,
+}
+
+impl Parse for PropertyDefinition {
+ fn parse(input: ParseStream) -> Result<Self> {
+ // Face {
+ // Floor,
+ // Wall,
+ // Ceiling
+ // };
+ let name = input.parse()?;
+ let variants = input.parse_terminated(Ident::parse)?;
+ input.parse::<Token![;]>()?;
+ Ok(PropertyDefinition { name, variants })
+ }
+}
+
+impl Parse for PropertyDefinitions {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut property_definitions = Vec::new();
+ while !input.is_empty() {
+ property_definitions.push(input.parse()?);
+ }
+
+ Ok(PropertyDefinitions {
+ properties: property_definitions,
+ })
+ }
+}
+
+impl Parse for BlockDefinition {
+ fn parse(input: ParseStream) -> Result<Self> {
+ // acacia_button => BlockBehavior { has_collision: false }, {
+ // Face,
+ // Facing,
+ // Powered
+ // };
+ let name = input.parse()?;
+ input.parse::<Token![=>]>()?;
+ let behavior = input.parse()?;
+ input.parse::<Token![,]>()?;
+ let content;
+ braced!(content in input);
+ let properties = content.parse_terminated(Ident::parse)?;
+ input.parse::<Token![;]>()?;
+ Ok(BlockDefinition {
+ name,
+ behavior,
+ properties,
+ })
+ }
+}
+
+impl Parse for BlockDefinitions {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let mut blocks = Vec::new();
+ while !input.is_empty() {
+ blocks.push(input.parse()?);
+ }
+
+ Ok(BlockDefinitions { blocks })
+ }
+}
+
+impl Parse for MakeBlockStates {
+ fn parse(input: ParseStream) -> Result<Self> {
+ // PROPERTIES => { ... } BLOCKS => { ... }
+ let properties_ident = input.parse::<Ident>()?;
+ assert_eq!(properties_ident.to_string(), "PROPERTIES");
+ input.parse::<Token![=>]>()?;
+ let content;
+ braced!(content in input);
+ let properties = content.parse()?;
+
+ let blocks_ident = input.parse::<Ident>()?;
+ assert_eq!(blocks_ident.to_string(), "BLOCKS");
+ input.parse::<Token![=>]>()?;
+ let content;
+ braced!(content in input);
+ let blocks = content.parse()?;
+
+ Ok(MakeBlockStates {
+ property_definitions: properties,
+ block_definitions: blocks,
+ })
+ }
+}
+
+#[proc_macro]
+pub fn make_block_states(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as MakeBlockStates);
+
+ let mut property_enums = quote! {};
+
+ for property in &input.property_definitions.properties {
+ let mut property_enum_variants = quote! {};
+
+ for variant in &property.variants {
+ property_enum_variants.extend(quote! {
+ #variant,
+ });
+ }
+
+ let property_name = property.name;
+
+ property_enums.extend(quote! {
+ #[derive(Debug, Clone, Copy)]
+ pub enum #property_name {
+ #property_enum_variants
+ }
+ });
+ }
+
+ // let mut block_state_enum_variants = quote! {};
+
+ // for block in &input.block_definitions.blocks {
+ // let block_state_enum_variant = quote! {
+ // #block.name(#block.behavior, #block.properties)
+ // };
+ // block_state_enum_variants.extend(block_state_enum_variant);
+ // }
+
+ quote! {
+ #property_enums
+ // #block_state_enum_variants
+ }
+ .into()
+}