mycroft_macros_impl/
lib.rs1extern crate combine;
4extern crate mycroft;
5extern crate proc_macro;
6#[macro_use]
7extern crate proc_macro_hack;
8extern crate quote;
9extern crate syn;
10
11use combine::Parser;
12
13fn compile(prog: &str) -> String {
14 let prog = match mycroft::parse::program().parse(prog) {
15 Ok((p, "")) => p,
16 Ok((_, trail)) => panic!("Trailing code in mycroft program: {}", trail),
17 Err(e) => panic!("Parse error in mycroft program: {}", e),
18 };
19 let ir = mycroft::ir::Program::from_ast(prog)
20 .unwrap_or_else(|e| panic!("Error raising mycroft program to IR: {}", e));
21 mycroft::codegen::program(&ir).to_string()
22}
23
24fn input_explanation<T, R>(_: R) -> T {
25 panic!("Input to 'mycroft_program!' must be a mycroft program as a string literal.")
26}
27
28proc_macro_item_impl! {
29pub fn mycroft_program_impl(input: &str) -> String {
31 let expr = syn::parse_expr(input).unwrap_or_else(input_explanation);
32 let prog_str = match expr.node {
33 syn::ExprKind::Lit(syn::Lit::Str(s, _)) => s,
34 _ => input_explanation(()),
35 };
36 compile(prog_str.as_str())
37}
38}
39
40fn input_explanation_file<T>(s: String) -> T {
41 panic!("Expected file name as a string, got {}", s)
42}
43
44proc_macro_item_impl! {
45pub fn mycroft_files_impl(input: &str) -> String {
48 use std::io::prelude::*;
49 use std::fs::File;
50 let prog_str = input
51 .split(',')
52 .map(|file_name_str| {
53 let expr = syn::parse_expr(file_name_str).unwrap_or_else(input_explanation_file);
54 let file_name = match expr.node {
55 syn::ExprKind::Lit(syn::Lit::Str(s, _)) => s,
56 e => input_explanation_file(format!("{:?}", e)),
57 };
58 let mut fd = File::open(&file_name).expect(&format!(
59 "Could not read mycroft program file: {}",
60 file_name
61 ));
62 let mut contents = String::new();
63 fd.read_to_string(&mut contents).expect(&format!(
64 "Could not read mycroft program file: {}",
65 file_name
66 ));
67 contents
68 })
69 .collect::<Vec<_>>()
70 .join("\n");
71 compile(prog_str.as_str())
72}
73}