So my current code has a procedural macro that is interpreting this algebraic expression as a function this is the error
error: expected expression, found keyword `fn`
--> src\main.rs:5:5
|
5 | symbolic!(x^2 2*x)
| ^^^^^^^^^^^^^^^^^^^^ expected expression
|
= note: this error originates in the macro `symbolic` (in Nightly builds, run with -Z macro-backtrace for more info)
I tried to install the nightly build and ran with the backtrace but ...
> cargo run nightly -Z macro-backtrace
5 | symbolic!(x^2 2*x)
| ^^^^^^^^^^^^^^^^^^^^ expected expression
= note: this error originates in the macro `symbolic` (in Nightly builds, run with -Z macro-backtrace for more info)
same error any clues as to what this is? I may be missing something about rusts interpreter but as far as I can tell this should be reading this as an expression this is my current code for the macro:
use proc_macro::*;
#[proc_macro]
pub fn symbolic(body: TokenStream) -> TokenStream {
// ---shunting yard---
let mut stack : Vec<TokenTree> = vec![];
let mut que : Vec<TokenTree> = vec![];
shunting_yard(body, &mut stack, &mut que);
println!(stringify!(output_que));
"fn answer() -> u32 { 42 }".parse().unwrap()
}
fn shunting_yard(body: TokenStream,
stack: &mut Vec<TokenTree>,
que: &mut Vec<TokenTree>,
) {
for tt in body.into_iter(){
match tt {
TokenTree::Ident(_) => que.push(tt),
TokenTree::Punct(_) => {
while precedence(Some(&tt)) <= precedence(stack.last()){
if let Some(punct) = stack.pop() { que.push(punct); }
}
stack.push(tt)
},
TokenTree::Literal(_) => que.push(tt),
TokenTree::Group(group) => shunting_yard(group.stream() , stack, que),
}
} while let Some(op) = stack.pop() {
que.push(op);
}
}
fn precedence(tt: Option<&TokenTree>) -> usize{
if let Some(TokenTree::Punct(punct)) = tt{
match punct.as_char() {
'^' => 3,
'/' | '*' => 2,
'-' | ' ' => 1,
_ => 0
}
} else {
0
}
}
CodePudding user response:
It's not the macro trying to interpret anything as function.
Your macro produces a fn
item because you tell it to produce one here:
"fn answer() -> u32 { 42 }".parse().unwrap()
Since you ignore all other input writing this:
symbolic!{whatever garbage}
is equivalent to writing this:
fn answer() -> u32 { 42 }
which seems to be illegal in the context you're trying to call symbolic
.