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