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 translation of function calls
author
Danielle Maywood
committer
nandi
date
14 hours ago
(Jul 26, 2026, 12:11 PM -0700)
commit
5e69ae7b
5e69ae7b598c7f779eed02bb88bc0f6ad1e7d8c2
parent
34064946
340649464225813b71dffb222d257e7c0ddce0e7
change-id
qqwknvtk
qqwknvtkuzsvxrvnmypynqqumvmwwlpo
+393
-72
6 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-4.snap
gleam_core__cranelift__mir__tests__translates_samples.snap
test
project_cranelift
src
project_cranelift.gleam
+234
-43
compiler-core/src/cranelift/mir.rs
View file
Reviewed
···
1
1
-
use std::ops::Deref;
1
1
+
use std::{collections::HashMap, ops::Deref};
2
2
3
3
use ecow::{EcoString, eco_format};
4
4
-
use im::HashSet;
5
4
use num_bigint::BigInt;
6
5
use vec1::Vec1;
7
6
···
40
39
}
41
40
42
41
#[derive(Debug, PartialEq, Eq, Clone)]
42
42
+
pub struct Var {
43
43
+
pub name: EcoString,
44
44
+
}
45
45
+
46
46
+
#[derive(Debug, PartialEq, Eq, Clone)]
43
47
pub enum Expression {
44
48
Block(Vec<Expression>),
45
49
46
46
-
Var {
50
50
+
FunctionRef {
51
51
+
module: EcoString,
47
52
name: EcoString,
48
53
},
49
54
55
55
+
Var(Var),
56
56
+
50
57
Int {
51
58
value: BigInt,
52
59
},
···
57
64
},
58
65
59
66
IntAdd {
67
67
+
lhs: Box<Expression>,
68
68
+
rhs: Box<Expression>,
69
69
+
},
70
70
+
71
71
+
IntSub {
60
72
lhs: Box<Expression>,
61
73
rhs: Box<Expression>,
62
74
},
63
75
64
76
Set {
65
65
-
name: EcoString,
77
77
+
name: Var,
66
78
value: Box<Expression>,
67
79
},
68
80
···
70
82
cond: Box<Expression>,
71
83
then: Box<Expression>,
72
84
else_: Box<Expression>,
85
85
+
},
86
86
+
87
87
+
Call {
88
88
+
target: Box<Expression>,
89
89
+
args: Vec<Expression>,
73
90
},
74
91
}
75
92
···
104
121
FunctionParameter { name, type_ }
105
122
}));
106
123
107
107
-
let body = Self::flatten_expression(BodyTranslator::default().translate(&function.body));
124
124
+
let mut translator = BodyTranslator::default();
125
125
+
for argument in &function.arguments {
126
126
+
if let Some(name) = argument.get_variable_name() {
127
127
+
_ = translator.make_var(name.clone());
128
128
+
}
129
129
+
}
130
130
+
131
131
+
let body = translator.translate(&function.body);
132
132
+
let body = Self::flatten_expression(body);
133
133
+
let body = Self::remove_unused_code(body);
108
134
109
135
Function {
110
136
name,
···
154
180
match expression {
155
181
Expression::Block(mut expressions) => block.append(&mut expressions),
156
182
Expression::Var { .. }
183
183
+
| Expression::FunctionRef { .. }
157
184
| Expression::Int { .. }
158
185
| Expression::Equals { .. }
159
186
| Expression::IntAdd { .. }
187
187
+
| Expression::IntSub { .. }
160
188
| Expression::Set { .. }
161
161
-
| Expression::If { .. } => block.push(expression),
189
189
+
| Expression::If { .. }
190
190
+
| Expression::Call { .. } => block.push(expression),
162
191
};
163
192
}
164
193
···
167
196
_ => Expression::Block(block),
168
197
}
169
198
}
170
170
-
Expression::Var { name: _ } => expression,
171
171
-
Expression::Int { value: _ } => expression,
199
199
+
Expression::FunctionRef { module, name } => Expression::FunctionRef { module, name },
200
200
+
Expression::Var(var) => Expression::Var(var),
201
201
+
Expression::Int { value } => Expression::Int { value },
172
202
Expression::Equals { lhs, rhs } => Expression::Equals {
173
203
lhs: Box::new(Self::flatten_expression(*lhs)),
174
204
rhs: Box::new(Self::flatten_expression(*rhs)),
175
205
},
176
206
Expression::IntAdd { lhs, rhs } => Expression::IntAdd {
207
207
+
lhs: Box::new(Self::flatten_expression(*lhs)),
208
208
+
rhs: Box::new(Self::flatten_expression(*rhs)),
209
209
+
},
210
210
+
Expression::IntSub { lhs, rhs } => Expression::IntSub {
177
211
lhs: Box::new(Self::flatten_expression(*lhs)),
178
212
rhs: Box::new(Self::flatten_expression(*rhs)),
179
213
},
···
186
220
then: Box::new(Self::flatten_expression(*then)),
187
221
else_: Box::new(Self::flatten_expression(*else_)),
188
222
},
223
223
+
Expression::Call { target, args } => Expression::Call {
224
224
+
target: Box::new(Self::flatten_expression(*target)),
225
225
+
args: args.into_iter().map(Self::flatten_expression).collect(),
226
226
+
},
227
227
+
}
228
228
+
}
229
229
+
230
230
+
fn remove_unused_code(expression: Expression) -> Expression {
231
231
+
match expression {
232
232
+
Expression::Block(expressions) => {
233
233
+
let mut block = vec![];
234
234
+
235
235
+
let last_expression_index = expressions.len() - 1;
236
236
+
237
237
+
for (index, expression) in expressions.into_iter().enumerate() {
238
238
+
let expression = Self::remove_unused_code(expression);
239
239
+
240
240
+
match expression {
241
241
+
Expression::Var { .. } | Expression::FunctionRef { .. }
242
242
+
if index != last_expression_index => {}
243
243
+
244
244
+
Expression::Block(_)
245
245
+
| Expression::FunctionRef { .. }
246
246
+
| Expression::Var { .. }
247
247
+
| Expression::Int { .. }
248
248
+
| Expression::Equals { .. }
249
249
+
| Expression::IntAdd { .. }
250
250
+
| Expression::IntSub { .. }
251
251
+
| Expression::Set { .. }
252
252
+
| Expression::If { .. }
253
253
+
| Expression::Call { .. } => block.push(expression),
254
254
+
}
255
255
+
}
256
256
+
257
257
+
match block.as_slice() {
258
258
+
[single] => single.clone(),
259
259
+
_ => Expression::Block(block),
260
260
+
}
261
261
+
}
262
262
+
Expression::FunctionRef { module, name } => Expression::FunctionRef { module, name },
263
263
+
Expression::Var(var) => Expression::Var(var),
264
264
+
Expression::Int { value } => Expression::Int { value },
265
265
+
Expression::Equals { lhs, rhs } => Expression::Equals {
266
266
+
lhs: Box::new(Self::remove_unused_code(*lhs)),
267
267
+
rhs: Box::new(Self::remove_unused_code(*rhs)),
268
268
+
},
269
269
+
Expression::IntAdd { lhs, rhs } => Expression::IntAdd {
270
270
+
lhs: Box::new(Self::remove_unused_code(*lhs)),
271
271
+
rhs: Box::new(Self::remove_unused_code(*rhs)),
272
272
+
},
273
273
+
Expression::IntSub { lhs, rhs } => Expression::IntSub {
274
274
+
lhs: Box::new(Self::remove_unused_code(*lhs)),
275
275
+
rhs: Box::new(Self::remove_unused_code(*rhs)),
276
276
+
},
277
277
+
Expression::Set { name, value } => Expression::Set {
278
278
+
name,
279
279
+
value: Box::new(Self::remove_unused_code(*value)),
280
280
+
},
281
281
+
Expression::If { cond, then, else_ } => Expression::If {
282
282
+
cond: Box::new(Self::remove_unused_code(*cond)),
283
283
+
then: Box::new(Self::remove_unused_code(*then)),
284
284
+
else_: Box::new(Self::remove_unused_code(*else_)),
285
285
+
},
286
286
+
Expression::Call { target, args } => Expression::Call {
287
287
+
target: Box::new(Self::remove_unused_code(*target)),
288
288
+
args: args.into_iter().map(Self::remove_unused_code).collect(),
289
289
+
},
189
290
}
190
291
}
191
292
}
192
293
193
294
#[derive(Debug, Default)]
194
295
pub struct BodyTranslator {
195
195
-
variables: HashSet<EcoString>,
296
296
+
variables: HashMap<EcoString, EcoString>,
196
297
variable_count: usize,
197
298
}
198
299
···
203
304
}
204
305
205
306
impl BodyTranslator {
307
307
+
fn make_tmp_var(&mut self) -> Var {
308
308
+
self.make_var("_tmp".into())
309
309
+
}
310
310
+
311
311
+
fn make_var(&mut self, name: EcoString) -> Var {
312
312
+
self.variable_count += 1;
313
313
+
314
314
+
let entry = eco_format!("{}${}", name.clone(), self.variable_count);
315
315
+
_ = self.variables.insert(name.clone(), entry.clone());
316
316
+
317
317
+
Var { name: entry }
318
318
+
}
319
319
+
320
320
+
fn get_var(&mut self, name: &EcoString) -> Var {
321
321
+
let variable = self
322
322
+
.variables
323
323
+
.get(name)
324
324
+
.cloned()
325
325
+
.unwrap_or_else(|| panic!("variable '{name}' not found"));
326
326
+
327
327
+
Var { name: variable }
328
328
+
}
329
329
+
330
330
+
fn in_var_scope<T>(&mut self, func: impl Fn(&mut Self) -> T) -> T {
331
331
+
let snapshot = self.variables.clone();
332
332
+
let result = func(self);
333
333
+
self.variables = snapshot;
334
334
+
result
335
335
+
}
336
336
+
206
337
fn translate(mut self, body: &Vec1<ast::TypedStatement>) -> Expression {
338
338
+
self.translate_statements(body)
339
339
+
}
340
340
+
341
341
+
fn translate_statements(&mut self, statements: &[ast::TypedStatement]) -> Expression {
207
342
Expression::Block(Iterator::collect(
208
208
-
body.iter().map(|stmt| self.translate_statement(stmt)),
343
343
+
statements.iter().map(|stmt| self.translate_statement(stmt)),
209
344
))
210
345
}
211
346
···
240
375
} => todo!(),
241
376
ast::TypedExpr::Block {
242
377
location: _,
243
243
-
statements: _,
244
244
-
} => todo!(),
378
378
+
statements,
379
379
+
} => self.in_var_scope(|this| this.translate_statements(statements)),
245
380
ast::TypedExpr::Pipeline {
246
381
location: _,
247
382
first_value: _,
···
251
386
} => todo!(),
252
387
ast::TypedExpr::Var {
253
388
location: _,
254
254
-
constructor: _,
389
389
+
constructor,
255
390
name,
256
256
-
} => Expression::Var { name: name.clone() },
391
391
+
} => match &constructor.variant {
392
392
+
type_::ValueConstructorVariant::LocalVariable {
393
393
+
location: _,
394
394
+
origin: _,
395
395
+
} => Expression::Var(self.get_var(name)),
396
396
+
type_::ValueConstructorVariant::ModuleConstant {
397
397
+
documentation: _,
398
398
+
location: _,
399
399
+
module: _,
400
400
+
name: _,
401
401
+
literal: _,
402
402
+
implementations: _,
403
403
+
} => todo!(),
404
404
+
type_::ValueConstructorVariant::LocalConstant { literal: _ } => todo!(),
405
405
+
type_::ValueConstructorVariant::ModuleFn {
406
406
+
name,
407
407
+
field_map: _,
408
408
+
module,
409
409
+
arity: _,
410
410
+
location: _,
411
411
+
documentation: _,
412
412
+
implementations: _,
413
413
+
external_erlang: _,
414
414
+
external_javascript: _,
415
415
+
external_cranelift: _,
416
416
+
purity: _,
417
417
+
} => Expression::FunctionRef {
418
418
+
module: module.clone(),
419
419
+
name: name.clone(),
420
420
+
},
421
421
+
type_::ValueConstructorVariant::Record {
422
422
+
name: _,
423
423
+
arity: _,
424
424
+
field_map: _,
425
425
+
location: _,
426
426
+
module: _,
427
427
+
variants_count: _,
428
428
+
variant_index: _,
429
429
+
documentation: _,
430
430
+
} => todo!(),
431
431
+
},
257
432
ast::TypedExpr::Fn {
258
433
location: _,
259
434
type_: _,
···
272
447
ast::TypedExpr::Call {
273
448
location: _,
274
449
type_: _,
275
275
-
fun: _,
276
276
-
arguments: _,
277
277
-
} => todo!(),
450
450
+
fun,
451
451
+
arguments,
452
452
+
} => {
453
453
+
let target = self.translate_expression(fun);
454
454
+
let args = arguments
455
455
+
.iter()
456
456
+
.map(|arg| self.translate_expression(&arg.value))
457
457
+
.collect();
458
458
+
459
459
+
Expression::Call {
460
460
+
target: Box::new(target),
461
461
+
args,
462
462
+
}
463
463
+
}
278
464
ast::TypedExpr::BinOp {
279
465
location: _,
280
466
type_: _,
···
301
487
ast::BinOp::GtFloat => todo!(),
302
488
ast::BinOp::AddInt => Expression::IntAdd { lhs, rhs },
303
489
ast::BinOp::AddFloat => todo!(),
304
304
-
ast::BinOp::SubInt => todo!(),
490
490
+
ast::BinOp::SubInt => Expression::IntSub { lhs, rhs },
305
491
ast::BinOp::SubFloat => todo!(),
306
492
ast::BinOp::MultInt => todo!(),
307
493
ast::BinOp::MultFloat => todo!(),
···
431
617
&assignment.compiled_case.tree,
432
618
));
433
619
434
434
-
block.push(Expression::Var { name: value_var });
620
620
+
block.push(Expression::Var(value_var));
435
621
436
622
Expression::Block(block)
437
623
}
438
624
439
439
-
fn make_tmp_var(&mut self) -> EcoString {
440
440
-
let variable_count = self.variable_count;
441
441
-
self.make_var(eco_format!("_tmp{variable_count}"))
442
442
-
}
443
443
-
444
444
-
fn make_var(&mut self, name: EcoString) -> EcoString {
445
445
-
self.variable_count += 1;
446
446
-
_ = self.variables.insert(name.clone());
447
447
-
name
448
448
-
}
449
449
-
450
625
fn translate_decision(
451
626
&mut self,
452
627
kind: DecisionKind,
453
453
-
subjects: &[EcoString],
628
628
+
subjects: &[Var],
454
629
clauses: &[ast::TypedClause],
455
630
decision: &exhaustiveness::Decision,
456
631
) -> Expression {
···
459
634
let mut block = vec![];
460
635
461
636
for (binding, value) in &body.bindings {
637
637
+
let binding = self.make_var(binding.clone());
638
638
+
462
639
block.push(self.translate_binding(subjects, binding.clone(), value));
463
640
}
464
641
···
488
665
.partition(|(binding, _)| referenced_in_guard.contains(binding));
489
666
490
667
for (binding, value) in guard_bindings {
491
491
-
block.push(self.translate_binding(subjects, binding.clone(), value));
668
668
+
let binding = self.make_var(binding.clone());
669
669
+
670
670
+
block.push(self.translate_binding(subjects, binding, value));
492
671
}
493
672
494
673
let cond = self.translate_guard(guard);
···
497
676
let mut block = vec![];
498
677
499
678
for (binding, value) in if_true_bindings {
679
679
+
let binding = self.make_var(binding.clone());
680
680
+
500
681
block.push(self.translate_binding(subjects, binding.clone(), value));
501
682
}
502
683
···
526
707
Expression::If {
527
708
cond: Box::new(self.translate_runtime_check(
528
709
check,
529
529
-
Expression::Var {
530
530
-
name: subjects[var.id].clone(),
531
531
-
},
710
710
+
Expression::Var(subjects[var.id].clone()),
532
711
)),
533
712
then: Box::new(self.translate_decision(kind, subjects, clauses, then)),
534
713
else_: Box::new(fallback),
···
667
846
type_: _,
668
847
name,
669
848
definition_location: _,
670
670
-
} => Expression::Var { name: name.clone() },
849
849
+
} => Expression::Var(self.get_var(name)),
671
850
ast::ClauseGuard::TupleIndex {
672
851
location: _,
673
852
index: _,
···
754
933
755
934
fn translate_binding(
756
935
&mut self,
757
757
-
subjects: &[EcoString],
758
758
-
binding: EcoString,
936
936
+
subjects: &[Var],
937
937
+
binding: Var,
759
938
value: &exhaustiveness::BoundValue,
760
939
) -> Expression {
761
940
let value = match value {
762
762
-
exhaustiveness::BoundValue::Variable(variable) => Expression::Var {
763
763
-
name: subjects[variable.id].clone(),
764
764
-
},
941
941
+
exhaustiveness::BoundValue::Variable(variable) => {
942
942
+
Expression::Var(subjects[variable.id].clone())
943
943
+
}
765
944
exhaustiveness::BoundValue::LiteralString(_eco_string) => todo!(),
766
945
exhaustiveness::BoundValue::LiteralInt(big_int) => Expression::Int {
767
946
value: big_int.clone(),
···
815
994
816
995
#[cfg(test)]
817
996
mod tests {
997
997
+
use std::collections::{HashMap, HashSet};
998
998
+
818
999
use super::*;
819
1000
use crate::analyse::TargetSupport;
820
1001
use crate::build::{Origin, Target};
···
844
1025
origin: Origin::Src,
845
1026
importable_modules: &modules,
846
1027
warnings: &TypeWarningEmitter::null(),
847
847
-
direct_dependencies: &std::collections::HashMap::new(),
848
848
-
dev_dependencies: &std::collections::HashSet::new(),
1028
1028
+
direct_dependencies: &HashMap::new(),
1029
1029
+
dev_dependencies: &HashSet::new(),
849
1030
target_support: TargetSupport::Enforced,
850
1031
package_config: &config,
851
1032
}
···
883
1064
y if y == 0 -> 2
884
1065
1 -> 4
885
1066
_ -> 6
1067
1067
+
}
1068
1068
+
}"#
1069
1069
+
));
1070
1070
+
1071
1071
+
insta::assert_debug_snapshot!(translate(
1072
1072
+
r#"pub fn fib(n: Int) -> Int {
1073
1073
+
case n {
1074
1074
+
0 -> 0
1075
1075
+
1 -> 1
1076
1076
+
_ -> fib(n - 1) + fib(n - 2)
886
1077
}
887
1078
}"#
888
1079
));
+17
-9
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-2.snap
View file
Reviewed
···
18
18
body: Block(
19
19
[
20
20
Set {
21
21
-
name: "_tmp0",
22
22
-
value: Var {
23
23
-
name: "n",
21
21
+
name: Var {
22
22
+
name: "_tmp$2",
24
23
},
24
24
+
value: Var(
25
25
+
Var {
26
26
+
name: "n$1",
27
27
+
},
28
28
+
),
25
29
},
26
30
If {
27
31
cond: Equals {
28
28
-
lhs: Var {
29
29
-
name: "_tmp0",
30
30
-
},
32
32
+
lhs: Var(
33
33
+
Var {
34
34
+
name: "_tmp$2",
35
35
+
},
36
36
+
),
31
37
rhs: Int {
32
38
value: 0,
33
39
},
···
37
43
},
38
44
else_: If {
39
45
cond: Equals {
40
40
-
lhs: Var {
41
41
-
name: "_tmp0",
42
42
-
},
46
46
+
lhs: Var(
47
47
+
Var {
48
48
+
name: "_tmp$2",
49
49
+
},
50
50
+
),
43
51
rhs: Int {
44
52
value: 1,
45
53
},
+24
-12
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-3.snap
View file
Reviewed
···
18
18
body: Block(
19
19
[
20
20
Set {
21
21
-
name: "_tmp0",
22
22
-
value: Var {
23
23
-
name: "n",
21
21
+
name: Var {
22
22
+
name: "_tmp$2",
24
23
},
24
24
+
value: Var(
25
25
+
Var {
26
26
+
name: "n$1",
27
27
+
},
28
28
+
),
25
29
},
26
30
Set {
27
27
-
name: "y",
28
28
-
value: Var {
29
29
-
name: "_tmp0",
31
31
+
name: Var {
32
32
+
name: "y$3",
30
33
},
34
34
+
value: Var(
35
35
+
Var {
36
36
+
name: "_tmp$2",
37
37
+
},
38
38
+
),
31
39
},
32
40
If {
33
41
cond: Equals {
34
34
-
lhs: Var {
35
35
-
name: "y",
36
36
-
},
42
42
+
lhs: Var(
43
43
+
Var {
44
44
+
name: "y$3",
45
45
+
},
46
46
+
),
37
47
rhs: Int {
38
48
value: 0,
39
49
},
···
43
53
},
44
54
else_: If {
45
55
cond: Equals {
46
46
-
lhs: Var {
47
47
-
name: "_tmp0",
48
48
-
},
56
56
+
lhs: Var(
57
57
+
Var {
58
58
+
name: "_tmp$2",
59
59
+
},
60
60
+
),
49
61
rhs: Int {
50
62
value: 1,
51
63
},
+102
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-4.snap
View file
Reviewed
···
1
1
+
---
2
2
+
source: compiler-core/src/cranelift/mir.rs
3
3
+
expression: "translate(r#\"pub fn fib(n: Int) -> Int {\n case n {\n 0 -> 0\n 1 -> 1\n _ -> fib(n - 1) + fib(n - 2)\n }\n }\"#)"
4
4
+
---
5
5
+
Module {
6
6
+
functions: [
7
7
+
Function {
8
8
+
name: "fib",
9
9
+
return_type: Int,
10
10
+
parameters: [
11
11
+
FunctionParameter {
12
12
+
type_: Int,
13
13
+
name: Some(
14
14
+
"n",
15
15
+
),
16
16
+
},
17
17
+
],
18
18
+
body: Block(
19
19
+
[
20
20
+
Set {
21
21
+
name: Var {
22
22
+
name: "_tmp$2",
23
23
+
},
24
24
+
value: Var(
25
25
+
Var {
26
26
+
name: "n$1",
27
27
+
},
28
28
+
),
29
29
+
},
30
30
+
If {
31
31
+
cond: Equals {
32
32
+
lhs: Var(
33
33
+
Var {
34
34
+
name: "_tmp$2",
35
35
+
},
36
36
+
),
37
37
+
rhs: Int {
38
38
+
value: 0,
39
39
+
},
40
40
+
},
41
41
+
then: Int {
42
42
+
value: 0,
43
43
+
},
44
44
+
else_: If {
45
45
+
cond: Equals {
46
46
+
lhs: Var(
47
47
+
Var {
48
48
+
name: "_tmp$2",
49
49
+
},
50
50
+
),
51
51
+
rhs: Int {
52
52
+
value: 1,
53
53
+
},
54
54
+
},
55
55
+
then: Int {
56
56
+
value: 1,
57
57
+
},
58
58
+
else_: IntAdd {
59
59
+
lhs: Call {
60
60
+
target: FunctionRef {
61
61
+
module: "",
62
62
+
name: "fib",
63
63
+
},
64
64
+
args: [
65
65
+
IntSub {
66
66
+
lhs: Var(
67
67
+
Var {
68
68
+
name: "n$1",
69
69
+
},
70
70
+
),
71
71
+
rhs: Int {
72
72
+
value: 1,
73
73
+
},
74
74
+
},
75
75
+
],
76
76
+
},
77
77
+
rhs: Call {
78
78
+
target: FunctionRef {
79
79
+
module: "",
80
80
+
name: "fib",
81
81
+
},
82
82
+
args: [
83
83
+
IntSub {
84
84
+
lhs: Var(
85
85
+
Var {
86
86
+
name: "n$1",
87
87
+
},
88
88
+
),
89
89
+
rhs: Int {
90
90
+
value: 2,
91
91
+
},
92
92
+
},
93
93
+
],
94
94
+
},
95
95
+
},
96
96
+
},
97
97
+
},
98
98
+
],
99
99
+
),
100
100
+
},
101
101
+
],
102
102
+
}
+10
-6
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples.snap
View file
Reviewed
···
22
22
},
23
23
],
24
24
body: IntAdd {
25
25
-
lhs: Var {
26
26
-
name: "lhs",
27
27
-
},
28
28
-
rhs: Var {
29
29
-
name: "rhs",
30
30
-
},
25
25
+
lhs: Var(
26
26
+
Var {
27
27
+
name: "lhs$1",
28
28
+
},
29
29
+
),
30
30
+
rhs: Var(
31
31
+
Var {
32
32
+
name: "rhs$2",
33
33
+
},
34
34
+
),
31
35
},
32
36
},
33
37
],
+6
-2
test/project_cranelift/src/project_cranelift.gleam
View file
Reviewed
···
1
1
-
pub fn add(lhs: Int, rhs: Int) -> Int {
2
2
-
let x = 10
1
1
+
pub fn fib(n: Int) -> Int {
2
2
+
case n {
3
3
+
0 -> 0
4
4
+
1 -> 1
5
5
+
_ -> fib(n - 1) + fib(n - 2)
6
6
+
}
3
7
}