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