Skip to main content

compiler/
lib.rs

1pub mod infer;
2mod symbol;
3use dynamic::{Dynamic, Type};
4use indexmap::IndexMap;
5use parser::{BinaryOp, Expr, ExprKind, Parser, Pattern, PatternKind, Span, Stmt, StmtKind};
6use smol_str::SmolStr;
7use std::{
8    collections::{BTreeMap, BTreeSet},
9    path::{Path, PathBuf},
10    sync::Arc,
11};
12pub use symbol::{Symbol, SymbolTable, eval_const_int_type, substitute_type};
13
14#[derive(Clone)]
15enum FnInferRet {
16    Pending(Option<Type>),
17    Done(Type),
18}
19
20#[derive(Clone)]
21pub enum ListElemState {
22    Unknown,
23    Known(Type),
24    Mixed,
25}
26
27#[derive(Clone)]
28pub struct Compiler {
29    pub symbols: SymbolTable,
30    pub frames: Vec<usize>,
31    pub tys: Vec<Type>,
32    /// 编译期常量表:键是稳定的 SmolStr 名字(通常来自字面量文本或字段名),
33    /// 值是 Dynamic。`ExprKind::Const(idx)` 中的 idx 是 IndexMap 中的位置,
34    /// 在单次编译中稳定;热重载场景下同一名字会拿到同一 idx,跨编译不保证。
35    pub consts: IndexMap<SmolStr, Dynamic>,
36    names: Vec<SmolStr>,
37    list_elem_states: Vec<Option<ListElemState>>,
38    arg_counts: Vec<usize>,
39    fns: BTreeMap<u32, Vec<(Vec<Type>, Vec<Type>, FnInferRet)>>,
40    local_type_hints: BTreeMap<u32, Vec<(Vec<Type>, Vec<Type>, Vec<Option<Type>>)>>,
41    infer_stack: Vec<(u32, Vec<Type>, Vec<Type>)>,
42    importing_paths: BTreeSet<PathBuf>,
43    source_files: BTreeMap<SmolStr, SourceFile>,
44}
45
46#[derive(Clone)]
47pub struct SourceFile {
48    pub path: Option<PathBuf>,
49    pub code: Arc<Vec<u8>>,
50}
51
52fn impl_target_name(target: &Type) -> anyhow::Result<SmolStr> {
53    match target {
54        Type::Ident { name, .. } => Ok(name.clone()),
55        _ => anyhow::bail!("impl 目标类型暂不支持: {:?}", target),
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::{Compiler, Symbol};
62    use dynamic::{Dynamic, Type};
63    use parser::{Pattern, PatternKind, Span};
64    use std::rc::Rc;
65
66    #[test]
67    fn inferred_function_return_type_is_written_back_to_symbol() -> anyhow::Result<()> {
68        let mut compiler = Compiler::new();
69        compiler.import_code(
70            "compiler_infer_return",
71            br#"
72            pub fn is_alive() {
73                true
74            }
75
76            pub fn can_act() {
77                is_alive() && true && is_alive()
78            }
79            "#
80            .to_vec(),
81        )?;
82
83        let is_alive = compiler.symbols.get_id("compiler_infer_return::is_alive")?;
84        assert_eq!(compiler.infer_fn(is_alive, &[])?, Type::Bool);
85
86        let (_, symbol) = compiler.symbols.get_symbol(is_alive)?;
87        let Symbol::Fn { ty: Type::Fn { ret, .. }, .. } = symbol else {
88            panic!("is_alive should be a function symbol");
89        };
90        assert_eq!(ret.as_ref(), &Type::Bool);
91
92        let can_act = compiler.symbols.get_id("compiler_infer_return::can_act")?;
93        assert_eq!(compiler.infer_fn(can_act, &[])?, Type::Bool);
94        Ok(())
95    }
96
97    #[test]
98    fn top_level_const_composite_resolves_const_idents() -> anyhow::Result<()> {
99        let mut compiler = Compiler::new();
100        compiler.import_code(
101            "compiler_const_table",
102            br#"
103            pub const GEM_ATK = "atk";
104            pub const GEM_DEF = "def";
105            pub const GEM_TABLE = [
106                { key: GEM_ATK, score: 3i32 },
107                { key: GEM_DEF, score: 1i32 },
108            ];
109            "#
110            .to_vec(),
111        )?;
112
113        let table = compiler.symbols.get_id("compiler_const_table::GEM_TABLE")?;
114        let (_, symbol) = compiler.symbols.get_symbol(table)?;
115        let Symbol::Const { value, .. } = symbol else {
116            panic!("GEM_TABLE should be a const symbol");
117        };
118
119        let first = value.get_idx(0).expect("first table row");
120        assert_eq!(first.get_dynamic("key").expect("key").as_str(), "atk");
121        assert_eq!(first.get_dynamic("score").expect("score").as_int(), Some(3));
122        Ok(())
123    }
124
125    #[test]
126    fn const_unary_neg_handles_min_integer_literal() -> anyhow::Result<()> {
127        let mut compiler = Compiler::new();
128        compiler.import_code(
129            "compiler_const_min_int",
130            br#"
131            pub const MIN_I32: i32 = -2147483648i32;
132            "#
133            .to_vec(),
134        )?;
135
136        let id = compiler.symbols.get_id("compiler_const_min_int::MIN_I32")?;
137        let (_, symbol) = compiler.symbols.get_symbol(id)?;
138        let Symbol::Const { value, .. } = symbol else {
139            panic!("MIN_I32 should be a const symbol");
140        };
141        assert_eq!(value.as_int(), Some(i32::MIN as i64));
142        Ok(())
143    }
144
145    #[test]
146    fn return_check_resolves_function_args_before_body_compile() -> anyhow::Result<()> {
147        let mut compiler = Compiler::new();
148        compiler.import_code(
149            "compiler_return_check_args",
150            br#"
151            pub fn no_value_return(flag: bool) {
152                if flag {
153                    return;
154                }
155            }
156
157            pub fn tail_if(flag: bool) {
158                if flag {
159                    1
160                } else {
161                    2
162                }
163            }
164
165            pub fn loop_index(low: i64, high: i64) {
166                let total = 0i64;
167                for i in low..high {
168                    total += i;
169                }
170                total
171            }
172
173            pub fn closure_capture() {
174                let base = 10i32;
175                let add_base = |value: i32| {
176                    value + base
177                };
178                add_base(1i32)
179            }
180
181            pub fn destructured_names() {
182                let (left, right) = (3i32, 4i32);
183                let [first, second] = [5i32, 6i32];
184                let _ = first;
185                left + right + second
186            }
187            "#
188            .to_vec(),
189        )?;
190
191        let no_value_return = compiler.symbols.get_id("compiler_return_check_args::no_value_return")?;
192        assert_eq!(compiler.infer_fn(no_value_return, &[Type::Bool])?, Type::Void);
193
194        let tail_if = compiler.symbols.get_id("compiler_return_check_args::tail_if")?;
195        // 无后缀整数字面量默认 I64
196        assert_eq!(compiler.infer_fn(tail_if, &[Type::Bool])?, Type::I64);
197
198        let loop_index = compiler.symbols.get_id("compiler_return_check_args::loop_index")?;
199        assert_eq!(compiler.infer_fn(loop_index, &[Type::I64, Type::I64])?, Type::I64);
200
201        Ok(())
202    }
203
204    #[test]
205    fn return_check_infers_raw_assoc_calls_before_body_compile() -> anyhow::Result<()> {
206        let mut compiler = Compiler::new();
207        compiler.import_code(
208            "compiler_return_check_assoc",
209            br#"
210            pub struct Box<N> {
211                data: [u32; N],
212            }
213
214            impl Box<N> {
215                pub fn make() {
216                    Box<N>{ data: [0u32; N] }
217                }
218
219                pub fn ok(self: Box<N>) {
220                    true
221                }
222            }
223
224            pub fn main() {
225                let item = Box<2>::make();
226                if item.ok() {
227                    1i32
228                } else {
229                    0i32
230                }
231            }
232            "#
233            .to_vec(),
234        )?;
235
236        let main_id = compiler.symbols.get_id("compiler_return_check_assoc::main")?;
237        assert_eq!(compiler.infer_fn(main_id, &[])?, Type::I32);
238        Ok(())
239    }
240
241    #[test]
242    fn top_level_unknown_statement_is_error() {
243        let mut compiler = Compiler::new();
244        let err = compiler
245            .import_code(
246                "compiler_top_level_unknown",
247                br#"
248                let value = 1i32;
249                "#
250                .to_vec(),
251            )
252            .expect_err("top-level let should be rejected");
253        assert!(format!("{err:#}").contains("不支持的顶层语句"));
254    }
255
256    #[test]
257    fn static_initializer_errors_instead_of_disappearing() {
258        let mut compiler = Compiler::new();
259        let err = compiler
260            .import_code(
261                "compiler_static_initializer",
262                br#"
263                pub fn make() {
264                    1i32
265                }
266                pub static VALUE: i32 = make();
267                "#
268                .to_vec(),
269            )
270            .expect_err("static initializer should be compile-time constant");
271        assert!(format!("{err:#}").contains("const 只能使用字面量"));
272    }
273
274    #[test]
275    fn return_expression_compile_error_is_preserved() {
276        let mut compiler = Compiler::new();
277        let err = compiler
278            .import_code(
279                "compiler_return_error",
280                br#"
281                pub fn bad() {
282                    return missing_call();
283                }
284                "#
285                .to_vec(),
286            )
287            .expect_err("return expression error should be reported");
288        assert!(format!("{err:#}").contains("未注册函数"));
289    }
290
291    #[test]
292    fn nested_pattern_errors_are_preserved() {
293        let mut compiler = Compiler::new();
294        let pat = Pattern { kind: PatternKind::List { elems: vec![Pattern { kind: PatternKind::Literal(Dynamic::I32(1)), span: Span::default() }], has_rest: false }, span: Span::default() };
295        let err = compiler.pat_to_var(pat, Type::List(Rc::new(Type::I32))).expect_err("invalid nested pattern should be reported");
296        assert!(format!("{err:#}").contains("未知的模式"));
297    }
298
299    #[test]
300    fn tuple_pattern_length_mismatch_is_error() {
301        let mut compiler = Compiler::new();
302        let pat = Pattern {
303            kind: PatternKind::Tuple(vec![
304                Pattern { kind: PatternKind::Ident { name: "a".into(), ty: Type::Any }, span: Span::default() },
305                Pattern { kind: PatternKind::Ident { name: "b".into(), ty: Type::Any }, span: Span::default() },
306                Pattern { kind: PatternKind::Ident { name: "c".into(), ty: Type::Any }, span: Span::default() },
307            ]),
308            span: Span::default(),
309        };
310        let err = compiler.pat_to_var(pat, Type::Tuple(vec![Type::I32, Type::I32])).expect_err("tuple pattern length mismatch should be rejected");
311        assert!(format!("{err:#}").contains("模式与元组类型不匹配"));
312    }
313
314    #[test]
315    fn forward_function_call_in_bool_condition_infers_callee_first() -> anyhow::Result<()> {
316        let mut compiler = Compiler::new();
317        compiler.import_code(
318            "compiler_forward_bool",
319            br#"
320            pub fn can_start() {
321                if is_ready() {
322                    return true;
323                }
324                false
325            }
326
327            pub fn is_ready() {
328                true
329            }
330            "#
331            .to_vec(),
332        )?;
333
334        let can_start = compiler.symbols.get_id("compiler_forward_bool::can_start")?;
335        assert_eq!(compiler.infer_fn(can_start, &[])?, Type::Bool);
336
337        let is_ready = compiler.symbols.get_id("compiler_forward_bool::is_ready")?;
338        assert_eq!(compiler.infer_fn(is_ready, &[])?, Type::Bool);
339        Ok(())
340    }
341
342    #[test]
343    fn inferred_return_cache_keeps_pending_separate_from_any() -> anyhow::Result<()> {
344        let mut compiler = Compiler::new();
345        compiler.import_code(
346            "compiler_pending_any",
347            br#"
348            pub fn dynamic_value(value) {
349                value
350            }
351
352            pub fn bool_value() {
353                true
354            }
355            "#
356            .to_vec(),
357        )?;
358
359        let dynamic_value = compiler.symbols.get_id("compiler_pending_any::dynamic_value")?;
360        assert_eq!(compiler.infer_fn(dynamic_value, &[Type::Any])?, Type::Any);
361
362        let bool_value = compiler.symbols.get_id("compiler_pending_any::bool_value")?;
363        assert_eq!(compiler.infer_fn(bool_value, &[])?, Type::Bool);
364        Ok(())
365    }
366
367    #[test]
368    fn recursive_function_uses_inferred_return_seed() -> anyhow::Result<()> {
369        let mut compiler = Compiler::new();
370        compiler.import_code(
371            "compiler_recursive_return",
372            br#"
373            pub fn factorial(n: i64) {
374                if n <= 1 {
375                    return 1;
376                }
377                n * factorial(n - 1)
378            }
379
380            pub fn factorial_reversed(n: i64) {
381                if n > 1 {
382                    return n * factorial_reversed(n - 1);
383                }
384                1
385            }
386            "#
387            .to_vec(),
388        )?;
389
390        let factorial = compiler.symbols.get_id("compiler_recursive_return::factorial")?;
391        assert_eq!(compiler.infer_fn(factorial, &[Type::I64])?, Type::I64);
392
393        let factorial_reversed = compiler.symbols.get_id("compiler_recursive_return::factorial_reversed")?;
394        assert_eq!(compiler.infer_fn(factorial_reversed, &[Type::I64])?, Type::I64);
395        Ok(())
396    }
397
398    #[test]
399    fn generic_function_infers_type_param_from_arg() -> anyhow::Result<()> {
400        let mut compiler = Compiler::new();
401        compiler.import_code(
402            "compiler_generic_identity",
403            br#"
404            pub fn identity<T>(value: T) {
405                value
406            }
407            "#
408            .to_vec(),
409        )?;
410
411        let identity = compiler.symbols.get_id("compiler_generic_identity::identity")?;
412        assert_eq!(compiler.infer_fn(identity, &[Type::I64])?, Type::I64);
413        assert_eq!(compiler.infer_fn(identity, &[Type::Bool])?, Type::Bool);
414        Ok(())
415    }
416
417    #[test]
418    fn generic_function_uses_explicit_const_param() -> anyhow::Result<()> {
419        let mut compiler = Compiler::new();
420        compiler.import_code(
421            "compiler_generic_const",
422            br#"
423            pub fn value<N>() {
424                N
425            }
426            "#
427            .to_vec(),
428        )?;
429
430        let value = compiler.symbols.get_id("compiler_generic_const::value")?;
431        assert_eq!(compiler.infer_fn_with_params(value, &[], &[Type::ConstInt(7)])?, Type::I32);
432        Ok(())
433    }
434
435    #[test]
436    fn generic_function_infers_const_param_from_array_len() -> anyhow::Result<()> {
437        let mut compiler = Compiler::new();
438        compiler.import_code(
439            "compiler_generic_array_len",
440            br#"
441            pub fn len<N>(items: [i32; N]) {
442                N
443            }
444            "#
445            .to_vec(),
446        )?;
447
448        let len = compiler.symbols.get_id("compiler_generic_array_len::len")?;
449        assert_eq!(compiler.infer_fn(len, &[Type::Array(std::rc::Rc::new(Type::I32), 3)])?, Type::I32);
450        Ok(())
451    }
452
453    #[test]
454    fn generic_function_reports_uninferred_param() -> anyhow::Result<()> {
455        let mut compiler = Compiler::new();
456        compiler.import_code(
457            "compiler_generic_uninferred",
458            br#"
459            pub fn value<T>() {
460                1i32
461            }
462            "#
463            .to_vec(),
464        )?;
465
466        let value = compiler.symbols.get_id("compiler_generic_uninferred::value")?;
467        let err = compiler.infer_fn(value, &[]).expect_err("generic parameter should not be inferred");
468        assert!(format!("{err:#}").contains("无法从实参类型推断函数范型参数"));
469        Ok(())
470    }
471
472    #[test]
473    fn assignment_target_type_keeps_dynamic_index_sum_static() -> anyhow::Result<()> {
474        let mut compiler = Compiler::new();
475        compiler.import_code(
476            "compiler_dynamic_index_sum",
477            br#"
478            pub fn sum_list(n: i64) {
479                let l = [];
480                for i in 0..n {
481                    l.push(i);
482                }
483                let sum = 0i64;
484                for i in 0..n {
485                    sum = sum + l[i];
486                }
487                sum
488            }
489            "#
490            .to_vec(),
491        )?;
492
493        let sum_list = compiler.symbols.get_id("compiler_dynamic_index_sum::sum_list")?;
494        assert_eq!(compiler.infer_fn(sum_list, &[Type::I64])?, Type::I64);
495        Ok(())
496    }
497
498    #[test]
499    fn list_literal_infers_element_type() -> anyhow::Result<()> {
500        let mut compiler = Compiler::new();
501        compiler.import_code(
502            "compiler_list_elem_type",
503            br#"
504            pub fn pushed_empty() {
505                let items = [];
506                items.push(1i64);
507                items[0]
508            }
509
510            pub fn ints() {
511                [1i64, 2i64]
512            }
513
514            pub fn mixed_then_int() {
515                let items = [];
516                items.push(1i64);
517                items.push("aaa");
518                items.push(2i64);
519                items[0]
520            }
521
522            "#
523            .to_vec(),
524        )?;
525
526        let pushed_empty = compiler.symbols.get_id("compiler_list_elem_type::pushed_empty")?;
527        assert_eq!(compiler.infer_fn(pushed_empty, &[])?, Type::I64);
528        let hints = compiler.inferred_local_type_hints(pushed_empty, &[], &[]);
529        assert_eq!(hints.first().cloned().flatten(), Some(Type::List(std::rc::Rc::new(Type::I64))));
530
531        let ints = compiler.symbols.get_id("compiler_list_elem_type::ints")?;
532        assert_eq!(compiler.infer_fn(ints, &[])?, Type::Any);
533
534        let mixed_then_int = compiler.symbols.get_id("compiler_list_elem_type::mixed_then_int")?;
535        assert_eq!(compiler.infer_fn(mixed_then_int, &[])?, Type::Any);
536        let hints = compiler.inferred_local_type_hints(mixed_then_int, &[], &[]);
537        assert_eq!(hints.first().cloned().flatten(), None);
538        Ok(())
539    }
540
541    #[test]
542    fn return_map_and_struct_is_type_error() -> anyhow::Result<()> {
543        let mut compiler = Compiler::new();
544        let err = match compiler.import_code(
545            "compiler_return_map_struct",
546            br#"
547            struct S {
548                hp: i32,
549            }
550
551            pub fn make_s_or_error(flag: i32) {
552                if flag == 0 {
553                    return { error: "bad" };
554                }
555                S{hp: 123}
556            }
557            "#
558            .to_vec(),
559        ) {
560            Ok(_) => panic!("expected mismatched return types to fail"),
561            Err(err) => err,
562        };
563
564        assert!(format!("{err:#}").contains("返回类型不一致"));
565        Ok(())
566    }
567
568    #[test]
569    fn unknown_function_call_strict_reports_error() -> anyhow::Result<()> {
570        let mut compiler = Compiler::new();
571        let err = match compiler.import_code(
572            "compiler_unknown_fn",
573            br#"
574            pub fn call_typo() {
575                prnt("hi")
576            }
577            "#
578            .to_vec(),
579        ) {
580            Ok(_) => panic!("expected unknown function to fail"),
581            Err(err) => err,
582        };
583
584        let msg = format!("{err:#}");
585        assert!(msg.contains("未注册函数"), "got: {msg}");
586        Ok(())
587    }
588}
589
590fn has_unresolved_generic_param(ty: &Type) -> bool {
591    match ty {
592        Type::Ident { name, params } => {
593            if params.is_empty() {
594                name.chars().next().map(|ch| ch.is_ascii_uppercase()).unwrap_or(false)
595            } else {
596                params.iter().any(has_unresolved_generic_param)
597            }
598        }
599        Type::Struct { params, fields } => params.iter().any(has_unresolved_generic_param) || fields.iter().any(|(_, ty)| has_unresolved_generic_param(ty)),
600        Type::Tuple(items) => items.iter().any(has_unresolved_generic_param),
601        Type::List(elem) | Type::Vec(elem, _) | Type::Array(elem, _) => has_unresolved_generic_param(elem),
602        Type::ArrayParam(elem, len) => has_unresolved_generic_param(elem) || has_unresolved_generic_param(len),
603        Type::Fn { tys, ret } => tys.iter().any(has_unresolved_generic_param) || has_unresolved_generic_param(ret),
604        Type::Symbol { params, .. } => params.iter().any(has_unresolved_generic_param),
605        Type::ConstBinary { left, right, .. } => has_unresolved_generic_param(left) || has_unresolved_generic_param(right),
606        _ => false,
607    }
608}
609
610fn is_top_level_import_expr(expr: &Expr) -> bool {
611    matches!(
612        &expr.kind,
613        ExprKind::Call { obj, .. } if matches!(&obj.kind, ExprKind::Ident(name) if name.as_str() == "import")
614    )
615}
616
617fn string_value(expr: &Expr) -> Option<&str> {
618    if let ExprKind::Value(Dynamic::String(value)) = &expr.kind { Some(value.as_str()) } else { None }
619}
620
621fn import_decl(stmt: &Stmt) -> Option<(SmolStr, SmolStr)> {
622    let StmtKind::Expr(expr, _) = &stmt.kind else {
623        return None;
624    };
625    let ExprKind::Call { obj, params } = &expr.kind else {
626        return None;
627    };
628    let ExprKind::Ident(name) = &obj.kind else {
629        return None;
630    };
631    if name.as_str() != "import" {
632        return None;
633    }
634
635    match params.as_slice() {
636        [module, path] => Some((string_value(module)?.into(), string_value(path)?.into())),
637        [module] => match &module.kind {
638            ExprKind::Value(Dynamic::String(value)) => Some((value.clone(), format!("{value}.zs").into())),
639            ExprKind::Ident(value) => Some((value.clone(), format!("{value}.zs").into())),
640            _ => None,
641        },
642        _ => None,
643    }
644}
645
646fn generic_arg_for_name<'a>(name: &str, params: &'a [Type], args: &'a [Type]) -> Option<&'a Type> {
647    params.iter().position(|param| matches!(param, Type::Ident { name: param_name, params } if params.is_empty() && param_name == name)).and_then(|idx| args.get(idx))
648}
649
650pub fn infer_generic_args_from_types(generic_params: &[Type], decl_tys: &[Type], arg_tys: &[Type]) -> Vec<Type> {
651    if generic_params.is_empty() {
652        return Vec::new();
653    }
654    let mut inferred = vec![None; generic_params.len()];
655    for (decl, actual) in decl_tys.iter().zip(arg_tys.iter()) {
656        infer_generic_arg_from_type(generic_params, decl, actual, &mut inferred);
657    }
658    if inferred.iter().all(|item| item.is_some()) {
659        return inferred.into_iter().map(Option::unwrap).collect();
660    }
661    if let Some(Type::Struct { params, .. }) = arg_tys.iter().find(|ty| matches!(ty, Type::Struct { params, .. } if params.len() == generic_params.len())) {
662        return params.clone();
663    }
664    for (decl, actual) in decl_tys.iter().zip(arg_tys.iter()) {
665        if let (Type::Ident { params: decl_params, .. }, Type::Ident { params: actual_params, .. }) = (decl, actual)
666            && decl_params.len() == actual_params.len()
667            && decl_params.iter().any(|param| generic_params.contains(param))
668        {
669            return actual_params.clone();
670        }
671    }
672    Vec::new()
673}
674
675pub fn resolve_generic_args_from_types(generic_params: &[Type], decl_tys: &[Type], arg_tys: &[Type], explicit_args: &[Type]) -> Result<Vec<Type>> {
676    if generic_params.is_empty() {
677        if explicit_args.is_empty() {
678            return Ok(Vec::new());
679        }
680        return Err(anyhow!("函数不接受范型参数,但传入了 {}", explicit_args.len()));
681    }
682    if !explicit_args.is_empty() {
683        if explicit_args.len() == generic_params.len() {
684            return Ok(explicit_args.to_vec());
685        }
686        return Err(anyhow!("函数范型参数数量不匹配,期望 {} 个,实际 {} 个", generic_params.len(), explicit_args.len()));
687    }
688
689    let inferred = infer_generic_args_from_types(generic_params, decl_tys, arg_tys);
690    if inferred.len() == generic_params.len() {
691        Ok(inferred)
692    } else if generic_params.len() == 1
693        && let Some(Type::List(elem) | Type::Vec(elem, _) | Type::Array(elem, _)) = arg_tys.first()
694    {
695        Ok(vec![elem.as_ref().clone()])
696    } else {
697        Err(anyhow!("无法从实参类型推断函数范型参数 {:?}", generic_params))
698    }
699}
700
701fn infer_generic_arg_from_type(generic_params: &[Type], decl: &Type, actual: &Type, inferred: &mut [Option<Type>]) {
702    if let Some(idx) = generic_params.iter().position(|param| param == decl) {
703        inferred[idx] = Some(actual.clone());
704        return;
705    }
706
707    match (decl, actual) {
708        (Type::List(decl_elem), Type::List(actual_elem)) => {
709            infer_generic_arg_from_type(generic_params, decl_elem, actual_elem, inferred);
710        }
711        (Type::Vec(decl_elem, decl_len), Type::Vec(actual_elem, actual_len)) | (Type::Array(decl_elem, decl_len), Type::Array(actual_elem, actual_len)) => {
712            infer_generic_arg_from_type(generic_params, decl_elem, actual_elem, inferred);
713            infer_generic_arg_from_type(generic_params, &Type::ConstInt(*decl_len as i64), &Type::ConstInt(*actual_len as i64), inferred);
714        }
715        (Type::ArrayParam(decl_elem, decl_len), Type::Array(actual_elem, actual_len)) => {
716            infer_generic_arg_from_type(generic_params, decl_elem, actual_elem, inferred);
717            infer_generic_arg_from_type(generic_params, decl_len, &Type::ConstInt(*actual_len as i64), inferred);
718        }
719        (Type::Ident { params: decl_params, .. }, Type::Ident { params: actual_params, .. })
720        | (Type::Ident { params: decl_params, .. }, Type::Symbol { params: actual_params, .. })
721        | (Type::Symbol { params: decl_params, .. }, Type::Symbol { params: actual_params, .. })
722        | (Type::Symbol { params: decl_params, .. }, Type::Ident { params: actual_params, .. })
723        | (Type::Struct { params: decl_params, .. }, Type::Struct { params: actual_params, .. }) => {
724            for (decl, actual) in decl_params.iter().zip(actual_params.iter()) {
725                infer_generic_arg_from_type(generic_params, decl, actual, inferred);
726            }
727        }
728        _ => {}
729    }
730}
731
732fn substitute_pattern(pattern: &Pattern, params: &[Type], args: &[Type]) -> Pattern {
733    let kind = match &pattern.kind {
734        PatternKind::Ident { name, ty } => PatternKind::Ident { name: name.clone(), ty: substitute_type(ty, params, args) },
735        PatternKind::Var { idx, ty } => PatternKind::Var { idx: *idx, ty: substitute_type(ty, params, args) },
736        PatternKind::Tuple(items) => PatternKind::Tuple(items.iter().map(|item| substitute_pattern(item, params, args)).collect()),
737        PatternKind::List { elems, has_rest } => PatternKind::List { elems: elems.iter().map(|item| substitute_pattern(item, params, args)).collect(), has_rest: *has_rest },
738        other => other.clone(),
739    };
740    Pattern { kind, span: pattern.span }
741}
742
743fn substitute_expr(expr: &Expr, params: &[Type], args: &[Type]) -> Expr {
744    let kind = match &expr.kind {
745        ExprKind::Ident(name) => match generic_arg_for_name(name, params, args) {
746            Some(Type::ConstInt(value)) => ExprKind::Value(Dynamic::I32(*value as i32)),
747            Some(ty) => eval_const_int_type(ty).map(|value| ExprKind::Value(Dynamic::I32(value as i32))).unwrap_or_else(|| expr.kind.clone()),
748            _ => expr.kind.clone(),
749        },
750        ExprKind::Typed { value, ty } => ExprKind::Typed { value: Box::new(substitute_expr(value, params, args)), ty: substitute_type(ty, params, args) },
751        ExprKind::Unary { op, value } => ExprKind::Unary { op: op.clone(), value: Box::new(substitute_expr(value, params, args)) },
752        ExprKind::Binary { left, op, right } => ExprKind::Binary { left: Box::new(substitute_expr(left, params, args)), op: op.clone(), right: Box::new(substitute_expr(right, params, args)) },
753        ExprKind::Generic { obj, params: nested } => ExprKind::Generic { obj: Box::new(substitute_expr(obj, params, args)), params: nested.iter().map(|param| substitute_type(param, params, args)).collect() },
754        ExprKind::Assoc { ty, name } => ExprKind::Assoc { ty: substitute_type(ty, params, args), name: name.clone() },
755        ExprKind::TypedMethod { obj, ty, name } => ExprKind::TypedMethod { obj: Box::new(substitute_expr(obj, params, args)), ty: substitute_type(ty, params, args), name: name.clone() },
756        ExprKind::AssocId { id, params: nested } => ExprKind::AssocId { id: *id, params: nested.iter().map(|param| substitute_type(param, params, args)).collect() },
757        ExprKind::Tuple(items) => ExprKind::Tuple(items.iter().map(|item| substitute_expr(item, params, args)).collect()),
758        ExprKind::List(items) => ExprKind::List(items.iter().map(|item| substitute_expr(item, params, args)).collect()),
759        ExprKind::Repeat { value, len } => ExprKind::Repeat { value: Box::new(substitute_expr(value, params, args)), len: substitute_type(len, params, args) },
760        ExprKind::Dict(items) => ExprKind::Dict(items.iter().map(|(name, value)| (name.clone(), substitute_expr(value, params, args))).collect()),
761        ExprKind::Range { start, stop, inclusive } => ExprKind::Range { start: Box::new(substitute_expr(start, params, args)), stop: Box::new(substitute_expr(stop, params, args)), inclusive: *inclusive },
762        ExprKind::Call { obj, params: call_params } => ExprKind::Call { obj: Box::new(substitute_expr(obj, params, args)), params: call_params.iter().map(|param| substitute_expr(param, params, args)).collect() },
763        ExprKind::Stmt(stmt) => ExprKind::Stmt(Box::new(substitute_stmt(stmt, params, args))),
764        ExprKind::Closure { args: closure_args, body } => {
765            ExprKind::Closure { args: closure_args.iter().map(|(name, ty)| (name.clone(), substitute_type(ty, params, args))).collect(), body: Box::new(substitute_stmt(body, params, args)) }
766        }
767        _ => expr.kind.clone(),
768    };
769    Expr::new(kind, expr.span)
770}
771
772pub fn substitute_stmt(stmt: &Stmt, params: &[Type], args: &[Type]) -> Stmt {
773    let kind = match &stmt.kind {
774        StmtKind::Let { pat, value } => StmtKind::Let { pat: substitute_pattern(pat, params, args), value: Box::new(substitute_stmt(value, params, args)) },
775        StmtKind::Expr(expr, close) => StmtKind::Expr(substitute_expr(expr, params, args), *close),
776        StmtKind::Block(stmts) => StmtKind::Block(stmts.iter().map(|stmt| substitute_stmt(stmt, params, args)).collect()),
777        StmtKind::Return(expr) => StmtKind::Return(expr.as_ref().map(|expr| substitute_expr(expr, params, args))),
778        StmtKind::While { cond, body } => StmtKind::While { cond: substitute_expr(cond, params, args), body: Box::new(substitute_stmt(body, params, args)) },
779        StmtKind::Loop(body) => StmtKind::Loop(Box::new(substitute_stmt(body, params, args))),
780        StmtKind::For { pat, range, body } => StmtKind::For { pat: substitute_pattern(pat, params, args), range: substitute_expr(range, params, args), body: Box::new(substitute_stmt(body, params, args)) },
781        StmtKind::Fn { name, generic_params, args: fn_args, body, is_pub } => StmtKind::Fn {
782            name: name.clone(),
783            generic_params: generic_params.iter().map(|param| substitute_type(param, params, args)).collect(),
784            args: fn_args.iter().map(|(name, ty)| (name.clone(), substitute_type(ty, params, args))).collect(),
785            body: Box::new(substitute_stmt(body, params, args)),
786            is_pub: *is_pub,
787        },
788        StmtKind::Struct { name, def, is_pub } => StmtKind::Struct { name: name.clone(), def: substitute_type(def, params, args), is_pub: *is_pub },
789        StmtKind::Impl { target, body } => StmtKind::Impl { target: substitute_type(target, params, args), body: Box::new(substitute_stmt(body, params, args)) },
790        StmtKind::If { cond, then_body, else_body } => StmtKind::If {
791            cond: substitute_expr(cond, params, args),
792            then_body: Box::new(substitute_stmt(then_body, params, args)),
793            else_body: else_body.as_ref().map(|body| Box::new(substitute_stmt(body, params, args))),
794        },
795        StmtKind::Static { name, ty, value, is_pub } => {
796            StmtKind::Static { name: name.clone(), ty: substitute_type(ty, params, args), value: value.as_ref().map(|value| substitute_expr(value, params, args)), is_pub: *is_pub }
797        }
798        StmtKind::Const { name, ty, value, is_pub } => StmtKind::Const { name: name.clone(), ty: substitute_type(ty, params, args), value: substitute_expr(value, params, args), is_pub: *is_pub },
799        other => other.clone(),
800    };
801    Stmt::new(kind, stmt.span)
802}
803
804#[derive(Debug, Clone, Default)]
805pub struct Capture {
806    pub names: Vec<(SmolStr, Type)>,
807    pub vars: Vec<usize>,
808}
809
810impl Capture {
811    pub fn new(names: Vec<(SmolStr, Type)>) -> Self {
812        Self { names, vars: Vec::new() }
813    }
814
815    pub fn get(&mut self, name: &str) -> Option<usize> {
816        if let Some(idx) = self.names.iter().position(|n| n.0 == name) {
817            if let Some(pos) = self.vars.iter().position(|v| *v == idx) {
818                Some(pos)
819            } else {
820                self.vars.push(idx);
821                Some(self.vars.len() - 1)
822            }
823        } else {
824            None
825        }
826    }
827
828    pub fn get_type(&self, idx: u32) -> Option<Type> {
829        self.names.get(idx as usize).map(|(_, ty)| ty.clone())
830    }
831}
832
833use anyhow::{Context, Result, anyhow};
834use thiserror::Error;
835
836#[derive(Debug, Error)]
837#[error("{message}")]
838pub struct SpannedCompilerError {
839    pub message: String,
840    pub span: Span,
841}
842
843#[derive(Debug, Clone)]
844pub struct CompilerDiagnostic {
845    pub message: String,
846    pub span: Span,
847}
848
849impl Compiler {
850    pub fn clear(&mut self) {
851        self.frames.clear();
852        self.names.clear();
853        self.tys.clear();
854        self.list_elem_states.clear();
855        self.arg_counts.clear();
856    }
857
858    pub fn take_local_state(&mut self) -> (Vec<usize>, Vec<SmolStr>, Vec<Type>, Vec<Option<ListElemState>>, Vec<usize>) {
859        (std::mem::take(&mut self.frames), std::mem::take(&mut self.names), std::mem::take(&mut self.tys), std::mem::take(&mut self.list_elem_states), std::mem::take(&mut self.arg_counts))
860    }
861
862    pub fn restore_local_state(&mut self, state: (Vec<usize>, Vec<SmolStr>, Vec<Type>, Vec<Option<ListElemState>>, Vec<usize>)) {
863        self.frames = state.0;
864        self.names = state.1;
865        self.tys = state.2;
866        self.list_elem_states = state.3;
867        self.arg_counts = state.4;
868    }
869
870    pub fn get_value(&self, expr: &Expr) -> Option<Dynamic> {
871        match &expr.kind {
872            ExprKind::Value(v) => Some(v.clone()),
873            ExprKind::Const(idx) => self.consts.get_index(*idx).map(|(_, v)| v.clone()),
874            _ => None,
875        }
876    }
877
878    pub fn get_const(&mut self, value: Dynamic) -> usize {
879        let key: SmolStr = if value.is_str() {
880            format!("str:{}", value.as_str()).into()
881        } else if value.is_null() {
882            "null".into()
883        } else {
884            format!("{value:?}").into()
885        };
886        if let Some((idx, _, _)) = self.consts.get_full(&key) {
887            return idx;
888        }
889        self.consts.insert_full(key, value).0
890    }
891
892    fn normalize_self_assign(left: Expr, op: BinaryOp, right: Expr, span: Span, arg_count: usize) -> Expr {
893        if let Some(idx) = left.var()
894            && (idx as usize) < arg_count
895        {
896            let base_op = match op {
897                BinaryOp::AddAssign => Some(BinaryOp::Add),
898                BinaryOp::SubAssign => Some(BinaryOp::Sub),
899                BinaryOp::MulAssign => Some(BinaryOp::Mul),
900                BinaryOp::DivAssign => Some(BinaryOp::Div),
901                BinaryOp::ModAssign => Some(BinaryOp::Mod),
902                BinaryOp::ShlAssign => Some(BinaryOp::Shl),
903                BinaryOp::ShrAssign => Some(BinaryOp::Shr),
904                BinaryOp::BitAndAssign => Some(BinaryOp::BitAnd),
905                BinaryOp::BitOrAssign => Some(BinaryOp::BitOr),
906                BinaryOp::BitXorAssign => Some(BinaryOp::BitXor),
907                _ => None,
908            };
909            if let Some(op) = base_op {
910                let right = Expr::new(ExprKind::Binary { left: Box::new(left.clone()), op, right: Box::new(right) }, span);
911                return Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Assign, right: Box::new(right) }, span);
912            }
913        }
914        if op == BinaryOp::Assign
915            && let Some(idx) = left.var()
916            && idx as usize >= arg_count
917            && let ExprKind::Binary { left: rhs_left, op: rhs_op, right: rhs_right } = &right.kind
918            && rhs_left.var() == Some(idx)
919        {
920            let compound_op = match rhs_op {
921                BinaryOp::Add => Some(BinaryOp::AddAssign),
922                BinaryOp::Sub => Some(BinaryOp::SubAssign),
923                BinaryOp::Mul => Some(BinaryOp::MulAssign),
924                BinaryOp::Div => Some(BinaryOp::DivAssign),
925                BinaryOp::Mod => Some(BinaryOp::ModAssign),
926                BinaryOp::Shl => Some(BinaryOp::ShlAssign),
927                BinaryOp::Shr => Some(BinaryOp::ShrAssign),
928                BinaryOp::BitAnd => Some(BinaryOp::BitAndAssign),
929                BinaryOp::BitOr => Some(BinaryOp::BitOrAssign),
930                BinaryOp::BitXor => Some(BinaryOp::BitXorAssign),
931                _ => None,
932            };
933            if let Some(op) = compound_op {
934                return Expr::new(ExprKind::Binary { left: Box::new(left), op, right: Box::new((**rhs_right).clone()) }, span);
935            }
936        }
937        Expr::new(ExprKind::Binary { left: Box::new(left), op, right: Box::new(right) }, span)
938    }
939
940    pub fn top(&self) -> usize {
941        self.frames.last().copied().unwrap_or(0)
942    }
943
944    fn add_name(&mut self, name: SmolStr) -> u32 {
945        self.names.push(name);
946        (self.names.len() - self.top() - 1) as u32
947    }
948
949    fn list_elem_state_for_ty(ty: &Type) -> Option<ListElemState> {
950        match ty {
951            Type::List(elem) if elem.is_any() => Some(ListElemState::Unknown),
952            Type::List(elem) => Some(ListElemState::Known(elem.as_ref().clone())),
953            _ => None,
954        }
955    }
956
957    pub(crate) fn list_elem_state(&self, idx: u32) -> Option<ListElemState> {
958        self.list_elem_states.get(self.top() + idx as usize).cloned().flatten()
959    }
960
961    pub(crate) fn set_list_elem_state(&mut self, idx: u32, state: Option<ListElemState>) {
962        let pos = idx as usize + self.top();
963        if self.list_elem_states.len() <= pos {
964            self.list_elem_states.resize(pos + 1, None);
965        }
966        self.list_elem_states[pos] = state;
967    }
968
969    fn add_ty(&mut self, ty: Type) -> u32 {
970        self.list_elem_states.push(Self::list_elem_state_for_ty(&ty));
971        self.tys.push(ty);
972        (self.tys.len() - self.top() - 1) as u32
973    }
974
975    /// 分配一个匿名临时变量槽,同时 push `names` 和 `tys` 保持对齐。
976    ///
977    /// `names` 和 `tys` 共享 slot 编号空间(都按 `len - top - 1` 算 idx,VM 侧
978    /// `BuildContext::vars` 也按同一 idx 索引)。`compile_fn` 里每个形参走
979    /// `add_name` + `add_ty` 配对保持两者同步;但临时变量如果只调 `add_ty`
980    /// 就会让 `names` 落后一格,后续 `add_name` 分到的 slot 会撞上之前的临时槽
981    /// —— 表现为 list/tuple 解构的临时数组槽被后续 `let` 复用,JIT verifier
982    /// 报 "invalid pointer width"。临时变量一律走这个入口。
983    fn add_temp(&mut self, ty: Type) -> u32 {
984        self.names.push(SmolStr::new_static(""));
985        self.list_elem_states.push(Self::list_elem_state_for_ty(&ty));
986        self.tys.push(ty);
987        (self.tys.len() - self.top() - 1) as u32
988    }
989
990    fn set_ty(&mut self, idx: u32, ty: Type) {
991        let pos = idx as usize + self.top();
992        if self.list_elem_states.len() <= pos {
993            self.list_elem_states.resize(pos + 1, None);
994        }
995        self.list_elem_states[pos] = Self::list_elem_state_for_ty(&ty);
996        if pos < self.tys.len() {
997            self.tys[pos] = ty;
998        } else if pos == self.tys.len() {
999            self.tys.push(ty);
1000        } else {
1001            self.tys.resize(pos + 1, Type::Any);
1002            self.tys[pos] = ty;
1003        }
1004    }
1005
1006    pub fn add_symbol(&mut self, name: &str, s: Symbol) -> u32 {
1007        self.symbols.add(name.into(), s)
1008    }
1009
1010    pub fn new() -> Self {
1011        let symbols = SymbolTable::default();
1012        Self {
1013            symbols,
1014            tys: Vec::new(),
1015            names: Vec::new(),
1016            consts: IndexMap::with_capacity(10240),
1017            frames: Vec::new(),
1018            list_elem_states: Vec::new(),
1019            arg_counts: Vec::new(),
1020            fns: BTreeMap::new(),
1021            local_type_hints: BTreeMap::new(),
1022            infer_stack: Vec::new(),
1023            importing_paths: BTreeSet::new(),
1024            source_files: BTreeMap::new(),
1025        }
1026    }
1027
1028    fn byte_to_line_col(src: &[u8], pos: usize) -> (usize, usize) {
1029        let mut line = 1;
1030        let mut col = 1;
1031        for &b in src.iter().take(pos.min(src.len())) {
1032            if b == b'\n' {
1033                line += 1;
1034                col = 1;
1035            } else {
1036                col += 1;
1037            }
1038        }
1039        (line, col)
1040    }
1041
1042    fn line_snippet(code: &[u8], span: Span) -> String {
1043        let pos = span.start.min(code.len());
1044        let line_start = code[..pos].iter().rposition(|&b| b == b'\n').map(|idx| idx + 1).unwrap_or(0);
1045        let line_end = code[pos..].iter().position(|&b| b == b'\n').map(|idx| pos + idx).unwrap_or(code.len());
1046        String::from_utf8_lossy(&code[line_start..line_end]).into_owned()
1047    }
1048
1049    fn semantic_error(span: Span, message: impl Into<String>) -> anyhow::Error {
1050        SpannedCompilerError { message: message.into(), span }.into()
1051    }
1052
1053    fn format_compile_error(code: &[u8], err: anyhow::Error) -> anyhow::Error {
1054        if let Some(err) = err.downcast_ref::<SpannedCompilerError>() {
1055            return Self::format_span_error(code, err.span, &err.message);
1056        }
1057        if let Some(err) = err.downcast_ref::<parser::ParserErr>() {
1058            return Self::format_span_error(code, err.span(), err.message());
1059        }
1060        if let Some(err) = err.downcast_ref::<parser::SpannedParseError>() {
1061            let pos = err.pos.min(code.len());
1062            let (line, col) = Self::byte_to_line_col(code, pos);
1063            let snippet = Self::line_snippet(code, Span::new(pos, pos));
1064            return anyhow!("解析错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{}\n{}", err.err, snippet);
1065        }
1066        err
1067    }
1068
1069    fn format_span_error(code: &[u8], span: Span, message: &str) -> anyhow::Error {
1070        let pos = span.start.min(code.len());
1071        let (line, col) = Self::byte_to_line_col(code, pos);
1072        let snippet = Self::line_snippet(code, span);
1073        anyhow!("语义错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{}\n{}", message, snippet)
1074    }
1075
1076    pub fn format_source_span(&self, fn_name: &str, span: Span, message: &str) -> String {
1077        let module = fn_name.split_once("::").map(|(module, _)| module).unwrap_or(fn_name);
1078        let Some(source) = self.source_files.get(module) else {
1079            return format!("{fn_name}: 字节偏移 {}:{message}", span.start);
1080        };
1081        let code = source.code.as_ref();
1082        let pos = span.start.min(code.len());
1083        let (line, col) = Self::byte_to_line_col(code, pos);
1084        let snippet = Self::line_snippet(code, span);
1085        let location = source.path.as_ref().map(|path| path.display().to_string()).unwrap_or_else(|| module.to_string());
1086        format!("{location}:{line}:{col}: {message}\n{snippet}")
1087    }
1088
1089    pub fn parse_code(code: Vec<u8>) -> Result<Vec<Stmt>> {
1090        let mut p = Parser::new(code.clone());
1091        let mut stmts = Vec::new();
1092        loop {
1093            match p.stmt(false) {
1094                Ok(stmt) => stmts.push(stmt),
1095                Err(e) => {
1096                    if p.is_eof() {
1097                        return Ok(stmts);
1098                    }
1099                    // 优先用 SpannedParseError / ParserErr 拿精确 pos;
1100                    // 取不到时(老接口 Err 链)fallback 到当前位置。
1101                    let pos = e.downcast_ref::<parser::SpannedParseError>().map(|s| s.pos).or_else(|| e.downcast_ref::<parser::ParserErr>().map(|s| s.span().start)).unwrap_or_else(|| p.current_pos());
1102                    let (line, col) = Self::byte_to_line_col(&code, pos);
1103                    return Err(anyhow!("解析错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{e:#}\n{}", p.error_stmt()));
1104                }
1105            }
1106        }
1107    }
1108
1109    pub fn parse_source(source: &str) -> Result<Vec<Stmt>> {
1110        Self::parse_code(source.as_bytes().to_vec())
1111    }
1112
1113    pub fn import_code(&mut self, name: &str, code: Vec<u8>) -> Result<Vec<u32>> {
1114        self.import_code_with_source(name, code, None, None)
1115    }
1116
1117    pub fn import_source(&mut self, name: &str, source: &str) -> Result<Vec<u32>> {
1118        self.import_code(name, source.as_bytes().to_vec())
1119    }
1120
1121    pub fn import_code_from_path(&mut self, name: &str, code: Vec<u8>, path: impl AsRef<Path>) -> Result<Vec<u32>> {
1122        let path = path.as_ref();
1123        self.import_code_with_source(name, code, path.parent(), Some(path))
1124    }
1125
1126    pub fn import_file(&mut self, name: &str, path: impl AsRef<Path>) -> Result<Vec<u32>> {
1127        let path = path.as_ref();
1128        let canonical = std::fs::canonicalize(path).with_context(|| format!("failed to resolve import path {}", path.display()))?;
1129        if !self.importing_paths.insert(canonical.clone()) {
1130            return Ok(Vec::new());
1131        }
1132        let code = std::fs::read(&canonical).with_context(|| format!("failed to read import path {}", canonical.display()))?;
1133        let result = self.import_code_from_path(name, code, &canonical);
1134        self.importing_paths.remove(&canonical);
1135        result
1136    }
1137
1138    fn import_code_with_source(&mut self, name: &str, code: Vec<u8>, base_dir: Option<&Path>, source_path: Option<&Path>) -> Result<Vec<u32>> {
1139        self.source_files.insert(name.into(), SourceFile { path: source_path.map(Path::to_path_buf), code: Arc::new(code.clone()) });
1140        let stmts = Self::parse_code(code.clone())?;
1141        log::debug!("func->{}", name);
1142        for s in stmts.iter() {
1143            log::debug!("{}", s);
1144        }
1145        self.resolve_imports(&stmts, base_dir).map_err(|err| Self::format_compile_error(&code, err))?;
1146        self.clear();
1147        self.compile(name.into(), stmts).map_err(|err| Self::format_compile_error(&code, err))
1148    }
1149
1150    pub fn resolve_imports(&mut self, stmts: &[Stmt], base_dir: Option<&Path>) -> Result<()> {
1151        for stmt in stmts {
1152            let Some((module, path)) = import_decl(stmt) else {
1153                continue;
1154            };
1155            if !self.symbols.symbol(module.as_str()).is_empty() {
1156                continue;
1157            }
1158            let path = Path::new(path.as_str());
1159            let resolved = if path.is_absolute() {
1160                path.to_path_buf()
1161            } else if let Some(base_dir) = base_dir {
1162                base_dir.join(path)
1163            } else {
1164                std::env::current_dir()?.join(path)
1165            };
1166            self.import_file(module.as_str(), &resolved).with_context(|| format!("failed to import {module} from {}", resolved.display()))?;
1167        }
1168        Ok(())
1169    }
1170
1171    pub fn check_code(name: &str, code: Vec<u8>) -> Vec<CompilerDiagnostic> {
1172        let mut parser = Parser::new(code.clone());
1173        let mut stmts = Vec::new();
1174        loop {
1175            match parser.stmt(false) {
1176                Ok(stmt) => stmts.push(stmt),
1177                Err(err) => {
1178                    if parser.is_eof() {
1179                        break;
1180                    }
1181                    return vec![CompilerDiagnostic { message: format!("解析错误:{err:#}"), span: Span::empty(parser.current_pos()) }];
1182                }
1183            }
1184        }
1185
1186        let mut compiler = Self::new();
1187        compiler.clear();
1188        match compiler.compile(name.into(), stmts) {
1189            Ok(_) => Vec::new(),
1190            Err(err) => {
1191                if let Some(err) = err.downcast_ref::<SpannedCompilerError>() {
1192                    vec![CompilerDiagnostic { message: err.message.clone(), span: err.span }]
1193                } else {
1194                    vec![CompilerDiagnostic { message: format!("{err:#}"), span: Span::default() }]
1195                }
1196            }
1197        }
1198    }
1199
1200    pub fn get_field(&self, ty: &Type, name: &str) -> Result<(usize, Type)> {
1201        self.symbols.get_field(ty, name)
1202    }
1203
1204    pub fn get_ident(&mut self, ident: &str, span: Span) -> Result<Expr> {
1205        for idx in (self.top()..self.names.len()).rev() {
1206            if self.names[idx].eq(ident) {
1207                return Ok(Expr::new(ExprKind::Var((idx - self.top()) as u32), span));
1208            }
1209        }
1210        let id = self.symbols.get_id(ident).map_err(|_| Self::semantic_error(span, format!("未找到标识符 {}", ident)))?;
1211        let s = self.symbols.get_symbol(id).map(|(_, v)| v.clone()).unwrap();
1212        if let Symbol::Const { value, ty, .. } = s {
1213            let c = self.get_const(value);
1214            return Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Const(c), span)), ty }, span));
1215        } else if let Symbol::Static { value, ty, .. } = s
1216            && let Some(v) = value
1217        {
1218            let c = self.get_const(v);
1219            return Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Const(c), span)), ty }, span));
1220        }
1221        Ok(Expr::new(ExprKind::Id(id, None), span))
1222    }
1223
1224    fn field_access_expr(&mut self, left: Expr, idx: usize, ty: Type, key: &str, span: Span) -> Expr {
1225        if let Type::Symbol { id, .. } = ty {
1226            Expr::new(ExprKind::Id(id, Some(Box::new(left))), span)
1227        } else if ty.is_bool() && idx == usize::MAX {
1228            Expr::new(ExprKind::Value(Dynamic::Bool(false)), span)
1229        } else if ty.is_any() && idx == usize::MAX {
1230            let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(key.into()))), span);
1231            Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, span)
1232        } else {
1233            Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(Expr::new(ExprKind::Value(Dynamic::U32(idx as u32)), span)) }, span)
1234        }
1235    }
1236
1237    fn literal_field_access_expr(&mut self, left: Expr, key: &str, span: Span) -> Expr {
1238        let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(key.into()))), span);
1239        Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, span)
1240    }
1241
1242    fn type_field_access_expr(&mut self, left: Expr, key: &str, span: Span, prefer_dynamic_field: bool) -> Option<Expr> {
1243        let ty = self.infer_expr(&left).ok()?;
1244        if prefer_dynamic_field && ty.is_any() {
1245            return Some(self.literal_field_access_expr(left, key, span));
1246        }
1247        let (idx, field_ty) = self.get_field(&ty, key).ok()?;
1248        Some(self.field_access_expr(left, idx, field_ty, key, span))
1249    }
1250
1251    fn global_method_access_expr(&self, left: Expr, method: &str, span: Span) -> Result<Option<Expr>> {
1252        let Ok(id) = self.symbols.get_id(method) else {
1253            return Ok(None);
1254        };
1255        if self.symbols.get_symbol(id)?.1.is_fn() { Ok(Some(Expr::new(ExprKind::Id(id, Some(Box::new(left))), span))) } else { Ok(None) }
1256    }
1257
1258    fn method_call_obj_expr(&mut self, obj: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Option<Expr>> {
1259        if let ExprKind::TypedMethod { obj: left, ty, name } = &obj.kind {
1260            let left = self.eval(left, stmts, cap)?;
1261            let base_name = match ty {
1262                Type::Ident { name, .. } => name.clone(),
1263                Type::Symbol { id, .. } => self.symbols.get_symbol(*id)?.0.clone(),
1264                _ => return Err(Self::semantic_error(obj.span, format!("方法调用类型提示必须是类型: {:?}", ty))),
1265            };
1266            let method = format!("{}::{}", base_name, name);
1267            let id = self.symbols.get_id(&method).map_err(|_| Self::semantic_error(obj.span, format!("未找到类型方法 {}", method)))?;
1268            return Ok(Some(Expr::new(ExprKind::Id(id, Some(Box::new(left))), obj.span)));
1269        }
1270
1271        let ExprKind::Binary { left, op: BinaryOp::Idx, right } = &obj.kind else {
1272            return Ok(None);
1273        };
1274        let Some(method) = self.get_value(right).and_then(|v| if v.is_str() { Some(v.as_str().to_string()) } else { None }) else {
1275            return Ok(None);
1276        };
1277        let left = self.eval(left, stmts, cap)?;
1278        if let Some(field) = self.type_field_access_expr(left.clone(), &method, obj.span, false) {
1279            return Ok(Some(field));
1280        }
1281        if let Some(method_fn) = self.global_method_access_expr(left.clone(), &method, obj.span)? {
1282            return Ok(Some(method_fn));
1283        }
1284        Ok(Some(self.literal_field_access_expr(left, &method, obj.span)))
1285    }
1286
1287    pub fn compile_fn(&mut self, args: &[SmolStr], tys: &mut Vec<Type>, body: Stmt, cap: &mut Capture) -> Result<Vec<Stmt>> {
1288        let top = self.tys.len();
1289        self.frames.push(top);
1290        self.arg_counts.push(args.len());
1291        let result = (|| -> Result<Vec<Stmt>> {
1292            for (arg, ty) in args.iter().zip(tys.iter_mut()) {
1293                *ty = self.symbols.get_type(ty)?;
1294                self.add_name(arg.clone());
1295                self.add_ty(ty.clone());
1296            }
1297            if cap.names.is_empty() && tys.iter().all(|ty| !ty.is_any()) {
1298                let saved_state = (self.frames.clone(), self.names.clone(), self.tys.clone(), self.list_elem_states.clone(), self.arg_counts.clone());
1299                let result = self.check_return_type(&body);
1300                self.restore_local_state(saved_state);
1301                result?;
1302            }
1303            let mut compiled = Vec::new();
1304            self.compile_stmt(body, &mut compiled, cap)?;
1305            if !compiled.last_mut().map(|stmt| stmt.last_return()).unwrap_or(false) {
1306                compiled.push(Stmt::new(StmtKind::Return(None), Span::default()));
1307            }
1308            Ok(compiled)
1309        })();
1310        if let Some(top) = self.frames.pop() {
1311            self.tys.truncate(top);
1312            self.names.truncate(top);
1313            self.list_elem_states.truncate(top);
1314        }
1315        self.arg_counts.pop();
1316        result
1317    }
1318
1319    pub fn compile(&mut self, mod_name: SmolStr, stmts: Vec<Stmt>) -> Result<Vec<u32>> {
1320        self.symbols.add_module(mod_name.clone());
1321        for stmt in stmts {
1322            match stmt.kind {
1323                StmtKind::Struct { name, def, is_pub } => {
1324                    self.symbols.add(name, Symbol::Struct(def, is_pub));
1325                }
1326                StmtKind::Static { name, ty, value, is_pub } => {
1327                    let value = value.map(|value| self.const_expr_value(&value)).transpose()?;
1328                    self.symbols.add(name, Symbol::Static { value, ty, is_pub });
1329                }
1330                StmtKind::Const { name, ty, value, is_pub } => {
1331                    let value = self.const_expr_value(&value)?;
1332                    let ty = if ty.is_any() { value.get_type() } else { ty };
1333                    self.symbols.add(name, Symbol::Const { value, ty, is_pub });
1334                }
1335                StmtKind::Fn { name, generic_params, args, body, is_pub } => {
1336                    let (ty, args) = Type::from_args(args);
1337                    self.symbols.add(name, Symbol::Fn { ty, args, generic_params, cap: Capture::default(), body: Arc::new(*body), is_pub });
1338                }
1339                StmtKind::Impl { target, body } => {
1340                    let name = impl_target_name(&target)?;
1341                    let def_id = match self.symbols.get_id(&name) {
1342                        Ok(id) => id,
1343                        Err(_) if name.as_str() == "Vec" => self.symbols.add(name.clone(), Symbol::Struct(Type::Struct { params: Vec::new(), fields: Vec::new() }, true)),
1344                        Err(err) => return Err(err),
1345                    };
1346                    if let StmtKind::Block(fns) = body.kind {
1347                        for f in fns {
1348                            if let StmtKind::Fn { name: fn_name, generic_params: fn_generic_params, args, body, is_pub } = f.kind {
1349                                let (ty, args) = Type::from_args(args);
1350                                let mut generic_params = if has_unresolved_generic_param(&target) {
1351                                    match &target {
1352                                        Type::Ident { params, .. } => params.clone(),
1353                                        _ => Vec::new(),
1354                                    }
1355                                } else {
1356                                    Vec::new()
1357                                };
1358                                for param in fn_generic_params {
1359                                    if !generic_params.contains(&param) {
1360                                        generic_params.push(param);
1361                                    }
1362                                }
1363                                let fn_id = self.symbols.add(SmolStr::from(format!("{}::{}", name, fn_name)), Symbol::Fn { ty, args, generic_params, cap: Capture::default(), body: Arc::new(*body), is_pub });
1364                                if let Symbol::Struct(ty, _) = &mut self.symbols.symbols[def_id as usize] {
1365                                    ty.add_field(fn_name.into(), Type::Symbol { id: fn_id, params: Vec::new() })?;
1366                                }
1367                            } else {
1368                                log::debug!("impl 包含非函数语句 {:?}", f);
1369                            }
1370                        }
1371                    }
1372                }
1373                StmtKind::Expr(expr, _) if is_top_level_import_expr(&expr) => {}
1374                _ => return Err(Self::semantic_error(stmt.span, format!("不支持的顶层语句: {:?}", stmt.kind))),
1375            }
1376        }
1377        let mut fn_ids = Vec::new();
1378        for (name, id) in self.symbols.symbol(&mod_name) {
1379            log::debug!("compile symbol {:?}[{}]", name, id);
1380            if let Some((_, Symbol::Fn { ty, generic_params, .. })) = self.symbols.get_symbol(id).ok() {
1381                let resolved_ty = self.symbols.get_type(ty).unwrap_or_else(|_| ty.clone());
1382                if has_unresolved_generic_param(&resolved_ty) || !generic_params.is_empty() {
1383                    continue;
1384                }
1385            }
1386            if let Some(s) = self.symbols.get_symbol(id).ok().map(|(_, symbol)| symbol.clone()) {
1387                if let Symbol::Fn { ty, args, generic_params, mut cap, body, is_pub } = s {
1388                    if let Type::Fn { mut tys, ret } = ty {
1389                        let compiled = self.compile_fn(&args, &mut tys, body.as_ref().clone(), &mut cap)?;
1390                        for s in compiled.iter() {
1391                            log::debug!("{}", s);
1392                        }
1393                        self.symbols.symbols[id as usize] = Symbol::Fn { ty: Type::Fn { tys, ret }, args, generic_params, cap, body: Arc::new(Stmt::new(StmtKind::Block(compiled), Span::default())), is_pub };
1394                        fn_ids.push(id);
1395                    }
1396                }
1397            }
1398        }
1399        self.symbols.pop_module();
1400        Ok(fn_ids)
1401    }
1402
1403    fn pat_to_var(&mut self, pat: Pattern, expr_ty: Type) -> Result<Pattern> {
1404        match pat.kind {
1405            PatternKind::Var { idx, ty } => Ok(Pattern { kind: PatternKind::Var { idx, ty }, span: pat.span }),
1406            PatternKind::Ident { name, ty } => {
1407                let ty = self.symbols.get_type(&ty)?;
1408                let ty = if ty.is_any() { expr_ty } else { ty };
1409                self.add_ty(ty.clone());
1410                Ok(Pattern { kind: PatternKind::Var { idx: self.add_name(name), ty }, span: pat.span })
1411            }
1412            PatternKind::Tuple(pats) => {
1413                if let Type::Tuple(tys) = &expr_ty {
1414                    if pats.len() != tys.len() {
1415                        return Err(Self::semantic_error(pat.span, format!("模式与元组类型不匹配: {:?}", expr_ty)));
1416                    }
1417                    let pats: Vec<Pattern> = pats.into_iter().zip(tys).map(|p| self.pat_to_var(p.0, p.1.clone())).collect::<Result<_>>()?;
1418                    Ok(Pattern { kind: PatternKind::Tuple(pats), span: pat.span })
1419                } else if expr_ty.is_any() {
1420                    let pats = pats.into_iter().map(|p| self.pat_to_var(p, Type::Any)).collect::<Result<_>>()?;
1421                    Ok(Pattern { kind: PatternKind::Tuple(pats), span: pat.span })
1422                } else {
1423                    Err(Self::semantic_error(pat.span, format!("元组模式 {:?} 与类型 {:?} 不匹配", pats, expr_ty)))
1424                }
1425            }
1426            PatternKind::List { elems, has_rest } => {
1427                if expr_ty.is_any() {
1428                    let elems: Vec<Pattern> = elems.into_iter().map(|p| self.pat_to_var(p, Type::Any)).collect::<Result<_>>()?;
1429                    Ok(Pattern { kind: PatternKind::List { elems, has_rest }, span: pat.span })
1430                } else if let Type::List(elem_ty) | Type::Array(elem_ty, _) | Type::Vec(elem_ty, _) = &expr_ty {
1431                    let elems: Vec<Pattern> = elems.into_iter().map(|p| self.pat_to_var(p, elem_ty.as_ref().clone())).collect::<Result<_>>()?;
1432                    Ok(Pattern { kind: PatternKind::List { elems, has_rest }, span: pat.span })
1433                } else {
1434                    Err(Self::semantic_error(pat.span, format!("列表模式 {:?} 与类型 {:?} 不匹配", elems, expr_ty)))
1435                }
1436            }
1437            PatternKind::Wildcard => {
1438                self.add_ty(expr_ty.clone());
1439                Ok(Pattern { kind: PatternKind::Var { idx: self.add_name(SmolStr::new_static("")), ty: expr_ty }, span: pat.span })
1440            }
1441            _ => Err(Self::semantic_error(pat.span, format!("未知的模式 {:?}", pat))),
1442        }
1443    }
1444
1445    fn infer_range_type(&self, range: &Expr) -> Type {
1446        if let ExprKind::Range { start, stop, .. } = &range.kind {
1447            let start_ty = start.get_type();
1448            let stop_ty = stop.get_type();
1449            if start_ty.is_any() {
1450                stop_ty
1451            } else if stop_ty.is_any() {
1452                start_ty
1453            } else if start_ty == Type::I32 && stop_ty.is_uint() {
1454                stop_ty
1455            } else if stop_ty == Type::I32 && start_ty.is_uint() {
1456                start_ty
1457            } else {
1458                start_ty + stop_ty
1459            }
1460        } else {
1461            range.get_type()
1462        }
1463    }
1464
1465    fn dyn_init(&mut self, expr: Expr, stmts: &mut Vec<Stmt>, items: Vec<(Expr, Expr)>, ty: Type) -> Expr {
1466        self.add_name("".into());
1467        let temp = self.add_ty(ty);
1468        let span = expr.span;
1469        stmts.push(Stmt::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(Expr::new(ExprKind::Var(temp), span)), op: BinaryOp::Assign, right: Box::new(expr) }, span), true), span));
1470        for (idx, item) in items {
1471            let item_span = idx.span.merge(item.span);
1472            let left = Expr::new(ExprKind::Binary { left: Box::new(Expr::new(ExprKind::Var(temp), item_span)), op: BinaryOp::Idx, right: Box::new(idx) }, item_span);
1473            stmts.push(Stmt::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Assign, right: Box::new(item) }, item_span), true), item_span));
1474        }
1475        Expr::new(ExprKind::Var(temp), span)
1476    }
1477
1478    fn is_spawn_closure_call(obj: &Expr, params: &[Expr]) -> bool {
1479        params.len() == 2 && matches!(&obj.kind, ExprKind::Ident(name) if name.as_str() == "spawn") && matches!(&params[0].kind, ExprKind::Closure { .. })
1480    }
1481
1482    fn eval_spawn_arg_pack(&mut self, expr: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Expr> {
1483        match &expr.kind {
1484            ExprKind::Tuple(items) | ExprKind::List(items) => Ok(Expr::new(ExprKind::Tuple(items.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?), expr.span)),
1485            _ => Err(Self::semantic_error(expr.span, "spawn closure args must be tuple")),
1486        }
1487    }
1488
1489    fn is_multi_assign_target(expr: &Expr) -> bool {
1490        matches!(expr.kind, ExprKind::Tuple(_) | ExprKind::List(_))
1491    }
1492
1493    fn push_assign(stmts: &mut Vec<Stmt>, left: Expr, right: Expr, span: Span) {
1494        stmts.push(Stmt::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Assign, right: Box::new(right) }, span), true), span));
1495    }
1496
1497    fn temp_var(&mut self, ty: Type, span: Span) -> Expr {
1498        self.add_name("".into());
1499        let idx = self.add_ty(ty);
1500        Expr::new(ExprKind::Var(idx), span)
1501    }
1502
1503    fn typed_expr(value: Expr, ty: &Type) -> Expr {
1504        if ty.is_any() {
1505            value
1506        } else {
1507            let span = value.span;
1508            Expr::new(ExprKind::Typed { value: Box::new(value), ty: ty.clone() }, span)
1509        }
1510    }
1511
1512    fn lower_multi_assign(&mut self, left: &Expr, right: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture, span: Span) -> Result<Expr> {
1513        let left_items = match &left.kind {
1514            ExprKind::Tuple(items) | ExprKind::List(items) => items,
1515            _ => return Err(Self::semantic_error(left.span, "多重赋值左侧必须是 tuple 或 list")),
1516        };
1517        if left_items.is_empty() {
1518            return Err(Self::semantic_error(left.span, "多重赋值左侧不能为空"));
1519        }
1520
1521        let mut temps = Vec::with_capacity(left_items.len());
1522        if let ExprKind::Tuple(right_items) | ExprKind::List(right_items) = &right.kind {
1523            if left_items.len() != right_items.len() {
1524                return Err(Self::semantic_error(span, format!("多重赋值数量不匹配: 左侧 {} 个,右侧 {} 个", left_items.len(), right_items.len())));
1525            }
1526            for item in right_items {
1527                let value = self.eval(item, stmts, cap)?;
1528                let ty = self.infer_expr(&value)?;
1529                let temp = self.temp_var(ty.clone(), item.span);
1530                Self::push_assign(stmts, temp.clone(), Self::typed_expr(value, &ty), item.span);
1531                temps.push((temp, ty));
1532            }
1533        } else {
1534            let value = self.eval(right, stmts, cap)?;
1535            let ty = self.infer_expr(&value)?;
1536            let source = self.temp_var(ty.clone(), right.span);
1537            Self::push_assign(stmts, source.clone(), Self::typed_expr(value, &ty), right.span);
1538            for idx in 0..left_items.len() {
1539                let item_span = left_items[idx].span;
1540                let item = Expr::new(ExprKind::Binary { left: Box::new(source.clone()), op: BinaryOp::Idx, right: Box::new(Expr::new(ExprKind::Value((idx as u32).into()), item_span)) }, item_span);
1541                let value = self.eval(&item, stmts, cap)?;
1542                let ty = self.infer_expr(&value)?;
1543                let temp = self.temp_var(ty.clone(), item_span);
1544                Self::push_assign(stmts, temp.clone(), Self::typed_expr(value, &ty), item_span);
1545                temps.push((temp, ty));
1546            }
1547        }
1548
1549        for (target, (temp, ty)) in left_items.iter().zip(temps.iter()) {
1550            let target = self.eval(target, stmts, cap)?;
1551            let assign_span = target.span.merge(temp.span);
1552            Self::push_assign(stmts, target, Self::typed_expr(temp.clone(), ty), assign_span);
1553        }
1554
1555        Ok(temps.last().map(|(temp, ty)| Self::typed_expr(temp.clone(), ty)).unwrap_or_else(|| Expr::new(ExprKind::Value(Dynamic::Null), span)))
1556    }
1557
1558    fn static_composite_literal(&self, expr: &Expr) -> Result<Option<Dynamic>> {
1559        match &expr.kind {
1560            ExprKind::List(items) | ExprKind::Tuple(items) => {
1561                let mut values = Vec::with_capacity(items.len());
1562                for item in items {
1563                    let Some(value) = self.static_literal_value(item)? else {
1564                        return Ok(None);
1565                    };
1566                    values.push(value);
1567                }
1568                Ok(Some(Dynamic::list(values)))
1569            }
1570            ExprKind::Dict(items) => {
1571                let mut values = BTreeMap::new();
1572                for (key, item) in items {
1573                    let Some(value) = self.static_literal_value(item)? else {
1574                        return Ok(None);
1575                    };
1576                    values.insert(key.clone(), value);
1577                }
1578                Ok(Some(Dynamic::map(values)))
1579            }
1580            _ => Ok(None),
1581        }
1582    }
1583
1584    fn static_literal_value(&self, expr: &Expr) -> Result<Option<Dynamic>> {
1585        match &expr.kind {
1586            ExprKind::Value(value) => Ok(Some(value.clone())),
1587            ExprKind::Const(idx) => Ok(self.consts.get_index(*idx).map(|(_, v)| v.clone())),
1588            ExprKind::Typed { value, ty } if ty.is_native() => Ok(self.static_literal_value(value)?.map(|value| ty.force(value)).transpose()?),
1589            _ => self.static_composite_literal(expr),
1590        }
1591    }
1592
1593    fn const_expr_value(&self, expr: &Expr) -> Result<Dynamic> {
1594        match &expr.kind {
1595            ExprKind::Value(value) => Ok(value.clone()),
1596            ExprKind::Const(idx) => self.consts.get_index(*idx).map(|(_, v)| v.clone()).ok_or_else(|| Self::semantic_error(expr.span, format!("常量索引 {} 不存在", idx))),
1597            ExprKind::Ident(ident) => {
1598                let id = self.symbols.get_id(ident).map_err(|_| Self::semantic_error(expr.span, format!("未找到常量 {}", ident)))?;
1599                match self.symbols.get_symbol(id).map(|(_, symbol)| symbol) {
1600                    Ok(Symbol::Const { value, .. }) => Ok(value.clone()),
1601                    Ok(Symbol::Static { value: Some(value), .. }) => Ok(value.clone()),
1602                    _ => Err(Self::semantic_error(expr.span, format!("{} 不是可用于 const 的静态值", ident))),
1603                }
1604            }
1605            ExprKind::Typed { value, ty } if ty.is_native() => Ok(ty.force(self.const_expr_value(value)?)?),
1606            ExprKind::Typed { value, .. } => self.const_expr_value(value),
1607            ExprKind::List(items) | ExprKind::Tuple(items) => {
1608                let values = items.iter().map(|item| self.const_expr_value(item)).collect::<Result<Vec<_>>>()?;
1609                Ok(Dynamic::list(values))
1610            }
1611            ExprKind::Dict(items) => {
1612                let mut values = BTreeMap::new();
1613                for (key, item) in items {
1614                    values.insert(key.clone(), self.const_expr_value(item)?);
1615                }
1616                Ok(Dynamic::map(values))
1617            }
1618            ExprKind::Unary { op, value } => {
1619                let value = self.const_expr_value(value)?;
1620                match op {
1621                    parser::UnaryOp::Neg => Ok(-value),
1622                    parser::UnaryOp::Not => Ok(!value),
1623                    parser::UnaryOp::Unknow => Err(Self::semantic_error(expr.span, "const 一元表达式无法在编译期求值")),
1624                }
1625            }
1626            ExprKind::Binary { left, op, right } => {
1627                let left = Expr::new(ExprKind::Value(self.const_expr_value(left)?), left.span);
1628                let right = Expr::new(ExprKind::Value(self.const_expr_value(right)?), right.span);
1629                Expr::new(ExprKind::Binary { left: Box::new(left), op: op.clone(), right: Box::new(right) }, expr.span).compact().ok_or_else(|| Self::semantic_error(expr.span, "const 二元表达式无法在编译期求值"))
1630            }
1631            _ => Err(Self::semantic_error(expr.span, "const 只能使用字面量、已声明常量和静态 composite literal")),
1632        }
1633    }
1634
1635    fn eval_stmt_expr(&mut self, stmt: &Stmt, stmts: &mut Vec<Stmt>, cap: &mut Capture, span: Span) -> Result<Expr> {
1636        self.compile_stmt(stmt.clone(), stmts, cap)?;
1637        let expr_ty = if let Some(stmt) = stmts.last() { if let StmtKind::Expr(expr, _) = &stmt.kind { self.infer_expr(expr)? } else { self.infer_stmt(stmt)? } } else { Type::Any };
1638        self.add_name("".into());
1639        let temp = self.add_ty(expr_ty.clone());
1640        let pat = Pattern { kind: PatternKind::Var { idx: temp, ty: expr_ty }, span };
1641        stmts.last_mut().ok_or_else(|| Self::semantic_error(span, "没有生成可求值语句表达式")).and_then(|stmt| stmt.bind_pattern(pat))?;
1642        Ok(Expr::new(ExprKind::Var(temp), span))
1643    }
1644
1645    fn eval(&mut self, expr: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Expr> {
1646        match &expr.kind {
1647            ExprKind::Stmt(stmt) => self.eval_stmt_expr(stmt, stmts, cap, expr.span),
1648            ExprKind::Closure { args, body } => {
1649                let (mut names, mut tys): (Vec<SmolStr>, Vec<Type>) = args.clone().into_iter().unzip();
1650                let top = self.top();
1651                let mut cap_vars: Vec<(SmolStr, Type)> = self.names[top..].iter().zip(self.tys[top..].iter()).map(|(n, ty)| (n.clone(), ty.clone())).collect();
1652                let parent_cap_start = cap_vars.len();
1653                cap_vars.extend(cap.names.iter().cloned());
1654                let mut local_cap = Capture::new(cap_vars);
1655                let _ = self.compile_fn(names.as_slice(), &mut tys.clone(), *body.clone(), &mut local_cap)?;
1656                for cap_idx in local_cap.vars.iter() {
1657                    if *cap_idx >= parent_cap_start {
1658                        let _ = cap.get(&local_cap.names[*cap_idx].0);
1659                    }
1660                    names.push(local_cap.names[*cap_idx].0.clone());
1661                    tys.push(local_cap.names[*cap_idx].1.clone());
1662                }
1663                let mut compiled = self.compile_fn(names.as_slice(), &mut tys.clone(), *body.clone(), &mut Capture::default())?;
1664                let (ty, args) = Type::from_args(args.clone());
1665                let body_stmt = if compiled.len() == 1 { compiled.pop().unwrap() } else { Stmt::new(StmtKind::Block(compiled), expr.span) };
1666                let name = SmolStr::from(format!("__closure_{}_{}", expr.span.start, expr.span.end));
1667                let fn_id = self.symbols.add(name, Symbol::Fn { ty, args, generic_params: Vec::new(), cap: local_cap, body: Arc::new(body_stmt), is_pub: false });
1668                Ok(Expr::new(ExprKind::Id(fn_id, None), expr.span))
1669            }
1670            ExprKind::Value(v) => {
1671                if v.is_native() {
1672                    Ok(Expr::new(ExprKind::Value(v.clone()), expr.span))
1673                } else {
1674                    Ok(Expr::new(ExprKind::Const(self.get_const(v.clone())), expr.span))
1675                }
1676            }
1677            ExprKind::Typed { value, ty } => {
1678                let ty = self.symbols.get_type(ty)?;
1679                if let Type::Struct { fields, .. } = &ty
1680                    && let ExprKind::Dict(dict) = &value.kind
1681                {
1682                    let mut items = Vec::new();
1683                    for field in fields {
1684                        if let Some((_, v)) = dict.iter().find(|(name, _)| name == &field.0) {
1685                            items.push(self.eval(v, stmts, cap)?);
1686                        }
1687                    }
1688                    Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty }, expr.span))
1689                } else if let Type::Struct { .. } = &ty
1690                    && let ExprKind::List(list) = &value.kind
1691                {
1692                    let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1693                    Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty }, expr.span))
1694                } else if let Type::Array(elem_ty, _) = &ty
1695                    && let ExprKind::List(list) = &value.kind
1696                {
1697                    let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1698                    Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty: Type::Array(elem_ty.clone(), list.len() as u32) }, expr.span))
1699                } else if let Type::Vec(elem_ty, _) = &ty
1700                    && let ExprKind::List(list) = &value.kind
1701                {
1702                    let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1703                    Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty: Type::Vec(elem_ty.clone(), list.len() as u32) }, expr.span))
1704                } else if let Type::Array(elem_ty, _) | Type::Vec(elem_ty, _) = &ty
1705                    && let ExprKind::Value(Dynamic::List(items)) = &value.kind
1706                {
1707                    // Parser 把字面量 `[1.0, 2.0, ...]` 折成单个 `Dynamic::List`,丢失了
1708                    // 内层 ExprKind::Value 包装。这里按目标元素类型 (`force`) 把每个内层
1709                    // Dynamic 强转回去,并展回 `ExprKind::List` —— GPU 后端只识别后者,
1710                    // CPU JIT 也走相同路径所以语义不变。这条路径覆盖了 `[f32; N]` /
1711                    // `[f64; N]` / `Vec<fXX>` 等所有把无后缀字面量推断成默认 f32 但目标
1712                    // 元素是别的类型的场景。
1713                    let items = items.read();
1714                    let exprs = items
1715                        .iter()
1716                        .map(|v| {
1717                            let coerced = elem_ty.force(v.clone()).unwrap_or_else(|_| v.clone());
1718                            Expr::new(ExprKind::Value(coerced), expr.span)
1719                        })
1720                        .collect::<Vec<_>>();
1721                    let len = exprs.len() as u32;
1722                    let new_ty = match &ty {
1723                        Type::Array(_, _) => Type::Array(elem_ty.clone(), len),
1724                        Type::Vec(_, _) => Type::Vec(elem_ty.clone(), len),
1725                        _ => unreachable!(),
1726                    };
1727                    Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(exprs), expr.span)), ty: new_ty }, expr.span))
1728                } else if value.is_value() {
1729                    let value = value.clone().value()?;
1730                    // 字符串字面量被类型注解为 string 时,当前 VM 没有原生 String 通路,
1731                    // 退化为 Dynamic::String(Any) 行为更稳。这里不再 log warn,因为这条
1732                    // 路径是设计选择,不是 bug。
1733                    if ty.is_str() && value.is_str() { Ok(Expr::new(ExprKind::Const(self.get_const(value)), expr.span)) } else { Ok(Expr::new(ExprKind::Value(ty.force(value)?), expr.span)) }
1734                } else {
1735                    Ok(Expr::new(ExprKind::Typed { value: Box::new(self.eval(value, stmts, cap)?), ty }, expr.span))
1736                }
1737            }
1738            ExprKind::Ident(ident) => {
1739                // 局部变量 → 捕获变量 → 全局符号
1740                for idx in (self.top()..self.names.len()).rev() {
1741                    if self.names[idx].eq(ident) {
1742                        return Ok(Expr::new(ExprKind::Var((idx - self.top()) as u32), expr.span));
1743                    }
1744                }
1745                if let Some(idx) = cap.get(ident) {
1746                    return Ok(Expr::new(ExprKind::Capture(idx as u32), expr.span));
1747                }
1748                self.get_ident(ident, expr.span)
1749            }
1750            ExprKind::Generic { obj, params } => {
1751                let obj = self.eval(obj, stmts, cap)?;
1752                let params = params.iter().map(|param| self.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect();
1753                match obj.kind {
1754                    ExprKind::Id(id, None) | ExprKind::AssocId { id, .. } => Ok(Expr::new(ExprKind::AssocId { id, params }, expr.span)),
1755                    _ => Err(Self::semantic_error(expr.span, format!("范型参数只能用于函数或关联函数调用: {:?}", obj))),
1756                }
1757            }
1758            ExprKind::Assoc { ty, name } => {
1759                let base_name = match ty {
1760                    Type::Ident { name, .. } => name.clone(),
1761                    Type::Symbol { id, .. } => self.symbols.get_symbol(*id)?.0.clone(),
1762                    _ => return Err(Self::semantic_error(expr.span, format!("关联函数目标必须是类型: {:?}", ty))),
1763                };
1764                let id = self.symbols.get_id(&format!("{}::{}", base_name, name)).map_err(|_| Self::semantic_error(expr.span, format!("未找到关联函数 {}::{}", base_name, name)))?;
1765                let params = match ty {
1766                    Type::Ident { params, .. } | Type::Symbol { params, .. } => params.iter().map(|param| self.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect(),
1767                    _ => Vec::new(),
1768                };
1769                Ok(Expr::new(ExprKind::AssocId { id, params }, expr.span))
1770            }
1771            ExprKind::Unary { op, value } => {
1772                let value = Expr::new(ExprKind::Unary { op: op.clone(), value: Box::new(self.eval(value, stmts, cap)?) }, expr.span);
1773                if let Some(v) = value.compact() { Ok(Expr::new(ExprKind::Value(v), expr.span)) } else { Ok(value) }
1774            }
1775            ExprKind::Binary { left, op, right } => {
1776                if *op == BinaryOp::Assign && Self::is_multi_assign_target(left) {
1777                    return self.lower_multi_assign(left, right, stmts, cap, expr.span);
1778                }
1779                let left = self.eval(left, stmts, cap)?;
1780                if *op == BinaryOp::Idx {
1781                    if let Some(key) = self.get_value(right).and_then(|v| if v.is_str() { Some(v.as_str().to_string()) } else { None }) {
1782                        if let Some(field) = self.type_field_access_expr(left.clone(), &key, expr.span, true) {
1783                            return Ok(field);
1784                        }
1785                        return Ok(self.literal_field_access_expr(left, &key, expr.span));
1786                    } else if let Ok(ident) = right.ident() {
1787                        if let Ok(found) = self.get_ident(ident, right.span) {
1788                            return Ok(if let Some(id) = found.id() {
1789                                Expr::new(ExprKind::Id(id, Some(Box::new(left))), expr.span)
1790                            } else {
1791                                Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(found) }, expr.span)
1792                            });
1793                        }
1794                        if let Ok(ty) = self.infer_expr(&left)
1795                            && let Ok((idx, ty)) = self.get_field(&ty, ident)
1796                        {
1797                            return Ok(if let Type::Symbol { id, .. } = ty {
1798                                Expr::new(ExprKind::Id(id, Some(Box::new(left))), expr.span)
1799                            } else if ty.is_bool() && idx == usize::MAX {
1800                                Expr::new(ExprKind::Value(Dynamic::Bool(false)), expr.span)
1801                            } else if ty.is_any() && idx == usize::MAX {
1802                                let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(ident.into()))), expr.span);
1803                                Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, expr.span)
1804                            } else {
1805                                Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(Expr::new(ExprKind::Value(Dynamic::U32(idx as u32)), expr.span)) }, expr.span)
1806                            });
1807                        } else {
1808                            let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(ident.into()))), expr.span);
1809                            return Ok(Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, expr.span));
1810                        }
1811                    }
1812                }
1813                let right = self.eval(right, stmts, cap)?;
1814                let value = Self::normalize_self_assign(left, op.clone(), right, expr.span, self.arg_counts.last().copied().unwrap_or(0));
1815                if let Some(v) = value.compact() { Ok(Expr::new(ExprKind::Value(v), expr.span)) } else { Ok(value) }
1816            }
1817            ExprKind::Call { obj, params } => {
1818                let params: Vec<Expr> = if Self::is_spawn_closure_call(obj, params) {
1819                    vec![self.eval(&params[0], stmts, cap)?, self.eval_spawn_arg_pack(&params[1], stmts, cap)?]
1820                } else {
1821                    params.iter().map(|p| self.eval(p, stmts, cap)).collect::<Result<Vec<_>>>()?
1822                };
1823                let obj_result = if let Some(method_obj) = self.method_call_obj_expr(obj, stmts, cap)? { Ok(method_obj) } else { self.eval(obj, stmts, cap) };
1824                match obj_result {
1825                    Ok(obj) if obj.is_value() && params.is_empty() => Ok(obj),
1826                    Ok(obj) => Ok(Expr::new(ExprKind::Call { obj: Box::new(obj), params }, expr.span)),
1827                    Err(e) => {
1828                        // 严格模式:未注册函数 / 方法调用直接报错,不再用 Symbol::Null 兜底。
1829                        // 隐藏 typo 在生产代码里代价大于修复编译期的便利。
1830                        Err(Self::semantic_error(obj.span, format!("未注册函数 {:?}: {}", obj.kind, e)))
1831                    }
1832                }
1833            }
1834            ExprKind::Range { start, stop, inclusive } => {
1835                let start = Box::new(self.eval(start, stmts, cap)?);
1836                let stop = Box::new(self.eval(stop, stmts, cap)?);
1837                Ok(Expr::new(ExprKind::Range { start, stop, inclusive: *inclusive }, expr.span))
1838            }
1839            ExprKind::List(list) | ExprKind::Tuple(list) => {
1840                if let Some(value) = self.static_composite_literal(expr)? {
1841                    let idx = self.get_const(value);
1842                    return Ok(Expr::new(ExprKind::Const(idx), expr.span));
1843                }
1844                let mut v = Vec::new();
1845                let mut items = Vec::new();
1846                for (idx, item) in list.iter().enumerate() {
1847                    if item.is_value() {
1848                        v.push(item.clone().value().unwrap());
1849                    } else {
1850                        items.push((Expr::new(ExprKind::Value((idx as u32).into()), item.span), self.eval(item, stmts, cap)?));
1851                        v.push(Dynamic::Null);
1852                    }
1853                }
1854                let list = Expr::new(ExprKind::Const(self.get_const(Dynamic::list(v))), expr.span);
1855                Ok(self.dyn_init(list, stmts, items, Type::Any))
1856            }
1857            ExprKind::Repeat { value, len } => {
1858                let len = self.symbols.get_type(len)?;
1859                let Type::ConstInt(len) = len else {
1860                    return Err(Self::semantic_error(expr.span, format!("重复数组长度必须是编译期整数: {:?}", len)));
1861                };
1862                if len < 0 {
1863                    return Err(Self::semantic_error(expr.span, "重复数组长度不能为负数"));
1864                }
1865                Ok(Expr::new(ExprKind::Repeat { value: Box::new(self.eval(value, stmts, cap)?), len: Type::ConstInt(len) }, expr.span))
1866            }
1867            ExprKind::Dict(dict) => {
1868                if let Some(value) = self.static_composite_literal(expr)? {
1869                    let idx = self.get_const(value);
1870                    return Ok(Expr::new(ExprKind::Const(idx), expr.span));
1871                }
1872                let mut dyn_kv = Vec::new();
1873                let mut m = BTreeMap::new();
1874                for (k, v) in dict {
1875                    if v.is_value() {
1876                        m.insert(k.clone(), v.clone().value()?);
1877                    } else {
1878                        let key = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(k.clone()))), v.span);
1879                        dyn_kv.push((key, self.eval(v, stmts, cap)?));
1880                        m.insert(k.clone(), Dynamic::Null);
1881                    }
1882                }
1883                let dict = Expr::new(ExprKind::Const(self.get_const(Dynamic::map(m))), expr.span);
1884                Ok(self.dyn_init(dict, stmts, dyn_kv, Type::Any))
1885            }
1886            ExprKind::Id(_, _) | ExprKind::AssocId { .. } => Ok(expr.clone()),
1887            _ => Ok(expr.clone()),
1888        }
1889    }
1890
1891    fn get_stmt(&mut self, stmt: Stmt, cap: &mut Capture) -> Result<Stmt> {
1892        let span = stmt.span;
1893        let mut stmts = Vec::new();
1894        self.compile_stmt(stmt, &mut stmts, cap)?;
1895        Ok(Stmt::new(StmtKind::Block(stmts), span))
1896    }
1897
1898    fn compile_stmt(&mut self, stmt: Stmt, compiled: &mut Vec<Stmt>, cap: &mut Capture) -> Result<()> {
1899        let stmt_span = stmt.span;
1900        match stmt.kind {
1901            StmtKind::Let { pat, value } => {
1902                let value = *value;
1903                let annotated_ty = if let PatternKind::Ident { ty, .. } = &pat.kind {
1904                    let ty = self.symbols.get_type(ty)?;
1905                    if ty.is_any() { None } else { Some(ty) }
1906                } else {
1907                    None
1908                };
1909                let pattern_expr_ty = if matches!(pat.kind, PatternKind::List { .. } | PatternKind::Tuple(_)) {
1910                    if let StmtKind::Expr(expr, _) = &value.kind { Some(if matches!(expr.kind, ExprKind::List(_) | ExprKind::Tuple(_)) { expr.get_type() } else { self.infer_expr(expr)? }) } else { None }
1911                } else {
1912                    None
1913                };
1914                if let Some(ty) = annotated_ty {
1915                    if let StmtKind::Expr(expr, close) = value.kind {
1916                        let span = expr.span;
1917                        let typed = Expr::new(ExprKind::Typed { value: Box::new(expr), ty }, span);
1918                        self.compile_stmt(Stmt::new(StmtKind::Expr(typed, close), value.span), compiled, cap)?;
1919                    } else {
1920                        self.compile_stmt(value, compiled, cap)?;
1921                    }
1922                } else {
1923                    self.compile_stmt(value, compiled, cap)?;
1924                }
1925                let expr_ty = if let Some(ty) = pattern_expr_ty {
1926                    ty
1927                } else if let Some(stmt) = compiled.last() {
1928                    if let StmtKind::Expr(expr, _) = &stmt.kind { self.infer_expr(expr)? } else { self.infer_stmt(stmt)? }
1929                } else {
1930                    Type::Any
1931                };
1932                let pat = self.pat_to_var(pat, expr_ty.clone())?;
1933                if matches!(pat.kind, PatternKind::Tuple(_) | PatternKind::List { .. }) {
1934                    // list/tuple 解构的 scrutinee 临时槽:必须走 add_temp 同步 push
1935                    // names+tys,否则后续 `let` 的 add_name 会撞上这个临时槽的 idx,
1936                    // 导致 JIT verifier 报 "invalid pointer width"(临时数组槽被 i32 复用)。
1937                    let temp = self.add_temp(expr_ty.clone());
1938                    let temp_pat = Pattern { kind: PatternKind::Var { idx: temp, ty: expr_ty }, span: stmt_span };
1939                    compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "没有生成可绑定模式的编译语句")).and_then(|stmt| stmt.bind_pattern(temp_pat))?;
1940                    let temp_expr = Expr::new(ExprKind::Var(temp), stmt_span);
1941                    compiled.push(Stmt::new(StmtKind::Expr(temp_expr, false), stmt_span));
1942                    compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "临时变量 stmt 缺失")).and_then(|stmt| stmt.bind_pattern(pat))?;
1943                } else {
1944                    compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "没有生成可绑定模式的编译语句")).and_then(|stmt| stmt.bind_pattern(pat))?;
1945                }
1946            }
1947            StmtKind::Expr(expr, close) => {
1948                if let ExprKind::Binary { left, op: BinaryOp::Assign, right } = &expr.kind
1949                    && Self::is_multi_assign_target(left)
1950                {
1951                    self.lower_multi_assign(left, right, compiled, cap, stmt_span)?;
1952                    return Ok(());
1953                }
1954                let e = self.eval(&expr, compiled, cap)?;
1955                compiled.push(Stmt::new(StmtKind::Expr(e, close), stmt_span));
1956            }
1957            StmtKind::Block(stmts) => {
1958                let mut block = Vec::new();
1959                for stmt in stmts {
1960                    self.compile_stmt(stmt, &mut block, cap)?;
1961                }
1962                compiled.push(Stmt::new(StmtKind::Block(block), stmt_span));
1963            }
1964            StmtKind::Fn { name, generic_params, args, body, is_pub } => {
1965                let (ty, args) = Type::from_args(args);
1966                if let Type::Fn { mut tys, ret } = ty {
1967                    let mut fn_cap = Capture::default();
1968                    let compiled_body = self.compile_fn(&args, &mut tys, *body, &mut fn_cap)?;
1969                    self.symbols.add(name, Symbol::Fn { ty: Type::Fn { tys, ret }, args, generic_params, cap: fn_cap, body: Arc::new(Stmt::new(StmtKind::Block(compiled_body), stmt_span)), is_pub });
1970                } else {
1971                    panic!("nested functions are not supported here")
1972                }
1973            }
1974            StmtKind::Return(expr) => {
1975                let expr = expr.map(|e| self.eval(&e, compiled, cap)).transpose()?;
1976                compiled.push(Stmt::new(StmtKind::Return(expr), stmt_span));
1977            }
1978            StmtKind::If { cond, then_body, else_body } => {
1979                let cond = self.eval(&cond, compiled, cap)?;
1980                if let Some(cond_value) = cond.compact()
1981                    && let Some(cond_bool) = cond_value.as_bool()
1982                {
1983                    if cond_bool {
1984                        self.compile_stmt(*then_body, compiled, cap)?;
1985                    } else if let Some(body) = else_body {
1986                        self.compile_stmt(*body, compiled, cap)?;
1987                    }
1988                } else {
1989                    let then_body = Box::new(self.get_stmt(*then_body, cap)?);
1990                    let else_body = if let Some(body) = else_body { Some(Box::new(self.get_stmt(*body, cap)?)) } else { None };
1991                    compiled.push(Stmt::new(StmtKind::If { cond, then_body, else_body }, stmt_span));
1992                }
1993            }
1994            StmtKind::Loop(body) => {
1995                compiled.push(Stmt::new(StmtKind::Loop(Box::new(self.get_stmt(*body, cap)?)), stmt_span));
1996            }
1997            StmtKind::While { cond, body } => {
1998                let cond = self.eval(&cond, compiled, cap)?;
1999                compiled.push(Stmt::new(StmtKind::While { cond, body: Box::new(self.get_stmt(*body, cap)?) }, stmt_span));
2000            }
2001            StmtKind::For { pat, range, body } => {
2002                let range = self.eval(&range, compiled, cap)?;
2003                let range_ty = self.infer_range_type(&range);
2004                let pat = self.pat_to_var(pat, range_ty)?;
2005                compiled.push(Stmt::new(StmtKind::For { pat, range, body: Box::new(self.get_stmt(*body, cap)?) }, stmt_span));
2006            }
2007            stmt_kind => {
2008                compiled.push(Stmt::new(stmt_kind, stmt_span));
2009            }
2010        }
2011        Ok(())
2012    }
2013}