wright/ast/
ty.rs

1//! AST models for type signatures in wright source.
2
3use crate::{ast::path::Path, source_tracking::fragment::Fragment};
4
5/// A type signature in source code.
6#[derive(Debug)]
7#[allow(missing_docs)]
8pub enum Type {
9    Atomic(AtomicTy),
10    Reference(ReferenceTy),
11    Named(NamedTy),
12    // Constrained(ConstrainedTy),
13}
14
15impl Type {
16    /// Get the matching source for this type signature in source code.
17    pub fn matching_source(&self) -> &Fragment {
18        match self {
19            Type::Atomic(atomic_ty) => &atomic_ty.matching_source,
20            Type::Reference(reference_ty) => &reference_ty.matching_source,
21            Type::Named(named_ty) => &named_ty.matching_source,
22            // Type::Constrained(constrained_ty) => &constrained_ty.matching_source,
23        }
24    }
25
26    /// Attempt to "downcast" this to an atomic type signature if it is one.
27    pub fn downcast_primitive(&self) -> Option<&AtomicTy> {
28        match self {
29            Type::Atomic(atomic) => Some(atomic),
30            _ => None,
31        }
32    }
33
34    /// Attempt to "downcast" this to a reference type signature if it is one.
35    pub fn downcast_reference(&self) -> Option<&ReferenceTy> {
36        match self {
37            Type::Reference(reference) => Some(reference),
38            _ => None,
39        }
40    }
41
42    /// Attempt to "downcast" this to a named type signature if it is one.
43    pub fn downcast_named(&self) -> Option<&NamedTy> {
44        match self {
45            Type::Named(named) => Some(named),
46            _ => None,
47        }
48    }
49
50    // /// Attempt to "downcast" this to a constrained type signature if it is one.
51    // pub fn downcast_constrained_ty(&self) -> Option<&ConstrainedTy> {
52    //     match self {
53    //         Type::Constrained(constrained) => Some(constrained),
54    //         _ => None,
55    //     }
56    // }
57}
58
59/// The atomic types of wright -- primitive numeric types, boolean, char, etc.
60#[derive(Clone, Copy, Debug, PartialEq, Eq)]
61#[allow(missing_docs)]
62pub enum AtomicTyVariant {
63    Bool,
64    U8,
65    I8,
66    U16,
67    I16,
68    U32,
69    I32,
70    U64,
71    I64,
72    F32,
73    F64,
74    Char,
75}
76
77/// An atomic type signature in wright source code.
78#[derive(Debug)]
79#[allow(missing_docs)]
80pub struct AtomicTy {
81    pub variant: AtomicTyVariant,
82    pub matching_source: Fragment,
83}
84
85/// Source code for a reference type signature, such as `@u64`.
86#[derive(Debug)]
87pub struct ReferenceTy {
88    /// The source code of the target type.
89    pub target_ty: Box<Type>,
90    /// The fragment of the whole reference.
91    pub matching_source: Fragment,
92}
93
94/// A named type (such as a reference to a type from the standard libarary or a user defined struct).
95///
96/// i.e. `MyType<Generics>`
97#[derive(Debug)]
98pub struct NamedTy {
99    /// The matching source code of the type signature.
100    pub matching_source: Fragment,
101
102    /// The name/identifier of the type.
103    pub name: Path,
104
105    /// An ordered series of generic type parameters passed to it.
106    pub generic_tys: Vec<Type>,
107    // // eventually:
108    // pub generic_consts: (),
109}
110
111// /// A type with a given set of constraints.
112// ///
113// /// Constraints in wright are functions that the compiler can verify are strictly [pure]
114// /// (which is informally defined here, and a point of further work eventually).
115// ///
116// /// A constrained type declaration lists a base type and then one or more "strictly pure"
117// /// functions that have a signature exactly matching T -> bool (where T is the constrained type).
118// ///
119// /// An example of this could be
120// /// ```text
121// /// pure func is_even(i: u8) -> bool {
122// ///     i % 2 == 0
123// /// }
124// ///
125// /// type EvenU8 = u8 constrain is_even;
126// /// ```
127// ///
128// /// The wright compiler can then optimize agressively around these constraints later on (I hope).
129// ///
130// /// [pure]: https://en.wikipedia.org/w/index.php?title=Pure_function&oldid=1291437073
131// #[derive(Debug)]
132// struct ConstrainedTy {
133//     /// The entire type signature from the beginning of the base type
134//     /// to the end of the last constraining item.
135//     pub matching_source: Fragment,
136
137//     /// The type being constrained.
138//     pub base_ty: Box<Type>,
139
140//     /// The functions constraining it.
141//     pub constraining_items: Vec<Path>,
142// }