diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2018-12-13 20:17:30 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-13 20:17:30 -0600 |
| commit | cb921381c42712e6098839543d80181c30b87483 (patch) | |
| tree | 88f60a95ae0addce423df63599b8c1394b02e236 /library/stdarch/crates/assert-instr-macro/src | |
| parent | 591ce8fe6fc784d493734ea9092b995426d22667 (diff) | |
| download | rust-cb921381c42712e6098839543d80181c30b87483.tar.gz rust-cb921381c42712e6098839543d80181c30b87483.zip | |
Rewrite simd128 and wasm support (#620)
* Update representation of `v128` * Rename everything with new naming convention of underscores and no modules/impls * Remove no longer necessary `wasm_simd128` feature * Remove `#[target_feature]` attributes (use `#[cfg]` instead) * Update `assert_instr` tests * Update some implementations as LLVM has evolved * Allow some more esoteric syntax in `#[assert_instr]` * Adjust the safety of APIs where appropriate * Remove macros in favor of hand-coded implementations * Comment out the tests for now as there's no known runtime for these yet
Diffstat (limited to 'library/stdarch/crates/assert-instr-macro/src')
| -rw-r--r-- | library/stdarch/crates/assert-instr-macro/src/lib.rs | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/library/stdarch/crates/assert-instr-macro/src/lib.rs b/library/stdarch/crates/assert-instr-macro/src/lib.rs index 43a8b8a7e62..eba00e6b2b4 100644 --- a/library/stdarch/crates/assert-instr-macro/src/lib.rs +++ b/library/stdarch/crates/assert-instr-macro/src/lib.rs @@ -22,8 +22,14 @@ pub fn assert_instr( attr: proc_macro::TokenStream, item: proc_macro::TokenStream, ) -> proc_macro::TokenStream { - let invoc = syn::parse::<Invoc>(attr).expect("expected #[assert_instr(instr, a = b, ...)]"); - let item = syn::parse::<syn::Item>(item).expect("must be attached to an item"); + let invoc = match syn::parse::<Invoc>(attr) { + Ok(s) => s, + Err(e) => return e.to_compile_error().into(), + }; + let item = match syn::parse::<syn::Item>(item) { + Ok(s) => s, + Err(e) => return e.to_compile_error().into(), + }; let func = match item { syn::Item::Fn(ref f) => f, _ => panic!("must be attached to a function"), @@ -39,6 +45,8 @@ pub fn assert_instr( let instr_str = instr .replace('.', "_") + .replace('/', "_") + .replace(':', "_") .replace(|c: char| c.is_whitespace(), ""); let assert_name = syn::Ident::new(&format!("assert_{}_{}", name, instr_str), name.span()); let shim_name = syn::Ident::new(&format!("{}_shim", name), name.span()); @@ -143,18 +151,44 @@ struct Invoc { impl syn::parse::Parse for Invoc { fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> { - use syn::Token; - - let instr = match input.parse::<syn::Ident>() { - Ok(s) => s.to_string(), - Err(_) => input.parse::<syn::LitStr>()?.value(), - }; + use syn::{ext::IdentExt, Token}; + + let mut instr = String::new(); + while !input.is_empty() { + if input.parse::<Token![,]>().is_ok() { + break; + } + if let Ok(ident) = syn::Ident::parse_any(input) { + instr.push_str(&ident.to_string()); + continue; + } + if input.parse::<Token![.]>().is_ok() { + instr.push_str("."); + continue; + } + if let Ok(s) = input.parse::<syn::LitStr>() { + instr.push_str(&s.value()); + continue; + } + println!("{:?}", input.cursor().token_stream()); + return Err(input.error("expected an instruction")); + } + if instr.len() == 0 { + return Err(input.error("expected an instruction before comma")); + } let mut args = Vec::new(); - while input.parse::<Token![,]>().is_ok() { + while !input.is_empty() { let name = input.parse::<syn::Ident>()?; input.parse::<Token![=]>()?; let expr = input.parse::<syn::Expr>()?; args.push((name, expr)); + + if input.parse::<Token![,]>().is_err() { + if !input.is_empty() { + return Err(input.error("extra tokens at end")); + } + break; + } } Ok(Self { instr, args }) } |
