Start stdin

This commit is contained in:
2026-03-13 11:15:52 +01:00
parent f67718c3fe
commit de6ef959ce
18 changed files with 347 additions and 72 deletions

View File

@@ -10,3 +10,4 @@ proc-macro = true
proc-macro2 = "1"
quote = "1"
syn = { version = "2", features = ["full"] }
zyn = "0.5"

View File

@@ -1,27 +1,44 @@
use core::iter::Iterator;
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{Meta, parse_macro_input, spanned::Spanned};
use syn::{Meta, spanned::Spanned};
use zyn::zyn;
#[proc_macro_derive(VolatilePackedStruct, attributes(read_only))]
pub fn derive_volatile_packed_struct(item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as syn::DeriveInput);
#[zyn::element(debug)]
fn struct_getter(field: syn::Field) -> zyn::TokenStream {
let field_name = field.ident.as_ref().unwrap();
zyn! {
pub fn {{ field_name | ident:"get_{}" }}(self: *const Self) -> {{ field.ty }} {
unsafe {
(&raw const (*self).{{ field_name }}).read_volatile()
}
}
}
}
#[zyn::element]
fn struct_setter(field: syn::Field) -> zyn::TokenStream {
let field_name = field.ident.as_ref().unwrap();
zyn! {
pub fn {{ field_name | ident:"set_{}" }}(self: *mut Self, value: {{ field.ty }}) {
unsafe {
(&raw mut (*self).{{ field_name }}).write_volatile(value);
}
}
}
}
#[zyn::derive("VolatilePackedStruct", attributes(read_only), debug)]
pub fn derive_volatile_packed_struct(#[zyn(input)] input: syn::DeriveInput) -> TokenStream {
if !input.attrs.iter().any(|attr| match &attr.meta {
Meta::List(list) => list.path.segments.last().is_some_and(|s| s.ident == "repr"),
_ => false,
}) {
return syn::Error::new(
input.span(),
"Item should use a #[repr(packed)] representation",
)
.into_compile_error()
.into();
bail!("Item should use a #[repr(packed)] representation");
}
let fields = match input.data {
syn::Data::Struct(data_struct) => match data_struct.fields {
let fields = match &input.data {
syn::Data::Struct(data_struct) => match &data_struct.fields {
syn::Fields::Named(fields_named) => fields_named,
syn::Fields::Unnamed(_) | syn::Fields::Unit => unimplemented!(),
},
@@ -29,42 +46,16 @@ pub fn derive_volatile_packed_struct(item: TokenStream) -> TokenStream {
syn::Data::Union(_) => unimplemented!(),
};
let mut getters = Vec::new();
let mut setters = Vec::new();
for field in fields.named {
let field_name = field.ident.unwrap();
if field_name.to_string().starts_with("_") {
continue;
}
let ty = field.ty;
let getter_name = format_ident!("get_{}", field_name);
let setter_name = format_ident!("set_{}", field_name);
getters.push(quote! {
pub fn #getter_name(self: *const Self) -> #ty {
unsafe {
(&raw const (*self).#field_name).read_volatile()
}
}
});
setters.push(quote! {
pub fn #setter_name(self: *mut Self, value: #ty) {
unsafe {
(&raw mut (*self).#field_name).write_volatile(value);
}
}
});
}
let struct_path = input.ident;
let (impl_generics, type_generics, where_clause) = input.generics.split_for_impl();
quote! {
impl #impl_generics #struct_path #type_generics #where_clause {
#(#getters)*
#(#setters)*
zyn! {
impl {{ impl_generics }} {{ input.ident }} {{ type_generics }} {{ where_clause }} {
@for (field in &fields.named) {
@if (!field.ident.as_ref().unwrap().to_string().starts_with("_")) {
@struct_getter(field = field.clone())
@struct_setter(field = field.clone())
}
}
}
}
.into()
}

View File

@@ -12,3 +12,4 @@ regex = "1"
proc-macro2 = "1"
quote = "1"
syn = { version = "2", features = ["full"] }
zyn = "0.5"

View File

@@ -96,7 +96,7 @@ pub fn parse_image(
Ok((width, height, name_ident, byte_count, byte_tokens))
}
pub fn include_font_plate_impl(input: TokenStream) -> TokenStream {
pub fn include_bitmap_image_impl(input: TokenStream) -> TokenStream {
let (_, _, _, _, byte_tokens) = parse_image(input).unwrap();
let output = quote! {

View File

@@ -3,6 +3,6 @@ mod image;
use proc_macro::TokenStream;
#[proc_macro]
pub fn include_font_plate(input: TokenStream) -> TokenStream {
image::include_font_plate_impl(input)
pub fn include_bitmap_image(input: TokenStream) -> TokenStream {
image::include_bitmap_image_impl(input)
}

View File

@@ -7,6 +7,7 @@ use crate::fs::File;
#[repr(u64)]
pub enum SysCall {
Read = 0,
Write = 1,
Open = 2,
Seek = 8,
@@ -22,6 +23,7 @@ pub enum SysCall {
impl From<u64> for SysCall {
fn from(value: u64) -> Self {
match value {
0 => SysCall::Read,
1 => SysCall::Write,
2 => SysCall::Open,
8 => SysCall::Seek,
@@ -151,6 +153,13 @@ pub fn write(file: &mut File, buf: &[u8]) {
syscall!(SysCall::Write, file.as_fd(), ptr as u64, size as u64);
}
}
pub fn read(file: &mut File, buf: &mut [u8]) {
unsafe {
let ptr = buf.as_ptr();
let size = buf.len();
syscall!(SysCall::Read, file.as_fd(), ptr as u64, size as u64);
}
}
pub fn seek(file: &mut File, seek: SeekFrom) {
unsafe {
let (discriminant, value) = match seek {