bern_kernel_macros/lib.rs
1//! Procedural macros for the `bern_kernel`.
2//!
3//! This crate provides macros that:
4//! - simplify the kernel usage
5//! - make kernel development less tedious (used internally)
6mod enum_map;
7mod process;
8
9use proc_macro::TokenStream;
10use quote::ToTokens;
11
12/// Generates an enum with values and a map to match the enum to another type.
13///
14/// e.g.
15/// ```ignore
16/// enum_map!{
17/// Size, u8;
18/// S128 = 5, 128;
19/// S256 = 6, 256;
20/// }
21/// ```
22/// expands to
23/// ```ignore
24/// #[derive(Copy, Clone, Debug, Eq, PartialEq)]
25/// #[repr(u8)]
26/// pub enum Size {
27/// S128 = 5,
28/// S256 = 6,
29/// }
30/// impl Size {
31/// pub const fn bits(self) -> u8 {
32/// self as u8
33/// }
34/// }
35///
36/// #[macro_export]
37/// macro_rules! size_from {
38/// (128) => { Size::S128 };
39/// (256) => { Size::S256 };
40/// ($x:expr) => {
41/// compile_error!("Invalid parameter - possible values are: 128, 256");
42/// }
43/// }
44/// ```
45/// ```
46#[doc(hidden)]
47#[proc_macro]
48pub fn enum_map(input: TokenStream) -> TokenStream {
49 let map = syn::parse_macro_input!(input as enum_map::EnumMap);
50 let mut output = proc_macro2::TokenStream::new();
51 map.to_tokens(&mut output);
52 TokenStream::from(output)
53}
54
55/// Creates a new process and the required linker sections.
56///
57/// # Example
58/// ```ignore
59/// // Create a process named `my_proc` with 32kB memory.
60/// static MY_PROC: &Process = bern_kernel::new_process!(my_proc, 32768);
61///
62/// // Place static variable in process memory.
63/// #[link_section = ".process.my_proc"]
64/// static DATA: u32 = 0xDEADBEEF;
65///
66/// #[entry]
67/// fn main() -> ! {
68/// let board = Board::new();
69/// bern_kernel::init();
70/// /*..*/
71/// MY_PROC.init(move |c| {
72/// // Spawn threads.
73/// }).unwrap();
74/// /*..*/
75/// bern_kernel::start();
76/// }
77/// ```
78#[proc_macro]
79pub fn new_process(input: TokenStream) -> TokenStream {
80 let map = syn::parse_macro_input!(input as process::ProcessInfo);
81 let mut output = proc_macro2::TokenStream::new();
82 map.to_tokens(&mut output);
83 TokenStream::from(output)
84}