Files
wasmtime/crates/generate/src/names.rs
Pat Hickey 62e00434b0 structs implementing Copy are scaffolded out.
todo: need an unsafe method for casting pointers in order to validate
contents via recursive descent
2020-01-28 15:45:52 -08:00

105 lines
3.4 KiB
Rust

use heck::{CamelCase, SnakeCase};
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote};
use witx::{AtomType, BuiltinType, Id, TypeRef};
#[derive(Debug, Clone)]
pub struct Names {
// FIXME: overrides go in here, so we can map e.g. 2big => TooBig
}
impl Names {
pub fn new() -> Names {
Names {}
}
pub fn type_(&self, id: &Id) -> TokenStream {
let ident = format_ident!("{}", id.as_str().to_camel_case());
quote!(#ident)
}
pub fn builtin_type(&self, b: BuiltinType) -> TokenStream {
match b {
BuiltinType::String => quote!(String),
BuiltinType::U8 => quote!(u8),
BuiltinType::U16 => quote!(u16),
BuiltinType::U32 => quote!(u32),
BuiltinType::U64 => quote!(u64),
BuiltinType::S8 => quote!(i8),
BuiltinType::S16 => quote!(i16),
BuiltinType::S32 => quote!(i32),
BuiltinType::S64 => quote!(i64),
BuiltinType::F32 => quote!(f32),
BuiltinType::F64 => quote!(f64),
BuiltinType::Char8 => quote!(char),
BuiltinType::USize => quote!(usize),
}
}
pub fn atom_type(&self, atom: AtomType) -> TokenStream {
match atom {
AtomType::I32 => quote!(i32),
AtomType::I64 => quote!(i64),
AtomType::F32 => quote!(f32),
AtomType::F64 => quote!(f64),
}
}
pub fn type_ref(&self, tref: &TypeRef) -> TokenStream {
match tref {
TypeRef::Name(nt) => {
let ident = self.type_(&nt.name);
quote!(#ident)
}
TypeRef::Value(ty) => match &**ty {
witx::Type::Builtin(builtin) => self.builtin_type(*builtin),
witx::Type::Pointer(pointee) => {
let pointee_type = self.type_ref(&pointee);
quote!(::memory::GuestPtrMut<#pointee_type>)
}
witx::Type::ConstPointer(pointee) => {
let pointee_type = self.type_ref(&pointee);
quote!(::memory::GuestPtr<#pointee_type>)
}
_ => unimplemented!("anonymous type ref"),
},
}
}
pub fn enum_variant(&self, id: &Id) -> Ident {
// FIXME this is a hack - just a proof of concept.
if id.as_str().starts_with('2') {
format_ident!("TooBig")
} else {
format_ident!("{}", id.as_str().to_camel_case())
}
}
pub fn struct_member(&self, id: &Id) -> Ident {
format_ident!("{}", id.as_str().to_snake_case())
}
pub fn module(&self, id: &Id) -> Ident {
format_ident!("{}", id.as_str().to_snake_case())
}
pub fn trait_name(&self, id: &Id) -> Ident {
format_ident!("{}", id.as_str().to_camel_case())
}
pub fn func(&self, id: &Id) -> Ident {
format_ident!("{}", id.as_str().to_snake_case())
}
pub fn func_param(&self, id: &Id) -> Ident {
format_ident!("{}", id.as_str().to_snake_case())
}
/// For when you need a {name}_ptr binding for passing a value by reference:
pub fn func_ptr_binding(&self, id: &Id) -> Ident {
format_ident!("{}_ptr", id.as_str().to_snake_case())
}
/// For when you need a {name}_len binding for passing an array:
pub fn func_len_binding(&self, id: &Id) -> Ident {
format_ident!("{}_len", id.as_str().to_snake_case())
}
}