/macros/src/lib.rs

https://github.com/korken89/smlang-rs · Rust · 58 lines · 39 code · 11 blank · 8 comment · 3 complexity · eb7978664e7238e7a139bb6b8e34760c MD5 · raw file

  1. #![recursion_limit = "512"]
  2. extern crate proc_macro;
  3. mod codegen;
  4. #[cfg(feature = "graphviz")]
  5. mod diagramgen;
  6. mod parser;
  7. use syn::parse_macro_input;
  8. // dot -Tsvg statemachine.gv -o statemachine.svg
  9. #[proc_macro]
  10. pub fn statemachine(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
  11. // Parse the syntax into structures
  12. let input = parse_macro_input!(input as parser::StateMachine);
  13. // Validate syntax
  14. match parser::ParsedStateMachine::new(input) {
  15. // Generate code and hand the output tokens back to the compiler
  16. Ok(sm) => {
  17. #[cfg(feature = "graphviz")]
  18. {
  19. use std::io::Write;
  20. // Generate dot syntax for the statemachine.
  21. let diagram = diagramgen::generate_diagram(&sm);
  22. // Start the 'dot' process.
  23. let mut process = std::process::Command::new("dot")
  24. .args(&["-Tsvg", "-o", "statemachine.svg"])
  25. .stdin(std::process::Stdio::piped())
  26. .spawn()
  27. .expect("Failed to execute 'dot'. Are you sure graphviz is installed?");
  28. // Write the dot syntax string to the 'dot' process stdin.
  29. process
  30. .stdin
  31. .as_mut()
  32. .map(|s| s.write_all(diagram.as_bytes()));
  33. // Check the graphviz return status to see if it was successful.
  34. match process.wait() {
  35. Ok(status) => {
  36. if !status.success() {
  37. panic!("'dot' failed to run. Are you sure graphviz is installed?");
  38. }
  39. }
  40. Err(_) => panic!("'dot' failed to run. Are you sure graphviz is installed?"),
  41. }
  42. }
  43. codegen::generate_code(&sm).into()
  44. }
  45. Err(error) => error.to_compile_error().into(),
  46. }
  47. }