Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

Allow monomorphizing generated mir

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