1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
extern crate cc; extern crate proc_macro2; extern crate syn; use std::path::{Path, PathBuf}; use syn::Item; mod generate; mod extract; use extract::extract_asm; use std::fs::{read_dir, File}; use std::io::Read; use std::env; #[macro_export] macro_rules! lasm { ($abi:tt fn $name:tt -> %$ret:tt { $($dontcare:tt)* } $($more:tt)*) => (lasm!($($more)*);); ($abi:tt fn $name:tt { $($dontcare:tt)* } $($more:tt)*) => (lasm!($($more)*);); ($abi:tt fn $name:tt -> $ret:tt { $($dontcare:tt)* } $($more:tt)*) => (lasm!($($more)*);); ($abi:tt fn $name:tt { $($dontcare:tt)* } $($more:tt)*) => (lasm!($($more)*);); () => {}; } #[derive(Clone, Debug, PartialEq)] pub struct Asm { pub name: String, pub ret: Option<String>, pub body: Vec<String>, } pub fn parse_file(code: String) { let syntax = syn::parse_file(&code).expect("Unable to parse file"); for item in syntax.items { match item { Item::Macro(macro_item) => { let mac = macro_item.mac; if mac.path == "lasm".into() { extract_asm(mac.tts); } } _ => {} } } } pub fn parse_dir(dir: &Path) { for item in read_dir(dir).unwrap() { match item { Ok(item) => { let item_type = item.file_type().unwrap(); if item_type.is_dir() { parse_dir(&item.path()) } else if item.path().to_str().unwrap().ends_with(".rs") { let mut file = File::open(item.path()).unwrap(); let mut content = String::new(); file.read_to_string(&mut content).unwrap(); parse_file(content); } } _ => println!("cargo:warning=unable to read all source files"), } } } pub fn parse() { let dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("src"); parse_dir(&dir); } #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }