(
&mut self,
name: &'gc str,
mangle_name: &str,
mut params: IndexMap<Token<'gc>, ParameterDecl<'gc>>,
_return_type: Option<Token<'gc>>,
body: Vec<Stmt<'
| 1421 | } |
| 1422 | |
| 1423 | fn generate_function( |
| 1424 | &mut self, |
| 1425 | name: &'gc str, |
| 1426 | mangle_name: &str, |
| 1427 | mut params: IndexMap<Token<'gc>, ParameterDecl<'gc>>, |
| 1428 | _return_type: Option<Token<'gc>>, |
| 1429 | body: Vec<Stmt<'gc>>, |
| 1430 | fn_type: FunctionType, |
| 1431 | ) -> Result<ChunkId, VmError> { |
| 1432 | let compiler = Self::new(self.ctx, fn_type, name); |
| 1433 | |
| 1434 | // Create a new compiler taking ownership of current one |
| 1435 | let mut enclosing = mem::replace(self, *compiler); |
| 1436 | self.named_id_map = mem::take(&mut enclosing.named_id_map); |
| 1437 | self.defined_enums = mem::take(&mut enclosing.defined_enums); |
| 1438 | self.enclosing = Some(Box::new(enclosing)); |
| 1439 | |
| 1440 | self.begin_scope(); |
| 1441 | |
| 1442 | // Store parameter count and default value count |
| 1443 | let param_count = params.len(); |
| 1444 | let default_count = params |
| 1445 | .values() |
| 1446 | .filter(|p| p.default_value.is_some()) |
| 1447 | .count(); |
| 1448 | self.function.arity = (param_count - default_count) as u8; |
| 1449 | self.function.max_arity = param_count as u8; |
| 1450 | |
| 1451 | // Compile parameters and their default values |
| 1452 | for (index, param) in params.values_mut().enumerate() { |
| 1453 | self.declare_variable(param.name, Mutability::Mutable); |
| 1454 | self.mark_initialized(); |
| 1455 | |
| 1456 | let name = self.ctx.intern(param.name.lexeme.as_bytes()); |
| 1457 | // Store default value if present |
| 1458 | if let Some(expr) = mem::take(&mut param.default_value) { |
| 1459 | let default_value = match expr { |
| 1460 | Expr::Literal { value, .. } => Value::from(value), |
| 1461 | Expr::EnumVariant { |
| 1462 | enum_name, variant, .. |
| 1463 | } => { |
| 1464 | if let Some(enum_) = self.get_enum(enum_name.lexeme) { |
| 1465 | let variant_name = self.ctx.intern(variant.lexeme.as_bytes()); |
| 1466 | let variant_value = match enum_.borrow().get_variant_value(variant_name) |
| 1467 | { |
| 1468 | Some(value) => value, |
| 1469 | None => { |
| 1470 | self.error_at( |
| 1471 | variant, |
| 1472 | &format!( |
| 1473 | "No variant called '{}' in enum '{}'.", |
| 1474 | variant.lexeme, enum_name.lexeme |
| 1475 | ), |
| 1476 | ); |
| 1477 | Value::default() |
| 1478 | } |
| 1479 | }; |
| 1480 | Value::EnumVariant(Gc::new( |
no test coverage detected