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// }