Skip to content

Commit

Permalink
WIP Fixing generator for test.capnp
Browse files Browse the repository at this point in the history
  • Loading branch information
ObsidianMinor committed Sep 18, 2024
1 parent 9ce70b6 commit d893da3
Show file tree
Hide file tree
Showing 11 changed files with 26,092 additions and 183 deletions.
90 changes: 40 additions & 50 deletions recapnc/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,12 @@ struct FileContext {
required_imports: BTreeSet<u64>,
}

#[derive(Clone, Copy, PartialEq, Eq)]
enum TypeContext {
Field,
Const,
}

pub struct GeneratorContext {
loader: SchemaLoader,
info: NodeInfoMap,
Expand Down Expand Up @@ -715,7 +721,7 @@ impl GeneratorContext {
Box::new(syn::parse_quote!(_p::Group<#path>))
},
FieldType::Slot { field_type, .. } => {
self.resolve_type(scope, &field_type, ctx)?
self.resolve_type(scope, &field_type, TypeContext::Field, ctx)?
},
})
}
Expand All @@ -724,23 +730,10 @@ impl GeneratorContext {
&self,
scope: &TypeScope,
info: &Type,
ty_ctx: TypeContext,
ctx: &mut FileContext,
) -> Result<Box<syn::Type>> {
let base = self.resolve_type_kind(scope, &info.kind, ctx)?;
let mut wrapped = base;
for _ in 0..info.list_depth {
wrapped = syn::parse_quote!(_p::List<#wrapped>);
}
Ok(wrapped)
}

fn resolve_type_kind(
&self,
scope: &TypeScope,
info: &TypeKind,
ctx: &mut FileContext,
) -> Result<Box<syn::Type>> {
Ok(match info {
let mut rust_ty = match &info.kind {
TypeKind::Void => syn::parse_quote!(()),
TypeKind::Bool => syn::parse_quote!(bool),
TypeKind::Int8 => syn::parse_quote!(i8),
Expand All @@ -759,8 +752,12 @@ impl GeneratorContext {
ctx.required_imports.insert(type_info.scope.file.id);
}

let resolved = type_info.resolve_path(scope);
syn::parse_quote!(_p::Enum<#resolved>)
let path = type_info.resolve_path(scope);
if ty_ctx == TypeContext::Const && !info.is_list() {
syn::parse_quote!(#path)
} else {
syn::parse_quote!(_p::Enum<#path>)
}
},
TypeKind::Data => syn::parse_quote!(_p::Data),
TypeKind::Text => syn::parse_quote!(_p::Text),
Expand All @@ -770,8 +767,8 @@ impl GeneratorContext {
ctx.required_imports.insert(type_info.scope.file.id);
}

let resolved = type_info.resolve_path(scope);
syn::parse_quote!(_p::Struct<#resolved>)
let path = type_info.resolve_path(scope);
syn::parse_quote!(_p::Struct<#path>)
},
TypeKind::Interface { .. } => syn::parse_quote!(_p::AnyPtr), // TODO
TypeKind::AnyPointer => syn::parse_quote!(_p::AnyPtr),
Expand All @@ -780,7 +777,14 @@ impl GeneratorContext {
TypeKind::AnyCapability => syn::parse_quote!(_p::AnyPtr), // TODO
TypeKind::ScopeBound { .. } => syn::parse_quote!(_p::AnyPtr), // TODO
TypeKind::ImplicitMethodParameter { .. } => syn::parse_quote!(_p::AnyPtr), // TODO
})
};
for _ in 0..info.list_depth {
rust_ty = syn::parse_quote!(_p::List<#rust_ty>);
}
if ty_ctx == TypeContext::Const && info.is_ptr_field() {
rust_ty = syn::parse_quote!(_p::ty::ConstPtr<#rust_ty>)
}
Ok(rust_ty)
}

fn generate_field_default_for_type(
Expand Down Expand Up @@ -842,12 +846,12 @@ impl GeneratorContext {
} else {
use TypeKind::*;
match &type_info.kind {
Void => todo!(),
Bool => todo!(),
Int8 | Uint8 => todo!(),
Int16 | Uint16 | Enum { .. } => todo!(),
Int32 | Uint32 | Float32 => todo!(),
Int64 | Uint64 | Float64 => todo!(),
Void => ElementSize::Void,
Bool => ElementSize::Bit,
Int8 | Uint8 => ElementSize::Byte,
Int16 | Uint16 | Enum { .. } => ElementSize::TwoBytes,
Int32 | Uint32 | Float32 => ElementSize::FourBytes,
Int64 | Uint64 | Float64 => ElementSize::EightBytes,
Struct { schema, .. } =>
ElementSize::InlineComposite(schema.struct_size()),
AnyStruct => {
Expand All @@ -863,7 +867,8 @@ impl GeneratorContext {

assert_eq!(value_element_size, expected_element_size);

generate_untyped_list_value(&value)
let expr = generate_untyped_list_value(&value);
syn::parse_quote!(::core::option::Option::Some(#expr))
} else {
quote_none!()
});
Expand Down Expand Up @@ -1007,26 +1012,11 @@ impl GeneratorContext {
let v = schema.value();
Ok(GeneratedConst {
ident: info.ident.clone(),
const_type: self.resolve_const_type(&info.scope, &t, ctx)?,
const_type: self.resolve_type(&info.scope, &t, TypeContext::Const, ctx)?,
value: self.generate_const_value(&info.scope, &t, &v)?,
})
}

fn resolve_const_type(
&self,
scope: &TypeScope,
info: &Type,
ctx: &mut FileContext,
) -> Result<Box<syn::Type>> {
let base = self.resolve_type(scope, info, ctx)?;
let wrapped = if info.is_ptr_field() {
syn::parse_quote!(_p::ty::ConstPtr<#base>)
} else {
base
};
Ok(wrapped)
}

fn generate_const_value(
&self,
scope: &TypeScope,
Expand Down Expand Up @@ -1076,12 +1066,12 @@ impl GeneratorContext {
};

let expr = if ptr.is_null() {
syn::parse_quote!(_p::ConstPtr::null())
syn::parse_quote!(_p::ty::ConstPtr::null())
} else {
let slice = ptr_to_slice(&ptr);
let words = words_lit(&slice);

syn::parse_quote!(unsafe { _p::ConstPtr::new(#words) })
syn::parse_quote!(unsafe { _p::ty::ConstPtr::new(#words) })
};

Ok(expr)
Expand All @@ -1090,7 +1080,7 @@ impl GeneratorContext {

fn words_lit(words: &[Word]) -> TokenStream {
let words = words.iter().map(|Word([b0, b1, b2, b3, b4, b5, b6, b7])| {
quote!(Word([#b0, #b1, #b2, #b3, #b4, #b5, #b6, #b7]))
quote!(_p::Word([#b0, #b1, #b2, #b3, #b4, #b5, #b6, #b7]))
});

quote!(&[#(#words),*])
Expand Down Expand Up @@ -1118,7 +1108,7 @@ fn generate_untyped_ptr_value(s: &any::PtrReader) -> Box<syn::Expr> {
let slice = ptr_to_slice(s);
let words = words_lit(&slice);

syn::parse_quote!(_p::PtrReader::slice_unchecked(#words))
syn::parse_quote!(unsafe { _p::PtrReader::slice_unchecked(#words) })
}

fn ptr_to_slice(p: &any::PtrReader) -> Box<[Word]> {
Expand Down Expand Up @@ -1163,7 +1153,7 @@ fn generate_untyped_struct_value(s: &any::StructReader) -> Box<syn::Expr> {
let StructSize { data, ptrs } = s.as_ref().size();
let size = quote!(_p::StructSize { data: #data, ptrs: #ptrs });

syn::parse_quote!(_p::StructReader::slice_unchecked(#words, #size))
syn::parse_quote!(unsafe { _p::StructReader::slice_unchecked(#words, #size) })
}

/// Deep-clone a struct into an array of words without the root pointer.
Expand Down Expand Up @@ -1211,7 +1201,7 @@ fn generate_untyped_list_value(list: &any::ListReader) -> Box<syn::Expr> {

let element_size_quote = element_size_to_tokens(value_element_size);

syn::parse_quote!(_p::ListReader::slice_unchecked(#words, #len, #element_size_quote))
syn::parse_quote!(unsafe { _p::ListReader::slice_unchecked(#words, #len, #element_size_quote) })
}

/// Deep-clone a list into an array of words without the root pointer.
Expand Down
Loading

0 comments on commit d893da3

Please sign in to comment.