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
Allow monomorphizing generated mir
author
Danielle Maywood
committer
nandi
date
14 hours ago
(Jul 26, 2026, 12:11 PM -0700)
commit
ad476218
ad4762184b781056cb010f09042994fae06e5fda
parent
0f1323ab
0f1323ab0e58678f0a6d65ee8066add4aeeac384
change-id
kmkuovqv
kmkuovqvmmtvnwzoutkrtmvzpntuxvlr
+1444
-548
7 changed files
Expand all
Collapse all
Unified
Split
compiler-core
src
codegen.rs
cranelift
mir
ast.rs
lower.rs
visit.rs
mir.rs
cranelift.rs
test
project_cranelift
src
project_cranelift.gleam
+6
-4
compiler-core/src/codegen.rs
View file
Reviewed
···
353
353
_ = self.output_directory;
354
354
_ = writer;
355
355
356
356
-
for module in modules {
357
357
-
let mir_module = cranelift::mir::Translator::default().translate(&module.ast);
356
356
+
let modules: Vec<_> = modules
357
357
+
.iter()
358
358
+
.map(|module| cranelift::mir::Translator::new(&module.ast).translate())
359
359
+
.collect();
358
360
359
359
-
cranelift::compile(mir_module);
360
360
-
}
361
361
+
let monomorphized = cranelift::mir::lower::lower(modules);
362
362
+
dbg!(monomorphized);
361
363
362
364
Ok(())
363
365
}
+206
-206
compiler-core/src/cranelift.rs
View file
Reviewed
···
1
1
-
use std::collections::HashMap;
1
1
+
// use std::collections::HashMap;
2
2
3
3
-
use cranelift::{codegen::ir::BlockArg, prelude::*};
4
4
-
use cranelift_jit::{JITBuilder, JITModule};
5
5
-
use cranelift_module::{FuncOrDataId, Linkage, Module, default_libcall_names};
6
6
-
use ecow::EcoString;
7
7
-
use num_bigint::BigInt;
3
3
+
// use cranelift::{codegen::ir::BlockArg, prelude::*};
4
4
+
// use cranelift_jit::{JITBuilder, JITModule};
5
5
+
// use cranelift_module::{FuncOrDataId, Linkage, Module, default_libcall_names};
6
6
+
// use ecow::EcoString;
7
7
+
// use num_bigint::BigInt;
8
8
9
9
pub mod mir;
10
10
11
11
-
pub fn compile(m: mir::ast::Module) {
12
12
-
let mut flag_builder = settings::builder();
11
11
+
// pub fn compile(m: mir::ast::Module<mir::ast::IncompleteType>) {
12
12
+
// let mut flag_builder = settings::builder();
13
13
14
14
-
flag_builder
15
15
-
.set("is_pic", "false")
16
16
-
.expect("unable to set `is_pic` to false");
14
14
+
// flag_builder
15
15
+
// .set("is_pic", "false")
16
16
+
// .expect("unable to set `is_pic` to false");
17
17
18
18
-
let isa = cranelift_native::builder()
19
19
-
.unwrap_or_else(|reason| panic!("host machine not support: {reason}"))
20
20
-
.finish(settings::Flags::new(flag_builder))
21
21
-
.expect("unable to build isa target");
18
18
+
// let isa = cranelift_native::builder()
19
19
+
// .unwrap_or_else(|reason| panic!("host machine not support: {reason}"))
20
20
+
// .finish(settings::Flags::new(flag_builder))
21
21
+
// .expect("unable to build isa target");
22
22
23
23
-
let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
24
24
-
let mut context = module.make_context();
25
25
-
let mut function_context = FunctionBuilderContext::new();
23
23
+
// let mut module = JITModule::new(JITBuilder::with_isa(isa, default_libcall_names()));
24
24
+
// let mut context = module.make_context();
25
25
+
// let mut function_context = FunctionBuilderContext::new();
26
26
27
27
-
for function in m.functions {
28
28
-
let sig = &mut context.func.signature;
27
27
+
// for function in m.functions {
28
28
+
// let sig = &mut context.func.signature;
29
29
30
30
-
for _ in &function.parameters {
31
31
-
sig.params.push(AbiParam::new(types::I64));
32
32
-
}
30
30
+
// for _ in &function.parameters {
31
31
+
// sig.params.push(AbiParam::new(types::I64));
32
32
+
// }
33
33
34
34
-
sig.returns.push(AbiParam::new(types::I64));
34
34
+
// sig.returns.push(AbiParam::new(types::I64));
35
35
36
36
-
let mut builder = FunctionBuilder::new(&mut context.func, &mut function_context);
36
36
+
// let mut builder = FunctionBuilder::new(&mut context.func, &mut function_context);
37
37
38
38
-
let entry = builder.create_block();
39
39
-
builder.append_block_params_for_function_params(entry);
40
40
-
builder.switch_to_block(entry);
41
41
-
builder.seal_block(entry);
38
38
+
// let entry = builder.create_block();
39
39
+
// builder.append_block_params_for_function_params(entry);
40
40
+
// builder.switch_to_block(entry);
41
41
+
// builder.seal_block(entry);
42
42
43
43
-
let mut translator = FunctionTranslator {
44
44
-
builder,
45
45
-
module: &mut module,
46
46
-
variables: HashMap::new(),
47
47
-
};
43
43
+
// let mut translator = FunctionTranslator {
44
44
+
// builder,
45
45
+
// module: &mut module,
46
46
+
// variables: HashMap::new(),
47
47
+
// };
48
48
49
49
-
for (index, parameter) in function.parameters.into_iter().enumerate() {
50
50
-
if let Some(name) = parameter.name {
51
51
-
let var = translator.make_var(name);
52
52
-
let val = translator.builder.block_params(entry)[index];
49
49
+
// for (index, parameter) in function.parameters.into_iter().enumerate() {
50
50
+
// if let Some(name) = parameter.name {
51
51
+
// let var = translator.make_var(name);
52
52
+
// let val = translator.builder.block_params(entry)[index];
53
53
54
54
-
translator.builder.def_var(var, val);
55
55
-
}
56
56
-
}
54
54
+
// translator.builder.def_var(var, val);
55
55
+
// }
56
56
+
// }
57
57
58
58
-
let output = translator.translate_expression(function.body);
58
58
+
// let output = translator.translate_expression(function.body);
59
59
60
60
-
_ = translator.builder.ins().return_(&[output]);
61
61
-
translator.builder.finalize();
60
60
+
// _ = translator.builder.ins().return_(&[output]);
61
61
+
// translator.builder.finalize();
62
62
63
63
-
let id = module
64
64
-
.declare_function(&function.name, Linkage::Export, &context.func.signature)
65
65
-
.expect("unable to declare function");
63
63
+
// let id = module
64
64
+
// .declare_function(&function.name, Linkage::Export, &context.func.signature)
65
65
+
// .expect("unable to declare function");
66
66
67
67
-
module
68
68
-
.define_function(id, &mut context)
69
69
-
.expect("unable to define function");
67
67
+
// module
68
68
+
// .define_function(id, &mut context)
69
69
+
// .expect("unable to define function");
70
70
71
71
-
module.clear_context(&mut context);
72
72
-
}
71
71
+
// module.clear_context(&mut context);
72
72
+
// }
73
73
74
74
-
module
75
75
-
.finalize_definitions()
76
76
-
.expect("unable to finalize definitions");
74
74
+
// module
75
75
+
// .finalize_definitions()
76
76
+
// .expect("unable to finalize definitions");
77
77
78
78
-
let FuncOrDataId::Func(main) = module.get_name("main").expect("expected a main function")
79
79
-
else {
80
80
-
panic!("expected main to be a function")
81
81
-
};
78
78
+
// let FuncOrDataId::Func(main) = module.get_name("main").expect("expected a main function")
79
79
+
// else {
80
80
+
// panic!("expected main to be a function")
81
81
+
// };
82
82
83
83
-
let code = module.get_finalized_function(main);
84
84
-
#[allow(unsafe_code)]
85
85
-
let main = unsafe { std::mem::transmute::<_, extern "C" fn() -> i64>(code) };
83
83
+
// let code = module.get_finalized_function(main);
84
84
+
// #[allow(unsafe_code)]
85
85
+
// let main = unsafe { std::mem::transmute::<_, extern "C" fn() -> i64>(code) };
86
86
87
87
-
println!("{}", main());
88
88
-
}
87
87
+
// println!("{}", main());
88
88
+
// }
89
89
90
90
-
struct FunctionTranslator<'a, M: Module> {
91
91
-
builder: FunctionBuilder<'a>,
92
92
-
module: &'a mut M,
93
93
-
variables: HashMap<EcoString, Variable>,
94
94
-
}
90
90
+
// struct FunctionTranslator<'a, M: Module> {
91
91
+
// builder: FunctionBuilder<'a>,
92
92
+
// module: &'a mut M,
93
93
+
// variables: HashMap<EcoString, Variable>,
94
94
+
// }
95
95
96
96
-
impl<'a, M: Module> FunctionTranslator<'a, M> {
97
97
-
fn make_var(&mut self, name: EcoString) -> Variable {
98
98
-
let variable = self.builder.declare_var(types::I64);
99
99
-
_ = self.variables.insert(name, variable);
100
100
-
variable
101
101
-
}
96
96
+
// impl<'a, M: Module> FunctionTranslator<'a, M> {
97
97
+
// fn make_var(&mut self, name: EcoString) -> Variable {
98
98
+
// let variable = self.builder.declare_var(types::I64);
99
99
+
// _ = self.variables.insert(name, variable);
100
100
+
// variable
101
101
+
// }
102
102
103
103
-
fn get_var(&mut self, name: &EcoString) -> Variable {
104
104
-
self.variables
105
105
-
.get(name)
106
106
-
.cloned()
107
107
-
.unwrap_or_else(|| panic!("variable '{}' not found", name))
108
108
-
}
103
103
+
// fn get_var(&mut self, name: &EcoString) -> Variable {
104
104
+
// self.variables
105
105
+
// .get(name)
106
106
+
// .cloned()
107
107
+
// .unwrap_or_else(|| panic!("variable '{}' not found", name))
108
108
+
// }
109
109
110
110
-
fn make_int(&mut self, value: BigInt) -> Value {
111
111
-
let value: i64 = value.try_into().expect("bigint out of representable range");
110
110
+
// fn make_int(&mut self, value: BigInt) -> Value {
111
111
+
// let value: i64 = value.try_into().expect("bigint out of representable range");
112
112
113
113
-
self.builder.ins().iconst(types::I64, value)
114
114
-
}
113
113
+
// self.builder.ins().iconst(types::I64, value)
114
114
+
// }
115
115
116
116
-
fn translate_expression(&mut self, expression: mir::ast::Expression) -> Value {
117
117
-
_ = self.module;
116
116
+
// fn translate_expression(&mut self, expression: mir::ast::Expression) -> Value {
117
117
+
// _ = self.module;
118
118
119
119
-
match expression {
120
120
-
mir::ast::Expression::Block(expressions) => expressions
121
121
-
.into_iter()
122
122
-
.map(|expression| self.translate_expression(expression))
123
123
-
.last()
124
124
-
.expect("block shouldn't be empty"),
125
125
-
mir::ast::Expression::FunctionRef {
126
126
-
module: _,
127
127
-
name,
128
128
-
arity,
129
129
-
} => {
130
130
-
let mut signature = self.module.make_signature();
119
119
+
// match expression {
120
120
+
// mir::ast::Expression::Block(expressions) => expressions
121
121
+
// .into_iter()
122
122
+
// .map(|expression| self.translate_expression(expression))
123
123
+
// .last()
124
124
+
// .expect("block shouldn't be empty"),
125
125
+
// mir::ast::Expression::FunctionRef {
126
126
+
// module: _,
127
127
+
// name,
128
128
+
// arity,
129
129
+
// } => {
130
130
+
// let mut signature = self.module.make_signature();
131
131
132
132
-
for _ in 0..arity {
133
133
-
signature.params.push(AbiParam::new(types::I64));
134
134
-
}
135
135
-
signature.returns.push(AbiParam::new(types::I64));
132
132
+
// for _ in 0..arity {
133
133
+
// signature.params.push(AbiParam::new(types::I64));
134
134
+
// }
135
135
+
// signature.returns.push(AbiParam::new(types::I64));
136
136
137
137
-
let id = self
138
138
-
.module
139
139
-
.declare_function(&name, Linkage::Import, &signature)
140
140
-
.expect("unable to declare function for import");
137
137
+
// let id = self
138
138
+
// .module
139
139
+
// .declare_function(&name, Linkage::Import, &signature)
140
140
+
// .expect("unable to declare function for import");
141
141
142
142
-
let func = self.module.declare_func_in_func(id, self.builder.func);
142
142
+
// let func = self.module.declare_func_in_func(id, self.builder.func);
143
143
144
144
-
self.builder.ins().func_addr(types::I64, func)
145
145
-
}
146
146
-
mir::ast::Expression::Var(var) => {
147
147
-
let var = self.get_var(&var.name);
144
144
+
// self.builder.ins().func_addr(types::I64, func)
145
145
+
// }
146
146
+
// mir::ast::Expression::Var(var) => {
147
147
+
// let var = self.get_var(&var.name);
148
148
149
149
-
self.builder.use_var(var)
150
150
-
}
151
151
-
mir::ast::Expression::Int { value } => self.make_int(value),
152
152
-
mir::ast::Expression::Float { value: _ } => todo!(),
153
153
-
mir::ast::Expression::Bool { value: _ } => todo!(),
154
154
-
mir::ast::Expression::String { value: _ } => todo!(),
155
155
-
mir::ast::Expression::Equals { lhs, rhs } => {
156
156
-
let lhs = self.translate_expression(*lhs);
157
157
-
let rhs = self.translate_expression(*rhs);
149
149
+
// self.builder.use_var(var)
150
150
+
// }
151
151
+
// mir::ast::Expression::Int { value } => self.make_int(value),
152
152
+
// mir::ast::Expression::Float { value: _ } => todo!(),
153
153
+
// mir::ast::Expression::Bool { value: _ } => todo!(),
154
154
+
// mir::ast::Expression::String { value: _ } => todo!(),
155
155
+
// mir::ast::Expression::Equals { lhs, rhs } => {
156
156
+
// let lhs = self.translate_expression(*lhs);
157
157
+
// let rhs = self.translate_expression(*rhs);
158
158
159
159
-
self.builder.ins().icmp(IntCC::Equal, lhs, rhs)
160
160
-
}
161
161
-
mir::ast::Expression::NotEquals { lhs: _, rhs: _ } => todo!(),
162
162
-
mir::ast::Expression::IntGt { lhs: _, rhs: _ } => todo!(),
163
163
-
mir::ast::Expression::IntGtEq { lhs: _, rhs: _ } => todo!(),
164
164
-
mir::ast::Expression::IntLt { lhs: _, rhs: _ } => todo!(),
165
165
-
mir::ast::Expression::IntLtEq { lhs: _, rhs: _ } => todo!(),
166
166
-
mir::ast::Expression::IntAdd { lhs, rhs } => {
167
167
-
let lhs = self.translate_expression(*lhs);
168
168
-
let rhs = self.translate_expression(*rhs);
159
159
+
// self.builder.ins().icmp(IntCC::Equal, lhs, rhs)
160
160
+
// }
161
161
+
// mir::ast::Expression::NotEquals { lhs: _, rhs: _ } => todo!(),
162
162
+
// mir::ast::Expression::IntGt { lhs: _, rhs: _ } => todo!(),
163
163
+
// mir::ast::Expression::IntGtEq { lhs: _, rhs: _ } => todo!(),
164
164
+
// mir::ast::Expression::IntLt { lhs: _, rhs: _ } => todo!(),
165
165
+
// mir::ast::Expression::IntLtEq { lhs: _, rhs: _ } => todo!(),
166
166
+
// mir::ast::Expression::IntAdd { lhs, rhs } => {
167
167
+
// let lhs = self.translate_expression(*lhs);
168
168
+
// let rhs = self.translate_expression(*rhs);
169
169
170
170
-
self.builder.ins().iadd(lhs, rhs)
171
171
-
}
172
172
-
mir::ast::Expression::IntSub { lhs, rhs } => {
173
173
-
let lhs = self.translate_expression(*lhs);
174
174
-
let rhs = self.translate_expression(*rhs);
170
170
+
// self.builder.ins().iadd(lhs, rhs)
171
171
+
// }
172
172
+
// mir::ast::Expression::IntSub { lhs, rhs } => {
173
173
+
// let lhs = self.translate_expression(*lhs);
174
174
+
// let rhs = self.translate_expression(*rhs);
175
175
176
176
-
self.builder.ins().isub(lhs, rhs)
177
177
-
}
178
178
-
mir::ast::Expression::IntMul { lhs: _, rhs: _ } => todo!(),
179
179
-
mir::ast::Expression::IntDiv { lhs: _, rhs: _ } => todo!(),
180
180
-
mir::ast::Expression::IntRem { lhs: _, rhs: _ } => todo!(),
181
181
-
mir::ast::Expression::FloatGt { lhs: _, rhs: _ } => todo!(),
182
182
-
mir::ast::Expression::FloatGtEq { lhs: _, rhs: _ } => todo!(),
183
183
-
mir::ast::Expression::FloatLt { lhs: _, rhs: _ } => todo!(),
184
184
-
mir::ast::Expression::FloatLtEq { lhs: _, rhs: _ } => todo!(),
185
185
-
mir::ast::Expression::FloatAdd { lhs: _, rhs: _ } => todo!(),
186
186
-
mir::ast::Expression::FloatSub { lhs: _, rhs: _ } => todo!(),
187
187
-
mir::ast::Expression::FloatMul { lhs: _, rhs: _ } => todo!(),
188
188
-
mir::ast::Expression::FloatDiv { lhs: _, rhs: _ } => todo!(),
189
189
-
mir::ast::Expression::StringConcat { lhs: _, rhs: _ } => todo!(),
190
190
-
mir::ast::Expression::List { items: _, tail: _ } => todo!(),
191
191
-
mir::ast::Expression::Struct { tag: _, items: _ } => todo!(),
192
192
-
mir::ast::Expression::StructTag { value: _ } => todo!(),
193
193
-
mir::ast::Expression::StructAccess { value: _, index: _ } => todo!(),
194
194
-
mir::ast::Expression::Set { name, value } => {
195
195
-
let var = self.make_var(name.name);
196
196
-
let val = self.translate_expression(*value);
176
176
+
// self.builder.ins().isub(lhs, rhs)
177
177
+
// }
178
178
+
// mir::ast::Expression::IntMul { lhs: _, rhs: _ } => todo!(),
179
179
+
// mir::ast::Expression::IntDiv { lhs: _, rhs: _ } => todo!(),
180
180
+
// mir::ast::Expression::IntRem { lhs: _, rhs: _ } => todo!(),
181
181
+
// mir::ast::Expression::FloatGt { lhs: _, rhs: _ } => todo!(),
182
182
+
// mir::ast::Expression::FloatGtEq { lhs: _, rhs: _ } => todo!(),
183
183
+
// mir::ast::Expression::FloatLt { lhs: _, rhs: _ } => todo!(),
184
184
+
// mir::ast::Expression::FloatLtEq { lhs: _, rhs: _ } => todo!(),
185
185
+
// mir::ast::Expression::FloatAdd { lhs: _, rhs: _ } => todo!(),
186
186
+
// mir::ast::Expression::FloatSub { lhs: _, rhs: _ } => todo!(),
187
187
+
// mir::ast::Expression::FloatMul { lhs: _, rhs: _ } => todo!(),
188
188
+
// mir::ast::Expression::FloatDiv { lhs: _, rhs: _ } => todo!(),
189
189
+
// mir::ast::Expression::StringConcat { lhs: _, rhs: _ } => todo!(),
190
190
+
// mir::ast::Expression::List { items: _, tail: _ } => todo!(),
191
191
+
// mir::ast::Expression::Struct { tag: _, items: _ } => todo!(),
192
192
+
// mir::ast::Expression::StructTag { value: _ } => todo!(),
193
193
+
// mir::ast::Expression::StructAccess { value: _, index: _ } => todo!(),
194
194
+
// mir::ast::Expression::Set { name, value } => {
195
195
+
// let var = self.make_var(name.name);
196
196
+
// let val = self.translate_expression(*value);
197
197
198
198
-
self.builder.def_var(var, val);
199
199
-
self.builder.use_var(var)
200
200
-
}
201
201
-
mir::ast::Expression::If { cond, then, else_ } => {
202
202
-
let cond = self.translate_expression(*cond);
198
198
+
// self.builder.def_var(var, val);
199
199
+
// self.builder.use_var(var)
200
200
+
// }
201
201
+
// mir::ast::Expression::If { cond, then, else_ } => {
202
202
+
// let cond = self.translate_expression(*cond);
203
203
204
204
-
let then_block = self.builder.create_block();
205
205
-
let else_block = self.builder.create_block();
206
206
-
let merge_block = self.builder.create_block();
204
204
+
// let then_block = self.builder.create_block();
205
205
+
// let else_block = self.builder.create_block();
206
206
+
// let merge_block = self.builder.create_block();
207
207
208
208
-
_ = self.builder.append_block_param(merge_block, types::I64);
208
208
+
// _ = self.builder.append_block_param(merge_block, types::I64);
209
209
210
210
-
_ = self
211
211
-
.builder
212
212
-
.ins()
213
213
-
.brif(cond, then_block, &[], else_block, &[]);
210
210
+
// _ = self
211
211
+
// .builder
212
212
+
// .ins()
213
213
+
// .brif(cond, then_block, &[], else_block, &[]);
214
214
215
215
-
self.builder.switch_to_block(then_block);
216
216
-
self.builder.seal_block(then_block);
215
215
+
// self.builder.switch_to_block(then_block);
216
216
+
// self.builder.seal_block(then_block);
217
217
218
218
-
let then_return = self.translate_expression(*then);
219
219
-
_ = self
220
220
-
.builder
221
221
-
.ins()
222
222
-
.jump(merge_block, &[BlockArg::Value(then_return)]);
218
218
+
// let then_return = self.translate_expression(*then);
219
219
+
// _ = self
220
220
+
// .builder
221
221
+
// .ins()
222
222
+
// .jump(merge_block, &[BlockArg::Value(then_return)]);
223
223
224
224
-
self.builder.switch_to_block(else_block);
225
225
-
self.builder.seal_block(else_block);
224
224
+
// self.builder.switch_to_block(else_block);
225
225
+
// self.builder.seal_block(else_block);
226
226
227
227
-
let else_return = self.translate_expression(*else_);
228
228
-
_ = self
229
229
-
.builder
230
230
-
.ins()
231
231
-
.jump(merge_block, &[BlockArg::Value(else_return)]);
227
227
+
// let else_return = self.translate_expression(*else_);
228
228
+
// _ = self
229
229
+
// .builder
230
230
+
// .ins()
231
231
+
// .jump(merge_block, &[BlockArg::Value(else_return)]);
232
232
233
233
-
self.builder.switch_to_block(merge_block);
234
234
-
self.builder.seal_block(merge_block);
233
233
+
// self.builder.switch_to_block(merge_block);
234
234
+
// self.builder.seal_block(merge_block);
235
235
236
236
-
self.builder.block_params(merge_block)[0]
237
237
-
}
238
238
-
mir::ast::Expression::Call { target, args } => {
239
239
-
let mut signature = self.module.make_signature();
236
236
+
// self.builder.block_params(merge_block)[0]
237
237
+
// }
238
238
+
// mir::ast::Expression::Call { target, args } => {
239
239
+
// let mut signature = self.module.make_signature();
240
240
241
241
-
for _ in 0..args.len() {
242
242
-
signature.params.push(AbiParam::new(types::I64));
243
243
-
}
244
244
-
signature.returns.push(AbiParam::new(types::I64));
241
241
+
// for _ in 0..args.len() {
242
242
+
// signature.params.push(AbiParam::new(types::I64));
243
243
+
// }
244
244
+
// signature.returns.push(AbiParam::new(types::I64));
245
245
246
246
-
let target = self.translate_expression(*target);
247
247
-
let args: Vec<_> = args
248
248
-
.into_iter()
249
249
-
.map(|arg| self.translate_expression(arg))
250
250
-
.collect();
246
246
+
// let target = self.translate_expression(*target);
247
247
+
// let args: Vec<_> = args
248
248
+
// .into_iter()
249
249
+
// .map(|arg| self.translate_expression(arg))
250
250
+
// .collect();
251
251
252
252
-
let sig = self.builder.import_signature(signature);
253
253
-
let call = self.builder.ins().call_indirect(sig, target, &args);
252
252
+
// let sig = self.builder.import_signature(signature);
253
253
+
// let call = self.builder.ins().call_indirect(sig, target, &args);
254
254
255
255
-
self.builder.inst_results(call)[0]
256
256
-
}
257
257
-
}
258
258
-
}
259
259
-
}
255
255
+
// self.builder.inst_results(call)[0]
256
256
+
// }
257
257
+
// }
258
258
+
// }
259
259
+
// }
+160
-85
compiler-core/src/cranelift/mir.rs
View file
Reviewed
···
10
10
};
11
11
12
12
pub mod ast;
13
13
+
pub mod lower;
13
14
pub mod visit;
14
15
15
16
struct FlattenBlockPass;
16
17
17
17
-
impl<'mir> Visit<'mir> for FlattenBlockPass {
18
18
-
fn visit_expression(&mut self, expression: &'mir mut Expression) {
18
18
+
impl<'mir, T> Visit<'mir, T> for FlattenBlockPass {
19
19
+
fn visit_expression(&mut self, expression: &'mir mut Expression<T>) {
19
20
visit::visit_expression(self, expression);
20
21
21
22
if let Expression::Block(inner) = expression
···
25
26
}
26
27
}
27
28
28
28
-
fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression>) {
29
29
+
fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression<T>>) {
29
30
visit::visit_expression_block(self, expressions);
30
31
31
32
*expressions = std::mem::take(expressions)
···
40
41
41
42
struct RemoveUnusedPass;
42
43
43
43
-
impl<'mir> Visit<'mir> for RemoveUnusedPass {
44
44
-
fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression>) {
44
44
+
impl<'mir, T> Visit<'mir, T> for RemoveUnusedPass {
45
45
+
fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression<T>>) {
45
46
visit::visit_expression_block(self, expressions);
46
47
47
48
let last_index = expressions.len() - 1;
···
72
73
replacements: HashMap<EcoString, EcoString>,
73
74
}
74
75
75
75
-
impl<'mir> Visit<'mir> for RemoveUselessSetPass {
76
76
-
fn visit_expression(&mut self, expression: &'mir mut Expression) {
76
76
+
impl<'mir, T> Visit<'mir, T> for RemoveUselessSetPass {
77
77
+
fn visit_expression(&mut self, expression: &'mir mut Expression<T>) {
77
78
visit::visit_expression(self, expression);
78
79
79
80
if let Expression::Set { name, value } = expression {
···
88
89
}
89
90
}
90
91
91
91
-
fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression>) {
92
92
+
fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression<T>>) {
92
93
visit::visit_expression_block(self, expressions);
93
94
94
95
*expressions = std::mem::take(expressions)
···
104
105
.collect();
105
106
}
106
107
107
107
-
fn visit_expression_var(&mut self, var: &'mir mut Var) {
108
108
+
fn visit_expression_var(&mut self, var: &'mir mut Var<T>) {
108
109
if let Some(replacement) = self.replacements.get(&var.name) {
109
110
var.name = replacement.clone();
110
111
}
111
112
}
112
113
}
113
114
114
114
-
#[derive(Debug, Default, PartialEq, Eq)]
115
115
-
pub struct Translator {
116
116
-
module: Module,
115
115
+
#[derive(Debug)]
116
116
+
pub struct Translator<'ast> {
117
117
+
module: &'ast crate::ast::TypedModule,
117
118
}
118
119
119
119
-
impl Translator {
120
120
-
pub fn translate(mut self, module: &crate::ast::TypedModule) -> Module {
121
121
-
for definition in &module.definitions {
120
120
+
impl<'ast> Translator<'ast> {
121
121
+
pub fn new(module: &'ast crate::ast::TypedModule) -> Self {
122
122
+
Self { module }
123
123
+
}
124
124
+
125
125
+
pub fn translate(self) -> Module<IncompleteType> {
126
126
+
let mut module = Module {
127
127
+
name: self.module.name.clone(),
128
128
+
functions: vec![],
129
129
+
};
130
130
+
131
131
+
for definition in &self.module.definitions {
122
132
match definition {
123
133
crate::ast::Definition::Function(function) => {
124
124
-
self.module
125
125
-
.functions
126
126
-
.push(Self::translate_function(function));
134
134
+
module.functions.push(self.translate_function(function));
127
135
}
128
136
crate::ast::Definition::TypeAlias(_type_alias) => todo!(),
129
137
crate::ast::Definition::CustomType(_custom_type) => {}
···
132
140
}
133
141
}
134
142
135
135
-
FlattenBlockPass.visit_module(&mut self.module);
136
136
-
RemoveUnusedPass.visit_module(&mut self.module);
137
137
-
RemoveUselessSetPass::default().visit_module(&mut self.module);
143
143
+
FlattenBlockPass.visit_module(&mut module);
144
144
+
RemoveUnusedPass.visit_module(&mut module);
145
145
+
RemoveUselessSetPass::default().visit_module(&mut module);
138
146
139
139
-
self.module
147
147
+
module
140
148
}
141
149
142
142
-
fn translate_function(function: &crate::ast::TypedFunction) -> Function {
150
150
+
fn translate_function(&self, function: &crate::ast::TypedFunction) -> Function<IncompleteType> {
143
151
let (_, name) = function.name.clone().expect("function should have a name");
144
152
145
153
let return_type = Self::translate_type(&function.return_type);
146
154
147
155
let mut translator = BodyTranslator::default();
148
156
let arguments: Vec<_> = Iterator::collect(function.arguments.iter().map(|argument| {
149
149
-
argument
150
150
-
.get_variable_name()
151
151
-
.map(|name| translator.make_var(name.clone()))
157
157
+
argument.get_variable_name().map(|name| {
158
158
+
translator.make_var(name.clone(), Self::translate_type(&argument.type_))
159
159
+
})
152
160
}));
153
161
154
162
let parameters = Iterator::collect(function.arguments.iter().zip(arguments.iter()).map(
···
172
180
}
173
181
}
174
182
175
175
-
fn translate_type(type_: &type_::Type) -> Type {
183
183
+
fn translate_type(type_: &type_::Type) -> IncompleteType {
176
184
match type_ {
177
185
type_::Type::Named {
178
186
publicity: _,
···
182
190
arguments,
183
191
inferred_variant: _,
184
192
} => match (module.as_str(), name.as_str()) {
185
185
-
("gleam", "Int") => Type::Int,
186
186
-
("gleam", "Float") => Type::Float,
187
187
-
("gleam", "Bool") => Type::Bool,
188
188
-
("gleam", "String") => Type::String,
193
193
+
("gleam", "Int") => IncompleteType::Int,
194
194
+
("gleam", "Float") => IncompleteType::Float,
195
195
+
("gleam", "Bool") => IncompleteType::Bool,
196
196
+
("gleam", "String") => IncompleteType::String,
189
197
("gleam", "List") => {
190
198
let list_type = Self::translate_type(&arguments[0]);
191
199
192
192
-
Type::List(Box::new(list_type))
200
200
+
IncompleteType::List(Box::new(list_type))
193
201
}
194
194
-
(_, _) => Type::Struct {
202
202
+
(_, _) => IncompleteType::Struct {
195
203
elements: arguments
196
204
.iter()
197
205
.map(|type_| Self::translate_type(type_))
198
206
.collect(),
199
207
},
200
208
},
201
201
-
type_::Type::Fn {
202
202
-
arguments: _,
203
203
-
return_: _,
204
204
-
} => todo!(),
209
209
+
type_::Type::Fn { arguments, return_ } => IncompleteType::Func {
210
210
+
arguments: arguments
211
211
+
.iter()
212
212
+
.map(|arg| Self::translate_type(arg))
213
213
+
.collect(),
214
214
+
returns: Box::new(Self::translate_type(return_)),
215
215
+
},
205
216
type_::Type::Var { type_ } => match type_.borrow().deref() {
206
217
type_::TypeVar::Link { type_ } => Self::translate_type(type_),
207
207
-
type_::TypeVar::Unbound { id: _ } | type_::TypeVar::Generic { id: _ } => {
208
208
-
Type::Generic
218
218
+
type_::TypeVar::Unbound { id } | type_::TypeVar::Generic { id } => {
219
219
+
IncompleteType::Generic { id: *id }
209
220
}
210
221
},
211
211
-
type_::Type::Tuple { elements: _ } => todo!(),
222
222
+
type_::Type::Tuple { elements } => IncompleteType::Struct {
223
223
+
elements: elements
224
224
+
.iter()
225
225
+
.map(|elem| Self::translate_type(elem))
226
226
+
.collect(),
227
227
+
},
212
228
}
213
229
}
214
230
}
215
231
216
232
#[derive(Debug, Default)]
217
233
pub struct BodyTranslator {
218
218
-
variables: HashMap<EcoString, EcoString>,
234
234
+
variables: HashMap<EcoString, Var<IncompleteType>>,
219
235
variable_count: usize,
220
236
}
221
237
···
226
242
}
227
243
228
244
impl BodyTranslator {
229
229
-
fn make_tmp_var(&mut self) -> Var {
230
230
-
self.make_var("_tmp".into())
245
245
+
fn make_tmp_var(&mut self, type_: IncompleteType) -> Var<IncompleteType> {
246
246
+
self.make_var("_tmp".into(), type_)
231
247
}
232
248
233
233
-
fn make_var(&mut self, name: EcoString) -> Var {
249
249
+
fn make_var(&mut self, name: EcoString, type_: IncompleteType) -> Var<IncompleteType> {
234
250
self.variable_count += 1;
235
251
236
252
let entry = eco_format!("{}${}", name.clone(), self.variable_count);
237
237
-
_ = self.variables.insert(name.clone(), entry.clone());
253
253
+
let var = Var {
254
254
+
name: entry,
255
255
+
type_: type_,
256
256
+
};
238
257
239
239
-
Var { name: entry }
258
258
+
_ = self.variables.insert(name.clone(), var.clone());
259
259
+
260
260
+
var
240
261
}
241
262
242
242
-
fn get_var(&mut self, name: &EcoString) -> Var {
243
243
-
let variable = self
244
244
-
.variables
263
263
+
fn get_var(&mut self, name: &EcoString) -> Var<IncompleteType> {
264
264
+
self.variables
245
265
.get(name)
246
266
.cloned()
247
247
-
.unwrap_or_else(|| panic!("variable '{name}' not found"));
248
248
-
249
249
-
Var { name: variable }
267
267
+
.unwrap_or_else(|| panic!("variable '{name}' not found"))
250
268
}
251
269
252
270
fn in_var_scope<T>(&mut self, func: impl Fn(&mut Self) -> T) -> T {
···
256
274
result
257
275
}
258
276
259
259
-
fn translate(mut self, body: &Vec1<crate::ast::TypedStatement>) -> Expression {
277
277
+
fn translate(mut self, body: &Vec1<crate::ast::TypedStatement>) -> Expression<IncompleteType> {
260
278
self.translate_statements(body)
261
279
}
262
280
263
263
-
fn translate_statements(&mut self, statements: &[crate::ast::TypedStatement]) -> Expression {
281
281
+
fn translate_statements(
282
282
+
&mut self,
283
283
+
statements: &[crate::ast::TypedStatement],
284
284
+
) -> Expression<IncompleteType> {
264
285
Expression::Block(Iterator::collect(
265
286
statements.iter().map(|stmt| self.translate_statement(stmt)),
266
287
))
267
288
}
268
289
269
269
-
fn translate_statement(&mut self, statement: &crate::ast::TypedStatement) -> Expression {
290
290
+
fn translate_statement(
291
291
+
&mut self,
292
292
+
statement: &crate::ast::TypedStatement,
293
293
+
) -> Expression<IncompleteType> {
270
294
match statement {
271
295
crate::ast::Statement::Expression(expression) => self.translate_expression(expression),
272
296
crate::ast::Statement::Assignment(assignment) => self.translate_assignment(assignment),
···
275
299
}
276
300
}
277
301
278
278
-
fn translate_expression(&mut self, expression: &crate::ast::TypedExpr) -> Expression {
302
302
+
fn translate_expression(
303
303
+
&mut self,
304
304
+
expression: &crate::ast::TypedExpr,
305
305
+
) -> Expression<IncompleteType> {
279
306
match expression {
280
307
crate::ast::TypedExpr::Int {
281
308
location: _,
···
314
341
315
342
let value = self.translate_expression(&first_value.value);
316
343
block.push(Expression::Set {
317
317
-
name: self.make_var(first_value.name.clone()),
344
344
+
name: self.make_var(
345
345
+
first_value.name.clone(),
346
346
+
Translator::translate_type(&first_value.type_()),
347
347
+
),
318
348
value: Box::new(value),
319
349
});
320
350
321
351
for (assignment, _) in assignments {
322
352
let value = self.translate_expression(&assignment.value);
323
353
block.push(Expression::Set {
324
324
-
name: self.make_var(assignment.name.clone()),
354
354
+
name: self.make_var(
355
355
+
assignment.name.clone(),
356
356
+
Translator::translate_type(&assignment.value.type_()),
357
357
+
),
325
358
value: Box::new(value),
326
359
});
327
360
}
···
364
397
module: module.clone(),
365
398
name: name.clone(),
366
399
arity: *arity,
400
400
+
type_: Translator::translate_type(&constructor.type_),
367
401
},
368
402
type_::ValueConstructorVariant::Record {
369
403
name,
···
381
415
module: module.clone(),
382
416
name: name.clone(),
383
417
arity: usize::from(*arity),
418
418
+
type_: Translator::translate_type(&constructor.type_),
384
419
},
385
420
},
386
421
},
···
395
430
} => todo!(),
396
431
crate::ast::TypedExpr::List {
397
432
location: _,
398
398
-
type_: _,
433
433
+
type_,
399
434
elements,
400
435
tail,
401
436
} => {
···
408
443
.as_ref()
409
444
.map(|tail| Box::new(self.translate_expression(tail)));
410
445
411
411
-
Expression::List { items, tail }
446
446
+
Expression::List {
447
447
+
items,
448
448
+
tail,
449
449
+
type_: Translator::translate_type(type_),
450
450
+
}
412
451
}
413
452
crate::ast::TypedExpr::Call {
414
453
location: _,
415
415
-
type_: _,
454
454
+
type_,
416
455
fun,
417
456
arguments,
418
457
} => {
···
425
464
Expression::Call {
426
465
target: Box::new(target),
427
466
args,
467
467
+
type_: Translator::translate_type(type_),
428
468
}
429
469
}
430
470
crate::ast::TypedExpr::BinOp {
···
481
521
let mut block = vec![];
482
522
483
523
let subject_vars: Vec<_> = Iterator::collect(subjects.iter().map(|subject| {
484
484
-
let name = self.make_tmp_var();
524
524
+
let name = self.make_tmp_var(Translator::translate_type(&subject.type_()));
485
525
let value = self.translate_expression(subject);
486
526
487
527
block.push(Expression::Set {
···
504
544
crate::ast::TypedExpr::RecordAccess {
505
545
location: _,
506
546
field_start: _,
507
507
-
type_: _,
547
547
+
type_,
508
548
label: _,
509
549
index,
510
550
record,
511
551
} => Expression::StructAccess {
512
552
value: Box::new(self.translate_expression(record)),
513
553
index: *index,
554
554
+
type_: Translator::translate_type(type_),
514
555
},
515
556
crate::ast::TypedExpr::ModuleSelect {
516
557
location: _,
···
523
564
} => todo!(),
524
565
crate::ast::TypedExpr::Tuple {
525
566
location: _,
526
526
-
type_: _,
567
567
+
type_,
527
568
elements,
528
569
} => Expression::Struct {
529
570
tag: None,
···
531
572
.iter()
532
573
.map(|element| self.translate_expression(element))
533
574
.collect(),
575
575
+
type_: Translator::translate_type(type_),
534
576
},
535
577
crate::ast::TypedExpr::TupleIndex {
536
578
location: _,
537
537
-
type_: _,
579
579
+
type_,
538
580
index,
539
581
tuple,
540
582
} => Expression::StructAccess {
541
583
value: Box::new(self.translate_expression(tuple)),
542
584
index: *index,
585
585
+
type_: Translator::translate_type(type_),
543
586
},
544
587
crate::ast::TypedExpr::Todo {
545
588
location: _,
···
565
608
} => todo!(),
566
609
crate::ast::TypedExpr::RecordUpdate {
567
610
location: _,
568
568
-
type_: _,
611
611
+
type_,
569
612
record_assignment,
570
613
constructor,
571
614
arguments,
···
585
628
block.push(Expression::Call {
586
629
target: Box::new(constructor),
587
630
args: arguments,
631
631
+
type_: Translator::translate_type(type_),
588
632
});
589
633
590
634
Expression::Block(block)
···
606
650
}
607
651
}
608
652
609
609
-
fn translate_assignment(&mut self, assignment: &crate::ast::TypedAssignment) -> Expression {
653
653
+
fn translate_assignment(
654
654
+
&mut self,
655
655
+
assignment: &crate::ast::TypedAssignment,
656
656
+
) -> Expression<IncompleteType> {
610
657
let mut block = vec![];
611
658
612
612
-
let value_var = self.make_tmp_var();
659
659
+
let value_var = self.make_tmp_var(Translator::translate_type(&assignment.value.type_()));
613
660
let value = self.translate_expression(&assignment.value);
614
661
615
662
block.push(Expression::Set {
···
629
676
Expression::Block(block)
630
677
}
631
678
679
679
+
fn translate_bound_value_type(&mut self, value: &exhaustiveness::BoundValue) -> IncompleteType {
680
680
+
match value {
681
681
+
exhaustiveness::BoundValue::Variable(variable) => {
682
682
+
Translator::translate_type(&variable.type_)
683
683
+
}
684
684
+
exhaustiveness::BoundValue::LiteralString(_) => IncompleteType::String,
685
685
+
exhaustiveness::BoundValue::LiteralInt(_) => IncompleteType::Int,
686
686
+
exhaustiveness::BoundValue::LiteralFloat(_) => IncompleteType::Float,
687
687
+
exhaustiveness::BoundValue::BitArraySlice {
688
688
+
bit_array: _,
689
689
+
read_action: _,
690
690
+
} => todo!(),
691
691
+
}
692
692
+
}
693
693
+
632
694
fn translate_decision(
633
695
&mut self,
634
696
kind: DecisionKind,
635
635
-
subjects: &[Var],
697
697
+
subjects: &[Var<IncompleteType>],
636
698
clauses: &[crate::ast::TypedClause],
637
699
decision: &exhaustiveness::Decision,
638
638
-
) -> Expression {
700
700
+
) -> Expression<IncompleteType> {
639
701
match decision {
640
702
exhaustiveness::Decision::Run { body } => {
641
703
let mut block = vec![];
642
704
643
705
for (binding, value) in &body.bindings {
644
644
-
let binding = self.make_var(binding.clone());
706
706
+
let binding_type = self.translate_bound_value_type(value);
707
707
+
let binding = self.make_var(binding.clone(), binding_type);
645
708
646
709
block.push(self.translate_binding(subjects, binding.clone(), value));
647
710
}
···
672
735
.partition(|(binding, _)| referenced_in_guard.contains(binding));
673
736
674
737
for (binding, value) in guard_bindings {
675
675
-
let binding = self.make_var(binding.clone());
738
738
+
let binding_type = self.translate_bound_value_type(value);
739
739
+
let binding = self.make_var(binding.clone(), binding_type);
676
740
677
741
block.push(self.translate_binding(subjects, binding, value));
678
742
}
···
683
747
let mut block = vec![];
684
748
685
749
for (binding, value) in if_true_bindings {
686
686
-
let binding = self.make_var(binding.clone());
750
750
+
let binding_type = self.translate_bound_value_type(value);
751
751
+
let binding = self.make_var(binding.clone(), binding_type);
687
752
688
753
block.push(self.translate_binding(subjects, binding.clone(), value));
689
754
}
···
725
790
}
726
791
}
727
792
728
728
-
fn translate_guard(&mut self, guard: &crate::ast::TypedClauseGuard) -> Expression {
793
793
+
fn translate_guard(
794
794
+
&mut self,
795
795
+
guard: &crate::ast::TypedClauseGuard,
796
796
+
) -> Expression<IncompleteType> {
729
797
match guard {
730
798
crate::ast::ClauseGuard::Block { location: _, value } => self.translate_guard(value),
731
799
crate::ast::ClauseGuard::Equals {
···
919
987
crate::ast::ClauseGuard::TupleIndex {
920
988
location: _,
921
989
index,
922
922
-
type_: _,
990
990
+
type_,
923
991
tuple,
924
992
} => Expression::StructAccess {
925
993
value: Box::new(self.translate_guard(tuple)),
926
994
index: *index,
995
995
+
type_: Translator::translate_type(type_),
927
996
},
928
997
crate::ast::ClauseGuard::FieldAccess {
929
998
label_location: _,
930
999
index,
931
1000
label: _,
932
932
-
type_: _,
1001
1001
+
type_,
933
1002
container,
934
1003
} => Expression::StructAccess {
935
1004
value: Box::new(self.translate_guard(container)),
936
1005
index: index.expect("field access expected an index"),
1006
1006
+
type_: Translator::translate_type(type_),
937
1007
},
938
1008
crate::ast::ClauseGuard::ModuleSelect {
939
1009
location: _,
···
947
1017
}
948
1018
}
949
1019
950
950
-
fn translate_constant(&mut self, constant: &crate::ast::TypedConstant) -> Expression {
1020
1020
+
fn translate_constant(
1021
1021
+
&mut self,
1022
1022
+
constant: &crate::ast::TypedConstant,
1023
1023
+
) -> Expression<IncompleteType> {
951
1024
match constant {
952
1025
crate::ast::Constant::Int {
953
1026
location: _,
···
971
1044
.iter()
972
1045
.map(|element| self.translate_constant(element))
973
1046
.collect(),
1047
1047
+
type_: Translator::translate_type(&constant.type_()),
974
1048
},
975
1049
crate::ast::Constant::List {
976
1050
location: _,
977
1051
elements,
978
978
-
type_: _,
1052
1052
+
type_,
979
1053
} => Expression::List {
980
1054
items: elements
981
1055
.iter()
982
1056
.map(|element| self.translate_constant(element))
983
1057
.collect(),
984
1058
tail: None,
1059
1059
+
type_: Translator::translate_type(type_),
985
1060
},
986
1061
crate::ast::Constant::Record {
987
1062
location: _,
···
1021
1096
1022
1097
fn translate_binding(
1023
1098
&mut self,
1024
1024
-
subjects: &[Var],
1025
1025
-
binding: Var,
1099
1099
+
subjects: &[Var<IncompleteType>],
1100
1100
+
binding: Var<IncompleteType>,
1026
1101
value: &exhaustiveness::BoundValue,
1027
1027
-
) -> Expression {
1102
1102
+
) -> Expression<IncompleteType> {
1028
1103
let value = match value {
1029
1104
exhaustiveness::BoundValue::Variable(variable) => {
1030
1105
Expression::Var(subjects[variable.id].clone())
···
1049
1124
fn translate_runtime_check(
1050
1125
&mut self,
1051
1126
check: &exhaustiveness::RuntimeCheck,
1052
1052
-
against: Expression,
1053
1053
-
) -> Expression {
1127
1127
+
against: Expression<IncompleteType>,
1128
1128
+
) -> Expression<IncompleteType> {
1054
1129
match check {
1055
1130
exhaustiveness::RuntimeCheck::Int { value } => {
1056
1131
let value = parse::parse_int_value(&value).expect("unable to parse integer value");
···
1139
1214
.expect("should successfully infer")
1140
1215
}
1141
1216
1142
1142
-
fn translate(src: &str) -> Module {
1217
1217
+
fn translate(src: &str) -> Module<IncompleteType> {
1143
1218
let typed_module = compile_module(src);
1144
1219
1145
1145
-
Translator::default().translate(&typed_module)
1220
1220
+
Translator::new(&typed_module).translate()
1146
1221
}
1147
1222
1148
1223
#[test]
+152
-77
compiler-core/src/cranelift/mir/ast.rs
View file
Reviewed
···
1
1
use ecow::EcoString;
2
2
use num_bigint::BigInt;
3
3
4
4
+
#[derive(Debug, Clone, PartialEq, Eq)]
5
5
+
pub enum IncompleteType {
6
6
+
Int,
7
7
+
Float,
8
8
+
Bool,
9
9
+
String,
10
10
+
Func {
11
11
+
arguments: Vec<IncompleteType>,
12
12
+
returns: Box<IncompleteType>,
13
13
+
},
14
14
+
Struct {
15
15
+
elements: Vec<IncompleteType>,
16
16
+
},
17
17
+
List(Box<IncompleteType>),
18
18
+
Generic {
19
19
+
id: u64,
20
20
+
},
21
21
+
}
22
22
+
23
23
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24
24
+
pub enum CompleteType {
25
25
+
Int,
26
26
+
Float,
27
27
+
Bool,
28
28
+
String,
29
29
+
Func {
30
30
+
arguments: Vec<CompleteType>,
31
31
+
returns: Box<CompleteType>,
32
32
+
},
33
33
+
Struct {
34
34
+
elements: Vec<CompleteType>,
35
35
+
},
36
36
+
List(Box<CompleteType>),
37
37
+
}
38
38
+
4
39
#[derive(Debug, PartialEq, Eq, Default)]
5
5
-
pub struct Module {
6
6
-
pub functions: Vec<Function>,
40
40
+
pub struct Module<T> {
41
41
+
pub name: EcoString,
42
42
+
pub functions: Vec<Function<T>>,
7
43
}
8
44
9
9
-
#[derive(Debug, PartialEq, Eq)]
10
10
-
pub struct Function {
45
45
+
#[derive(Debug, PartialEq, Eq, Clone)]
46
46
+
pub struct Function<T> {
11
47
pub name: EcoString,
12
12
-
pub return_type: Type,
13
13
-
pub parameters: Vec<FunctionParameter>,
14
14
-
pub body: Expression,
48
48
+
pub return_type: T,
49
49
+
pub parameters: Vec<FunctionParameter<T>>,
50
50
+
pub body: Expression<T>,
15
51
}
16
52
17
17
-
#[derive(Debug, PartialEq, Eq)]
18
18
-
pub struct FunctionParameter {
19
19
-
pub type_: Type,
53
53
+
#[derive(Debug, PartialEq, Eq, Clone)]
54
54
+
pub struct FunctionParameter<T> {
55
55
+
pub type_: T,
20
56
pub name: Option<EcoString>,
21
57
}
22
58
23
23
-
#[derive(Debug, Clone, PartialEq, Eq)]
24
24
-
pub enum Type {
25
25
-
Int,
26
26
-
Float,
27
27
-
Bool,
28
28
-
String,
29
29
-
Struct { elements: Vec<Type> },
30
30
-
List(Box<Type>),
31
31
-
Generic,
32
32
-
}
33
33
-
34
59
#[derive(Debug, PartialEq, Eq, Clone)]
35
35
-
pub struct Var {
60
60
+
pub struct Var<T> {
36
61
pub name: EcoString,
62
62
+
pub type_: T,
37
63
}
38
64
39
65
#[derive(Debug, PartialEq, Eq, Clone)]
40
40
-
pub enum Expression {
41
41
-
Block(Vec<Expression>),
66
66
+
pub enum Expression<T> {
67
67
+
Block(Vec<Expression<T>>),
42
68
43
69
FunctionRef {
44
70
module: EcoString,
45
71
name: EcoString,
46
72
arity: usize,
73
73
+
type_: T,
47
74
},
48
75
49
49
-
Var(Var),
76
76
+
Var(Var<T>),
50
77
51
78
Int {
52
79
value: BigInt,
···
65
92
},
66
93
67
94
Equals {
68
68
-
lhs: Box<Expression>,
69
69
-
rhs: Box<Expression>,
95
95
+
lhs: Box<Expression<T>>,
96
96
+
rhs: Box<Expression<T>>,
70
97
},
71
98
72
99
NotEquals {
73
73
-
lhs: Box<Expression>,
74
74
-
rhs: Box<Expression>,
100
100
+
lhs: Box<Expression<T>>,
101
101
+
rhs: Box<Expression<T>>,
75
102
},
76
103
77
104
IntGt {
78
78
-
lhs: Box<Expression>,
79
79
-
rhs: Box<Expression>,
105
105
+
lhs: Box<Expression<T>>,
106
106
+
rhs: Box<Expression<T>>,
80
107
},
81
108
82
109
IntGtEq {
83
83
-
lhs: Box<Expression>,
84
84
-
rhs: Box<Expression>,
110
110
+
lhs: Box<Expression<T>>,
111
111
+
rhs: Box<Expression<T>>,
85
112
},
86
113
87
114
IntLt {
88
88
-
lhs: Box<Expression>,
89
89
-
rhs: Box<Expression>,
115
115
+
lhs: Box<Expression<T>>,
116
116
+
rhs: Box<Expression<T>>,
90
117
},
91
118
92
119
IntLtEq {
93
93
-
lhs: Box<Expression>,
94
94
-
rhs: Box<Expression>,
120
120
+
lhs: Box<Expression<T>>,
121
121
+
rhs: Box<Expression<T>>,
95
122
},
96
123
97
124
IntAdd {
98
98
-
lhs: Box<Expression>,
99
99
-
rhs: Box<Expression>,
125
125
+
lhs: Box<Expression<T>>,
126
126
+
rhs: Box<Expression<T>>,
100
127
},
101
128
102
129
IntSub {
103
103
-
lhs: Box<Expression>,
104
104
-
rhs: Box<Expression>,
130
130
+
lhs: Box<Expression<T>>,
131
131
+
rhs: Box<Expression<T>>,
105
132
},
106
133
107
134
IntMul {
108
108
-
lhs: Box<Expression>,
109
109
-
rhs: Box<Expression>,
135
135
+
lhs: Box<Expression<T>>,
136
136
+
rhs: Box<Expression<T>>,
110
137
},
111
138
112
139
IntDiv {
113
113
-
lhs: Box<Expression>,
114
114
-
rhs: Box<Expression>,
140
140
+
lhs: Box<Expression<T>>,
141
141
+
rhs: Box<Expression<T>>,
115
142
},
116
143
117
144
IntRem {
118
118
-
lhs: Box<Expression>,
119
119
-
rhs: Box<Expression>,
145
145
+
lhs: Box<Expression<T>>,
146
146
+
rhs: Box<Expression<T>>,
120
147
},
121
148
122
149
FloatGt {
123
123
-
lhs: Box<Expression>,
124
124
-
rhs: Box<Expression>,
150
150
+
lhs: Box<Expression<T>>,
151
151
+
rhs: Box<Expression<T>>,
125
152
},
126
153
127
154
FloatGtEq {
128
128
-
lhs: Box<Expression>,
129
129
-
rhs: Box<Expression>,
155
155
+
lhs: Box<Expression<T>>,
156
156
+
rhs: Box<Expression<T>>,
130
157
},
131
158
132
159
FloatLt {
133
133
-
lhs: Box<Expression>,
134
134
-
rhs: Box<Expression>,
160
160
+
lhs: Box<Expression<T>>,
161
161
+
rhs: Box<Expression<T>>,
135
162
},
136
163
137
164
FloatLtEq {
138
138
-
lhs: Box<Expression>,
139
139
-
rhs: Box<Expression>,
165
165
+
lhs: Box<Expression<T>>,
166
166
+
rhs: Box<Expression<T>>,
140
167
},
141
168
142
169
FloatAdd {
143
143
-
lhs: Box<Expression>,
144
144
-
rhs: Box<Expression>,
170
170
+
lhs: Box<Expression<T>>,
171
171
+
rhs: Box<Expression<T>>,
145
172
},
146
173
147
174
FloatSub {
148
148
-
lhs: Box<Expression>,
149
149
-
rhs: Box<Expression>,
175
175
+
lhs: Box<Expression<T>>,
176
176
+
rhs: Box<Expression<T>>,
150
177
},
151
178
152
179
FloatMul {
153
153
-
lhs: Box<Expression>,
154
154
-
rhs: Box<Expression>,
180
180
+
lhs: Box<Expression<T>>,
181
181
+
rhs: Box<Expression<T>>,
155
182
},
156
183
157
184
FloatDiv {
158
158
-
lhs: Box<Expression>,
159
159
-
rhs: Box<Expression>,
185
185
+
lhs: Box<Expression<T>>,
186
186
+
rhs: Box<Expression<T>>,
160
187
},
161
188
162
189
StringConcat {
163
163
-
lhs: Box<Expression>,
164
164
-
rhs: Box<Expression>,
190
190
+
lhs: Box<Expression<T>>,
191
191
+
rhs: Box<Expression<T>>,
165
192
},
166
193
167
194
List {
168
168
-
items: Vec<Expression>,
169
169
-
tail: Option<Box<Expression>>,
195
195
+
items: Vec<Expression<T>>,
196
196
+
tail: Option<Box<Expression<T>>>,
197
197
+
type_: T,
170
198
},
171
199
172
200
Struct {
173
201
tag: Option<u32>,
174
174
-
items: Vec<Expression>,
202
202
+
items: Vec<Expression<T>>,
203
203
+
type_: T,
175
204
},
176
205
177
206
StructTag {
178
178
-
value: Box<Expression>,
207
207
+
value: Box<Expression<T>>,
179
208
},
180
209
181
210
StructAccess {
182
182
-
value: Box<Expression>,
211
211
+
value: Box<Expression<T>>,
183
212
index: u64,
213
213
+
type_: T,
184
214
},
185
215
186
216
Set {
187
187
-
name: Var,
188
188
-
value: Box<Expression>,
217
217
+
name: Var<T>,
218
218
+
value: Box<Expression<T>>,
189
219
},
190
220
191
221
If {
192
192
-
cond: Box<Expression>,
193
193
-
then: Box<Expression>,
194
194
-
else_: Box<Expression>,
222
222
+
cond: Box<Expression<T>>,
223
223
+
then: Box<Expression<T>>,
224
224
+
else_: Box<Expression<T>>,
195
225
},
196
226
197
227
Call {
198
198
-
target: Box<Expression>,
199
199
-
args: Vec<Expression>,
228
228
+
target: Box<Expression<T>>,
229
229
+
args: Vec<Expression<T>>,
230
230
+
type_: T,
200
231
},
201
232
}
233
233
+
234
234
+
impl Expression<IncompleteType> {
235
235
+
pub fn type_(&self) -> IncompleteType {
236
236
+
match self {
237
237
+
Expression::Block(expressions) => expressions
238
238
+
.last()
239
239
+
.expect("a block should not be empty")
240
240
+
.type_(),
241
241
+
Expression::FunctionRef { type_, .. } => type_.clone(),
242
242
+
Expression::Var(var) => var.type_.clone(),
243
243
+
Expression::Int { .. } => IncompleteType::Int,
244
244
+
Expression::Float { .. } => IncompleteType::Float,
245
245
+
Expression::Bool { .. } => IncompleteType::Bool,
246
246
+
Expression::String { .. } => IncompleteType::String,
247
247
+
Expression::Equals { .. } => IncompleteType::Bool,
248
248
+
Expression::NotEquals { .. } => IncompleteType::Bool,
249
249
+
Expression::IntGt { .. } => IncompleteType::Bool,
250
250
+
Expression::IntGtEq { .. } => IncompleteType::Bool,
251
251
+
Expression::IntLt { .. } => IncompleteType::Bool,
252
252
+
Expression::IntLtEq { .. } => IncompleteType::Bool,
253
253
+
Expression::IntAdd { .. } => IncompleteType::Int,
254
254
+
Expression::IntSub { .. } => IncompleteType::Int,
255
255
+
Expression::IntMul { .. } => IncompleteType::Int,
256
256
+
Expression::IntDiv { .. } => IncompleteType::Int,
257
257
+
Expression::IntRem { .. } => IncompleteType::Int,
258
258
+
Expression::FloatGt { .. } => IncompleteType::Bool,
259
259
+
Expression::FloatGtEq { .. } => IncompleteType::Bool,
260
260
+
Expression::FloatLt { .. } => IncompleteType::Bool,
261
261
+
Expression::FloatLtEq { .. } => IncompleteType::Bool,
262
262
+
Expression::FloatAdd { .. } => IncompleteType::Bool,
263
263
+
Expression::FloatSub { .. } => IncompleteType::Bool,
264
264
+
Expression::FloatMul { .. } => IncompleteType::Bool,
265
265
+
Expression::FloatDiv { .. } => IncompleteType::Bool,
266
266
+
Expression::StringConcat { .. } => IncompleteType::Bool,
267
267
+
Expression::List { type_, .. } => type_.clone(),
268
268
+
Expression::Struct { type_, .. } => type_.clone(),
269
269
+
Expression::StructTag { .. } => IncompleteType::Int,
270
270
+
Expression::StructAccess { type_, .. } => type_.clone(),
271
271
+
Expression::Set { value, .. } => value.type_(),
272
272
+
Expression::If { then, .. } => then.type_(),
273
273
+
Expression::Call { type_, .. } => type_.clone(),
274
274
+
}
275
275
+
}
276
276
+
}
+638
compiler-core/src/cranelift/mir/lower.rs
View file
Reviewed
···
1
1
+
use std::collections::{HashMap, HashSet, VecDeque};
2
2
+
3
3
+
use ecow::EcoString;
4
4
+
5
5
+
use crate::cranelift::mir::{
6
6
+
ast::{CompleteType, Expression, Function, FunctionParameter, IncompleteType, Module, Var},
7
7
+
visit::Visit,
8
8
+
};
9
9
+
10
10
+
pub fn lower(modules: Vec<Module<IncompleteType>>) -> Vec<Module<CompleteType>> {
11
11
+
let (generics, functions): (HashMap<_, _>, HashMap<_, _>) = modules
12
12
+
.into_iter()
13
13
+
.flat_map(|module| {
14
14
+
module
15
15
+
.functions
16
16
+
.into_iter()
17
17
+
.map(|function| ((module.name.clone(), function.name.clone()), function))
18
18
+
.collect::<Vec<_>>()
19
19
+
})
20
20
+
.partition(|(_, function)| is_generic(function));
21
21
+
22
22
+
let mut functions = functions
23
23
+
.into_iter()
24
24
+
.map(|((module, name), function)| {
25
25
+
let function = Function::<CompleteType>::try_from(function)?;
26
26
+
27
27
+
let instantiation = Instantiation {
28
28
+
argument_types: function
29
29
+
.parameters
30
30
+
.iter()
31
31
+
.map(|parameter| parameter.type_.clone())
32
32
+
.collect(),
33
33
+
return_type: function.return_type.clone(),
34
34
+
};
35
35
+
36
36
+
Ok(((module, name, instantiation), function))
37
37
+
})
38
38
+
.collect::<Result<
39
39
+
HashMap<(EcoString, EcoString, Instantiation), Function<CompleteType>>,
40
40
+
NonGenericError,
41
41
+
>>()
42
42
+
.expect("expected all functions to be non-generic");
43
43
+
44
44
+
let mut monomorphizer = Monomorphizer::new(&generics);
45
45
+
for (_, function) in functions.iter_mut() {
46
46
+
monomorphizer.visit_function(function);
47
47
+
}
48
48
+
49
49
+
let mut queue: VecDeque<_> = monomorphizer.instantiations.into_iter().collect();
50
50
+
51
51
+
while let Some((module, name, instantiation)) = queue.pop_front() {
52
52
+
if let Some(function) = generics.get(&(module.clone(), name.clone())).cloned() {
53
53
+
let mut function = FunctionMonomorphizer::default()
54
54
+
.translate_function(function, instantiation.clone());
55
55
+
56
56
+
_ = functions.insert((module, name, instantiation), function.clone());
57
57
+
58
58
+
let mut monomorphizer = Monomorphizer::new(&generics);
59
59
+
monomorphizer.visit_function(&mut function);
60
60
+
61
61
+
for instantiation in monomorphizer.instantiations {
62
62
+
if !functions.contains_key(&instantiation) {
63
63
+
queue.push_back(instantiation);
64
64
+
}
65
65
+
}
66
66
+
}
67
67
+
}
68
68
+
69
69
+
let mut module_map: HashMap<EcoString, Vec<Function<CompleteType>>> = HashMap::new();
70
70
+
for ((module, _, _), function) in functions {
71
71
+
module_map
72
72
+
.entry(module)
73
73
+
.or_insert_with(Vec::new)
74
74
+
.push(function);
75
75
+
}
76
76
+
77
77
+
module_map
78
78
+
.into_iter()
79
79
+
.map(|(name, functions)| Module { name, functions })
80
80
+
.collect()
81
81
+
}
82
82
+
83
83
+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
84
84
+
struct Instantiation {
85
85
+
argument_types: Vec<CompleteType>,
86
86
+
return_type: CompleteType,
87
87
+
}
88
88
+
89
89
+
#[derive(Default)]
90
90
+
struct FunctionMonomorphizer {
91
91
+
generic_id_map: HashMap<u64, CompleteType>,
92
92
+
}
93
93
+
94
94
+
impl FunctionMonomorphizer {
95
95
+
fn collect_type_ids(&mut self, incomplete: &IncompleteType, complete: &CompleteType) {
96
96
+
match incomplete {
97
97
+
IncompleteType::Generic { id } => {
98
98
+
_ = self.generic_id_map.insert(*id, complete.clone());
99
99
+
}
100
100
+
101
101
+
IncompleteType::Func { arguments, returns } => {
102
102
+
let CompleteType::Func {
103
103
+
arguments: complete_arguments,
104
104
+
returns: complete_returns,
105
105
+
} = complete
106
106
+
else {
107
107
+
unreachable!("types should not be diverged")
108
108
+
};
109
109
+
110
110
+
for (argument, complete) in arguments.iter().zip(complete_arguments.iter()) {
111
111
+
self.collect_type_ids(argument, complete);
112
112
+
}
113
113
+
114
114
+
self.collect_type_ids(returns, complete_returns);
115
115
+
}
116
116
+
IncompleteType::Struct { elements } => {
117
117
+
let CompleteType::Struct { elements: complete } = complete else {
118
118
+
unreachable!("types should not be diverged")
119
119
+
};
120
120
+
121
121
+
for (element, complete) in elements.iter().zip(complete.iter()) {
122
122
+
self.collect_type_ids(element, complete);
123
123
+
}
124
124
+
}
125
125
+
IncompleteType::List(element_type) => {
126
126
+
let CompleteType::List(complete) = complete else {
127
127
+
unreachable!("types should not be diverged")
128
128
+
};
129
129
+
130
130
+
self.collect_type_ids(element_type, complete);
131
131
+
}
132
132
+
133
133
+
IncompleteType::Int
134
134
+
| IncompleteType::Float
135
135
+
| IncompleteType::Bool
136
136
+
| IncompleteType::String => {}
137
137
+
}
138
138
+
}
139
139
+
140
140
+
fn translate_function(
141
141
+
mut self,
142
142
+
function: Function<IncompleteType>,
143
143
+
instantiation: Instantiation,
144
144
+
) -> Function<CompleteType> {
145
145
+
for (parameter, argument_type) in function
146
146
+
.parameters
147
147
+
.iter()
148
148
+
.zip(instantiation.argument_types.iter())
149
149
+
{
150
150
+
self.collect_type_ids(¶meter.type_, argument_type);
151
151
+
}
152
152
+
153
153
+
self.collect_type_ids(&function.return_type, &instantiation.return_type);
154
154
+
155
155
+
Function {
156
156
+
name: function.name,
157
157
+
return_type: instantiation.return_type,
158
158
+
parameters: function
159
159
+
.parameters
160
160
+
.into_iter()
161
161
+
.zip(instantiation.argument_types.into_iter())
162
162
+
.map(|(parameter, argument_type)| FunctionParameter {
163
163
+
name: parameter.name,
164
164
+
type_: argument_type,
165
165
+
})
166
166
+
.collect(),
167
167
+
body: self.translate_expression(function.body),
168
168
+
}
169
169
+
}
170
170
+
171
171
+
fn translate_expression(
172
172
+
&mut self,
173
173
+
expression: Expression<IncompleteType>,
174
174
+
) -> Expression<CompleteType> {
175
175
+
match expression {
176
176
+
Expression::Block(expressions) => Expression::Block(
177
177
+
expressions
178
178
+
.into_iter()
179
179
+
.map(|expression| self.translate_expression(expression))
180
180
+
.collect(),
181
181
+
),
182
182
+
Expression::FunctionRef {
183
183
+
module,
184
184
+
name,
185
185
+
arity,
186
186
+
type_,
187
187
+
} => Expression::FunctionRef {
188
188
+
module,
189
189
+
name,
190
190
+
arity,
191
191
+
type_: self.translate_type(type_),
192
192
+
},
193
193
+
Expression::Var(var) => Expression::Var(Var {
194
194
+
name: var.name,
195
195
+
type_: self.translate_type(var.type_),
196
196
+
}),
197
197
+
Expression::Int { value } => Expression::Int { value },
198
198
+
Expression::Float { value } => Expression::Float { value },
199
199
+
Expression::Bool { value } => Expression::Bool { value },
200
200
+
Expression::String { value } => Expression::String { value },
201
201
+
Expression::Equals { lhs, rhs } => Expression::Equals {
202
202
+
lhs: Box::new(self.translate_expression(*lhs)),
203
203
+
rhs: Box::new(self.translate_expression(*rhs)),
204
204
+
},
205
205
+
Expression::NotEquals { lhs, rhs } => Expression::NotEquals {
206
206
+
lhs: Box::new(self.translate_expression(*lhs)),
207
207
+
rhs: Box::new(self.translate_expression(*rhs)),
208
208
+
},
209
209
+
Expression::IntGt { lhs, rhs } => Expression::IntGt {
210
210
+
lhs: Box::new(self.translate_expression(*lhs)),
211
211
+
rhs: Box::new(self.translate_expression(*rhs)),
212
212
+
},
213
213
+
Expression::IntGtEq { lhs, rhs } => Expression::IntGtEq {
214
214
+
lhs: Box::new(self.translate_expression(*lhs)),
215
215
+
rhs: Box::new(self.translate_expression(*rhs)),
216
216
+
},
217
217
+
Expression::IntLt { lhs, rhs } => Expression::IntLt {
218
218
+
lhs: Box::new(self.translate_expression(*lhs)),
219
219
+
rhs: Box::new(self.translate_expression(*rhs)),
220
220
+
},
221
221
+
Expression::IntLtEq { lhs, rhs } => Expression::IntLtEq {
222
222
+
lhs: Box::new(self.translate_expression(*lhs)),
223
223
+
rhs: Box::new(self.translate_expression(*rhs)),
224
224
+
},
225
225
+
Expression::IntAdd { lhs, rhs } => Expression::IntAdd {
226
226
+
lhs: Box::new(self.translate_expression(*lhs)),
227
227
+
rhs: Box::new(self.translate_expression(*rhs)),
228
228
+
},
229
229
+
Expression::IntSub { lhs, rhs } => Expression::IntSub {
230
230
+
lhs: Box::new(self.translate_expression(*lhs)),
231
231
+
rhs: Box::new(self.translate_expression(*rhs)),
232
232
+
},
233
233
+
Expression::IntMul { lhs, rhs } => Expression::IntMul {
234
234
+
lhs: Box::new(self.translate_expression(*lhs)),
235
235
+
rhs: Box::new(self.translate_expression(*rhs)),
236
236
+
},
237
237
+
Expression::IntDiv { lhs, rhs } => Expression::IntDiv {
238
238
+
lhs: Box::new(self.translate_expression(*lhs)),
239
239
+
rhs: Box::new(self.translate_expression(*rhs)),
240
240
+
},
241
241
+
Expression::IntRem { lhs, rhs } => Expression::IntRem {
242
242
+
lhs: Box::new(self.translate_expression(*lhs)),
243
243
+
rhs: Box::new(self.translate_expression(*rhs)),
244
244
+
},
245
245
+
Expression::FloatGt { lhs, rhs } => Expression::FloatGt {
246
246
+
lhs: Box::new(self.translate_expression(*lhs)),
247
247
+
rhs: Box::new(self.translate_expression(*rhs)),
248
248
+
},
249
249
+
Expression::FloatGtEq { lhs, rhs } => Expression::FloatGtEq {
250
250
+
lhs: Box::new(self.translate_expression(*lhs)),
251
251
+
rhs: Box::new(self.translate_expression(*rhs)),
252
252
+
},
253
253
+
Expression::FloatLt { lhs, rhs } => Expression::FloatLt {
254
254
+
lhs: Box::new(self.translate_expression(*lhs)),
255
255
+
rhs: Box::new(self.translate_expression(*rhs)),
256
256
+
},
257
257
+
Expression::FloatLtEq { lhs, rhs } => Expression::FloatLtEq {
258
258
+
lhs: Box::new(self.translate_expression(*lhs)),
259
259
+
rhs: Box::new(self.translate_expression(*rhs)),
260
260
+
},
261
261
+
Expression::FloatAdd { lhs, rhs } => Expression::FloatAdd {
262
262
+
lhs: Box::new(self.translate_expression(*lhs)),
263
263
+
rhs: Box::new(self.translate_expression(*rhs)),
264
264
+
},
265
265
+
Expression::FloatSub { lhs, rhs } => Expression::FloatSub {
266
266
+
lhs: Box::new(self.translate_expression(*lhs)),
267
267
+
rhs: Box::new(self.translate_expression(*rhs)),
268
268
+
},
269
269
+
Expression::FloatMul { lhs, rhs } => Expression::FloatMul {
270
270
+
lhs: Box::new(self.translate_expression(*lhs)),
271
271
+
rhs: Box::new(self.translate_expression(*rhs)),
272
272
+
},
273
273
+
Expression::FloatDiv { lhs, rhs } => Expression::FloatDiv {
274
274
+
lhs: Box::new(self.translate_expression(*lhs)),
275
275
+
rhs: Box::new(self.translate_expression(*rhs)),
276
276
+
},
277
277
+
Expression::StringConcat { lhs, rhs } => Expression::StringConcat {
278
278
+
lhs: Box::new(self.translate_expression(*lhs)),
279
279
+
rhs: Box::new(self.translate_expression(*rhs)),
280
280
+
},
281
281
+
Expression::List { items, tail, type_ } => Expression::List {
282
282
+
items: items
283
283
+
.into_iter()
284
284
+
.map(|item| self.translate_expression(item))
285
285
+
.collect(),
286
286
+
tail: tail.map(|t| Box::new(self.translate_expression(*t))),
287
287
+
type_: self.translate_type(type_),
288
288
+
},
289
289
+
Expression::Struct { tag, items, type_ } => Expression::Struct {
290
290
+
tag,
291
291
+
items: items
292
292
+
.into_iter()
293
293
+
.map(|item| self.translate_expression(item))
294
294
+
.collect(),
295
295
+
type_: self.translate_type(type_),
296
296
+
},
297
297
+
Expression::StructTag { value } => Expression::StructTag {
298
298
+
value: Box::new(self.translate_expression(*value)),
299
299
+
},
300
300
+
Expression::StructAccess {
301
301
+
value,
302
302
+
index,
303
303
+
type_,
304
304
+
} => Expression::StructAccess {
305
305
+
value: Box::new(self.translate_expression(*value)),
306
306
+
index,
307
307
+
type_: self.translate_type(type_),
308
308
+
},
309
309
+
Expression::Set { name, value } => Expression::Set {
310
310
+
name: Var {
311
311
+
name: name.name,
312
312
+
type_: self.translate_type(name.type_),
313
313
+
},
314
314
+
value: Box::new(self.translate_expression(*value)),
315
315
+
},
316
316
+
Expression::If { cond, then, else_ } => Expression::If {
317
317
+
cond: Box::new(self.translate_expression(*cond)),
318
318
+
then: Box::new(self.translate_expression(*then)),
319
319
+
else_: Box::new(self.translate_expression(*else_)),
320
320
+
},
321
321
+
Expression::Call {
322
322
+
target,
323
323
+
args,
324
324
+
type_,
325
325
+
} => Expression::Call {
326
326
+
target: Box::new(self.translate_expression(*target)),
327
327
+
args: args
328
328
+
.into_iter()
329
329
+
.map(|arg| self.translate_expression(arg))
330
330
+
.collect(),
331
331
+
type_: self.translate_type(type_),
332
332
+
},
333
333
+
}
334
334
+
}
335
335
+
336
336
+
fn translate_type(&mut self, type_: IncompleteType) -> CompleteType {
337
337
+
match type_ {
338
338
+
IncompleteType::Int => CompleteType::Int,
339
339
+
IncompleteType::Float => CompleteType::Float,
340
340
+
IncompleteType::Bool => CompleteType::Bool,
341
341
+
IncompleteType::String => CompleteType::String,
342
342
+
IncompleteType::Func { arguments, returns } => CompleteType::Func {
343
343
+
arguments: arguments
344
344
+
.into_iter()
345
345
+
.map(|argument| self.translate_type(argument))
346
346
+
.collect(),
347
347
+
returns: Box::new(self.translate_type(*returns)),
348
348
+
},
349
349
+
IncompleteType::Struct { elements } => CompleteType::Struct {
350
350
+
elements: elements
351
351
+
.into_iter()
352
352
+
.map(|element| self.translate_type(element))
353
353
+
.collect(),
354
354
+
},
355
355
+
IncompleteType::List(element_type) => {
356
356
+
CompleteType::List(Box::new(self.translate_type(*element_type)))
357
357
+
}
358
358
+
IncompleteType::Generic { id } => self
359
359
+
.generic_id_map
360
360
+
.get(&id)
361
361
+
.cloned()
362
362
+
.expect("expected generic id to have a matching type"),
363
363
+
}
364
364
+
}
365
365
+
}
366
366
+
367
367
+
struct Monomorphizer<'g> {
368
368
+
generics: &'g HashMap<(EcoString, EcoString), Function<IncompleteType>>,
369
369
+
instantiations: HashSet<(EcoString, EcoString, Instantiation)>,
370
370
+
}
371
371
+
372
372
+
impl<'g> Monomorphizer<'g> {
373
373
+
fn new(generics: &'g HashMap<(EcoString, EcoString), Function<IncompleteType>>) -> Self {
374
374
+
Self {
375
375
+
generics,
376
376
+
instantiations: Default::default(),
377
377
+
}
378
378
+
}
379
379
+
}
380
380
+
381
381
+
impl<'mir, 'g> Visit<'mir, CompleteType> for Monomorphizer<'g> {
382
382
+
fn visit_expression_function_ref(
383
383
+
&mut self,
384
384
+
module: &mut EcoString,
385
385
+
name: &mut EcoString,
386
386
+
_arity: &mut usize,
387
387
+
type_: &mut CompleteType,
388
388
+
) {
389
389
+
if !self.generics.contains_key(&(module.clone(), name.clone())) {
390
390
+
return;
391
391
+
}
392
392
+
393
393
+
let CompleteType::Func { arguments, returns } = type_ else {
394
394
+
unreachable!("a function ref should always have a func type")
395
395
+
};
396
396
+
397
397
+
let instantiation = Instantiation {
398
398
+
argument_types: arguments.clone(),
399
399
+
return_type: *returns.clone(),
400
400
+
};
401
401
+
402
402
+
_ = self
403
403
+
.instantiations
404
404
+
.insert((module.clone(), name.clone(), instantiation));
405
405
+
}
406
406
+
}
407
407
+
408
408
+
fn is_generic(function: &Function<IncompleteType>) -> bool {
409
409
+
let has_generic_parameter = function
410
410
+
.parameters
411
411
+
.iter()
412
412
+
.any(|parameter| matches!(parameter.type_, IncompleteType::Generic { .. }));
413
413
+
414
414
+
has_generic_parameter || matches!(function.return_type, IncompleteType::Generic { .. })
415
415
+
}
416
416
+
417
417
+
#[derive(Debug, Clone, Copy)]
418
418
+
pub struct NonGenericError;
419
419
+
420
420
+
impl TryFrom<Function<IncompleteType>> for Function<CompleteType> {
421
421
+
type Error = NonGenericError;
422
422
+
423
423
+
fn try_from(value: Function<IncompleteType>) -> Result<Self, Self::Error> {
424
424
+
Ok(Function {
425
425
+
name: value.name,
426
426
+
return_type: value.return_type.try_into()?,
427
427
+
parameters: value
428
428
+
.parameters
429
429
+
.into_iter()
430
430
+
.map(|parameter| {
431
431
+
Ok(FunctionParameter {
432
432
+
name: parameter.name,
433
433
+
type_: CompleteType::try_from(parameter.type_)?,
434
434
+
})
435
435
+
})
436
436
+
.collect::<Result<Vec<_>, _>>()?,
437
437
+
body: Expression::<CompleteType>::try_from(value.body)?,
438
438
+
})
439
439
+
}
440
440
+
}
441
441
+
442
442
+
impl TryFrom<Expression<IncompleteType>> for Expression<CompleteType> {
443
443
+
type Error = NonGenericError;
444
444
+
445
445
+
fn try_from(value: Expression<IncompleteType>) -> Result<Self, Self::Error> {
446
446
+
match value {
447
447
+
Expression::Block(expressions) => Ok(Expression::Block(
448
448
+
expressions
449
449
+
.into_iter()
450
450
+
.map(Expression::try_from)
451
451
+
.collect::<Result<Vec<_>, _>>()?,
452
452
+
)),
453
453
+
Expression::FunctionRef {
454
454
+
module,
455
455
+
name,
456
456
+
arity,
457
457
+
type_,
458
458
+
} => Ok(Expression::FunctionRef {
459
459
+
module,
460
460
+
name,
461
461
+
arity,
462
462
+
type_: type_.try_into()?,
463
463
+
}),
464
464
+
Expression::Var(var) => Ok(Expression::Var(Var {
465
465
+
name: var.name,
466
466
+
type_: var.type_.try_into()?,
467
467
+
})),
468
468
+
Expression::Int { value } => Ok(Expression::Int { value }),
469
469
+
Expression::Float { value } => Ok(Expression::Float { value }),
470
470
+
Expression::Bool { value } => Ok(Expression::Bool { value }),
471
471
+
Expression::String { value } => Ok(Expression::String { value }),
472
472
+
Expression::Equals { lhs, rhs } => Ok(Expression::Equals {
473
473
+
lhs: Box::new(Expression::try_from(*lhs)?),
474
474
+
rhs: Box::new(Expression::try_from(*rhs)?),
475
475
+
}),
476
476
+
Expression::NotEquals { lhs, rhs } => Ok(Expression::NotEquals {
477
477
+
lhs: Box::new(Expression::try_from(*lhs)?),
478
478
+
rhs: Box::new(Expression::try_from(*rhs)?),
479
479
+
}),
480
480
+
Expression::IntGt { lhs, rhs } => Ok(Expression::IntGt {
481
481
+
lhs: Box::new(Expression::try_from(*lhs)?),
482
482
+
rhs: Box::new(Expression::try_from(*rhs)?),
483
483
+
}),
484
484
+
Expression::IntGtEq { lhs, rhs } => Ok(Expression::IntGtEq {
485
485
+
lhs: Box::new(Expression::try_from(*lhs)?),
486
486
+
rhs: Box::new(Expression::try_from(*rhs)?),
487
487
+
}),
488
488
+
Expression::IntLt { lhs, rhs } => Ok(Expression::IntLt {
489
489
+
lhs: Box::new(Expression::try_from(*lhs)?),
490
490
+
rhs: Box::new(Expression::try_from(*rhs)?),
491
491
+
}),
492
492
+
Expression::IntLtEq { lhs, rhs } => Ok(Expression::IntLtEq {
493
493
+
lhs: Box::new(Expression::try_from(*lhs)?),
494
494
+
rhs: Box::new(Expression::try_from(*rhs)?),
495
495
+
}),
496
496
+
Expression::IntAdd { lhs, rhs } => Ok(Expression::IntAdd {
497
497
+
lhs: Box::new(Expression::try_from(*lhs)?),
498
498
+
rhs: Box::new(Expression::try_from(*rhs)?),
499
499
+
}),
500
500
+
Expression::IntSub { lhs, rhs } => Ok(Expression::IntSub {
501
501
+
lhs: Box::new(Expression::try_from(*lhs)?),
502
502
+
rhs: Box::new(Expression::try_from(*rhs)?),
503
503
+
}),
504
504
+
Expression::IntMul { lhs, rhs } => Ok(Expression::IntMul {
505
505
+
lhs: Box::new(Expression::try_from(*lhs)?),
506
506
+
rhs: Box::new(Expression::try_from(*rhs)?),
507
507
+
}),
508
508
+
Expression::IntDiv { lhs, rhs } => Ok(Expression::IntDiv {
509
509
+
lhs: Box::new(Expression::try_from(*lhs)?),
510
510
+
rhs: Box::new(Expression::try_from(*rhs)?),
511
511
+
}),
512
512
+
Expression::IntRem { lhs, rhs } => Ok(Expression::IntRem {
513
513
+
lhs: Box::new(Expression::try_from(*lhs)?),
514
514
+
rhs: Box::new(Expression::try_from(*rhs)?),
515
515
+
}),
516
516
+
Expression::FloatGt { lhs, rhs } => Ok(Expression::FloatGt {
517
517
+
lhs: Box::new(Expression::try_from(*lhs)?),
518
518
+
rhs: Box::new(Expression::try_from(*rhs)?),
519
519
+
}),
520
520
+
Expression::FloatGtEq { lhs, rhs } => Ok(Expression::FloatGtEq {
521
521
+
lhs: Box::new(Expression::try_from(*lhs)?),
522
522
+
rhs: Box::new(Expression::try_from(*rhs)?),
523
523
+
}),
524
524
+
Expression::FloatLt { lhs, rhs } => Ok(Expression::FloatLt {
525
525
+
lhs: Box::new(Expression::try_from(*lhs)?),
526
526
+
rhs: Box::new(Expression::try_from(*rhs)?),
527
527
+
}),
528
528
+
Expression::FloatLtEq { lhs, rhs } => Ok(Expression::FloatLtEq {
529
529
+
lhs: Box::new(Expression::try_from(*lhs)?),
530
530
+
rhs: Box::new(Expression::try_from(*rhs)?),
531
531
+
}),
532
532
+
Expression::FloatAdd { lhs, rhs } => Ok(Expression::FloatAdd {
533
533
+
lhs: Box::new(Expression::try_from(*lhs)?),
534
534
+
rhs: Box::new(Expression::try_from(*rhs)?),
535
535
+
}),
536
536
+
Expression::FloatSub { lhs, rhs } => Ok(Expression::FloatSub {
537
537
+
lhs: Box::new(Expression::try_from(*lhs)?),
538
538
+
rhs: Box::new(Expression::try_from(*rhs)?),
539
539
+
}),
540
540
+
Expression::FloatMul { lhs, rhs } => Ok(Expression::FloatMul {
541
541
+
lhs: Box::new(Expression::try_from(*lhs)?),
542
542
+
rhs: Box::new(Expression::try_from(*rhs)?),
543
543
+
}),
544
544
+
Expression::FloatDiv { lhs, rhs } => Ok(Expression::FloatDiv {
545
545
+
lhs: Box::new(Expression::try_from(*lhs)?),
546
546
+
rhs: Box::new(Expression::try_from(*rhs)?),
547
547
+
}),
548
548
+
Expression::StringConcat { lhs, rhs } => Ok(Expression::StringConcat {
549
549
+
lhs: Box::new(Expression::try_from(*lhs)?),
550
550
+
rhs: Box::new(Expression::try_from(*rhs)?),
551
551
+
}),
552
552
+
Expression::List { items, tail, type_ } => Ok(Expression::List {
553
553
+
items: items
554
554
+
.into_iter()
555
555
+
.map(Expression::try_from)
556
556
+
.collect::<Result<Vec<_>, _>>()?,
557
557
+
tail: tail
558
558
+
.map(|t| Ok(Box::new(Expression::try_from(*t)?)))
559
559
+
.transpose()?,
560
560
+
type_: type_.try_into()?,
561
561
+
}),
562
562
+
Expression::Struct { tag, items, type_ } => Ok(Expression::Struct {
563
563
+
tag,
564
564
+
items: items
565
565
+
.into_iter()
566
566
+
.map(Expression::try_from)
567
567
+
.collect::<Result<Vec<_>, _>>()?,
568
568
+
type_: type_.try_into()?,
569
569
+
}),
570
570
+
Expression::StructTag { value } => Ok(Expression::StructTag {
571
571
+
value: Box::new(Expression::try_from(*value)?),
572
572
+
}),
573
573
+
Expression::StructAccess {
574
574
+
value,
575
575
+
index,
576
576
+
type_,
577
577
+
} => Ok(Expression::StructAccess {
578
578
+
value: Box::new(Expression::try_from(*value)?),
579
579
+
index,
580
580
+
type_: type_.try_into()?,
581
581
+
}),
582
582
+
Expression::Set { name, value } => Ok(Expression::Set {
583
583
+
name: Var {
584
584
+
name: name.name,
585
585
+
type_: name.type_.try_into()?,
586
586
+
},
587
587
+
value: Box::new(Expression::try_from(*value)?),
588
588
+
}),
589
589
+
Expression::If { cond, then, else_ } => Ok(Expression::If {
590
590
+
cond: Box::new(Expression::try_from(*cond)?),
591
591
+
then: Box::new(Expression::try_from(*then)?),
592
592
+
else_: Box::new(Expression::try_from(*else_)?),
593
593
+
}),
594
594
+
Expression::Call {
595
595
+
target,
596
596
+
args,
597
597
+
type_,
598
598
+
} => Ok(Expression::Call {
599
599
+
target: Box::new(Expression::try_from(*target)?),
600
600
+
args: args
601
601
+
.into_iter()
602
602
+
.map(Expression::try_from)
603
603
+
.collect::<Result<Vec<_>, _>>()?,
604
604
+
type_: type_.try_into()?,
605
605
+
}),
606
606
+
}
607
607
+
}
608
608
+
}
609
609
+
610
610
+
impl TryFrom<IncompleteType> for CompleteType {
611
611
+
type Error = NonGenericError;
612
612
+
613
613
+
fn try_from(value: IncompleteType) -> Result<Self, Self::Error> {
614
614
+
match value {
615
615
+
IncompleteType::Int => Ok(Self::Int),
616
616
+
IncompleteType::Float => Ok(Self::Float),
617
617
+
IncompleteType::Bool => Ok(Self::Bool),
618
618
+
IncompleteType::String => Ok(Self::String),
619
619
+
IncompleteType::Func { arguments, returns } => Ok(Self::Func {
620
620
+
arguments: arguments
621
621
+
.into_iter()
622
622
+
.map(Self::try_from)
623
623
+
.collect::<Result<Vec<_>, _>>()?,
624
624
+
returns: Box::new(Self::try_from(*returns)?),
625
625
+
}),
626
626
+
IncompleteType::Struct { elements } => Ok(Self::Struct {
627
627
+
elements: elements
628
628
+
.into_iter()
629
629
+
.map(Self::try_from)
630
630
+
.collect::<Result<Vec<_>, _>>()?,
631
631
+
}),
632
632
+
IncompleteType::List(element_type) => {
633
633
+
Ok(Self::List(Box::new(Self::try_from(*element_type)?)))
634
634
+
}
635
635
+
IncompleteType::Generic { id: _ } => Err(NonGenericError),
636
636
+
}
637
637
+
}
638
638
+
}
+261
-175
compiler-core/src/cranelift/mir/visit.rs
View file
Reviewed
···
3
3
4
4
use crate::cranelift::mir::ast::{Expression, Function, Module, Var};
5
5
6
6
-
pub trait Visit<'mir> {
7
7
-
fn visit_module(&mut self, module: &'mir mut Module) {
6
6
+
pub trait Visit<'mir, T> {
7
7
+
fn visit_module(&mut self, module: &'mir mut Module<T>) {
8
8
visit_module(self, module);
9
9
}
10
10
11
11
-
fn visit_function(&mut self, function: &'mir mut Function) {
11
11
+
fn visit_function(&mut self, function: &'mir mut Function<T>) {
12
12
visit_function(self, function);
13
13
}
14
14
15
15
-
fn visit_expression(&mut self, expression: &'mir mut Expression) {
15
15
+
fn visit_expression(&mut self, expression: &'mir mut Expression<T>) {
16
16
visit_expression(self, expression);
17
17
}
18
18
19
19
-
fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression>) {
19
19
+
fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression<T>>) {
20
20
visit_expression_block(self, expressions);
21
21
}
22
22
···
25
25
module: &mut EcoString,
26
26
name: &mut EcoString,
27
27
arity: &mut usize,
28
28
+
type_: &mut T,
28
29
) {
29
29
-
visit_expression_function_ref(self, module, name, arity);
30
30
+
visit_expression_function_ref(self, module, name, arity, type_);
30
31
}
31
32
32
32
-
fn visit_expression_var(&mut self, var: &'mir mut Var) {
33
33
+
fn visit_expression_var(&mut self, var: &'mir mut Var<T>) {
33
34
visit_expression_var(self, var);
34
35
}
35
36
···
49
50
visit_expression_string(self, value);
50
51
}
51
52
52
52
-
fn visit_expression_equals(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
53
53
+
fn visit_expression_equals(
54
54
+
&mut self,
55
55
+
lhs: &'mir mut Expression<T>,
56
56
+
rhs: &'mir mut Expression<T>,
57
57
+
) {
53
58
visit_expression_equals(self, lhs, rhs);
54
59
}
55
60
56
61
fn visit_expression_not_equals(
57
62
&mut self,
58
58
-
lhs: &'mir mut Expression,
59
59
-
rhs: &'mir mut Expression,
63
63
+
lhs: &'mir mut Expression<T>,
64
64
+
rhs: &'mir mut Expression<T>,
60
65
) {
61
66
visit_expression_not_equals(self, lhs, rhs);
62
67
}
63
68
64
64
-
fn visit_expression_int_gt(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
69
69
+
fn visit_expression_int_gt(
70
70
+
&mut self,
71
71
+
lhs: &'mir mut Expression<T>,
72
72
+
rhs: &'mir mut Expression<T>,
73
73
+
) {
65
74
visit_expression_int_gt(self, lhs, rhs);
66
75
}
67
76
68
68
-
fn visit_expression_int_gt_eq(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
77
77
+
fn visit_expression_int_gt_eq(
78
78
+
&mut self,
79
79
+
lhs: &'mir mut Expression<T>,
80
80
+
rhs: &'mir mut Expression<T>,
81
81
+
) {
69
82
visit_expression_int_gt_eq(self, lhs, rhs);
70
83
}
71
84
72
72
-
fn visit_expression_int_lt(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
85
85
+
fn visit_expression_int_lt(
86
86
+
&mut self,
87
87
+
lhs: &'mir mut Expression<T>,
88
88
+
rhs: &'mir mut Expression<T>,
89
89
+
) {
73
90
visit_expression_int_lt(self, lhs, rhs);
74
91
}
75
92
76
76
-
fn visit_expression_int_lt_eq(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
93
93
+
fn visit_expression_int_lt_eq(
94
94
+
&mut self,
95
95
+
lhs: &'mir mut Expression<T>,
96
96
+
rhs: &'mir mut Expression<T>,
97
97
+
) {
77
98
visit_expression_int_lt_eq(self, lhs, rhs);
78
99
}
79
100
80
80
-
fn visit_expression_int_add(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
101
101
+
fn visit_expression_int_add(
102
102
+
&mut self,
103
103
+
lhs: &'mir mut Expression<T>,
104
104
+
rhs: &'mir mut Expression<T>,
105
105
+
) {
81
106
visit_expression_int_add(self, lhs, rhs);
82
107
}
83
108
84
84
-
fn visit_expression_int_sub(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
109
109
+
fn visit_expression_int_sub(
110
110
+
&mut self,
111
111
+
lhs: &'mir mut Expression<T>,
112
112
+
rhs: &'mir mut Expression<T>,
113
113
+
) {
85
114
visit_expression_int_sub(self, lhs, rhs);
86
115
}
87
116
88
88
-
fn visit_expression_int_mul(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
117
117
+
fn visit_expression_int_mul(
118
118
+
&mut self,
119
119
+
lhs: &'mir mut Expression<T>,
120
120
+
rhs: &'mir mut Expression<T>,
121
121
+
) {
89
122
visit_expression_int_mul(self, lhs, rhs);
90
123
}
91
124
92
92
-
fn visit_expression_int_div(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
125
125
+
fn visit_expression_int_div(
126
126
+
&mut self,
127
127
+
lhs: &'mir mut Expression<T>,
128
128
+
rhs: &'mir mut Expression<T>,
129
129
+
) {
93
130
visit_expression_int_div(self, lhs, rhs);
94
131
}
95
132
96
96
-
fn visit_expression_int_rem(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
133
133
+
fn visit_expression_int_rem(
134
134
+
&mut self,
135
135
+
lhs: &'mir mut Expression<T>,
136
136
+
rhs: &'mir mut Expression<T>,
137
137
+
) {
97
138
visit_expression_int_rem(self, lhs, rhs);
98
139
}
99
140
100
100
-
fn visit_expression_float_gt(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
141
141
+
fn visit_expression_float_gt(
142
142
+
&mut self,
143
143
+
lhs: &'mir mut Expression<T>,
144
144
+
rhs: &'mir mut Expression<T>,
145
145
+
) {
101
146
visit_expression_float_gt(self, lhs, rhs);
102
147
}
103
148
104
149
fn visit_expression_float_gt_eq(
105
150
&mut self,
106
106
-
lhs: &'mir mut Expression,
107
107
-
rhs: &'mir mut Expression,
151
151
+
lhs: &'mir mut Expression<T>,
152
152
+
rhs: &'mir mut Expression<T>,
108
153
) {
109
154
visit_expression_float_gt_eq(self, lhs, rhs);
110
155
}
111
156
112
112
-
fn visit_expression_float_lt(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
157
157
+
fn visit_expression_float_lt(
158
158
+
&mut self,
159
159
+
lhs: &'mir mut Expression<T>,
160
160
+
rhs: &'mir mut Expression<T>,
161
161
+
) {
113
162
visit_expression_float_lt(self, lhs, rhs);
114
163
}
115
164
116
165
fn visit_expression_float_lt_eq(
117
166
&mut self,
118
118
-
lhs: &'mir mut Expression,
119
119
-
rhs: &'mir mut Expression,
167
167
+
lhs: &'mir mut Expression<T>,
168
168
+
rhs: &'mir mut Expression<T>,
120
169
) {
121
170
visit_expression_float_lt_eq(self, lhs, rhs);
122
171
}
123
172
124
124
-
fn visit_expression_float_add(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
173
173
+
fn visit_expression_float_add(
174
174
+
&mut self,
175
175
+
lhs: &'mir mut Expression<T>,
176
176
+
rhs: &'mir mut Expression<T>,
177
177
+
) {
125
178
visit_expression_float_add(self, lhs, rhs);
126
179
}
127
180
128
128
-
fn visit_expression_float_sub(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
181
181
+
fn visit_expression_float_sub(
182
182
+
&mut self,
183
183
+
lhs: &'mir mut Expression<T>,
184
184
+
rhs: &'mir mut Expression<T>,
185
185
+
) {
129
186
visit_expression_float_sub(self, lhs, rhs);
130
187
}
131
188
132
132
-
fn visit_expression_float_mul(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
189
189
+
fn visit_expression_float_mul(
190
190
+
&mut self,
191
191
+
lhs: &'mir mut Expression<T>,
192
192
+
rhs: &'mir mut Expression<T>,
193
193
+
) {
133
194
visit_expression_float_mul(self, lhs, rhs);
134
195
}
135
196
136
136
-
fn visit_expression_float_div(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) {
197
197
+
fn visit_expression_float_div(
198
198
+
&mut self,
199
199
+
lhs: &'mir mut Expression<T>,
200
200
+
rhs: &'mir mut Expression<T>,
201
201
+
) {
137
202
visit_expression_float_div(self, lhs, rhs);
138
203
}
139
204
140
205
fn visit_expression_string_concat(
141
206
&mut self,
142
142
-
lhs: &'mir mut Expression,
143
143
-
rhs: &'mir mut Expression,
207
207
+
lhs: &'mir mut Expression<T>,
208
208
+
rhs: &'mir mut Expression<T>,
144
209
) {
145
210
visit_expression_string_concat(self, lhs, rhs);
146
211
}
147
212
148
213
fn visit_expression_list(
149
214
&mut self,
150
150
-
items: &'mir mut Vec<Expression>,
151
151
-
tail: &'mir mut Option<Box<Expression>>,
215
215
+
items: &'mir mut Vec<Expression<T>>,
216
216
+
tail: &'mir mut Option<Box<Expression<T>>>,
217
217
+
type_: &'mir mut T,
152
218
) {
153
153
-
visit_expression_list(self, items, tail);
219
219
+
visit_expression_list(self, items, tail, type_);
154
220
}
155
221
156
222
fn visit_expression_struct(
157
223
&mut self,
158
224
tag: &'mir mut Option<u32>,
159
159
-
items: &'mir mut Vec<Expression>,
225
225
+
items: &'mir mut Vec<Expression<T>>,
226
226
+
type_: &'mir mut T,
160
227
) {
161
161
-
visit_expression_struct(self, tag, items);
228
228
+
visit_expression_struct(self, tag, items, type_);
162
229
}
163
230
164
164
-
fn visit_expression_struct_tag(&mut self, value: &'mir mut Expression) {
231
231
+
fn visit_expression_struct_tag(&mut self, value: &'mir mut Expression<T>) {
165
232
visit_expression_struct_tag(self, value);
166
233
}
167
234
168
235
fn visit_expression_struct_access(
169
236
&mut self,
170
170
-
value: &'mir mut Expression,
237
237
+
value: &'mir mut Expression<T>,
171
238
index: &'mir mut u64,
239
239
+
type_: &'mir mut T,
172
240
) {
173
173
-
visit_expression_struct_access(self, value, index);
241
241
+
visit_expression_struct_access(self, value, index, type_);
174
242
}
175
243
176
176
-
fn visit_expression_set(&mut self, name: &'mir mut Var, value: &'mir mut Expression) {
244
244
+
fn visit_expression_set(&mut self, name: &'mir mut Var<T>, value: &'mir mut Expression<T>) {
177
245
visit_expression_set(self, name, value);
178
246
}
179
247
180
248
fn visit_expression_if(
181
249
&mut self,
182
182
-
cond: &'mir mut Expression,
183
183
-
then: &'mir mut Expression,
184
184
-
else_: &'mir mut Expression,
250
250
+
cond: &'mir mut Expression<T>,
251
251
+
then: &'mir mut Expression<T>,
252
252
+
else_: &'mir mut Expression<T>,
185
253
) {
186
254
visit_expression_if(self, cond, then, else_);
187
255
}
188
256
189
257
fn visit_expression_call(
190
258
&mut self,
191
191
-
target: &'mir mut Expression,
192
192
-
args: &'mir mut Vec<Expression>,
259
259
+
target: &'mir mut Expression<T>,
260
260
+
args: &'mir mut Vec<Expression<T>>,
261
261
+
type_: &'mir mut T,
193
262
) {
194
194
-
visit_expression_call(self, target, args);
263
263
+
visit_expression_call(self, target, args, type_);
195
264
}
196
265
}
197
266
198
198
-
pub fn visit_module<'mir, V>(v: &mut V, module: &'mir mut Module)
267
267
+
pub fn visit_module<'mir, T, V>(v: &mut V, module: &'mir mut Module<T>)
199
268
where
200
200
-
V: Visit<'mir> + ?Sized,
269
269
+
V: Visit<'mir, T> + ?Sized,
201
270
{
202
271
for function in &mut module.functions {
203
272
v.visit_function(function);
204
273
}
205
274
}
206
275
207
207
-
pub fn visit_function<'mir, V>(v: &mut V, function: &'mir mut Function)
276
276
+
pub fn visit_function<'mir, T, V>(v: &mut V, function: &'mir mut Function<T>)
208
277
where
209
209
-
V: Visit<'mir> + ?Sized,
278
278
+
V: Visit<'mir, T> + ?Sized,
210
279
{
211
280
v.visit_expression(&mut function.body);
212
281
}
213
282
214
214
-
pub fn visit_expression<'mir, V>(v: &mut V, expression: &'mir mut Expression)
283
283
+
pub fn visit_expression<'mir, T, V>(v: &mut V, expression: &'mir mut Expression<T>)
215
284
where
216
216
-
V: Visit<'mir> + ?Sized,
285
285
+
V: Visit<'mir, T> + ?Sized,
217
286
{
218
287
match expression {
219
288
Expression::Block(expressions) => v.visit_expression_block(expressions),
···
221
290
module,
222
291
name,
223
292
arity,
224
224
-
} => v.visit_expression_function_ref(module, name, arity),
293
293
+
type_,
294
294
+
} => v.visit_expression_function_ref(module, name, arity, type_),
225
295
Expression::Var(var) => v.visit_expression_var(var),
226
296
Expression::Int { value } => v.visit_expression_int(value),
227
297
Expression::Float { value } => v.visit_expression_float(value),
···
247
317
Expression::FloatMul { lhs, rhs } => v.visit_expression_float_mul(lhs, rhs),
248
318
Expression::FloatDiv { lhs, rhs } => v.visit_expression_float_div(lhs, rhs),
249
319
Expression::StringConcat { lhs, rhs } => v.visit_expression_string_concat(lhs, rhs),
250
250
-
Expression::List { items, tail } => v.visit_expression_list(items, tail),
251
251
-
Expression::Struct { tag, items } => v.visit_expression_struct(tag, items),
320
320
+
Expression::List { items, tail, type_ } => v.visit_expression_list(items, tail, type_),
321
321
+
Expression::Struct { tag, items, type_ } => v.visit_expression_struct(tag, items, type_),
252
322
Expression::StructTag { value } => v.visit_expression_struct_tag(value),
253
253
-
Expression::StructAccess { value, index } => v.visit_expression_struct_access(value, index),
323
323
+
Expression::StructAccess {
324
324
+
value,
325
325
+
index,
326
326
+
type_,
327
327
+
} => v.visit_expression_struct_access(value, index, type_),
254
328
Expression::Set { name, value } => v.visit_expression_set(name, value),
255
329
Expression::If { cond, then, else_ } => v.visit_expression_if(cond, then, else_),
256
256
-
Expression::Call { target, args } => v.visit_expression_call(target, args),
330
330
+
Expression::Call {
331
331
+
target,
332
332
+
args,
333
333
+
type_,
334
334
+
} => v.visit_expression_call(target, args, type_),
257
335
}
258
336
}
259
337
260
260
-
pub fn visit_expression_block<'mir, V>(v: &mut V, expressions: &'mir mut Vec<Expression>)
338
338
+
pub fn visit_expression_block<'mir, T, V>(v: &mut V, expressions: &'mir mut Vec<Expression<T>>)
261
339
where
262
262
-
V: Visit<'mir> + ?Sized,
340
340
+
V: Visit<'mir, T> + ?Sized,
263
341
{
264
342
for expression in expressions {
265
343
v.visit_expression(expression);
266
344
}
267
345
}
268
346
269
269
-
pub fn visit_expression_function_ref<'mir, V>(
347
347
+
pub fn visit_expression_function_ref<'mir, T, V>(
270
348
_v: &mut V,
271
349
_module: &mut EcoString,
272
350
_name: &mut EcoString,
273
351
_arity: &mut usize,
352
352
+
_type: &mut T,
274
353
) where
275
275
-
V: Visit<'mir> + ?Sized,
354
354
+
V: Visit<'mir, T> + ?Sized,
276
355
{
277
356
}
278
357
279
279
-
pub fn visit_expression_var<'mir, V>(_v: &mut V, _var: &mut Var)
358
358
+
pub fn visit_expression_var<'mir, T, V>(_v: &mut V, _var: &mut Var<T>)
280
359
where
281
281
-
V: Visit<'mir> + ?Sized,
360
360
+
V: Visit<'mir, T> + ?Sized,
282
361
{
283
362
}
284
363
285
285
-
pub fn visit_expression_int<'mir, V>(_v: &mut V, _value: &mut BigInt)
364
364
+
pub fn visit_expression_int<'mir, T, V>(_v: &mut V, _value: &mut BigInt)
286
365
where
287
287
-
V: Visit<'mir> + ?Sized,
366
366
+
V: Visit<'mir, T> + ?Sized,
288
367
{
289
368
}
290
369
291
291
-
pub fn visit_expression_float<'mir, V>(_v: &mut V, _value: &mut EcoString)
370
370
+
pub fn visit_expression_float<'mir, T, V>(_v: &mut V, _value: &mut EcoString)
292
371
where
293
293
-
V: Visit<'mir> + ?Sized,
372
372
+
V: Visit<'mir, T> + ?Sized,
294
373
{
295
374
}
296
375
297
297
-
pub fn visit_expression_bool<'mir, V>(_v: &mut V, _value: &mut bool)
376
376
+
pub fn visit_expression_bool<'mir, T, V>(_v: &mut V, _value: &mut bool)
298
377
where
299
299
-
V: Visit<'mir> + ?Sized,
378
378
+
V: Visit<'mir, T> + ?Sized,
300
379
{
301
380
}
302
381
303
303
-
pub fn visit_expression_string<'mir, V>(_v: &mut V, _value: &mut EcoString)
382
382
+
pub fn visit_expression_string<'mir, T, V>(_v: &mut V, _value: &mut EcoString)
304
383
where
305
305
-
V: Visit<'mir> + ?Sized,
384
384
+
V: Visit<'mir, T> + ?Sized,
306
385
{
307
386
}
308
387
309
309
-
pub fn visit_expression_equals<'mir, V>(
388
388
+
pub fn visit_expression_equals<'mir, T, V>(
310
389
v: &mut V,
311
311
-
lhs: &'mir mut Expression,
312
312
-
rhs: &'mir mut Expression,
390
390
+
lhs: &'mir mut Expression<T>,
391
391
+
rhs: &'mir mut Expression<T>,
313
392
) where
314
314
-
V: Visit<'mir> + ?Sized,
393
393
+
V: Visit<'mir, T> + ?Sized,
315
394
{
316
395
v.visit_expression(lhs);
317
396
v.visit_expression(rhs);
318
397
}
319
398
320
320
-
pub fn visit_expression_not_equals<'mir, V>(
399
399
+
pub fn visit_expression_not_equals<'mir, T, V>(
321
400
v: &mut V,
322
322
-
lhs: &'mir mut Expression,
323
323
-
rhs: &'mir mut Expression,
401
401
+
lhs: &'mir mut Expression<T>,
402
402
+
rhs: &'mir mut Expression<T>,
324
403
) where
325
325
-
V: Visit<'mir> + ?Sized,
404
404
+
V: Visit<'mir, T> + ?Sized,
326
405
{
327
406
v.visit_expression(lhs);
328
407
v.visit_expression(rhs);
329
408
}
330
409
331
331
-
pub fn visit_expression_int_gt<'mir, V>(
410
410
+
pub fn visit_expression_int_gt<'mir, T, V>(
332
411
v: &mut V,
333
333
-
lhs: &'mir mut Expression,
334
334
-
rhs: &'mir mut Expression,
412
412
+
lhs: &'mir mut Expression<T>,
413
413
+
rhs: &'mir mut Expression<T>,
335
414
) where
336
336
-
V: Visit<'mir> + ?Sized,
415
415
+
V: Visit<'mir, T> + ?Sized,
337
416
{
338
417
v.visit_expression(lhs);
339
418
v.visit_expression(rhs);
340
419
}
341
420
342
342
-
pub fn visit_expression_int_gt_eq<'mir, V>(
421
421
+
pub fn visit_expression_int_gt_eq<'mir, T, V>(
343
422
v: &mut V,
344
344
-
lhs: &'mir mut Expression,
345
345
-
rhs: &'mir mut Expression,
423
423
+
lhs: &'mir mut Expression<T>,
424
424
+
rhs: &'mir mut Expression<T>,
346
425
) where
347
347
-
V: Visit<'mir> + ?Sized,
426
426
+
V: Visit<'mir, T> + ?Sized,
348
427
{
349
428
v.visit_expression(lhs);
350
429
v.visit_expression(rhs);
351
430
}
352
431
353
353
-
pub fn visit_expression_int_lt<'mir, V>(
432
432
+
pub fn visit_expression_int_lt<'mir, T, V>(
354
433
v: &mut V,
355
355
-
lhs: &'mir mut Expression,
356
356
-
rhs: &'mir mut Expression,
434
434
+
lhs: &'mir mut Expression<T>,
435
435
+
rhs: &'mir mut Expression<T>,
357
436
) where
358
358
-
V: Visit<'mir> + ?Sized,
437
437
+
V: Visit<'mir, T> + ?Sized,
359
438
{
360
439
v.visit_expression(lhs);
361
440
v.visit_expression(rhs);
362
441
}
363
442
364
364
-
pub fn visit_expression_int_lt_eq<'mir, V>(
443
443
+
pub fn visit_expression_int_lt_eq<'mir, T, V>(
365
444
v: &mut V,
366
366
-
lhs: &'mir mut Expression,
367
367
-
rhs: &'mir mut Expression,
445
445
+
lhs: &'mir mut Expression<T>,
446
446
+
rhs: &'mir mut Expression<T>,
368
447
) where
369
369
-
V: Visit<'mir> + ?Sized,
448
448
+
V: Visit<'mir, T> + ?Sized,
370
449
{
371
450
v.visit_expression(lhs);
372
451
v.visit_expression(rhs);
373
452
}
374
453
375
375
-
pub fn visit_expression_int_add<'mir, V>(
454
454
+
pub fn visit_expression_int_add<'mir, T, V>(
376
455
v: &mut V,
377
377
-
lhs: &'mir mut Expression,
378
378
-
rhs: &'mir mut Expression,
456
456
+
lhs: &'mir mut Expression<T>,
457
457
+
rhs: &'mir mut Expression<T>,
379
458
) where
380
380
-
V: Visit<'mir> + ?Sized,
459
459
+
V: Visit<'mir, T> + ?Sized,
381
460
{
382
461
v.visit_expression(lhs);
383
462
v.visit_expression(rhs);
384
463
}
385
464
386
386
-
pub fn visit_expression_int_sub<'mir, V>(
465
465
+
pub fn visit_expression_int_sub<'mir, T, V>(
387
466
v: &mut V,
388
388
-
lhs: &'mir mut Expression,
389
389
-
rhs: &'mir mut Expression,
467
467
+
lhs: &'mir mut Expression<T>,
468
468
+
rhs: &'mir mut Expression<T>,
390
469
) where
391
391
-
V: Visit<'mir> + ?Sized,
470
470
+
V: Visit<'mir, T> + ?Sized,
392
471
{
393
472
v.visit_expression(lhs);
394
473
v.visit_expression(rhs);
395
474
}
396
475
397
397
-
pub fn visit_expression_int_mul<'mir, V>(
476
476
+
pub fn visit_expression_int_mul<'mir, T, V>(
398
477
v: &mut V,
399
399
-
lhs: &'mir mut Expression,
400
400
-
rhs: &'mir mut Expression,
478
478
+
lhs: &'mir mut Expression<T>,
479
479
+
rhs: &'mir mut Expression<T>,
401
480
) where
402
402
-
V: Visit<'mir> + ?Sized,
481
481
+
V: Visit<'mir, T> + ?Sized,
403
482
{
404
483
v.visit_expression(lhs);
405
484
v.visit_expression(rhs);
406
485
}
407
486
408
408
-
pub fn visit_expression_int_div<'mir, V>(
487
487
+
pub fn visit_expression_int_div<'mir, T, V>(
409
488
v: &mut V,
410
410
-
lhs: &'mir mut Expression,
411
411
-
rhs: &'mir mut Expression,
489
489
+
lhs: &'mir mut Expression<T>,
490
490
+
rhs: &'mir mut Expression<T>,
412
491
) where
413
413
-
V: Visit<'mir> + ?Sized,
492
492
+
V: Visit<'mir, T> + ?Sized,
414
493
{
415
494
v.visit_expression(lhs);
416
495
v.visit_expression(rhs);
417
496
}
418
497
419
419
-
pub fn visit_expression_int_rem<'mir, V>(
498
498
+
pub fn visit_expression_int_rem<'mir, T, V>(
420
499
v: &mut V,
421
421
-
lhs: &'mir mut Expression,
422
422
-
rhs: &'mir mut Expression,
500
500
+
lhs: &'mir mut Expression<T>,
501
501
+
rhs: &'mir mut Expression<T>,
423
502
) where
424
424
-
V: Visit<'mir> + ?Sized,
503
503
+
V: Visit<'mir, T> + ?Sized,
425
504
{
426
505
v.visit_expression(lhs);
427
506
v.visit_expression(rhs);
428
507
}
429
508
430
430
-
pub fn visit_expression_float_gt<'mir, V>(
509
509
+
pub fn visit_expression_float_gt<'mir, T, V>(
431
510
v: &mut V,
432
432
-
lhs: &'mir mut Expression,
433
433
-
rhs: &'mir mut Expression,
511
511
+
lhs: &'mir mut Expression<T>,
512
512
+
rhs: &'mir mut Expression<T>,
434
513
) where
435
435
-
V: Visit<'mir> + ?Sized,
514
514
+
V: Visit<'mir, T> + ?Sized,
436
515
{
437
516
v.visit_expression(lhs);
438
517
v.visit_expression(rhs);
439
518
}
440
519
441
441
-
pub fn visit_expression_float_gt_eq<'mir, V>(
520
520
+
pub fn visit_expression_float_gt_eq<'mir, T, V>(
442
521
v: &mut V,
443
443
-
lhs: &'mir mut Expression,
444
444
-
rhs: &'mir mut Expression,
522
522
+
lhs: &'mir mut Expression<T>,
523
523
+
rhs: &'mir mut Expression<T>,
445
524
) where
446
446
-
V: Visit<'mir> + ?Sized,
525
525
+
V: Visit<'mir, T> + ?Sized,
447
526
{
448
527
v.visit_expression(lhs);
449
528
v.visit_expression(rhs);
450
529
}
451
530
452
452
-
pub fn visit_expression_float_lt<'mir, V>(
531
531
+
pub fn visit_expression_float_lt<'mir, T, V>(
453
532
v: &mut V,
454
454
-
lhs: &'mir mut Expression,
455
455
-
rhs: &'mir mut Expression,
533
533
+
lhs: &'mir mut Expression<T>,
534
534
+
rhs: &'mir mut Expression<T>,
456
535
) where
457
457
-
V: Visit<'mir> + ?Sized,
536
536
+
V: Visit<'mir, T> + ?Sized,
458
537
{
459
538
v.visit_expression(lhs);
460
539
v.visit_expression(rhs);
461
540
}
462
541
463
463
-
pub fn visit_expression_float_lt_eq<'mir, V>(
542
542
+
pub fn visit_expression_float_lt_eq<'mir, T, V>(
464
543
v: &mut V,
465
465
-
lhs: &'mir mut Expression,
466
466
-
rhs: &'mir mut Expression,
544
544
+
lhs: &'mir mut Expression<T>,
545
545
+
rhs: &'mir mut Expression<T>,
467
546
) where
468
468
-
V: Visit<'mir> + ?Sized,
547
547
+
V: Visit<'mir, T> + ?Sized,
469
548
{
470
549
v.visit_expression(lhs);
471
550
v.visit_expression(rhs);
472
551
}
473
552
474
474
-
pub fn visit_expression_float_add<'mir, V>(
553
553
+
pub fn visit_expression_float_add<'mir, T, V>(
475
554
v: &mut V,
476
476
-
lhs: &'mir mut Expression,
477
477
-
rhs: &'mir mut Expression,
555
555
+
lhs: &'mir mut Expression<T>,
556
556
+
rhs: &'mir mut Expression<T>,
478
557
) where
479
479
-
V: Visit<'mir> + ?Sized,
558
558
+
V: Visit<'mir, T> + ?Sized,
480
559
{
481
560
v.visit_expression(lhs);
482
561
v.visit_expression(rhs);
483
562
}
484
563
485
485
-
pub fn visit_expression_float_sub<'mir, V>(
564
564
+
pub fn visit_expression_float_sub<'mir, T, V>(
486
565
v: &mut V,
487
487
-
lhs: &'mir mut Expression,
488
488
-
rhs: &'mir mut Expression,
566
566
+
lhs: &'mir mut Expression<T>,
567
567
+
rhs: &'mir mut Expression<T>,
489
568
) where
490
490
-
V: Visit<'mir> + ?Sized,
569
569
+
V: Visit<'mir, T> + ?Sized,
491
570
{
492
571
v.visit_expression(lhs);
493
572
v.visit_expression(rhs);
494
573
}
495
574
496
496
-
pub fn visit_expression_float_mul<'mir, V>(
575
575
+
pub fn visit_expression_float_mul<'mir, T, V>(
497
576
v: &mut V,
498
498
-
lhs: &'mir mut Expression,
499
499
-
rhs: &'mir mut Expression,
577
577
+
lhs: &'mir mut Expression<T>,
578
578
+
rhs: &'mir mut Expression<T>,
500
579
) where
501
501
-
V: Visit<'mir> + ?Sized,
580
580
+
V: Visit<'mir, T> + ?Sized,
502
581
{
503
582
v.visit_expression(lhs);
504
583
v.visit_expression(rhs);
505
584
}
506
585
507
507
-
pub fn visit_expression_float_div<'mir, V>(
586
586
+
pub fn visit_expression_float_div<'mir, T, V>(
508
587
v: &mut V,
509
509
-
lhs: &'mir mut Expression,
510
510
-
rhs: &'mir mut Expression,
588
588
+
lhs: &'mir mut Expression<T>,
589
589
+
rhs: &'mir mut Expression<T>,
511
590
) where
512
512
-
V: Visit<'mir> + ?Sized,
591
591
+
V: Visit<'mir, T> + ?Sized,
513
592
{
514
593
v.visit_expression(lhs);
515
594
v.visit_expression(rhs);
516
595
}
517
596
518
518
-
pub fn visit_expression_string_concat<'mir, V>(
597
597
+
pub fn visit_expression_string_concat<'mir, T, V>(
519
598
v: &mut V,
520
520
-
lhs: &'mir mut Expression,
521
521
-
rhs: &'mir mut Expression,
599
599
+
lhs: &'mir mut Expression<T>,
600
600
+
rhs: &'mir mut Expression<T>,
522
601
) where
523
523
-
V: Visit<'mir> + ?Sized,
602
602
+
V: Visit<'mir, T> + ?Sized,
524
603
{
525
604
v.visit_expression(lhs);
526
605
v.visit_expression(rhs);
527
606
}
528
607
529
529
-
pub fn visit_expression_list<'mir, V>(
608
608
+
pub fn visit_expression_list<'mir, T, V>(
530
609
v: &mut V,
531
531
-
items: &'mir mut Vec<Expression>,
532
532
-
tail: &'mir mut Option<Box<Expression>>,
610
610
+
items: &'mir mut Vec<Expression<T>>,
611
611
+
tail: &'mir mut Option<Box<Expression<T>>>,
612
612
+
_type_: &'mir mut T,
533
613
) where
534
534
-
V: Visit<'mir> + ?Sized,
614
614
+
V: Visit<'mir, T> + ?Sized,
535
615
{
536
616
for item in items {
537
617
v.visit_expression(item);
···
541
621
}
542
622
}
543
623
544
544
-
pub fn visit_expression_struct<'mir, V>(
624
624
+
pub fn visit_expression_struct<'mir, T, V>(
545
625
v: &mut V,
546
626
_tag: &'mir mut Option<u32>,
547
547
-
items: &'mir mut Vec<Expression>,
627
627
+
items: &'mir mut Vec<Expression<T>>,
628
628
+
_type: &'mir mut T,
548
629
) where
549
549
-
V: Visit<'mir> + ?Sized,
630
630
+
V: Visit<'mir, T> + ?Sized,
550
631
{
551
632
for item in items {
552
633
v.visit_expression(item);
553
634
}
554
635
}
555
636
556
556
-
pub fn visit_expression_struct_tag<'mir, V>(v: &mut V, value: &'mir mut Expression)
637
637
+
pub fn visit_expression_struct_tag<'mir, T, V>(v: &mut V, value: &'mir mut Expression<T>)
557
638
where
558
558
-
V: Visit<'mir> + ?Sized,
639
639
+
V: Visit<'mir, T> + ?Sized,
559
640
{
560
641
v.visit_expression(value);
561
642
}
562
643
563
563
-
pub fn visit_expression_struct_access<'mir, V>(
644
644
+
pub fn visit_expression_struct_access<'mir, T, V>(
564
645
v: &mut V,
565
565
-
value: &'mir mut Expression,
646
646
+
value: &'mir mut Expression<T>,
566
647
_index: &'mir mut u64,
648
648
+
_type: &'mir mut T,
567
649
) where
568
568
-
V: Visit<'mir> + ?Sized,
650
650
+
V: Visit<'mir, T> + ?Sized,
569
651
{
570
652
v.visit_expression(value);
571
653
}
572
654
573
573
-
pub fn visit_expression_set<'mir, V>(v: &mut V, _name: &'mir mut Var, value: &'mir mut Expression)
574
574
-
where
575
575
-
V: Visit<'mir> + ?Sized,
655
655
+
pub fn visit_expression_set<'mir, T, V>(
656
656
+
v: &mut V,
657
657
+
_name: &'mir mut Var<T>,
658
658
+
value: &'mir mut Expression<T>,
659
659
+
) where
660
660
+
V: Visit<'mir, T> + ?Sized,
576
661
{
577
662
v.visit_expression(value);
578
663
}
579
664
580
580
-
pub fn visit_expression_if<'mir, V>(
665
665
+
pub fn visit_expression_if<'mir, T, V>(
581
666
v: &mut V,
582
582
-
cond: &'mir mut Expression,
583
583
-
then: &'mir mut Expression,
584
584
-
else_: &'mir mut Expression,
667
667
+
cond: &'mir mut Expression<T>,
668
668
+
then: &'mir mut Expression<T>,
669
669
+
else_: &'mir mut Expression<T>,
585
670
) where
586
586
-
V: Visit<'mir> + ?Sized,
671
671
+
V: Visit<'mir, T> + ?Sized,
587
672
{
588
673
v.visit_expression(cond);
589
674
v.visit_expression(then);
590
675
v.visit_expression(else_);
591
676
}
592
677
593
593
-
pub fn visit_expression_call<'mir, V>(
678
678
+
pub fn visit_expression_call<'mir, T, V>(
594
679
v: &mut V,
595
595
-
target: &'mir mut Expression,
596
596
-
args: &'mir mut Vec<Expression>,
680
680
+
target: &'mir mut Expression<T>,
681
681
+
args: &'mir mut Vec<Expression<T>>,
682
682
+
_type_: &'mir mut T,
597
683
) where
598
598
-
V: Visit<'mir> + ?Sized,
684
684
+
V: Visit<'mir, T> + ?Sized,
599
685
{
600
686
v.visit_expression(target);
601
687
for arg in args {
+21
-1
test/project_cranelift/src/project_cranelift.gleam
View file
Reviewed
···
1
1
+
pub type Option(some) {
2
2
+
Some(some)
3
3
+
None
4
4
+
}
5
5
+
6
6
+
fn replace(option: Option(a), with: b) -> Option(b) {
7
7
+
case option {
8
8
+
Some(_) -> Some(with)
9
9
+
None -> None
10
10
+
}
11
11
+
}
12
12
+
13
13
+
fn are_equal(lhs: a, rhs: a) -> Bool {
14
14
+
lhs == rhs
15
15
+
}
16
16
+
1
17
pub fn main() {
2
2
-
let _ = [1, 2, 3]
18
18
+
are_equal(1, 2)
19
19
+
are_equal("hi", "hello")
20
20
+
21
21
+
replace(Some(10), 20)
22
22
+
replace(Some("hi"), "hello")
3
23
}