sizzle_parser/tysys.rs
1//! Core type system expressions.
2
3use std::path::PathBuf;
4
5use crate::Identifier;
6
7/// A type expression is something that we resolve from an identifier and are
8/// valid as type parameters. These aren't always necessarily types, but are
9/// type-related expressions.
10#[derive(Clone, Debug)]
11pub enum TyExpr {
12 /// None.
13 ///
14 /// This is a special type only for use in Union types.
15 None,
16
17 /// A type.
18 Ty(Ty),
19
20 /// A value, possibly resolved from a const.
21 ///
22 /// This isn't a normal type, but it's valid and we can resolve to it from
23 /// things that look like types and then would proceed to error from that.
24 Int(ConstValue),
25}
26
27impl TyExpr {
28 /// Create a new simple type expression.
29 pub fn new_simple(ident: Identifier) -> Self {
30 Self::Ty(Ty::Simple(ident))
31 }
32
33 /// Create a new integer type expression.
34 pub fn new_int(v: u64) -> Self {
35 Self::Int(ConstValue::Int(v))
36 }
37
38 /// Iterate over all the identifiers in the type expression.
39 pub fn iter_idents(&self) -> impl Iterator<Item = &Identifier> {
40 // FIXME I couldn't figure out how to make this no-alloc.
41 let idents = match self {
42 TyExpr::Ty(t) => t.iter_idents().collect::<Vec<_>>(),
43 TyExpr::Int(_) | TyExpr::None => Vec::new(),
44 };
45
46 idents.into_iter()
47 }
48}
49
50/// A type expression.
51///
52/// This can be used either to indicate the class's parent's type or a field's
53/// type.
54#[derive(Clone, Debug)]
55pub enum Ty {
56 /// An imported type.
57 Imported(PathBuf, Identifier, Identifier),
58
59 /// A simple type without arguments.
60 Simple(Identifier),
61
62 /// A complex type with arguments (possibly zero, like in an empty `Union`).
63 Complex(Identifier, Vec<TyExpr>),
64}
65
66impl Ty {
67 /// The base name of the type, without any arguments.
68 pub fn base_name(&self) -> &Identifier {
69 match self {
70 Ty::Imported(_, _, name) => name,
71 Ty::Simple(name) => name,
72 Ty::Complex(name, _) => name,
73 }
74 }
75
76 /// Iterate over all the identifiers in the type.
77 pub fn iter_idents(&self) -> impl Iterator<Item = &Identifier> {
78 let bn = self.base_name();
79
80 let ext = match self {
81 Ty::Imported(_, _, _) | Ty::Simple(_) => &[],
82 Ty::Complex(_, ch) => ch.as_slice(),
83 };
84
85 std::iter::once(bn).chain(ext.iter().flat_map(|e| e.iter_idents()))
86 }
87}
88
89/// A constant value.
90#[derive(Clone, Debug, Eq, PartialEq)]
91pub enum ConstValue {
92 /// Literal integer values.
93 Int(u64),
94
95 /// An integer value shifted to the left by another integer value. This is
96 /// useful for very large numbers like 2**256 - 1.
97 Binop(Binop, u64, u64),
98}
99
100/// A binary operation.
101#[derive(Copy, Clone, Debug, Eq, PartialEq)]
102pub enum Binop {
103 /// Addition.
104 Add,
105
106 /// Multiplication.
107 Mul,
108
109 /// Shift left.
110 Shl,
111}
112
113impl ConstValue {
114 /// Evaluate the constant value.
115 pub fn eval(&self) -> u64 {
116 match self {
117 ConstValue::Int(v) => *v,
118 ConstValue::Binop(op, a, b) => match op {
119 Binop::Add => a + b,
120 Binop::Mul => a * b,
121 Binop::Shl => a << b,
122 },
123 }
124 }
125}