proto
This commit is contained in:
17
macro/Cargo.toml
Normal file
17
macro/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "binnpatch_macro"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["b4tman <b4tm4n@mail.ru>"]
|
||||
readme = "../README.md"
|
||||
repository = "https://gitea.b4tman.ru/b4tman/binnpatch"
|
||||
license = "MIT"
|
||||
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
91
macro/src/lib.rs
Normal file
91
macro/src/lib.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
extern crate proc_macro;
|
||||
use proc_macro::{TokenStream, TokenTree};
|
||||
|
||||
use proc_macro::{Punct, Literal, Spacing, Span, Ident, Group, Delimiter};
|
||||
|
||||
fn parse_str(s: &str) -> TokenStream {
|
||||
s.parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn binnvec(_item: TokenStream) -> TokenStream {
|
||||
println!("- - - - -");
|
||||
println!("{}", _item.to_string());
|
||||
println!("- - - - -");
|
||||
println!("{:?}", _item);
|
||||
println!("- - - - -");
|
||||
|
||||
let mut new_tokens: Vec<TokenTree> = vec![];
|
||||
let comma: Punct = Punct::new(',', Spacing::Alone);
|
||||
let zero = Literal::u8_suffixed(0);
|
||||
let mut prev_separated: bool = true;
|
||||
let mut prev_is_mask: bool = false;
|
||||
|
||||
for token in _item {
|
||||
match token {
|
||||
TokenTree::Punct(ref x) if x.as_char() == ',' => {
|
||||
new_tokens.push(token.into());
|
||||
prev_separated = true;
|
||||
continue;
|
||||
}
|
||||
TokenTree::Punct(ref x) if x.as_char() == '?' => {
|
||||
if prev_is_mask {
|
||||
if !prev_separated {
|
||||
new_tokens.push(comma.clone().into());
|
||||
}
|
||||
let mut val = zero.clone();
|
||||
val.set_span(x.span());
|
||||
new_tokens.push(zero.clone().into());
|
||||
prev_is_mask = false;
|
||||
prev_separated = false;
|
||||
} else if !prev_is_mask {
|
||||
prev_is_mask = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
TokenTree::Ident(ref x) if x.to_string().len() == 2 => {
|
||||
if !prev_separated {
|
||||
new_tokens.push(comma.clone().into());
|
||||
}
|
||||
let lit_str = format!("0x{}u8", x.to_string());
|
||||
let mut val:Literal = lit_str.as_str().parse().expect("parse literal from ident");
|
||||
val.set_span(x.span());
|
||||
new_tokens.push(val.into());
|
||||
}
|
||||
TokenTree::Literal(ref x) => {
|
||||
if !prev_separated {
|
||||
new_tokens.push(comma.clone().into());
|
||||
}
|
||||
|
||||
let in_str = x.to_string();
|
||||
if in_str.starts_with("0x") {
|
||||
new_tokens.push(token.into());
|
||||
} else {
|
||||
let lit_str = format!("0x{}u8", in_str);
|
||||
let mut val:Literal = lit_str.as_str().parse().expect("parse literal");
|
||||
val.set_span(x.span());
|
||||
new_tokens.push(val.into());
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
||||
}
|
||||
}
|
||||
prev_separated = false;
|
||||
}
|
||||
|
||||
let mut ts_new = TokenStream::new();
|
||||
ts_new.extend(new_tokens);
|
||||
|
||||
let group = Group::new(Delimiter::Bracket, ts_new);
|
||||
let mut result = TokenStream::new();
|
||||
let vec_ident = Ident::new("vec", Span::call_site());
|
||||
let macro_marc = Punct::new('!', Spacing::Joint);
|
||||
result.extend([TokenTree::from(vec_ident), TokenTree::from(macro_marc)]);
|
||||
result.extend([TokenTree::from(group)]);
|
||||
|
||||
println!("result: \"{}\"", result.to_string());
|
||||
|
||||
result
|
||||
}
|
||||
|
Reference in New Issue
Block a user