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