(
&mut self,
params: Vec<Token<'gc>>,
body: Box<Expr<'gc>>,
)
| 1148 | |
| 1149 | impl<'gc> CodeGen<'gc> { |
| 1150 | fn generate_lambda( |
| 1151 | &mut self, |
| 1152 | params: Vec<Token<'gc>>, |
| 1153 | body: Box<Expr<'gc>>, |
| 1154 | ) -> Result<(), VmError> { |
| 1155 | // Create a new compiler for the lambda |
| 1156 | let name = format!("lambda_{}", CHUNK_ID.load(Ordering::Relaxed)); |
| 1157 | let chunk_id = CHUNK_ID.fetch_add(1, Ordering::AcqRel); |
| 1158 | |
| 1159 | // Create the lambda compiler and swap with self |
| 1160 | let mut lambda_compiler = Self::new(self.ctx, FunctionType::Lambda, &name); |
| 1161 | lambda_compiler.named_id_map = self.named_id_map.clone(); |
| 1162 | |
| 1163 | // Store current compiler as enclosing and set enclosing for lambda |
| 1164 | let current_compiler = mem::replace(self, *lambda_compiler); |
| 1165 | self.enclosing = Some(Box::new(current_compiler)); |
| 1166 | |
| 1167 | // Set up function parameters |
| 1168 | self.function.arity = params.len() as u8; |
| 1169 | self.function.max_arity = params.len() as u8; |
| 1170 | |
| 1171 | // Add parameters as locals |
| 1172 | self.begin_scope(); |
| 1173 | for param in params { |
| 1174 | self.declare_variable(param, Mutability::Mutable); |
| 1175 | self.mark_initialized(); |
| 1176 | } |
| 1177 | |
| 1178 | // Generate code for the body (which is a Block expression) |
| 1179 | self.generate_expr(body)?; |
| 1180 | |
| 1181 | // self.emit(OpCode::Return); |
| 1182 | // self.end_scope(); |
| 1183 | |
| 1184 | // Check for errors |
| 1185 | if self.error_reporter.had_error { |
| 1186 | return Err(VmError::CompileError); |
| 1187 | } |
| 1188 | |
| 1189 | // Get the generated function and chunks |
| 1190 | self.function.shrink_to_fit(); |
| 1191 | let generated_function = mem::take(&mut self.function); |
| 1192 | let generated_chunks = mem::take(&mut self.chunks); |
| 1193 | |
| 1194 | // Get the enclosing compiler back |
| 1195 | if let Some(enclosing) = self.enclosing.take() { |
| 1196 | let _ = mem::replace(self, *enclosing); |
| 1197 | } |
| 1198 | |
| 1199 | // Store the generated function and extend chunks |
| 1200 | self.chunks.insert(chunk_id, generated_function); |
| 1201 | self.chunks.extend(generated_chunks); |
| 1202 | |
| 1203 | // Emit closure instruction |
| 1204 | self.emit(OpCode::Closure { chunk_id }); |
| 1205 | Ok(()) |
| 1206 | } |
| 1207 |
no test coverage detected