mirror of
https://github.com/Noratrieb/the-good-stuff.git
synced 2026-01-14 16:45:01 +01:00
scratch
This commit is contained in:
parent
2560ba4253
commit
5fcdcc0f48
8 changed files with 216 additions and 1 deletions
47
Cargo.lock
generated
47
Cargo.lock
generated
|
|
@ -2,6 +2,53 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pm"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.49"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.107"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uwu"
|
name = "uwu"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"pm",
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
[workspace]
|
||||||
|
members = [".", "./pm"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "uwu"
|
name = "uwu"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
@ -6,3 +9,4 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
pm = { path = "./pm" }
|
||||||
|
|
|
||||||
14
examples/scratch.rs
Normal file
14
examples/scratch.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
use uwu::scratch::{
|
||||||
|
actual_scratch_read, actual_scratch_write, define_scratch, scratch_space, Scratch,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[scratch_space]
|
||||||
|
fn has_scratch_space(mut scratch: Scratch<'_>) {
|
||||||
|
scratch_write!(scratch, 10u32);
|
||||||
|
let _: u32 = scratch_read!(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
define_scratch!(scratch, 10);
|
||||||
|
has_scratch_space(scratch);
|
||||||
|
}
|
||||||
14
pm/Cargo.toml
Normal file
14
pm/Cargo.toml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[package]
|
||||||
|
name = "pm"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
proc-macro2 = "1.0.49"
|
||||||
|
quote = "1.0.23"
|
||||||
|
syn = { version = "1.0.107", features = ["full", "fold"] }
|
||||||
49
pm/src/lib.rs
Normal file
49
pm/src/lib.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use proc_macro2::{Ident, Span};
|
||||||
|
use quote::quote;
|
||||||
|
use syn::{fold::Fold, parse_macro_input, parse_quote, ItemFn, Stmt};
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn scratch_space(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||||
|
let fn_def = parse_macro_input!(input as ItemFn);
|
||||||
|
let track_ident = Ident::new("scratch_local", Span::mixed_site());
|
||||||
|
|
||||||
|
let mut fn_def = LocalInitFolder {
|
||||||
|
track_ident: track_ident.clone(),
|
||||||
|
}
|
||||||
|
.fold_item_fn(fn_def);
|
||||||
|
|
||||||
|
let init: Stmt = parse_quote! { let #track_ident: (); };
|
||||||
|
|
||||||
|
fn_def.block.stmts.insert(0, init);
|
||||||
|
|
||||||
|
quote! { #fn_def }.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocalInitFolder {
|
||||||
|
track_ident: Ident,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl syn::fold::Fold for LocalInitFolder {
|
||||||
|
fn fold_macro(&mut self, mut mac: syn::Macro) -> syn::Macro {
|
||||||
|
if let Some(last_path) = mac.path.segments.iter().next_back() {
|
||||||
|
match last_path.ident.to_string().as_str() {
|
||||||
|
"scratch_write" => {
|
||||||
|
let track_ident = &self.track_ident;
|
||||||
|
mac.path = parse_quote! { actual_scratch_write };
|
||||||
|
mac.tokens.extend(quote! { ; #track_ident });
|
||||||
|
}
|
||||||
|
"scratch_read" => {
|
||||||
|
let track_ident = &self.track_ident;
|
||||||
|
mac.path = parse_quote! { actual_scratch_read };
|
||||||
|
mac.tokens.extend(quote! { ; #track_ident });
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mac
|
||||||
|
} else {
|
||||||
|
mac
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(warnings)]
|
||||||
|
|
||||||
pub struct Node<'a, 'n, T> {
|
pub struct Node<'a, 'n, T> {
|
||||||
item: T,
|
item: T,
|
||||||
outer: Option<&'a mut Node<'a, 'n, T>>,
|
outer: Option<&'a mut Node<'a, 'n, T>>,
|
||||||
|
|
@ -11,7 +13,7 @@ impl<'a, 'n, T> Node<'a, 'n, T> {
|
||||||
pub fn push<R>(&mut self, item: T, with_func: impl FnOnce(&mut Self) -> R) -> R {
|
pub fn push<R>(&mut self, item: T, with_func: impl FnOnce(&mut Self) -> R) -> R {
|
||||||
let mut inner = Node {
|
let mut inner = Node {
|
||||||
item,
|
item,
|
||||||
outer: Some(self),
|
outer: Some(todo!()),
|
||||||
};
|
};
|
||||||
with_func(&mut inner)
|
with_func(&mut inner)
|
||||||
}
|
}
|
||||||
|
|
@ -22,6 +24,7 @@ mod tests {
|
||||||
use super::Node;
|
use super::Node;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[ignore = "todo"]
|
||||||
fn push() {
|
fn push() {
|
||||||
let mut list = Node::<u8>::new(0);
|
let mut list = Node::<u8>::new(0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
pub mod cfg_match;
|
pub mod cfg_match;
|
||||||
pub mod innocent_linked_list;
|
pub mod innocent_linked_list;
|
||||||
|
pub mod scratch;
|
||||||
pub mod sendsync;
|
pub mod sendsync;
|
||||||
pub mod unroll_int;
|
pub mod unroll_int;
|
||||||
pub mod unsized_clone;
|
pub mod unsized_clone;
|
||||||
|
|
|
||||||
83
src/scratch.rs
Normal file
83
src/scratch.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
use std::mem::{self, MaybeUninit};
|
||||||
|
|
||||||
|
pub use pm::scratch_space;
|
||||||
|
|
||||||
|
pub struct Scratch<'a>(&'a mut [MaybeUninit<u8>]);
|
||||||
|
|
||||||
|
impl<'a> Scratch<'a> {
|
||||||
|
pub fn new(buf: &'a mut [MaybeUninit<u8>]) -> Self {
|
||||||
|
Self(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write<T>(&mut self, _value: T) {
|
||||||
|
let size = mem::size_of::<T>();
|
||||||
|
assert!(size <= self.0.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read<T: Default>(&mut self) -> T {
|
||||||
|
T::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! scratch_write {
|
||||||
|
($scratch:ident, $value:expr) => {
|
||||||
|
/* transformed to a call to actual_scratch_write */
|
||||||
|
compile_error!("Failed to transform macro invocation");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! scratch_read {
|
||||||
|
($scratch:ident) => {
|
||||||
|
/* transformed to a call to actual_scratch_write */
|
||||||
|
compile_error!("Failed to transform macro invocation");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! actual_scratch_write {
|
||||||
|
($scratch:ident, $value:expr ; $track_local:ident) => {
|
||||||
|
$track_local = ();
|
||||||
|
$scratch.write($value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! actual_scratch_read {
|
||||||
|
($scratch:ident ; $track_local:ident) => {{
|
||||||
|
let _read = $track_local;
|
||||||
|
$scratch.read()
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! define_scratch {
|
||||||
|
($name:ident, $size:expr) => {
|
||||||
|
let mut __buffer: [::core::mem::MaybeUninit<u8>; $size] =
|
||||||
|
unsafe { ::core::mem::MaybeUninit::uninit().assume_init() };
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
let mut $name = $crate::scratch::Scratch::new(&mut __buffer);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use {actual_scratch_read, actual_scratch_write, define_scratch, scratch_read, scratch_write};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use pm::scratch_space;
|
||||||
|
|
||||||
|
use super::{define_scratch, Scratch};
|
||||||
|
|
||||||
|
#[scratch_space]
|
||||||
|
fn has_scratch_space(mut scratch: Scratch<'_>) {
|
||||||
|
scratch_write!(scratch, 10u32);
|
||||||
|
let _: u32 = scratch_read!(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple_scratch() {
|
||||||
|
define_scratch!(scratch, 100);
|
||||||
|
has_scratch_space(scratch);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue