use super::{StringId, TypeId};
pub use crate::type_system::TypeKind;
impl TypeKind {
pub const ARRAY_STAR: Self = Self::ArrayZeroOrMore;
pub const ARRAY_PLUS: Self = Self::ArrayOneOrMore;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(C)]
pub struct TypeDef {
data: u16,
count: u8,
kind: u8,
}
const _: () = assert!(std::mem::size_of::<TypeDef>() == 4);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TypeData {
Primitive(TypeKind),
Wrapper { kind: TypeKind, inner: TypeId },
Composite {
kind: TypeKind,
member_start: u16,
member_count: u8,
},
}
impl TypeDef {
pub fn builtin(kind: TypeKind) -> Self {
Self {
data: 0,
count: 0,
kind: kind as u8,
}
}
pub fn placeholder() -> Self {
Self {
data: 0,
count: 0,
kind: 0,
}
}
pub fn wrapper(kind: TypeKind, inner: TypeId) -> Self {
Self {
data: inner.0,
count: 0,
kind: kind as u8,
}
}
pub fn composite(kind: TypeKind, member_start: u16, member_count: u8) -> Self {
Self {
data: member_start,
count: member_count,
kind: kind as u8,
}
}
pub fn optional(inner: TypeId) -> Self {
Self::wrapper(TypeKind::Optional, inner)
}
pub fn alias(target: TypeId) -> Self {
Self::wrapper(TypeKind::Alias, target)
}
pub fn array_star(element: TypeId) -> Self {
Self::wrapper(TypeKind::ARRAY_STAR, element)
}
pub fn array_plus(element: TypeId) -> Self {
Self::wrapper(TypeKind::ARRAY_PLUS, element)
}
pub fn struct_type(member_start: u16, member_count: u8) -> Self {
Self::composite(TypeKind::Struct, member_start, member_count)
}
pub fn enum_type(member_start: u16, member_count: u8) -> Self {
Self::composite(TypeKind::Enum, member_start, member_count)
}
pub(crate) fn from_bytes(bytes: &[u8]) -> Self {
Self {
data: u16::from_le_bytes([bytes[0], bytes[1]]),
count: bytes[2],
kind: bytes[3],
}
}
pub fn to_bytes(&self) -> [u8; 4] {
let mut bytes = [0u8; 4];
bytes[0..2].copy_from_slice(&self.data.to_le_bytes());
bytes[2] = self.count;
bytes[3] = self.kind;
bytes
}
pub fn classify(&self) -> TypeData {
let kind = TypeKind::from_u8(self.kind)
.unwrap_or_else(|| panic!("invalid TypeKind byte: {}", self.kind));
match kind {
TypeKind::Void | TypeKind::Node | TypeKind::String => TypeData::Primitive(kind),
TypeKind::Optional
| TypeKind::ArrayZeroOrMore
| TypeKind::ArrayOneOrMore
| TypeKind::Alias => TypeData::Wrapper {
kind,
inner: TypeId(self.data),
},
TypeKind::Struct | TypeKind::Enum => TypeData::Composite {
kind,
member_start: self.data,
member_count: self.count,
},
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(C)]
pub struct TypeName {
pub name: StringId,
pub type_id: TypeId,
}
const _: () = assert!(std::mem::size_of::<TypeName>() == 4);
impl TypeName {
pub fn new(name: StringId, type_id: TypeId) -> Self {
Self { name, type_id }
}
pub fn to_bytes(&self) -> [u8; 4] {
let mut bytes = [0u8; 4];
bytes[0..2].copy_from_slice(&self.name.get().to_le_bytes());
bytes[2..4].copy_from_slice(&self.type_id.0.to_le_bytes());
bytes
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(C)]
pub struct TypeMember {
pub name: StringId,
pub type_id: TypeId,
}
const _: () = assert!(std::mem::size_of::<TypeMember>() == 4);
impl TypeMember {
pub fn new(name: StringId, type_id: TypeId) -> Self {
Self { name, type_id }
}
pub fn to_bytes(&self) -> [u8; 4] {
let mut bytes = [0u8; 4];
bytes[0..2].copy_from_slice(&self.name.get().to_le_bytes());
bytes[2..4].copy_from_slice(&self.type_id.0.to_le_bytes());
bytes
}
}