1#[cfg(feature = "ir-disassembly")]
2use compiler::Symbol;
3use compiler::{Capture, Compiler};
4use dynamic::{Dynamic, Type};
5use parser::{BinaryOp, Expr, ExprKind, PatternKind, Span, Stmt, StmtKind, UnaryOp};
6use std::collections::{BTreeMap, VecDeque};
7
8use crate::context::LocalVar;
9
10use super::{FnInfo, FnVariant, PTR_TYPE, context::BuildContext, ptr_type};
11use cranelift::prelude::*;
12use cranelift_jit::{JITBuilder, JITModule};
13use cranelift_module::{DataDescription, DataId, FuncId, Module};
14
15use anyhow::{Result, anyhow};
16use smol_str::SmolStr;
17
18pub struct JITRunTime {
19 pub compiler: Compiler,
20 pub fns: BTreeMap<u32, FnVariant>,
21 pub sigs: Vec<(Vec<Type>, Signature, Type)>,
22 pub(crate) pending_fns: VecDeque<PendingFn>,
23 pub(crate) compile_depth: usize,
24 #[cfg(feature = "ir-disassembly")]
25 pub ir_disassembly: BTreeMap<SmolStr, String>,
26 pub module: JITModule,
27 pub consts: Vec<Option<DataId>>,
28}
29
30pub(crate) struct PendingFn {
31 pub name: SmolStr,
32 pub symbol_id: u32,
33 pub fn_id: FuncId,
34 pub arg_tys: Vec<Type>,
35 pub ret_ty: Type,
36 pub body: Stmt,
37}
38
39impl JITRunTime {
40 fn expr(kind: ExprKind) -> Expr {
41 Expr::new(kind, Span::default())
42 }
43
44 fn stmt(kind: StmtKind) -> Stmt {
45 Stmt::new(kind, Span::default())
46 }
47
48 pub fn load(&mut self, code: Vec<u8>, arg_name: SmolStr) -> Result<(i64, Type)> {
49 let stmts = Compiler::parse_code(code)?;
50 self.compiler.clear();
51 self.compiler.symbols.add_module("__console".into());
52 let mut cap = Capture::default();
53 let body = Self::stmt(StmtKind::Block(self.compiler.compile_fn(&[arg_name], &mut vec![Type::Any], Self::stmt(StmtKind::Block(stmts)), &mut cap)?));
54 self.compiler.tys.push(Type::Any);
55 let ret_ty = self.compiler.infer_stmt(&body)?;
56 self.compiler.clear();
57 let fn_id = self.compile_fn(None, &[Type::Any], ret_ty.clone(), &body)?;
58 self.compiler.clear();
59 self.compiler.symbols.pop_module();
60 self.module.finalize_definitions()?;
61 Ok((self.module.get_finalized_function(fn_id) as i64, ret_ty))
62 }
63
64 pub fn import_code(&mut self, name: &str, code: Vec<u8>) -> Result<()> {
65 log::info!("import {}", name);
66 let _ = self.compiler.import_code(name, code)?;
67 Ok(())
68 }
69
70 #[cfg(feature = "ir-disassembly")]
71 pub fn disassemble_ir(&mut self, name: &str) -> Result<String> {
72 if let Some(ir) = self.ir_disassembly.get(name) {
73 return Ok(ir.clone());
74 }
75 let id = self.get_id(name)?;
76 let (_, symbol) = self.compiler.symbols.get_symbol(id)?;
77 if let Symbol::Fn { ty, .. } = symbol
78 && let Type::Fn { tys, .. } = ty
79 && tys.is_empty()
80 {
81 let _ = self.gen_fn(None, id, &[])?;
82 }
83 self.ir_disassembly.get(name).cloned().ok_or_else(|| anyhow!("未找到函数 {} 的 Cranelift IR;如果它需要参数,请先触发对应实例化", name))
84 }
85
86 pub fn get_fn_ptr(&mut self, name: &str, arg_tys: &[Type]) -> Result<(*const u8, Type)> {
87 let main_id = self.get_id(name)?;
88 let fn_info = self.gen_fn(None, main_id, arg_tys)?;
89 Ok((self.module.get_finalized_function(fn_info.get_id()?), fn_info.get_type()?))
90 }
91
92 pub fn get_const_value(&mut self, ctx: &mut BuildContext, idx: usize) -> Result<(Value, Type)> {
93 if self.consts.len() < idx + 1 {
94 self.consts.resize(idx + 1, None);
95 }
96 let id = if let Some(id) = self.consts.get(idx).cloned().unwrap_or(None) {
97 id
98 } else {
99 let id = self.module.declare_anonymous_data(true, false)?;
100 let mut desc = DataDescription::new();
101 let c = Box::new(self.compiler.consts[idx].deep_clone()); let ptr = Box::into_raw(c);
103 desc.define((ptr as i64).to_le_bytes().into());
104 self.module.define_data(id, &desc)?;
105 self.consts[idx] = Some(id);
106 id
107 };
108 let c = self.module.declare_data_in_func(id, &mut ctx.builder.func);
109 let addr = ctx.builder.ins().global_value(ptr_type(), c);
110 let value = ctx.builder.ins().load(ptr_type(), MemFlags::new(), addr, 0); Ok((self.call(ctx, self.get_method(&Type::Any, "clone")?, vec![value])?.0, Type::Any))
112 }
113
114 fn get_null_value(&mut self, ctx: &mut BuildContext) -> Result<(Value, Type)> {
115 let const_idx = self.compiler.get_const(Dynamic::Null);
116 self.get_const_value(ctx, const_idx)
117 }
118
119 pub fn get_dynamic(&self, expr: &Expr) -> Option<Dynamic> {
120 if let ExprKind::Const(idx) = &expr.kind { self.compiler.consts.get(*idx).cloned() } else { None }
121 }
122
123 pub fn get_method(&self, ty: &Type, name: &str) -> Result<FnInfo> {
124 self.compiler.get_field(ty, name).and_then(|(_, ty)| if let Type::Symbol { id, params: _ } = ty { self.get_fn(id, &[]) } else { Err(anyhow!("不是成员函数")) })
125 }
126
127 pub fn get_id(&self, name: &str) -> Result<u32> {
128 self.compiler.symbols.get_id(name)
129 }
130
131 pub fn get_type(&mut self, name: &str, arg_tys: &[Type]) -> Result<Type> {
132 let id = self.get_id(name)?;
133 if self.compiler.symbols.symbols.get(name).map(|s| s.is_fn()).unwrap_or(false) {
134 return self.compiler.infer_fn(id, arg_tys);
135 }
136 self.compiler.symbols.get_type(&Type::Symbol { id, params: Vec::new() })
137 }
138
139 pub fn new<F: FnMut(&mut JITBuilder)>(mut f: F) -> Self {
140 let mut builder = JITBuilder::new(cranelift_module::default_libcall_names()).unwrap();
141 f(&mut builder);
142 let module = JITModule::new(builder);
143 PTR_TYPE.get_or_init(|| module.isa().pointer_type());
144 let fns = BTreeMap::<u32, FnVariant>::new();
145 Self {
146 compiler: Compiler::new(),
147 fns,
148 sigs: Vec::new(),
149 pending_fns: VecDeque::new(),
150 compile_depth: 0,
151 #[cfg(feature = "ir-disassembly")]
152 ir_disassembly: BTreeMap::new(),
153 module,
154 consts: Vec::new(),
155 }
156 }
157
158 fn unary(ctx: &mut BuildContext, left: (Value, Type), op: UnaryOp) -> Result<(Value, Type)> {
159 match op {
160 UnaryOp::Neg => {
161 if left.1.is_int() || left.1.is_uint() {
162 if left.1.width() == 8 {
163 let zero = ctx.builder.ins().iconst(types::I64, 0);
164 return Ok((ctx.builder.ins().isub(zero, left.0), Type::I64));
165 } else if left.1.width() == 4 {
166 let zero = ctx.builder.ins().iconst(types::I32, 0);
167 return Ok((ctx.builder.ins().isub(zero, left.0), Type::I32));
168 }
169 } else if left.1.is_float() {
170 return Ok((ctx.builder.ins().fneg(left.0), left.1));
171 }
172 }
173 UnaryOp::Not => {
174 if left.1.is_any() {
175 return Err(anyhow!("defer any-bool not handling"));
176 }
177 let zero = ctx.builder.ins().iconst(types::I8, 0);
178 let one = ctx.builder.ins().iconst(types::I8, 1);
179 let is_zero = ctx.builder.ins().icmp_imm(IntCC::Equal, left.0, 0);
180 return Ok((ctx.builder.ins().select(is_zero, one, zero), Type::Bool));
181 }
182 _ => {}
183 }
184 Err(anyhow!("未实现 {:?} {:?}", left, op))
185 }
186
187 pub(crate) fn call(&mut self, ctx: &mut BuildContext, fn_info: FnInfo, args: Vec<Value>) -> Result<(Value, Type)> {
188 match fn_info {
189 FnInfo::Call { fn_id, arg_tys: _, caps: _, ret } => {
190 let fn_ref = self.get_fn_ref(ctx, fn_id);
191 let call_inst = ctx.builder.ins().call(fn_ref, &args);
192 if !ret.is_void() { Ok((ctx.builder.inst_results(call_inst)[0], ret)) } else { Err(anyhow!("没有返回值")) }
193 }
194 FnInfo::Inline { fn_ptr, arg_tys: _ } => fn_ptr(Some(ctx), args).map(|(v, t)| (v.unwrap(), t)),
195 }
196 }
197
198 fn call_for_side_effect(&mut self, ctx: &mut BuildContext, fn_info: FnInfo, args: Vec<Value>) -> Result<()> {
199 match fn_info {
200 FnInfo::Call { fn_id, arg_tys: _, caps: _, ret: _ } => {
201 let fn_ref = self.get_fn_ref(ctx, fn_id);
202 ctx.builder.ins().call(fn_ref, &args);
203 Ok(())
204 }
205 FnInfo::Inline { fn_ptr, arg_tys: _ } => fn_ptr(Some(ctx), args).map(|_| ()),
206 }
207 }
208
209 pub(crate) fn short_circuit_logic(&mut self, ctx: &mut BuildContext, left: (Value, Type), op: BinaryOp, right: &Expr) -> Result<(Value, Type)> {
210 let is_any = left.1.is_any();
211 if is_any {
212 let left_cond = self.bool_value(ctx, left.clone())?;
213 let rhs_block = ctx.builder.create_block();
214 let short_block = ctx.builder.create_block();
215 let end_block = ctx.builder.create_block();
216 ctx.builder.append_block_param(end_block, ptr_type());
217
218 match op {
219 BinaryOp::And => {
220 ctx.builder.ins().brif(left_cond, rhs_block, &[], short_block, &[]);
221 }
222 BinaryOp::Or => {
223 ctx.builder.ins().brif(left_cond, short_block, &[], rhs_block, &[]);
224 }
225 _ => unreachable!(),
226 }
227
228 ctx.builder.switch_to_block(rhs_block);
229 let right = self.eval(ctx, right)?.get(ctx).unwrap();
230 let right_any = self.convert(ctx, right, Type::Any)?;
231 ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(right_any)]);
232 ctx.builder.seal_block(rhs_block);
233
234 ctx.builder.switch_to_block(short_block);
235 ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(left.0)]);
236 ctx.builder.seal_block(short_block);
237
238 ctx.builder.switch_to_block(end_block);
239 let result = ctx.builder.block_params(end_block)[0];
240 Ok((result, Type::Any))
241 } else {
242 let left = self.bool_value(ctx, left)?;
243 let rhs_block = ctx.builder.create_block();
244 let short_block = ctx.builder.create_block();
245 let end_block = ctx.builder.create_block();
246 ctx.builder.append_block_param(end_block, types::I8);
247
248 match op {
249 BinaryOp::And => {
250 ctx.builder.ins().brif(left, rhs_block, &[], short_block, &[]);
251 }
252 BinaryOp::Or => {
253 ctx.builder.ins().brif(left, short_block, &[], rhs_block, &[]);
254 }
255 _ => unreachable!(),
256 }
257
258 ctx.builder.switch_to_block(rhs_block);
259 let right = self.eval(ctx, right)?.get(ctx).unwrap();
260 let right = self.bool_value(ctx, right)?;
261 ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(right)]);
262 ctx.builder.seal_block(rhs_block);
263
264 ctx.builder.switch_to_block(short_block);
265 let short_value = match op {
266 BinaryOp::And => ctx.builder.ins().iconst(types::I8, 0),
267 BinaryOp::Or => ctx.builder.ins().iconst(types::I8, 1),
268 _ => unreachable!(),
269 };
270 ctx.builder.ins().jump(end_block, &[cranelift::codegen::ir::BlockArg::Value(short_value)]);
271 ctx.builder.seal_block(short_block);
272
273 ctx.builder.switch_to_block(end_block);
274 let result = ctx.builder.block_params(end_block)[0];
275 Ok((result, Type::Bool))
276 }
277 }
278
279 fn struct_alloc(&mut self, ctx: &mut BuildContext, ty: &Type) -> Result<Value> {
280 let size = ctx.builder.ins().iconst(types::I64, ty.width() as i64);
281 let alloc_id = self.get_id("__struct_alloc")?;
282 let alloc = self.get_fn(alloc_id, &[Type::I64])?;
283 self.call(ctx, alloc, vec![size]).map(|(v, _)| v)
284 }
285
286 fn store_struct_field(&mut self, ctx: &mut BuildContext, base: Value, idx: usize, field_ty: &Type, value: (Value, Type), struct_ty: &Type) -> Result<()> {
287 let offset = struct_ty.field_offset(idx).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
288 let value = self.convert(ctx, value, field_ty.clone())?;
289 if field_ty.is_struct() || field_ty.is_array() {
290 let field_addr = ctx.builder.ins().iadd_imm(base, offset as i64);
291 self.copy_vec_element(ctx, field_addr, value, field_ty);
292 } else {
293 ctx.builder.ins().store(MemFlags::trusted(), value, base, offset as i32);
294 }
295 Ok(())
296 }
297
298 fn load_struct_field(&mut self, ctx: &mut BuildContext, base: Value, idx: usize, struct_ty: &Type) -> Result<(Value, Type)> {
299 if let Type::Struct { params: _, fields } = struct_ty {
300 let field_ty = fields.get(idx).map(|(_, ty)| ty).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
301 let offset = struct_ty.field_offset(idx).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
302 if field_ty.is_struct() || field_ty.is_array() {
303 return Ok((ctx.builder.ins().iadd_imm(base, offset as i64), field_ty.clone()));
304 }
305 let val = ctx.builder.ins().load(crate::get_type(field_ty)?, MemFlags::trusted(), base, offset as i32);
306 Ok((val, field_ty.clone()))
307 } else {
308 Err(anyhow!("不是结构体 {:?}", struct_ty))
309 }
310 }
311
312 fn struct_field_index(&self, struct_ty: &Type, right: &Expr) -> Result<usize> {
313 let value = if let ExprKind::Const(idx) = right.kind { self.compiler.consts.get(idx).cloned().ok_or_else(|| anyhow!("missing const {}", idx))? } else { right.clone().value()? };
314 if let Some(idx) = value.as_int() {
315 return usize::try_from(idx).map_err(|_| anyhow!("结构字段索引越界 {}", idx));
316 }
317 if value.is_str() {
318 return self.compiler.get_field(struct_ty, value.as_str()).map(|(idx, _)| idx);
319 }
320 Err(anyhow!("非立即数结构字段索引 {:?}", right))
321 }
322
323 fn vec_elem_ty(ty: &Type) -> Option<Type> {
324 if let Type::Vec(elem, 0) = ty { Some((**elem).clone()) } else { None }
325 }
326
327 fn array_elem_ty(ty: &Type) -> Option<Type> {
328 if let Type::Array(elem, _) = ty { Some((**elem).clone()) } else { None }
329 }
330
331 fn vec_index_addr(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<Value> {
332 let idx = self.convert(ctx, idx, Type::I64)?;
333 let width = ctx.builder.ins().iconst(types::I64, elem_ty.storage_width() as i64);
334 let offset = ctx.builder.ins().imul(idx, width);
335 Ok(ctx.builder.ins().iadd(base, offset))
336 }
337
338 fn array_index_addr(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<Value> {
339 self.vec_index_addr(ctx, base, idx, elem_ty)
340 }
341
342 fn load_array_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<(Value, Type)> {
343 let addr = self.array_index_addr(ctx, base, idx, elem_ty)?;
344 if elem_ty.is_struct() || elem_ty.is_array() {
345 Ok((addr, elem_ty.clone()))
346 } else {
347 let val = ctx.builder.ins().load(crate::get_type(elem_ty)?, MemFlags::trusted(), addr, 0);
348 Ok((val, elem_ty.clone()))
349 }
350 }
351
352 fn store_array_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type, value: (Value, Type)) -> Result<()> {
353 let addr = self.array_index_addr(ctx, base, idx, elem_ty)?;
354 let value = self.convert(ctx, value, elem_ty.clone())?;
355 if elem_ty.is_struct() || elem_ty.is_array() {
356 self.copy_vec_element(ctx, addr, value, elem_ty);
357 } else {
358 ctx.builder.ins().store(MemFlags::trusted(), value, addr, 0);
359 }
360 Ok(())
361 }
362
363 fn init_repeat_array(&mut self, ctx: &mut BuildContext, value: (Value, Type), len: u32) -> Result<(Value, Type)> {
364 let elem_ty = value.1.clone();
365 let array_ty = Type::Array(std::rc::Rc::new(elem_ty.clone()), len);
366 let base = self.struct_alloc(ctx, &array_ty)?;
367 for idx in 0..len {
368 let idx = (ctx.builder.ins().iconst(types::I64, idx as i64), Type::I64);
369 self.store_array_index(ctx, base, idx, &elem_ty, value.clone())?;
370 }
371 Ok((base, array_ty))
372 }
373
374 fn init_array_from_items(&mut self, ctx: &mut BuildContext, items: &[Expr], ty: &Type) -> Result<Value> {
375 let Type::Array(elem_ty, len) = ty else {
376 return Err(anyhow!("not an array type: {:?}", ty));
377 };
378 if items.len() != *len as usize {
379 return Err(anyhow!("array literal length {} does not match {}", items.len(), len));
380 }
381 let base = self.struct_alloc(ctx, ty)?;
382 for (idx, item) in items.iter().enumerate() {
383 let value = self.eval(ctx, item)?.get(ctx).ok_or(anyhow!("array item has no value"))?;
384 let idx = (ctx.builder.ins().iconst(types::I64, idx as i64), Type::I64);
385 self.store_array_index(ctx, base, idx, elem_ty, value)?;
386 }
387 Ok(base)
388 }
389
390 fn load_vec_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type) -> Result<(Value, Type)> {
391 let addr = self.vec_index_addr(ctx, base, idx, elem_ty)?;
392 if elem_ty.is_struct() {
393 Ok((addr, elem_ty.clone()))
394 } else {
395 let val = ctx.builder.ins().load(crate::get_type(elem_ty)?, MemFlags::trusted(), addr, 0);
396 Ok((val, elem_ty.clone()))
397 }
398 }
399
400 fn copy_vec_element(&mut self, ctx: &mut BuildContext, dst: Value, src: Value, elem_ty: &Type) {
401 let mut offset = 0u32;
402 let width = elem_ty.storage_width();
403 while offset < width {
404 let remaining = width - offset;
405 let (ty, size) = if remaining >= 8 {
406 (types::I64, 8)
407 } else if remaining >= 4 {
408 (types::I32, 4)
409 } else if remaining >= 2 {
410 (types::I16, 2)
411 } else {
412 (types::I8, 1)
413 };
414 let value = ctx.builder.ins().load(ty, MemFlags::trusted(), src, offset as i32);
415 ctx.builder.ins().store(MemFlags::trusted(), value, dst, offset as i32);
416 offset += size;
417 }
418 }
419
420 fn store_vec_index(&mut self, ctx: &mut BuildContext, base: Value, idx: (Value, Type), elem_ty: &Type, value: (Value, Type)) -> Result<()> {
421 let addr = self.vec_index_addr(ctx, base, idx, elem_ty)?;
422 let value = self.convert(ctx, value, elem_ty.clone())?;
423 if elem_ty.is_struct() {
424 self.copy_vec_element(ctx, addr, value, elem_ty);
425 } else {
426 ctx.builder.ins().store(MemFlags::trusted(), value, addr, 0);
427 }
428 Ok(())
429 }
430
431 fn swap_vec_index(&mut self, ctx: &mut BuildContext, base: Value, left: (Value, Type), right: (Value, Type), elem_ty: &Type) -> Result<()> {
432 let left_addr = self.vec_index_addr(ctx, base, left, elem_ty)?;
433 let right_addr = self.vec_index_addr(ctx, base, right, elem_ty)?;
434 let mut offset = 0u32;
435 let width = elem_ty.storage_width();
436 while offset < width {
437 let remaining = width - offset;
438 let (ty, size) = if remaining >= 8 {
439 (types::I64, 8)
440 } else if remaining >= 4 {
441 (types::I32, 4)
442 } else if remaining >= 2 {
443 (types::I16, 2)
444 } else {
445 (types::I8, 1)
446 };
447 let left_value = ctx.builder.ins().load(ty, MemFlags::trusted(), left_addr, offset as i32);
448 let right_value = ctx.builder.ins().load(ty, MemFlags::trusted(), right_addr, offset as i32);
449 ctx.builder.ins().store(MemFlags::trusted(), left_value, right_addr, offset as i32);
450 ctx.builder.ins().store(MemFlags::trusted(), right_value, left_addr, offset as i32);
451 offset += size;
452 }
453 Ok(())
454 }
455
456 fn init_struct_from_dynamic(&mut self, ctx: &mut BuildContext, value: (Value, Type), ty: &Type) -> Result<Value> {
457 let Type::Struct { params: _, fields } = ty else {
458 return Err(anyhow!("不是结构体 {:?}", ty));
459 };
460 let base = self.struct_alloc(ctx, ty)?;
461 for (idx, (_, field_ty)) in fields.iter().enumerate() {
462 let idx_val = ctx.builder.ins().iconst(types::I64, idx as i64);
463 let item = self.call(ctx, self.get_method(&Type::Any, "get_idx")?, vec![value.0, idx_val])?;
464 self.store_struct_field(ctx, base, idx, field_ty, item, ty)?;
465 }
466 Ok(base)
467 }
468
469 fn init_struct_from_items(&mut self, ctx: &mut BuildContext, items: &[Expr], ty: &Type) -> Result<Value> {
470 let Type::Struct { params: _, fields } = ty else {
471 return Err(anyhow!("not a struct type: {:?}", ty));
472 };
473 let base = self.struct_alloc(ctx, ty)?;
474 for (idx, item) in items.iter().enumerate() {
475 let Some((_, field_ty)) = fields.get(idx) else {
476 break;
477 };
478 let value = self.eval(ctx, item)?.get(ctx).ok_or(anyhow!("struct field has no value"))?;
479 self.store_struct_field(ctx, base, idx, field_ty, value, ty)?;
480 }
481 Ok(base)
482 }
483
484 fn expr_assigned_var(expr: &Expr) -> Option<(u32, Type)> {
485 if let ExprKind::Binary { left, op, right } = &expr.kind
486 && op.is_assign()
487 && let ExprKind::Var(idx) = left.kind
488 {
489 return Some((idx, right.get_type()));
490 }
491 None
492 }
493
494 fn declare_assigned_vars(&mut self, ctx: &mut BuildContext, stmt: &Stmt) -> Result<()> {
495 match &stmt.kind {
496 StmtKind::Expr(expr, _) => {
497 if let Some((idx, ty)) = Self::expr_assigned_var(expr) {
498 match ctx.get_var(idx).ok() {
499 Some(LocalVar::Variable { .. }) | Some(LocalVar::Closure(_)) => {}
500 Some(LocalVar::Value { val, ty }) => {
501 ctx.set_var(idx, LocalVar::Value { val, ty })?;
502 }
503 Some(LocalVar::None) | None => {
504 let init = self.zero_value(ctx, &ty)?;
505 ctx.set_var(idx, init.into())?;
506 }
507 }
508 }
509 }
510 StmtKind::Block(stmts) => {
511 for stmt in stmts {
512 self.declare_assigned_vars(ctx, stmt)?;
513 }
514 }
515 StmtKind::If { then_body, else_body, .. } => {
516 self.declare_assigned_vars(ctx, then_body)?;
517 if let Some(else_body) = else_body {
518 self.declare_assigned_vars(ctx, else_body)?;
519 }
520 }
521 StmtKind::While { body, .. } | StmtKind::Loop(body) => {
522 self.declare_assigned_vars(ctx, body)?;
523 }
524 StmtKind::For { body, .. } => {
525 self.declare_assigned_vars(ctx, body)?;
526 }
527 _ => {}
528 }
529 Ok(())
530 }
531
532 fn zero_value(&mut self, ctx: &mut BuildContext, ty: &Type) -> Result<(Value, Type)> {
533 if ty.is_struct() || ty.is_array() {
534 Ok((self.struct_alloc(ctx, ty)?, ty.clone()))
535 } else if ty.is_f32() {
536 Ok((ctx.builder.ins().f32const(0.0), ty.clone()))
537 } else if ty.is_f64() {
538 Ok((ctx.builder.ins().f64const(0.0), ty.clone()))
539 } else {
540 Ok((ctx.builder.ins().iconst(crate::get_type(ty)?, 0), ty.clone()))
541 }
542 }
543
544 fn assign(&mut self, ctx: &mut BuildContext, left: &Expr, value: LocalVar) -> Result<(Value, Type)> {
545 if let ExprKind::Var(idx) = &left.kind {
546 let value_ty = value.get_ty();
547 if let Some(ty) = ctx.get_var_ty(*idx) {
548 if ty.is_struct() || ty.is_array() {
549 let dst = ctx.get_var(*idx)?.get(ctx).ok_or(anyhow!("aggregate variable has no value"))?.0;
550 let src = value.get(ctx).ok_or(anyhow!("aggregate assignment has no value"))?;
551 let src = self.convert(ctx, src, ty.clone())?;
552 self.copy_vec_element(ctx, dst, src, &ty);
553 } else if value_ty != ty {
554 if let Some(vt) = value.get(ctx) {
555 let val = self.convert(ctx, vt, ty.clone())?;
556 ctx.set_var(*idx, LocalVar::Value { val, ty })?;
557 } else if ty.is_any() {
558 let const_idx = self.compiler.get_const(Dynamic::Null);
559 let (val, ty) = self.get_const_value(ctx, const_idx)?;
560 ctx.set_var(*idx, LocalVar::Value { val, ty })?;
561 } else {
562 ctx.set_var(*idx, LocalVar::None)?;
563 }
564 } else {
565 ctx.set_var(*idx, value)?;
566 }
567 } else if value_ty.is_struct() || value_ty.is_array() {
568 let src = value.get(ctx).ok_or(anyhow!("aggregate initializer has no value"))?;
569 let dst = self.struct_alloc(ctx, &value_ty)?;
570 let src = self.convert(ctx, src, value_ty.clone())?;
571 self.copy_vec_element(ctx, dst, src, &value_ty);
572 ctx.set_var(*idx, LocalVar::Value { val: dst, ty: value_ty })?;
573 } else {
574 ctx.set_var(*idx, value)?;
575 }
576 let val = ctx.get_var(*idx)?.get(ctx).ok_or(anyhow!("assigned variable has no value"))?;
577 return Ok(val);
578 } else if left.is_idx() {
579 let value = value.get(ctx).unwrap();
580 let (left, _, right) = left.clone().binary().unwrap();
581 let left = self.eval(ctx, &left)?.get(ctx).ok_or(anyhow!("未知局部变量 {:?}", left))?;
582 if let Type::Struct { params: _, fields } = &left.1 {
583 let idx = self.struct_field_index(&left.1, &right)?;
584 let field_ty = fields.get(idx).map(|(_, ty)| ty.clone()).ok_or_else(|| anyhow!("结构字段索引越界 {}", idx))?;
585 self.store_struct_field(ctx, left.0, idx, &field_ty, value.clone(), &left.1)?;
586 return Ok(value);
587 }
588 if let Some(elem_ty) = Self::vec_elem_ty(&left.1) {
589 let idx = if right.is_value() {
590 let idx = right.clone().value()?.as_int().ok_or(anyhow!("Vec 索引必须是整数"))?;
591 (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
592 } else {
593 self.eval(ctx, &right)?.get(ctx).ok_or(anyhow!("Vec 索引没有值"))?
594 };
595 self.store_vec_index(ctx, left.0, idx, &elem_ty, value.clone())?;
596 return Ok(value);
597 }
598 if let Some(elem_ty) = Self::array_elem_ty(&left.1) {
599 let idx = if right.is_value() {
600 let idx = right.clone().value()?.as_int().ok_or(anyhow!("array index must be integer"))?;
601 (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
602 } else {
603 self.eval(ctx, &right)?.get(ctx).ok_or(anyhow!("array index has no value"))?
604 };
605 self.store_array_index(ctx, left.0, idx, &elem_ty, value.clone())?;
606 return Ok(value);
607 }
608 if right.is_value() {
609 let right_value = right.clone().value()?;
610 if let Some(idx) = right_value.as_int() {
611 let idx = ctx.builder.ins().iconst(types::I64, idx);
612 let f = self.get_method(&left.1, "set_idx")?;
613 let args = self.adjust_args(ctx, vec![left, (idx, Type::I64), value.clone()], f.arg_tys()?)?;
614 self.call_for_side_effect(ctx, f, args)?;
615 } else {
616 let key = ctx.get_const(&right_value)?;
617 let f = self.get_method(&left.1, "set_key")?;
618 let args = self.adjust_args(ctx, vec![left, key, value.clone()], f.arg_tys()?)?;
619 self.call_for_side_effect(ctx, f, args)?;
620 }
621 } else {
622 let right = self.eval(ctx, &right)?.get(ctx).unwrap();
623 if right.1.is_any() {
624 let f = self.get_method(&left.1, "set_key")?;
625 let args = self.adjust_args(ctx, vec![left, right, value.clone()], f.arg_tys()?)?;
626 self.call_for_side_effect(ctx, f, args)?;
627 } else {
628 let f = self.get_method(&left.1, "set_idx")?;
629 let args = self.adjust_args(ctx, vec![left, right, value.clone()], f.arg_tys()?)?;
630 self.call_for_side_effect(ctx, f, args)?;
631 }
632 }
633 return Ok(value);
634 } else {
635 panic!("赋值给 {:?} {:?}", left, value)
636 }
637 }
638
639 pub(crate) fn call_fn(&mut self, ctx: &mut BuildContext, id: u32, obj: Option<Expr>, params: &Vec<Expr>) -> Result<LocalVar> {
640 self.call_fn_with_params(ctx, id, &[], obj, params)
641 }
642
643 pub(crate) fn call_fn_with_params(&mut self, ctx: &mut BuildContext, id: u32, generic_args: &[Type], obj: Option<Expr>, params: &Vec<Expr>) -> Result<LocalVar> {
644 let mut args: Vec<(Value, Type)> = if let Some(obj) = obj { vec![self.eval(ctx, &obj)?.get(ctx).unwrap()] } else { Vec::new() };
645 for p in params {
646 args.push(self.eval(ctx, p)?.get(ctx).unwrap());
647 }
648 let fn_name = self.compiler.symbols.get_symbol(id).map(|(name, _)| name.clone())?;
649 if fn_name.as_str().ends_with("Vec::swap")
650 && let Some((base, vec_ty)) = args.first().cloned()
651 && let Some(elem_ty) = Self::vec_elem_ty(&vec_ty)
652 {
653 let [_, left_idx, right_idx]: [(Value, Type); 3] = args.try_into().map_err(|_| anyhow!("Vec::swap 需要 self 和两个索引参数"))?;
654 self.swap_vec_index(ctx, base, left_idx, right_idx, &elem_ty)?;
655 return Ok(LocalVar::None);
656 }
657 let arg_tys: Vec<Type> = args.iter().map(|(_, ty)| ty.clone()).collect();
658 let fn_info = match if generic_args.is_empty() { self.get_fn(id, &arg_tys) } else { Err(anyhow!("generic function needs specialization")) } {
659 Ok(info) => info,
660 Err(_) => self.gen_fn_with_params(Some(ctx), id, &arg_tys, generic_args).map_err(|e| {
661 log::error!("{:?}", self.compiler.symbols.get_symbol(id));
662 e
663 })?,
664 };
665 match &fn_info {
666 FnInfo::Call { fn_id: _, arg_tys: want_tys, caps, ret } => {
667 let mut args = self.adjust_args(ctx, args, want_tys)?;
668 for c in caps {
669 args.push(ctx.get_var(*c as u32)?.get(ctx).unwrap().0);
670 }
671 if ret.is_void() {
672 self.call_for_side_effect(ctx, fn_info, args)?;
673 Ok(LocalVar::None)
674 } else {
675 self.call(ctx, fn_info, args).map(|r| r.into())
676 }
677 }
678 _ => panic!("不可能编译出 inline 函数"),
679 }
680 }
681
682 pub(crate) fn eval(&mut self, ctx: &mut BuildContext, expr: &Expr) -> Result<LocalVar> {
683 match &expr.kind {
684 ExprKind::Value(v) => Ok(ctx.get_const(v)?.into()),
685 ExprKind::Var(idx) => {
686 let v = ctx.get_var(*idx)?;
687 Ok(v)
688 }
689 ExprKind::Unary { op, value } => {
690 let v = self.eval(ctx, value)?.get(ctx).unwrap();
691 if op == &UnaryOp::Not {
692 let cond = self.bool_value(ctx, v)?;
693 let zero = ctx.builder.ins().iconst(types::I8, 0);
694 let one = ctx.builder.ins().iconst(types::I8, 1);
695 let is_zero = ctx.builder.ins().icmp_imm(IntCC::Equal, cond, 0);
696 Ok((ctx.builder.ins().select(is_zero, one, zero), Type::Bool).into())
697 } else {
698 Ok(Self::unary(ctx, v, op.clone())?.into())
699 }
700 }
701 ExprKind::Binary { left, op, right } => {
702 if op == &BinaryOp::Assign {
703 match self.eval(ctx, right) {
704 Ok(value) => self.assign(ctx, left, value).map(|v| v.into()),
705 Err(e) => {
706 log::error!("assign error {:?}", e);
707 Err(e)
708 }
709 }
710 } else {
711 let assign_expr = if op.is_assign() { Some(left.clone()) } else { None };
712 let left = match self.eval(ctx, left)?.get(ctx) {
713 Some(left) => left,
714 None if matches!(op, BinaryOp::And | BinaryOp::Or) => self.get_null_value(ctx)?,
715 None => return Err(anyhow!("binary left has no value: {:?}", left)),
716 };
717 if op == &BinaryOp::Idx {
718 if let Type::Struct { params: _, fields: _ } = &left.1 {
719 let idx = self.struct_field_index(&left.1, right)?;
720 return self.load_struct_field(ctx, left.0, idx, &left.1).map(|r| r.into());
721 }
722 if let Some(elem_ty) = Self::vec_elem_ty(&left.1) {
723 let idx = if right.is_value() {
724 let idx = right.clone().value()?.as_int().ok_or(anyhow!("Vec 索引必须是整数"))?;
725 (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
726 } else {
727 self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("Vec 索引没有值"))?
728 };
729 return self.load_vec_index(ctx, left.0, idx, &elem_ty).map(|r| r.into());
730 }
731 if let Some(elem_ty) = Self::array_elem_ty(&left.1) {
732 let idx = if right.is_value() {
733 let idx = right.clone().value()?.as_int().ok_or(anyhow!("array index must be integer"))?;
734 (ctx.builder.ins().iconst(types::I64, idx), Type::I64)
735 } else {
736 self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("array index has no value"))?
737 };
738 return self.load_array_index(ctx, left.0, idx, &elem_ty).map(|r| r.into());
739 }
740 if right.is_value() {
741 let right_value = right.clone().value()?;
742 if let Some(idx) = right_value.as_int() {
743 let idx = ctx.builder.ins().iconst(types::I64, idx);
744 self.call(ctx, self.get_method(&left.1, "get_idx")?, vec![left.0, idx]).map(|r| r.into())
745 } else {
746 let key = ctx.get_const(&right_value)?;
747 self.call(ctx, self.get_method(&left.1, "get_key")?, vec![left.0, key.0]).map(|r| r.into())
748 }
749 } else if let ExprKind::Range { start, stop, inclusive } = &right.kind {
750 let start = self.eval(ctx, start)?.get(ctx).ok_or(anyhow!("range start has no value"))?;
751 let start = self.convert(ctx, start, Type::I64)?;
752 let stop = self.eval(ctx, stop)?.get(ctx).ok_or(anyhow!("range stop has no value"))?;
753 let stop = self.convert(ctx, stop, Type::Any)?;
754 let inclusive = ctx.builder.ins().iconst(types::I8, i64::from(*inclusive));
755 self.call(ctx, self.get_method(&left.1, "slice")?, vec![left.0, start, stop, inclusive]).map(|r| r.into())
756 } else {
757 let right = self.eval(ctx, right)?.get(ctx).ok_or(anyhow!("非Value {:?}", right))?;
758 if right.1.is_any() {
759 self.call(ctx, self.get_method(&left.1, "get_key")?, vec![left.0, right.0]).map(|r| r.into())
760 } else {
761 let right = self.convert(ctx, right, Type::I64)?;
762 self.call(ctx, self.get_method(&left.1, "get_idx")?, vec![left.0, right]).map(|r| r.into())
763 }
764 }
765 } else {
766 let result = self.binary(ctx, left, op.clone(), right)?.into();
767 if let Some(expr) = assign_expr { self.assign(ctx, &expr, result).map(|r| r.into()) } else { Ok(result.into()) }
768 }
769 }
770 }
771 ExprKind::Call { obj, params } => {
772 if let ExprKind::AssocId { id, params: generic_args } = &obj.kind {
773 self.call_fn_with_params(ctx, *id, generic_args, None, params)
774 } else if let ExprKind::Id(id, obj) = &obj.kind {
775 self.call_fn(ctx, *id, obj.as_ref().map(|o| *o.clone()), params)
776 } else if obj.is_value() {
777 return Ok(LocalVar::None);
779 } else {
780 if obj.is_idx() {
781 let (left, _, right) = obj.clone().binary().unwrap();
782 let left = self.eval(ctx, &left)?.get(ctx).ok_or(anyhow!("obj {:?}", obj))?;
783 let ty = self.compiler.symbols.get_type(&left.1)?;
784 if let Some(name) = self.get_dynamic(&right) {
785 if name.as_str() == "swap"
786 && let Some(elem_ty) = Self::vec_elem_ty(&ty)
787 {
788 let [left_idx, right_idx]: [(Value, Type); 2] =
789 params.iter().map(|p| self.eval(ctx, p)?.get(ctx).ok_or(anyhow!("Vec::swap 参数没有值"))).collect::<Result<Vec<_>>>()?.try_into().map_err(|_| anyhow!("Vec::swap 需要两个索引参数"))?;
790 self.swap_vec_index(ctx, left.0, left_idx, right_idx, &elem_ty)?;
791 return Ok(LocalVar::None);
792 }
793 let mut args = vec![left];
794 for p in params {
795 args.push(self.eval(ctx, p)?.get(ctx).unwrap());
796 }
797 let (_, method_ty) = self.compiler.get_field(&ty, name.as_str())?;
798 let Type::Symbol { id, .. } = method_ty else {
799 return Err(anyhow!("不是成员函数"));
800 };
801 let arg_tys: Vec<Type> = args.iter().map(|(_, ty)| ty.clone()).collect();
802 let method = self.get_fn(id, &arg_tys).or_else(|_| self.gen_fn_with_params(Some(ctx), id, &arg_tys, &[]))?;
803 let args = self.adjust_args(ctx, args, method.arg_tys()?)?;
804 self.call(ctx, method, args).map(|r| r.into())
805 } else {
806 self.eval(ctx, obj)
807 }
808 } else {
809 let val = self.eval(ctx, obj)?;
810 if let LocalVar::Closure(id) = val {
811 return self.call_fn(ctx, id, None, params);
812 }
813 panic!("暂未实现 {:?}", val)
814 }
815 }
816 }
817 ExprKind::Typed { value, ty } => {
818 if let Type::Struct { params: _, fields: _ } = ty
819 && let ExprKind::List(items) = &value.kind
820 {
821 return Ok((self.init_struct_from_items(ctx, items, ty)?, ty.clone()).into());
822 }
823 if let Type::Array(_, _) = ty
824 && let ExprKind::List(items) = &value.kind
825 {
826 return Ok((self.init_array_from_items(ctx, items, ty)?, ty.clone()).into());
827 }
828 let vt = if let Some(vt) = self.eval(ctx, value)?.get(ctx) {
829 vt
830 } else if ty.is_any() {
831 let idx = self.compiler.get_const(Dynamic::Null);
832 self.get_const_value(ctx, idx)?
833 } else {
834 return Ok(LocalVar::None);
835 };
836 if let Type::Struct { params: _, fields: _ } = ty {
837 if &vt.1 == ty {
838 Ok(vt.into())
839 } else if vt.1.is_any() {
840 Ok((self.init_struct_from_dynamic(ctx, vt, ty)?, ty.clone()).into())
841 } else {
842 Err(anyhow!("cannot convert {:?} to {:?}", vt.1, ty))
843 }
844 } else if &vt.1 != ty {
845 Ok((self.convert(ctx, vt, ty.clone())?, ty.clone()).into())
846 } else {
847 Ok(vt.into())
848 }
849 }
850 ExprKind::List(_) => Err(anyhow!("未实现 {:?}", expr)),
851 ExprKind::Repeat { value, len } => {
852 let value = self.eval(ctx, value)?.get(ctx).ok_or(anyhow!("repeat value has no value"))?;
853 let Type::ConstInt(len) = len else {
854 return Err(anyhow!("repeat length must be a compile-time integer"));
855 };
856 let len = u32::try_from(*len).map_err(|_| anyhow!("repeat length out of range"))?;
857 self.init_repeat_array(ctx, value, len).map(|r| r.into())
858 }
859 ExprKind::Const(idx) => self.get_const_value(ctx, *idx).map(|v| v.into()),
860 ExprKind::Id(id, _) => Ok(LocalVar::Closure(*id)),
861 ExprKind::AssocId { id, .. } => Ok(LocalVar::Closure(*id)),
862 expr => {
863 panic!("未实现 {:?}", expr)
865 }
866 }
867 }
868
869 fn gen_loop(&mut self, ctx: &mut BuildContext, cond: Option<&Expr>, body: &Stmt, f: Option<impl FnMut(&mut BuildContext)>) -> Result<()> {
870 let loop_block = ctx.builder.create_block();
871 let end_block = ctx.builder.create_block();
872 if let Some(cond) = cond {
873 let start_block = ctx.builder.create_block();
874 ctx.builder.ins().jump(start_block, &[]);
875 ctx.builder.switch_to_block(start_block);
876 let cond = self.eval(ctx, cond)?.get(ctx).unwrap();
877 let cond = self.bool_value(ctx, cond)?;
878 let continue_block = if f.is_some() { ctx.builder.create_block() } else { start_block };
879 ctx.builder.ins().brif(cond, loop_block, &[], end_block, &[]);
880 ctx.builder.switch_to_block(loop_block);
881 let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(continue_block))?;
882 if !body_terminated {
883 ctx.builder.ins().jump(continue_block, &[]);
884 }
885 ctx.builder.seal_block(loop_block);
886 f.map(|mut f| {
887 ctx.builder.switch_to_block(continue_block);
888 f(ctx);
889 ctx.builder.ins().jump(start_block, &[]);
890 ctx.builder.seal_block(continue_block);
891 });
892 } else {
893 ctx.builder.ins().jump(loop_block, &[]);
894 ctx.builder.switch_to_block(loop_block);
895 let body_terminated = self.gen_stmt(ctx, body, Some(end_block), Some(loop_block))?;
896 if !body_terminated {
897 ctx.builder.ins().jump(loop_block, &[]);
898 }
899 ctx.builder.seal_block(loop_block);
900 }
901 ctx.builder.switch_to_block(end_block);
902 Ok(())
903 }
904
905 pub(crate) fn gen_stmt(&mut self, ctx: &mut BuildContext, stmt: &Stmt, break_block: Option<Block>, continue_block: Option<Block>) -> Result<bool> {
906 match &stmt.kind {
907 StmtKind::Expr(expr, _) => {
908 let _ = self.eval(ctx, expr)?;
909 }
910 StmtKind::Break => {
911 ctx.builder.ins().jump(break_block.unwrap(), &[]);
912 return Ok(true);
913 }
914 StmtKind::Continue => {
915 ctx.builder.ins().jump(continue_block.unwrap(), &[]);
916 return Ok(true);
917 }
918 StmtKind::Return(expr) => {
919 if let Some(expr) = expr {
920 let value = self.eval(ctx, expr)?;
921 if let Some((r, _)) = value.get(ctx) {
922 ctx.builder.ins().return_(&[r]);
923 } else {
924 ctx.builder.ins().return_(&[]);
925 }
926 } else {
927 ctx.builder.ins().return_(&[]);
928 }
929 return Ok(true);
930 }
931 StmtKind::If { cond, then_body, else_body } => {
932 self.declare_assigned_vars(ctx, then_body)?;
933 if let Some(else_body) = else_body {
934 self.declare_assigned_vars(ctx, else_body)?;
935 }
936 let then_block = ctx.builder.create_block();
937 let cond = self.eval(ctx, cond)?.get(ctx).ok_or(anyhow!("未知的条件 {:?}", cond))?;
938 let cond = self.bool_value(ctx, cond)?;
939 let mut end_block = None;
940 if let Some(else_body) = else_body {
941 let else_block = ctx.builder.create_block();
942 ctx.builder.ins().brif(cond, then_block, &[], else_block, &[]);
943 ctx.builder.switch_to_block(then_block);
944 if !self.gen_stmt(ctx, then_body, break_block, continue_block)? {
945 let block = ctx.builder.create_block();
946 ctx.builder.ins().jump(block, &[]);
947 end_block = Some(block);
948 }
949 ctx.builder.switch_to_block(else_block);
950 if !self.gen_stmt(ctx, else_body, break_block, continue_block)? {
951 if end_block.is_none() {
952 end_block = Some(ctx.builder.create_block());
953 }
954 ctx.builder.ins().jump(end_block.unwrap(), &[]);
955 }
956 ctx.builder.seal_block(else_block);
957 } else {
958 let block = ctx.builder.create_block();
959 ctx.builder.ins().brif(cond, then_block, &[], block, &[]);
960 end_block = Some(block);
961 ctx.builder.switch_to_block(then_block);
962 if !self.gen_stmt(ctx, then_body, break_block, continue_block)? {
963 ctx.builder.ins().jump(end_block.unwrap(), &[]); }
965 }
966 if let Some(block) = end_block {
967 ctx.builder.switch_to_block(block);
968 }
969 ctx.builder.seal_block(then_block);
970 return Ok(end_block.is_none());
971 }
972 StmtKind::Block(stmts) => {
973 for (idx, stmt) in stmts.iter().enumerate() {
974 let r = self.gen_stmt(ctx, stmt, break_block, continue_block)?;
975 if idx == stmts.len() - 1 {
976 return Ok(r);
977 }
978 }
979 }
980 StmtKind::While { cond, body } => {
981 self.declare_assigned_vars(ctx, body)?;
982 let no_loop: Option<fn(&mut BuildContext)> = None;
983 self.gen_loop(ctx, Some(cond), body, no_loop)?;
984 }
985 StmtKind::Loop(body) => {
986 self.declare_assigned_vars(ctx, body)?;
987 let no_loop: Option<fn(&mut BuildContext)> = None;
988 self.gen_loop(ctx, None, body, no_loop)?;
989 }
990 StmtKind::For { pat, range, body } => {
991 if let ExprKind::Range { start, stop, inclusive } = &range.kind {
992 if let PatternKind::Var { idx, .. } = &pat.kind {
993 let start = self.eval(ctx, start)?;
994 ctx.set_var(*idx, start)?;
995 self.declare_assigned_vars(ctx, body)?;
996 let op = if *inclusive { BinaryOp::Le } else { BinaryOp::Lt };
997 let cond = Self::expr(ExprKind::Binary { left: Box::new(Self::expr(ExprKind::Var(*idx))), op, right: Box::new(stop.as_ref().clone()) });
998 self.gen_loop(
999 ctx,
1000 Some(&cond),
1001 body,
1002 Some(|ctx: &mut BuildContext| {
1003 let v = ctx.get_var(*idx).unwrap().get(ctx).unwrap();
1004 let step = if v.1 == Type::I64 {
1005 ctx.builder.ins().iconst(types::I64, 1)
1006 } else if v.1 == Type::I32 {
1007 ctx.builder.ins().iconst(types::I32, 1)
1008 } else {
1009 panic!("{:?} 不能作为增量", v.1)
1010 };
1011 let vt = (ctx.builder.ins().iadd(v.0, step), v.1).into();
1012 let _ = ctx.set_var(*idx, vt);
1013 }),
1014 )?;
1015 }
1016 } else if let PatternKind::Var { idx, .. } = &pat.kind {
1017 let vt = self.eval(ctx, range)?.get(ctx).unwrap();
1018 if vt.1.is_any() {
1019 let iter = self.call(ctx, self.get_method(&vt.1, "iter")?, vec![vt.0])?;
1020 let next = self.get_method(&vt.1, "next")?;
1021 let next_id = next.get_id()?;
1022 let start = self.call(ctx, next, vec![iter.0])?;
1023 ctx.set_var(*idx, start.into())?;
1024 let cond = Self::expr(ExprKind::Binary { left: Box::new(Self::expr(ExprKind::Var(*idx))), op: BinaryOp::Ne, right: Box::new(Self::expr(ExprKind::Value(Dynamic::Null))) });
1025 self.gen_loop(
1026 ctx,
1027 Some(&cond),
1028 body,
1029 Some(|ctx: &mut BuildContext| {
1030 let fn_ref = ctx.get_fn_ref(next_id).unwrap();
1031 let call_inst = ctx.builder.ins().call(fn_ref, &[iter.0]);
1032 let ret = ctx.builder.inst_results(call_inst)[0];
1033 let _ = ctx.set_var(*idx, (ret, Type::Any).into());
1034 }),
1035 )?;
1036 }
1037 } else if let PatternKind::Tuple(pats) = &pat.kind {
1038 let vt = self.eval(ctx, range)?.get(ctx).unwrap();
1039 if vt.1.is_any() && pats.len() == 2 {
1040 let iter = self.call(ctx, self.get_method(&vt.1, "iter")?, vec![vt.0])?;
1042 let next = self.get_method(&vt.1, "next")?;
1043 let next_id = next.get_id()?;
1044 let get_idx = self.get_method(&vt.1, "get_idx")?.get_id()?;
1045
1046 let start = self.call(ctx, next, vec![iter.0])?;
1047 let key_idx = ctx.builder.ins().iconst(types::I64, 0);
1048 let key = self.call(ctx, self.get_method(&start.1, "get_idx")?, vec![start.0, key_idx])?;
1049 let value_idx = ctx.builder.ins().iconst(types::I64, 1);
1050 let value = self.call(ctx, self.get_method(&start.1, "get_idx")?, vec![start.0, value_idx])?;
1051 ctx.set_var(pats[0].var().unwrap(), key.into())?;
1052 ctx.set_var(pats[1].var().unwrap(), value.into())?;
1053 let cond = Self::expr(ExprKind::Binary { left: Box::new(Self::expr(ExprKind::Var(pats[0].var().unwrap()))), op: BinaryOp::Ne, right: Box::new(Self::expr(ExprKind::Value(Dynamic::Null))) });
1054 self.gen_loop(
1055 ctx,
1056 Some(&cond),
1057 body,
1058 Some(|ctx: &mut BuildContext| {
1059 let fn_ref = ctx.get_fn_ref(next_id).unwrap();
1060 let call_inst = ctx.builder.ins().call(fn_ref, &[iter.0]);
1061 let ret = ctx.builder.inst_results(call_inst)[0];
1062
1063 let fn_ref = ctx.get_fn_ref(get_idx).unwrap();
1064 let call_inst = ctx.builder.ins().call(fn_ref, &[ret, key_idx]);
1065 let key_ret = ctx.builder.inst_results(call_inst)[0];
1066 let call_inst = ctx.builder.ins().call(fn_ref, &[ret, value_idx]);
1067 let value_ret = ctx.builder.inst_results(call_inst)[0];
1068
1069 let _ = ctx.set_var(pats[0].var().unwrap(), (key_ret, Type::Any).into());
1070 let _ = ctx.set_var(pats[1].var().unwrap(), (value_ret, Type::Any).into());
1071 }),
1072 )?;
1073 }
1074 }
1075 }
1076 _ => {
1077 panic!("未实现 {:?}", stmt)
1078 }
1079 }
1080 Ok(false)
1081 }
1082}