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

Configure Feed

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

Begin translating records

author
Danielle Maywood
committer
nandi
date (Jul 26, 2026, 12:11 PM -0700) commit f39b5dc3 parent dca34eee change-id rzptxsnz
+268 -42
+124 -35
compiler-core/src/cranelift/mir.rs
··· 30 30 module: Module, 31 31 } 32 32 33 - #[derive(Debug, Clone, Copy, PartialEq, Eq)] 33 + #[derive(Debug, Clone, PartialEq, Eq)] 34 34 pub enum Type { 35 35 Int, 36 36 Float, 37 37 Bool, 38 38 String, 39 + Struct { elements: Vec<Type> }, 39 40 Generic, 40 41 } 41 42 ··· 171 172 rhs: Box<Expression>, 172 173 }, 173 174 175 + Struct { 176 + tag: Option<u32>, 177 + items: Vec<Expression>, 178 + }, 179 + 180 + StructAccess { 181 + value: Box<Expression>, 182 + index: u64, 183 + }, 184 + 174 185 Set { 175 186 name: Var, 176 187 value: Box<Expression>, ··· 198 209 .push(Self::translate_function(function)); 199 210 } 200 211 ast::Definition::TypeAlias(_type_alias) => todo!(), 201 - ast::Definition::CustomType(_custom_type) => todo!(), 212 + ast::Definition::CustomType(_custom_type) => {} 202 213 ast::Definition::Import(_import) => todo!(), 203 214 ast::Definition::ModuleConstant(_module_constant) => todo!(), 204 215 } ··· 212 223 213 224 let return_type = Self::translate_type(&function.return_type); 214 225 215 - let parameters = Iterator::collect(function.arguments.iter().map(|argument| { 216 - let name = argument.get_variable_name().cloned(); 217 - let type_ = Self::translate_type(&argument.type_); 218 - 219 - FunctionParameter { name, type_ } 226 + let mut translator = BodyTranslator::default(); 227 + let arguments: Vec<_> = Iterator::collect(function.arguments.iter().map(|argument| { 228 + argument 229 + .get_variable_name() 230 + .map(|name| translator.make_var(name.clone())) 220 231 })); 221 232 222 - let mut translator = BodyTranslator::default(); 223 - for argument in &function.arguments { 224 - if let Some(name) = argument.get_variable_name() { 225 - _ = translator.make_var(name.clone()); 226 - } 227 - } 233 + let parameters = Iterator::collect(function.arguments.iter().zip(arguments.iter()).map( 234 + |(argument, name)| { 235 + let type_ = Self::translate_type(&argument.type_); 236 + 237 + FunctionParameter { 238 + name: name.clone().map(|name| name.name), 239 + type_, 240 + } 241 + }, 242 + )); 228 243 229 244 let body = translator.translate(&function.body); 230 245 let body = Self::flatten_expression(body); ··· 245 260 package: _, 246 261 module, 247 262 name, 248 - arguments: _, 263 + arguments, 249 264 inferred_variant: _, 250 265 } => match (module.as_str(), name.as_str()) { 251 266 ("gleam", "Int") => Type::Int, 252 267 ("gleam", "Float") => Type::Float, 253 268 ("gleam", "Bool") => Type::Bool, 254 269 ("gleam", "String") => Type::String, 255 - (_, _) => todo!(), 270 + (_, _) => Type::Struct { 271 + elements: arguments 272 + .iter() 273 + .map(|type_| Self::translate_type(type_)) 274 + .collect(), 275 + }, 256 276 }, 257 277 type_::Type::Fn { 258 278 arguments: _, ··· 304 324 | Expression::FloatMul { .. } 305 325 | Expression::FloatDiv { .. } 306 326 | Expression::StringConcat { .. } 327 + | Expression::Struct { .. } 328 + | Expression::StructAccess { .. } 307 329 | Expression::Set { .. } 308 330 | Expression::If { .. } 309 331 | Expression::Call { .. } => block.push(expression), ··· 400 422 Expression::StringConcat { lhs, rhs } => Expression::StringConcat { 401 423 lhs: Box::new(Self::flatten_expression(*lhs)), 402 424 rhs: Box::new(Self::flatten_expression(*rhs)), 425 + }, 426 + Expression::Struct { tag, items } => Expression::Struct { 427 + tag, 428 + items: items.into_iter().map(Self::flatten_expression).collect(), 429 + }, 430 + Expression::StructAccess { value, index } => Expression::StructAccess { 431 + value: Box::new(Self::flatten_expression(*value)), 432 + index: index, 403 433 }, 404 434 Expression::Set { name, value } => Expression::Set { 405 435 name, ··· 463 493 | Expression::FloatMul { .. } 464 494 | Expression::FloatDiv { .. } 465 495 | Expression::StringConcat { .. } 496 + | Expression::Struct { .. } 497 + | Expression::StructAccess { .. } 466 498 | Expression::Set { .. } 467 499 | Expression::If { .. } 468 500 | Expression::Call { .. } => block.push(expression), ··· 559 591 Expression::StringConcat { lhs, rhs } => Expression::StringConcat { 560 592 lhs: Box::new(Self::remove_unused_code(*lhs)), 561 593 rhs: Box::new(Self::remove_unused_code(*rhs)), 594 + }, 595 + Expression::Struct { tag, items } => Expression::Struct { 596 + tag, 597 + items: items.into_iter().map(Self::remove_unused_code).collect(), 598 + }, 599 + Expression::StructAccess { value, index } => Expression::StructAccess { 600 + value: Box::new(Self::remove_unused_code(*value)), 601 + index: index, 562 602 }, 563 603 Expression::Set { name, value } => Expression::Set { 564 604 name, ··· 720 760 } => match (module.as_str(), name.as_str()) { 721 761 ("gleam", "True") => Expression::Bool { value: true }, 722 762 ("gleam", "False") => Expression::Bool { value: false }, 723 - (_, _) => todo!(), 763 + (_, _) => Expression::FunctionRef { 764 + module: module.clone(), 765 + name: name.clone(), 766 + }, 724 767 }, 725 768 }, 726 769 ast::TypedExpr::Fn { ··· 834 877 field_start: _, 835 878 type_: _, 836 879 label: _, 837 - index: _, 838 - record: _, 839 - } => todo!(), 880 + index, 881 + record, 882 + } => Expression::StructAccess { 883 + value: Box::new(self.translate_expression(record)), 884 + index: *index, 885 + }, 840 886 ast::TypedExpr::ModuleSelect { 841 887 location: _, 842 888 field_start: _, ··· 849 895 ast::TypedExpr::Tuple { 850 896 location: _, 851 897 type_: _, 852 - elements: _, 853 - } => todo!(), 898 + elements, 899 + } => Expression::Struct { 900 + tag: None, 901 + items: elements 902 + .iter() 903 + .map(|element| self.translate_expression(element)) 904 + .collect(), 905 + }, 854 906 ast::TypedExpr::TupleIndex { 855 907 location: _, 856 908 type_: _, 857 - index: _, 858 - tuple: _, 859 - } => todo!(), 909 + index, 910 + tuple, 911 + } => Expression::StructAccess { 912 + value: Box::new(self.translate_expression(tuple)), 913 + index: *index, 914 + }, 860 915 ast::TypedExpr::Todo { 861 916 location: _, 862 917 message: _, ··· 1215 1270 } => Expression::Var(self.get_var(name)), 1216 1271 ast::ClauseGuard::TupleIndex { 1217 1272 location: _, 1218 - index: _, 1273 + index, 1219 1274 type_: _, 1220 - tuple: _, 1221 - } => todo!(), 1275 + tuple, 1276 + } => Expression::StructAccess { 1277 + value: Box::new(self.translate_guard(tuple)), 1278 + index: *index, 1279 + }, 1222 1280 ast::ClauseGuard::FieldAccess { 1223 1281 label_location: _, 1224 - index: _, 1282 + index, 1225 1283 label: _, 1226 1284 type_: _, 1227 - container: _, 1228 - } => todo!(), 1285 + container, 1286 + } => Expression::StructAccess { 1287 + value: Box::new(self.translate_guard(container)), 1288 + index: index.expect("field access expected an index"), 1289 + }, 1229 1290 ast::ClauseGuard::ModuleSelect { 1230 1291 location: _, 1231 1292 type_: _, ··· 1255 1316 }, 1256 1317 ast::Constant::Tuple { 1257 1318 location: _, 1258 - elements: _, 1259 - } => todo!(), 1319 + elements, 1320 + } => Expression::Struct { 1321 + tag: None, 1322 + items: elements 1323 + .iter() 1324 + .map(|element| self.translate_constant(element)) 1325 + .collect(), 1326 + }, 1260 1327 ast::Constant::List { 1261 1328 location: _, 1262 1329 elements: _, ··· 1285 1352 } => todo!(), 1286 1353 ast::Constant::StringConcatenation { 1287 1354 location: _, 1288 - left: _, 1289 - right: _, 1290 - } => todo!(), 1355 + left, 1356 + right, 1357 + } => Expression::StringConcat { 1358 + lhs: Box::new(self.translate_constant(left)), 1359 + rhs: Box::new(self.translate_constant(right)), 1360 + }, 1291 1361 ast::Constant::Invalid { 1292 1362 location: _, 1293 1363 type_: _, ··· 1514 1584 r#"pub fn strings() { 1515 1585 let _ = "hello" 1516 1586 let _ = "hello, " <> "world!" 1587 + }"# 1588 + )); 1589 + 1590 + insta::assert_debug_snapshot!(translate( 1591 + r#"pub fn tuples() { 1592 + let a = #(1, 2, 3) 1593 + let _ = a.1 1594 + }"# 1595 + )); 1596 + 1597 + insta::assert_debug_snapshot!(translate( 1598 + r#"pub type Wibble { 1599 + Wibble(a: Int, b: Int) 1600 + } 1601 + 1602 + pub fn types(w: Wibble) { 1603 + let x = Wibble(a: 10, b: 20) 1604 + 1605 + w.a + x.b 1517 1606 }"# 1518 1607 )); 1519 1608 }
+73
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-10.snap
··· 1 + --- 2 + source: compiler-core/src/cranelift/mir.rs 3 + expression: "translate(r#\"pub type Wibble {\n Wibble(a: Int, b: Int)\n }\n\n pub fn types(w: Wibble) {\n let x = Wibble(a: 10, b: 20)\n\n w.a + x.b\n }\"#)" 4 + --- 5 + Module { 6 + functions: [ 7 + Function { 8 + name: "types", 9 + return_type: Int, 10 + parameters: [ 11 + FunctionParameter { 12 + type_: Struct { 13 + elements: [], 14 + }, 15 + name: Some( 16 + "w$1", 17 + ), 18 + }, 19 + ], 20 + body: Block( 21 + [ 22 + Set { 23 + name: Var { 24 + name: "_tmp$2", 25 + }, 26 + value: Call { 27 + target: FunctionRef { 28 + module: "", 29 + name: "Wibble", 30 + }, 31 + args: [ 32 + Int { 33 + value: 10, 34 + }, 35 + Int { 36 + value: 20, 37 + }, 38 + ], 39 + }, 40 + }, 41 + Set { 42 + name: Var { 43 + name: "x$3", 44 + }, 45 + value: Var( 46 + Var { 47 + name: "_tmp$2", 48 + }, 49 + ), 50 + }, 51 + IntAdd { 52 + lhs: StructAccess { 53 + value: Var( 54 + Var { 55 + name: "w$1", 56 + }, 57 + ), 58 + index: 0, 59 + }, 60 + rhs: StructAccess { 61 + value: Var( 62 + Var { 63 + name: "x$3", 64 + }, 65 + ), 66 + index: 1, 67 + }, 68 + }, 69 + ], 70 + ), 71 + }, 72 + ], 73 + }
+1 -1
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-2.snap
··· 11 11 FunctionParameter { 12 12 type_: Int, 13 13 name: Some( 14 - "n", 14 + "n$1", 15 15 ), 16 16 }, 17 17 ],
+1 -1
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-3.snap
··· 11 11 FunctionParameter { 12 12 type_: Int, 13 13 name: Some( 14 - "n", 14 + "n$1", 15 15 ), 16 16 }, 17 17 ],
+1 -1
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-4.snap
··· 11 11 FunctionParameter { 12 12 type_: Int, 13 13 name: Some( 14 - "n", 14 + "n$1", 15 15 ), 16 16 }, 17 17 ],
+2 -2
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-7.snap
··· 11 11 FunctionParameter { 12 12 type_: Int, 13 13 name: Some( 14 - "n", 14 + "n$1", 15 15 ), 16 16 }, 17 17 FunctionParameter { 18 18 type_: Float, 19 19 name: Some( 20 - "f", 20 + "f$2", 21 21 ), 22 22 }, 23 23 ],
+64
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples-9.snap
··· 1 + --- 2 + source: compiler-core/src/cranelift/mir.rs 3 + expression: "translate(r#\"pub fn tuples() {\n let a = #(1, 2, 3)\n let _ = a.1\n }\"#)" 4 + --- 5 + Module { 6 + functions: [ 7 + Function { 8 + name: "tuples", 9 + return_type: Int, 10 + parameters: [], 11 + body: Block( 12 + [ 13 + Set { 14 + name: Var { 15 + name: "_tmp$1", 16 + }, 17 + value: Struct { 18 + tag: None, 19 + items: [ 20 + Int { 21 + value: 1, 22 + }, 23 + Int { 24 + value: 2, 25 + }, 26 + Int { 27 + value: 3, 28 + }, 29 + ], 30 + }, 31 + }, 32 + Set { 33 + name: Var { 34 + name: "a$2", 35 + }, 36 + value: Var( 37 + Var { 38 + name: "_tmp$1", 39 + }, 40 + ), 41 + }, 42 + Set { 43 + name: Var { 44 + name: "_tmp$3", 45 + }, 46 + value: StructAccess { 47 + value: Var( 48 + Var { 49 + name: "a$2", 50 + }, 51 + ), 52 + index: 1, 53 + }, 54 + }, 55 + Var( 56 + Var { 57 + name: "_tmp$3", 58 + }, 59 + ), 60 + ], 61 + ), 62 + }, 63 + ], 64 + }
+2 -2
compiler-core/src/cranelift/snapshots/gleam_core__cranelift__mir__tests__translates_samples.snap
··· 11 11 FunctionParameter { 12 12 type_: Int, 13 13 name: Some( 14 - "lhs", 14 + "lhs$1", 15 15 ), 16 16 }, 17 17 FunctionParameter { 18 18 type_: Int, 19 19 name: Some( 20 - "rhs", 20 + "rhs$2", 21 21 ), 22 22 }, 23 23 ],