Fork of daniellemaywood.uk/gleam — Wasm codegen work
6.4 kB
276 lines
1use ecow::EcoString;
2use num_bigint::BigInt;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum IncompleteType {
6 Int,
7 Float,
8 Bool,
9 String,
10 Func {
11 arguments: Vec<IncompleteType>,
12 returns: Box<IncompleteType>,
13 },
14 Struct {
15 elements: Vec<IncompleteType>,
16 },
17 List(Box<IncompleteType>),
18 Generic {
19 id: u64,
20 },
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24pub enum CompleteType {
25 Int,
26 Float,
27 Bool,
28 String,
29 Func {
30 arguments: Vec<CompleteType>,
31 returns: Box<CompleteType>,
32 },
33 Struct {
34 elements: Vec<CompleteType>,
35 },
36 List(Box<CompleteType>),
37}
38
39#[derive(Debug, PartialEq, Eq, Default)]
40pub struct Module<T> {
41 pub name: EcoString,
42 pub functions: Vec<Function<T>>,
43}
44
45#[derive(Debug, PartialEq, Eq, Clone)]
46pub struct Function<T> {
47 pub name: EcoString,
48 pub return_type: T,
49 pub parameters: Vec<FunctionParameter<T>>,
50 pub body: Expression<T>,
51}
52
53#[derive(Debug, PartialEq, Eq, Clone)]
54pub struct FunctionParameter<T> {
55 pub type_: T,
56 pub name: Option<EcoString>,
57}
58
59#[derive(Debug, PartialEq, Eq, Clone)]
60pub struct Var<T> {
61 pub name: EcoString,
62 pub type_: T,
63}
64
65#[derive(Debug, PartialEq, Eq, Clone)]
66pub enum Expression<T> {
67 Block(Vec<Expression<T>>),
68
69 FunctionRef {
70 module: EcoString,
71 name: EcoString,
72 arity: usize,
73 type_: T,
74 },
75
76 Var(Var<T>),
77
78 Int {
79 value: BigInt,
80 },
81
82 Float {
83 value: EcoString,
84 },
85
86 Bool {
87 value: bool,
88 },
89
90 String {
91 value: EcoString,
92 },
93
94 Equals {
95 lhs: Box<Expression<T>>,
96 rhs: Box<Expression<T>>,
97 },
98
99 NotEquals {
100 lhs: Box<Expression<T>>,
101 rhs: Box<Expression<T>>,
102 },
103
104 IntGt {
105 lhs: Box<Expression<T>>,
106 rhs: Box<Expression<T>>,
107 },
108
109 IntGtEq {
110 lhs: Box<Expression<T>>,
111 rhs: Box<Expression<T>>,
112 },
113
114 IntLt {
115 lhs: Box<Expression<T>>,
116 rhs: Box<Expression<T>>,
117 },
118
119 IntLtEq {
120 lhs: Box<Expression<T>>,
121 rhs: Box<Expression<T>>,
122 },
123
124 IntAdd {
125 lhs: Box<Expression<T>>,
126 rhs: Box<Expression<T>>,
127 },
128
129 IntSub {
130 lhs: Box<Expression<T>>,
131 rhs: Box<Expression<T>>,
132 },
133
134 IntMul {
135 lhs: Box<Expression<T>>,
136 rhs: Box<Expression<T>>,
137 },
138
139 IntDiv {
140 lhs: Box<Expression<T>>,
141 rhs: Box<Expression<T>>,
142 },
143
144 IntRem {
145 lhs: Box<Expression<T>>,
146 rhs: Box<Expression<T>>,
147 },
148
149 FloatGt {
150 lhs: Box<Expression<T>>,
151 rhs: Box<Expression<T>>,
152 },
153
154 FloatGtEq {
155 lhs: Box<Expression<T>>,
156 rhs: Box<Expression<T>>,
157 },
158
159 FloatLt {
160 lhs: Box<Expression<T>>,
161 rhs: Box<Expression<T>>,
162 },
163
164 FloatLtEq {
165 lhs: Box<Expression<T>>,
166 rhs: Box<Expression<T>>,
167 },
168
169 FloatAdd {
170 lhs: Box<Expression<T>>,
171 rhs: Box<Expression<T>>,
172 },
173
174 FloatSub {
175 lhs: Box<Expression<T>>,
176 rhs: Box<Expression<T>>,
177 },
178
179 FloatMul {
180 lhs: Box<Expression<T>>,
181 rhs: Box<Expression<T>>,
182 },
183
184 FloatDiv {
185 lhs: Box<Expression<T>>,
186 rhs: Box<Expression<T>>,
187 },
188
189 StringConcat {
190 lhs: Box<Expression<T>>,
191 rhs: Box<Expression<T>>,
192 },
193
194 List {
195 items: Vec<Expression<T>>,
196 tail: Option<Box<Expression<T>>>,
197 type_: T,
198 },
199
200 Struct {
201 tag: Option<u32>,
202 items: Vec<Expression<T>>,
203 type_: T,
204 },
205
206 StructTag {
207 value: Box<Expression<T>>,
208 },
209
210 StructAccess {
211 value: Box<Expression<T>>,
212 index: u64,
213 type_: T,
214 },
215
216 Set {
217 name: Var<T>,
218 value: Box<Expression<T>>,
219 },
220
221 If {
222 cond: Box<Expression<T>>,
223 then: Box<Expression<T>>,
224 else_: Box<Expression<T>>,
225 },
226
227 Call {
228 target: Box<Expression<T>>,
229 args: Vec<Expression<T>>,
230 type_: T,
231 },
232}
233
234impl Expression<IncompleteType> {
235 pub fn type_(&self) -> IncompleteType {
236 match self {
237 Expression::Block(expressions) => expressions
238 .last()
239 .expect("a block should not be empty")
240 .type_(),
241 Expression::FunctionRef { type_, .. } => type_.clone(),
242 Expression::Var(var) => var.type_.clone(),
243 Expression::Int { .. } => IncompleteType::Int,
244 Expression::Float { .. } => IncompleteType::Float,
245 Expression::Bool { .. } => IncompleteType::Bool,
246 Expression::String { .. } => IncompleteType::String,
247 Expression::Equals { .. } => IncompleteType::Bool,
248 Expression::NotEquals { .. } => IncompleteType::Bool,
249 Expression::IntGt { .. } => IncompleteType::Bool,
250 Expression::IntGtEq { .. } => IncompleteType::Bool,
251 Expression::IntLt { .. } => IncompleteType::Bool,
252 Expression::IntLtEq { .. } => IncompleteType::Bool,
253 Expression::IntAdd { .. } => IncompleteType::Int,
254 Expression::IntSub { .. } => IncompleteType::Int,
255 Expression::IntMul { .. } => IncompleteType::Int,
256 Expression::IntDiv { .. } => IncompleteType::Int,
257 Expression::IntRem { .. } => IncompleteType::Int,
258 Expression::FloatGt { .. } => IncompleteType::Bool,
259 Expression::FloatGtEq { .. } => IncompleteType::Bool,
260 Expression::FloatLt { .. } => IncompleteType::Bool,
261 Expression::FloatLtEq { .. } => IncompleteType::Bool,
262 Expression::FloatAdd { .. } => IncompleteType::Bool,
263 Expression::FloatSub { .. } => IncompleteType::Bool,
264 Expression::FloatMul { .. } => IncompleteType::Bool,
265 Expression::FloatDiv { .. } => IncompleteType::Bool,
266 Expression::StringConcat { .. } => IncompleteType::Bool,
267 Expression::List { type_, .. } => type_.clone(),
268 Expression::Struct { type_, .. } => type_.clone(),
269 Expression::StructTag { .. } => IncompleteType::Int,
270 Expression::StructAccess { type_, .. } => type_.clone(),
271 Expression::Set { value, .. } => value.type_(),
272 Expression::If { then, .. } => then.type_(),
273 Expression::Call { type_, .. } => type_.clone(),
274 }
275 }
276}