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