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