alpha
Login
or
Join now
nandi.uk
/
gleam
Star
2
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Fork of daniellemaywood.uk/gleam — Wasm codegen work
Star
2
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
Perform expression flattening
author
Danielle Maywood
committer
nandi
date
14 hours ago
(Jul 26, 2026, 12:11 PM -0700)
commit
34064946
340649464225813b71dffb222d257e7c0ddce0e7
parent
969373cc
969373ccb8ad65d0ec3352ca311b7a6f9470f8f6
change-id
pkvyskmn
pkvyskmnxmrmppyrovunvumtoyrvtmyr
+166
-130
5 changed files
Expand all
Collapse all
Unified
Split
compiler-core
src
cranelift
mir.rs
snapshots
gleam_core__cranelift__mir__tests__translates_samples-2.snap
gleam_core__cranelift__mir__tests__translates_samples-3.snap
gleam_core__cranelift__mir__tests__translates_samples.snap
test
project_cranelift
src
project_cranelift.gleam
+88
-9
compiler-core/src/cranelift/mir.rs
View file
Reviewed
···
39
39
Generic,
40
40
}
41
41
42
42
-
#[derive(Debug, PartialEq, Eq)]
42
42
+
#[derive(Debug, PartialEq, Eq, Clone)]
43
43
pub enum Expression {
44
44
Block(Vec<Expression>),
45
45
···
104
104
FunctionParameter { name, type_ }
105
105
}));
106
106
107
107
-
let body = BodyTranslator::default().translate(&function.body);
107
107
+
let body = Self::flatten_expression(BodyTranslator::default().translate(&function.body));
108
108
109
109
Function {
110
110
name,
···
142
142
type_::Type::Tuple { elements: _ } => todo!(),
143
143
}
144
144
}
145
145
+
146
146
+
fn flatten_expression(expression: Expression) -> Expression {
147
147
+
match expression {
148
148
+
Expression::Block(expressions) => {
149
149
+
let mut block = vec![];
150
150
+
151
151
+
for expression in expressions {
152
152
+
let expression = Self::flatten_expression(expression);
153
153
+
154
154
+
match expression {
155
155
+
Expression::Block(mut expressions) => block.append(&mut expressions),
156
156
+
Expression::Var { .. }
157
157
+
| Expression::Int { .. }
158
158
+
| Expression::Equals { .. }
159
159
+
| Expression::IntAdd { .. }
160
160
+
| Expression::Set { .. }
161
161
+
| Expression::If { .. } => block.push(expression),
162
162
+
};
163
163
+
}
164
164
+
165
165
+
match block.as_slice() {
166
166
+
[single] => single.clone(),
167
167
+
_ => Expression::Block(block),
168
168
+
}
169
169
+
}
170
170
+
Expression::Var { name: _ } => expression,
171
171
+
Expression::Int { value: _ } => expression,
172
172
+
Expression::Equals { lhs, rhs } => Expression::Equals {
173
173
+
lhs: Box::new(Self::flatten_expression(*lhs)),
174
174
+
rhs: Box::new(Self::flatten_expression(*rhs)),
175
175
+
},
176
176
+
Expression::IntAdd { lhs, rhs } => Expression::IntAdd {
177
177
+
lhs: Box::new(Self::flatten_expression(*lhs)),
178
178
+
rhs: Box::new(Self::flatten_expression(*rhs)),
179
179
+
},
180
180
+
Expression::Set { name, value } => Expression::Set {
181
181
+
name,
182
182
+
value: Box::new(Self::flatten_expression(*value)),
183
183
+
},
184
184
+
Expression::If { cond, then, else_ } => Expression::If {
185
185
+
cond: Box::new(Self::flatten_expression(*cond)),
186
186
+
then: Box::new(Self::flatten_expression(*then)),
187
187
+
else_: Box::new(Self::flatten_expression(*else_)),
188
188
+
},
189
189
+
}
190
190
+
}
145
191
}
146
192
147
193
#[derive(Debug, Default)]
148
194
pub struct BodyTranslator {
149
195
variables: HashSet<EcoString>,
150
196
variable_count: usize,
197
197
+
}
198
198
+
199
199
+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
200
200
+
enum DecisionKind {
201
201
+
Case,
202
202
+
Let,
151
203
}
152
204
153
205
impl BodyTranslator {
···
280
332
return name;
281
333
}));
282
334
283
283
-
block.push(self.translate_decision(&subject_vars, clauses, &compiled_case.tree));
335
335
+
block.push(self.translate_decision(
336
336
+
DecisionKind::Case,
337
337
+
&subject_vars,
338
338
+
clauses,
339
339
+
&compiled_case.tree,
340
340
+
));
284
341
285
342
Expression::Block(block)
286
343
}
···
356
413
}
357
414
}
358
415
359
359
-
fn translate_assignment(&mut self, _assignment: &ast::TypedAssignment) -> Expression {
360
360
-
todo!()
416
416
+
fn translate_assignment(&mut self, assignment: &ast::TypedAssignment) -> Expression {
417
417
+
let mut block = vec![];
418
418
+
419
419
+
let value_var = self.make_tmp_var();
420
420
+
let value = self.translate_expression(&assignment.value);
421
421
+
422
422
+
block.push(Expression::Set {
423
423
+
name: value_var.clone(),
424
424
+
value: Box::new(value),
425
425
+
});
426
426
+
427
427
+
block.push(self.translate_decision(
428
428
+
DecisionKind::Let,
429
429
+
&[value_var.clone()],
430
430
+
&[],
431
431
+
&assignment.compiled_case.tree,
432
432
+
));
433
433
+
434
434
+
block.push(Expression::Var { name: value_var });
435
435
+
436
436
+
Expression::Block(block)
361
437
}
362
438
363
439
fn make_tmp_var(&mut self) -> EcoString {
···
373
449
374
450
fn translate_decision(
375
451
&mut self,
452
452
+
kind: DecisionKind,
376
453
subjects: &[EcoString],
377
454
clauses: &[ast::TypedClause],
378
455
decision: &exhaustiveness::Decision,
···
385
462
block.push(self.translate_binding(subjects, binding.clone(), value));
386
463
}
387
464
388
388
-
block.push(self.translate_expression(&clauses[body.clause_index].then));
465
465
+
if kind == DecisionKind::Case {
466
466
+
block.push(self.translate_expression(&clauses[body.clause_index].then));
467
467
+
}
389
468
390
469
Expression::Block(block)
391
470
}
···
425
504
block
426
505
};
427
506
428
428
-
let if_false = self.translate_decision(subjects, clauses, if_false);
507
507
+
let if_false = self.translate_decision(kind, subjects, clauses, if_false);
429
508
430
509
block.push(Expression::If {
431
510
cond: Box::new(cond),
···
441
520
fallback,
442
521
fallback_check: _,
443
522
} => {
444
444
-
let fallback = self.translate_decision(subjects, clauses, fallback);
523
523
+
let fallback = self.translate_decision(kind, subjects, clauses, fallback);
445
524
446
525
DoubleEndedIterator::rfold(choices.iter(), fallback, |fallback, (check, then)| {
447
526
Expression::If {
···
451
530
name: subjects[var.id].clone(),
452
531
},
453
532
)),
454
454
-
then: Box::new(self.translate_decision(subjects, clauses, then)),
533
533
+
then: Box::new(self.translate_decision(kind, subjects, clauses, then)),
455
534
else_: Box::new(fallback),
456
535
}
457
536
})
+30
-46
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-2.snap
View file
Reviewed
···
17
17
],
18
18
body: Block(
19
19
[
20
20
-
Block(
21
21
-
[
22
22
-
Set {
20
20
+
Set {
21
21
+
name: "_tmp0",
22
22
+
value: Var {
23
23
+
name: "n",
24
24
+
},
25
25
+
},
26
26
+
If {
27
27
+
cond: Equals {
28
28
+
lhs: Var {
23
29
name: "_tmp0",
24
24
-
value: Var {
25
25
-
name: "n",
26
26
-
},
27
30
},
28
28
-
If {
29
29
-
cond: Equals {
30
30
-
lhs: Var {
31
31
-
name: "_tmp0",
32
32
-
},
33
33
-
rhs: Int {
34
34
-
value: 0,
35
35
-
},
31
31
+
rhs: Int {
32
32
+
value: 0,
33
33
+
},
34
34
+
},
35
35
+
then: Int {
36
36
+
value: 2,
37
37
+
},
38
38
+
else_: If {
39
39
+
cond: Equals {
40
40
+
lhs: Var {
41
41
+
name: "_tmp0",
36
42
},
37
37
-
then: Block(
38
38
-
[
39
39
-
Int {
40
40
-
value: 2,
41
41
-
},
42
42
-
],
43
43
-
),
44
44
-
else_: If {
45
45
-
cond: Equals {
46
46
-
lhs: Var {
47
47
-
name: "_tmp0",
48
48
-
},
49
49
-
rhs: Int {
50
50
-
value: 1,
51
51
-
},
52
52
-
},
53
53
-
then: Block(
54
54
-
[
55
55
-
Int {
56
56
-
value: 4,
57
57
-
},
58
58
-
],
59
59
-
),
60
60
-
else_: Block(
61
61
-
[
62
62
-
Int {
63
63
-
value: 6,
64
64
-
},
65
65
-
],
66
66
-
),
43
43
+
rhs: Int {
44
44
+
value: 1,
67
45
},
68
46
},
69
69
-
],
70
70
-
),
47
47
+
then: Int {
48
48
+
value: 4,
49
49
+
},
50
50
+
else_: Int {
51
51
+
value: 6,
52
52
+
},
53
53
+
},
54
54
+
},
71
55
],
72
56
),
73
57
},
+39
-59
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-3.snap
View file
Reviewed
···
17
17
],
18
18
body: Block(
19
19
[
20
20
-
Block(
21
21
-
[
22
22
-
Set {
23
23
-
name: "_tmp0",
24
24
-
value: Var {
25
25
-
name: "n",
20
20
+
Set {
21
21
+
name: "_tmp0",
22
22
+
value: Var {
23
23
+
name: "n",
24
24
+
},
25
25
+
},
26
26
+
Set {
27
27
+
name: "y",
28
28
+
value: Var {
29
29
+
name: "_tmp0",
30
30
+
},
31
31
+
},
32
32
+
If {
33
33
+
cond: Equals {
34
34
+
lhs: Var {
35
35
+
name: "y",
36
36
+
},
37
37
+
rhs: Int {
38
38
+
value: 0,
39
39
+
},
40
40
+
},
41
41
+
then: Int {
42
42
+
value: 2,
43
43
+
},
44
44
+
else_: If {
45
45
+
cond: Equals {
46
46
+
lhs: Var {
47
47
+
name: "_tmp0",
48
48
+
},
49
49
+
rhs: Int {
50
50
+
value: 1,
26
51
},
27
52
},
28
28
-
Block(
29
29
-
[
30
30
-
Set {
31
31
-
name: "y",
32
32
-
value: Var {
33
33
-
name: "_tmp0",
34
34
-
},
35
35
-
},
36
36
-
If {
37
37
-
cond: Equals {
38
38
-
lhs: Var {
39
39
-
name: "y",
40
40
-
},
41
41
-
rhs: Int {
42
42
-
value: 0,
43
43
-
},
44
44
-
},
45
45
-
then: Block(
46
46
-
[
47
47
-
Int {
48
48
-
value: 2,
49
49
-
},
50
50
-
],
51
51
-
),
52
52
-
else_: If {
53
53
-
cond: Equals {
54
54
-
lhs: Var {
55
55
-
name: "_tmp0",
56
56
-
},
57
57
-
rhs: Int {
58
58
-
value: 1,
59
59
-
},
60
60
-
},
61
61
-
then: Block(
62
62
-
[
63
63
-
Int {
64
64
-
value: 4,
65
65
-
},
66
66
-
],
67
67
-
),
68
68
-
else_: Block(
69
69
-
[
70
70
-
Int {
71
71
-
value: 6,
72
72
-
},
73
73
-
],
74
74
-
),
75
75
-
},
76
76
-
},
77
77
-
],
78
78
-
),
79
79
-
],
80
80
-
),
53
53
+
then: Int {
54
54
+
value: 4,
55
55
+
},
56
56
+
else_: Int {
57
57
+
value: 6,
58
58
+
},
59
59
+
},
60
60
+
},
81
61
],
82
62
),
83
63
},
+8
-12
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples.snap
View file
Reviewed
···
21
21
),
22
22
},
23
23
],
24
24
-
body: Block(
25
25
-
[
26
26
-
IntAdd {
27
27
-
lhs: Var {
28
28
-
name: "lhs",
29
29
-
},
30
30
-
rhs: Var {
31
31
-
name: "rhs",
32
32
-
},
33
33
-
},
34
34
-
],
35
35
-
),
24
24
+
body: IntAdd {
25
25
+
lhs: Var {
26
26
+
name: "lhs",
27
27
+
},
28
28
+
rhs: Var {
29
29
+
name: "rhs",
30
30
+
},
31
31
+
},
36
32
},
37
33
],
38
34
}
+1
-4
test/project_cranelift/src/project_cranelift.gleam
View file
Reviewed
···
1
1
pub fn add(lhs: Int, rhs: Int) -> Int {
2
2
-
case lhs {
3
3
-
x if x == 0 -> 10
4
4
-
_ -> rhs
5
5
-
}
2
2
+
let x = 10
6
3
}