blob: e02e011aa0c857bc2b4432c17d02c79b0433a188 [file] [log] [blame]
David Tolnayc7a5d3d2017-06-04 12:11:05 -07001extern crate proc_macro2;
Michael Layzell53fc31a2017-06-07 09:21:53 -04002extern crate syn;
David Tolnayc7a5d3d2017-06-04 12:11:05 -07003extern crate synom;
David Tolnaycfa5cc02017-11-13 01:05:11 -08004extern crate syntax;
Michael Layzell53fc31a2017-06-07 09:21:53 -04005
David Tolnaycfa5cc02017-11-13 01:05:11 -08006use self::syntax::ast;
7use self::syntax::ptr::P;
8use self::syntax::parse::{self, ParseSess};
9use self::syntax::codemap::FilePathMapping;
Michael Layzell53fc31a2017-06-07 09:21:53 -040010
11use std::panic;
12
David Tolnayc7a5d3d2017-06-04 12:11:05 -070013use self::synom::{Synom, SynomBuffer};
14
David Tolnaycfa5cc02017-11-13 01:05:11 -080015pub fn libsyntax_expr(input: &str) -> Option<P<ast::Expr>> {
Michael Layzell53fc31a2017-06-07 09:21:53 -040016 match panic::catch_unwind(|| {
17 let sess = ParseSess::new(FilePathMapping::empty());
18 sess.span_diagnostic.set_continue_after_error(false);
19 let e = parse::parse_expr_from_source_str(
20 "test_precedence".to_string(),
21 input.to_string(),
22 &sess,
23 );
24 Some(match e {
25 Ok(expr) => expr,
26 Err(mut diagnostic) => {
27 diagnostic.emit();;
28 return None
29 }
30 })
31 }) {
32 Ok(Some(e)) => Some(e),
33 Ok(None) => {
34 None
35 }
36 Err(_) => {
David Tolnaycfa5cc02017-11-13 01:05:11 -080037 errorf!("libsyntax paniced\n");
Michael Layzell53fc31a2017-06-07 09:21:53 -040038 None
39 }
40 }
41}
42
43pub fn syn_expr(input: &str) -> Option<syn::Expr> {
David Tolnayc7a5d3d2017-06-04 12:11:05 -070044 match syn::parse_str(input) {
Michael Layzell53fc31a2017-06-07 09:21:53 -040045 Ok(e) => Some(e),
46 Err(msg) => {
47 errorf!("syn failed to parse\n{:?}\n", msg);
48 None
49 }
50 }
51}
David Tolnayc7a5d3d2017-06-04 12:11:05 -070052
53pub fn syn<T: Synom>(tokens: proc_macro2::TokenStream) -> T {
54 let buf = SynomBuffer::new(tokens);
55 let result = T::parse(buf.begin());
56 match result {
57 Ok((rest, t)) => {
58 if rest.eof() {
59 t
60 } else if rest == buf.begin() {
61 panic!("failed to parse anything")
62 } else {
63 panic!("failed to parse all tokens")
64 }
65 }
66 Err(err) => panic!("failed to parse: {}", err),
67 }
68}