plotnik_bytecode/type_system/kind.rs
1//! Canonical type kind definitions.
2//!
3//! This enum represents the semantic type kinds shared across the system.
4//! Different modules may have their own representations that map to/from this.
5
6/// Semantic type kinds.
7///
8/// This is the canonical enumeration of all type kinds, including primitives.
9/// Primitive types (Void, Node, String) are stored as TypeDefs like any other type.
10#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
11#[repr(u8)]
12pub enum TypeKind {
13 /// Unit type - used for definitions with no captures.
14 Void = 0,
15 /// AST node reference.
16 Node = 1,
17 /// Text content extracted from node.
18 String = 2,
19 /// `T?` - optional wrapper, contains zero or one value.
20 Optional = 3,
21 /// `T*` - array of zero or more values.
22 ArrayZeroOrMore = 4,
23 /// `T+` - array of one or more values (non-empty).
24 ArrayOneOrMore = 5,
25 /// Record with named fields.
26 Struct = 6,
27 /// Discriminated union with tagged variants.
28 Enum = 7,
29 /// Named reference to another type (e.g., `type Foo = Bar`).
30 Alias = 8,
31}
32
33impl TypeKind {
34 /// Convert from raw discriminant.
35 pub fn from_u8(v: u8) -> Option<Self> {
36 match v {
37 0 => Some(Self::Void),
38 1 => Some(Self::Node),
39 2 => Some(Self::String),
40 3 => Some(Self::Optional),
41 4 => Some(Self::ArrayZeroOrMore),
42 5 => Some(Self::ArrayOneOrMore),
43 6 => Some(Self::Struct),
44 7 => Some(Self::Enum),
45 8 => Some(Self::Alias),
46 _ => None,
47 }
48 }
49
50 /// Whether this is a primitive/builtin type (Void, Node, String).
51 pub fn is_primitive(self) -> bool {
52 matches!(self, Self::Void | Self::Node | Self::String)
53 }
54
55 /// Whether this is a wrapper type (Optional, ArrayZeroOrMore, ArrayOneOrMore).
56 ///
57 /// Wrapper types contain a single inner type.
58 /// Composite types (Struct, Enum) have named members.
59 pub fn is_wrapper(self) -> bool {
60 matches!(
61 self,
62 Self::Optional | Self::ArrayZeroOrMore | Self::ArrayOneOrMore
63 )
64 }
65
66 /// Whether this is a composite type (Struct, Enum).
67 pub fn is_composite(self) -> bool {
68 matches!(self, Self::Struct | Self::Enum)
69 }
70
71 /// Whether this is an array type.
72 pub fn is_array(self) -> bool {
73 matches!(self, Self::ArrayZeroOrMore | Self::ArrayOneOrMore)
74 }
75
76 /// For array types, whether the array is non-empty.
77 pub fn array_is_non_empty(self) -> bool {
78 matches!(self, Self::ArrayOneOrMore)
79 }
80
81 /// Whether this is an alias type.
82 pub fn is_alias(self) -> bool {
83 matches!(self, Self::Alias)
84 }
85
86 /// Get the display name for primitive types.
87 pub fn primitive_name(self) -> Option<&'static str> {
88 match self {
89 Self::Void => Some("Void"),
90 Self::Node => Some("Node"),
91 Self::String => Some("String"),
92 _ => None,
93 }
94 }
95}