feat: add no-std common runtime
Add an alloc-backed common library with direct platform I/O. Build a host attribute macro for async entry points and keep runtime boilerplate outside application code. Compile the library, macro, and example directly with rustc through CMake. Co-Authored-By: luna (openrouter/openai/gpt-5.6-luna): runtime work
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::{Ident, TokenStream, TokenTree};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let mut output = TokenStream::new();
|
||||
let mut saw_fn = false;
|
||||
let mut renamed = false;
|
||||
let mut is_async = false;
|
||||
|
||||
for token in item {
|
||||
match &token {
|
||||
TokenTree::Ident(identifier)
|
||||
if identifier.to_string() == "async" && !saw_fn =>
|
||||
{
|
||||
is_async = true;
|
||||
}
|
||||
TokenTree::Ident(identifier) if identifier.to_string() == "fn" => {
|
||||
saw_fn = true;
|
||||
}
|
||||
TokenTree::Ident(identifier)
|
||||
if saw_fn && !renamed && identifier.to_string() == "main" =>
|
||||
{
|
||||
output.extend([TokenTree::Ident(Ident::new(
|
||||
"__rslibc_user_main",
|
||||
identifier.span(),
|
||||
))]);
|
||||
renamed = true;
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
output.extend([token]);
|
||||
}
|
||||
|
||||
if !renamed {
|
||||
return "compile_error!(\"rslibc::main expects fn main()\");"
|
||||
.parse()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let wrapper = if is_async {
|
||||
"fn main() { rslibc::runtime::block_on(__rslibc_user_main()); } rslibc::entry!(main);"
|
||||
} else {
|
||||
"fn main() { __rslibc_user_main(); } rslibc::entry!(main);"
|
||||
};
|
||||
|
||||
output.extend(TokenStream::from_str(wrapper).unwrap());
|
||||
output
|
||||
}
|
||||
Reference in New Issue
Block a user