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#[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)]
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#[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 pub sym_tab: SymTab,
68 pub type_ctx: TypeCtx,
70 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 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 #[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 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 #[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 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 #[test]
667 fn generic_param_detection_uses_known_set_xyz() {
668 use dynamic::Type;
669 use smol_str::SmolStr;
670
671 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 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 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 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 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
696fn 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 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 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 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 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 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 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 return Ok(stmts);
1246 }
1247 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 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 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 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(¶m) {
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!(¶ms[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 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 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 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(¶ms[0], stmts, cap)?, self.eval_spawn_arg_pack(¶ms[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 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 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 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}