plotnik_bytecode/bytecode/
type_meta.rs1use super::{StringId, TypeId};
4
5pub use crate::type_system::TypeKind;
7
8impl TypeKind {
10 pub const ARRAY_STAR: Self = Self::ArrayZeroOrMore;
12 pub const ARRAY_PLUS: Self = Self::ArrayOneOrMore;
14}
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23#[repr(C)]
24pub struct TypeDef {
25 data: u16,
28 count: u8,
30 kind: u8,
32}
33
34const _: () = assert!(std::mem::size_of::<TypeDef>() == 4);
35
36#[derive(Clone, Copy, Debug, PartialEq, Eq)]
38pub enum TypeData {
39 Primitive(TypeKind),
41 Wrapper { kind: TypeKind, inner: TypeId },
43 Composite {
45 kind: TypeKind,
46 member_start: u16,
47 member_count: u8,
48 },
49}
50
51impl TypeDef {
52 pub fn builtin(kind: TypeKind) -> Self {
54 Self {
55 data: 0,
56 count: 0,
57 kind: kind as u8,
58 }
59 }
60
61 pub fn placeholder() -> Self {
63 Self {
64 data: 0,
65 count: 0,
66 kind: 0,
67 }
68 }
69
70 pub fn wrapper(kind: TypeKind, inner: TypeId) -> Self {
72 Self {
73 data: inner.0,
74 count: 0,
75 kind: kind as u8,
76 }
77 }
78
79 pub fn composite(kind: TypeKind, member_start: u16, member_count: u8) -> Self {
81 Self {
82 data: member_start,
83 count: member_count,
84 kind: kind as u8,
85 }
86 }
87
88 pub fn optional(inner: TypeId) -> Self {
90 Self::wrapper(TypeKind::Optional, inner)
91 }
92
93 pub fn alias(target: TypeId) -> Self {
95 Self::wrapper(TypeKind::Alias, target)
96 }
97
98 pub fn array_star(element: TypeId) -> Self {
100 Self::wrapper(TypeKind::ARRAY_STAR, element)
101 }
102
103 pub fn array_plus(element: TypeId) -> Self {
105 Self::wrapper(TypeKind::ARRAY_PLUS, element)
106 }
107
108 pub fn struct_type(member_start: u16, member_count: u8) -> Self {
110 Self::composite(TypeKind::Struct, member_start, member_count)
111 }
112
113 pub fn enum_type(member_start: u16, member_count: u8) -> Self {
115 Self::composite(TypeKind::Enum, member_start, member_count)
116 }
117
118 pub(crate) fn from_bytes(bytes: &[u8]) -> Self {
120 Self {
121 data: u16::from_le_bytes([bytes[0], bytes[1]]),
122 count: bytes[2],
123 kind: bytes[3],
124 }
125 }
126
127 pub fn to_bytes(&self) -> [u8; 4] {
129 let mut bytes = [0u8; 4];
130 bytes[0..2].copy_from_slice(&self.data.to_le_bytes());
131 bytes[2] = self.count;
132 bytes[3] = self.kind;
133 bytes
134 }
135
136 pub fn classify(&self) -> TypeData {
141 let kind = TypeKind::from_u8(self.kind)
142 .unwrap_or_else(|| panic!("invalid TypeKind byte: {}", self.kind));
143 match kind {
144 TypeKind::Void | TypeKind::Node | TypeKind::String => TypeData::Primitive(kind),
145 TypeKind::Optional
146 | TypeKind::ArrayZeroOrMore
147 | TypeKind::ArrayOneOrMore
148 | TypeKind::Alias => TypeData::Wrapper {
149 kind,
150 inner: TypeId(self.data),
151 },
152 TypeKind::Struct | TypeKind::Enum => TypeData::Composite {
153 kind,
154 member_start: self.data,
155 member_count: self.count,
156 },
157 }
158 }
159}
160
161#[derive(Clone, Copy, Debug, PartialEq, Eq)]
166#[repr(C)]
167pub struct TypeName {
168 pub name: StringId,
170 pub type_id: TypeId,
172}
173
174const _: () = assert!(std::mem::size_of::<TypeName>() == 4);
175
176impl TypeName {
177 pub fn new(name: StringId, type_id: TypeId) -> Self {
179 Self { name, type_id }
180 }
181
182 pub fn to_bytes(&self) -> [u8; 4] {
184 let mut bytes = [0u8; 4];
185 bytes[0..2].copy_from_slice(&self.name.get().to_le_bytes());
186 bytes[2..4].copy_from_slice(&self.type_id.0.to_le_bytes());
187 bytes
188 }
189}
190
191#[derive(Clone, Copy, Debug, PartialEq, Eq)]
193#[repr(C)]
194pub struct TypeMember {
195 pub name: StringId,
197 pub type_id: TypeId,
199}
200
201const _: () = assert!(std::mem::size_of::<TypeMember>() == 4);
202
203impl TypeMember {
204 pub fn new(name: StringId, type_id: TypeId) -> Self {
206 Self { name, type_id }
207 }
208
209 pub fn to_bytes(&self) -> [u8; 4] {
211 let mut bytes = [0u8; 4];
212 bytes[0..2].copy_from_slice(&self.name.get().to_le_bytes());
213 bytes[2..4].copy_from_slice(&self.type_id.0.to_le_bytes());
214 bytes
215 }
216}