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 return Ok(Vec::new());
1308 }
1309 let code = std::fs::read(&canonical).with_context(|| format!("failed to read import path {}", canonical.display()))?;
1310 let result = self.import_code_from_path(name, code, &canonical);
1311 self.io.importing_paths.remove(&canonical);
1312 result
1313 }
1314
1315 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>> {
1316 self.io.source_files.insert(name.into(), SourceFile { path: source_path.map(Path::to_path_buf), code: Arc::new(code.clone()) });
1317 let stmts = if strict { Self::parse_code_strict(code.clone())? } else { Self::parse_code(code.clone())? };
1318 log::debug!("func->{}", name);
1319 for s in stmts.iter() {
1320 log::debug!("{}", s);
1321 }
1322 self.resolve_imports(&stmts, base_dir).map_err(|err| Self::format_compile_error(&code, err))?;
1323 self.clear();
1324 self.compile(name.into(), stmts).map_err(|err| Self::format_compile_error(&code, err))
1325 }
1326
1327 pub fn resolve_imports(&mut self, stmts: &[Stmt], base_dir: Option<&Path>) -> Result<()> {
1328 for stmt in stmts {
1329 let Some((module, path)) = import_decl(stmt) else {
1330 continue;
1331 };
1332 if !self.sym_tab.symbols.symbol(module.as_str()).is_empty() {
1333 continue;
1334 }
1335 let path = Path::new(path.as_str());
1336 let resolved = if path.is_absolute() {
1337 path.to_path_buf()
1338 } else if let Some(base_dir) = base_dir {
1339 base_dir.join(path)
1340 } else {
1341 std::env::current_dir()?.join(path)
1342 };
1343 self.import_file(module.as_str(), &resolved).with_context(|| format!("failed to import {module} from {}", resolved.display()))?;
1344 }
1345 Ok(())
1346 }
1347
1348 pub fn check_code(name: &str, code: Vec<u8>) -> Vec<CompilerDiagnostic> {
1349 let mut parser = Parser::new(code.clone());
1350 let mut stmts = Vec::new();
1351 loop {
1352 match parser.stmt(false) {
1353 Ok(stmt) => stmts.push(stmt),
1354 Err(err) => {
1355 if parser.is_eof() {
1356 break;
1357 }
1358 return vec![CompilerDiagnostic { message: format!("解析错误:{err:#}"), span: Span::empty(parser.current_pos()) }];
1359 }
1360 }
1361 }
1362
1363 let mut compiler = Self::new();
1364 compiler.clear();
1365 match compiler.compile(name.into(), stmts) {
1366 Ok(_) => Vec::new(),
1367 Err(err) => {
1368 if let Some(err) = err.downcast_ref::<SpannedCompilerError>() {
1369 vec![CompilerDiagnostic { message: err.message.clone(), span: err.span }]
1370 } else {
1371 vec![CompilerDiagnostic { message: format!("{err:#}"), span: Span::default() }]
1372 }
1373 }
1374 }
1375 }
1376
1377 pub fn get_field(&self, ty: &Type, name: &str) -> Result<(usize, Type)> {
1378 self.sym_tab.symbols.get_field(ty, name)
1379 }
1380
1381 pub fn get_ident(&mut self, ident: &str, span: Span) -> Result<Expr> {
1382 for idx in (self.top()..self.sym_tab.names.len()).rev() {
1383 if self.sym_tab.names[idx].eq(ident) {
1384 return Ok(Expr::new(ExprKind::Var((idx - self.top()) as u32), span));
1385 }
1386 }
1387 let id = self.sym_tab.symbols.get_id(ident).map_err(|_| Self::semantic_error(span, format!("未找到标识符 {}", ident)))?;
1388 let s = self.sym_tab.symbols.get_symbol(id).map(|(_, v)| v.clone()).unwrap();
1389 if let Symbol::Const { value, ty, .. } = s {
1390 let c = self.get_const(value);
1391 return Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Const(c), span)), ty }, span));
1392 } else if let Symbol::Static { value, ty, .. } = s
1393 && let Some(v) = value
1394 {
1395 let c = self.get_const(v);
1396 return Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Const(c), span)), ty }, span));
1397 }
1398 Ok(Expr::new(ExprKind::Id(id, None), span))
1399 }
1400
1401 fn field_access_expr(&mut self, left: Expr, idx: usize, ty: Type, key: &str, span: Span) -> Expr {
1402 if let Type::Symbol { id, .. } = ty {
1403 Expr::new(ExprKind::Id(id, Some(Box::new(left))), span)
1404 } else if ty.is_bool() && idx == usize::MAX {
1405 Expr::new(ExprKind::Value(Dynamic::Bool(false)), span)
1406 } else if ty.is_any() && idx == usize::MAX {
1407 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(key.into()))), span);
1408 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, span)
1409 } else {
1410 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)
1411 }
1412 }
1413
1414 fn literal_field_access_expr(&mut self, left: Expr, key: &str, span: Span) -> Expr {
1415 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(key.into()))), span);
1416 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, span)
1417 }
1418
1419 fn type_field_access_expr(&mut self, left: Expr, key: &str, span: Span, prefer_dynamic_field: bool) -> Option<Expr> {
1420 let ty = self.infer_expr(&left).ok()?;
1421 if prefer_dynamic_field && ty.is_any() {
1422 return Some(self.literal_field_access_expr(left, key, span));
1423 }
1424 let (idx, field_ty) = self.get_field(&ty, key).ok()?;
1425 Some(self.field_access_expr(left, idx, field_ty, key, span))
1426 }
1427
1428 fn global_method_access_expr(&self, left: Expr, method: &str, span: Span) -> Result<Option<Expr>> {
1429 let Ok(id) = self.sym_tab.symbols.get_id(method) else {
1430 return Ok(None);
1431 };
1432 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) }
1433 }
1434
1435 fn method_call_obj_expr(&mut self, obj: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Option<Expr>> {
1436 if let ExprKind::TypedMethod { obj: left, ty, name } = &obj.kind {
1437 let left = self.eval(left, stmts, cap)?;
1438 let base_name = match ty {
1439 Type::Ident { name, .. } => name.clone(),
1440 Type::Symbol { id, .. } => self.sym_tab.symbols.get_symbol(*id)?.0.clone(),
1441 _ => return Err(Self::semantic_error(obj.span, format!("方法调用类型提示必须是类型: {:?}", ty))),
1442 };
1443 let method = format!("{}::{}", base_name, name);
1444 let id = self.sym_tab.symbols.get_id(&method).map_err(|_| Self::semantic_error(obj.span, format!("未找到类型方法 {}", method)))?;
1445 return Ok(Some(Expr::new(ExprKind::Id(id, Some(Box::new(left))), obj.span)));
1446 }
1447
1448 let ExprKind::Binary { left, op: BinaryOp::Idx, right } = &obj.kind else {
1449 return Ok(None);
1450 };
1451 let Some(method) = self.get_value(right).and_then(|v| if v.is_str() { Some(v.as_str().to_string()) } else { None }) else {
1452 return Ok(None);
1453 };
1454 let left = self.eval(left, stmts, cap)?;
1455 if let Some(field) = self.type_field_access_expr(left.clone(), &method, obj.span, false) {
1456 return Ok(Some(field));
1457 }
1458 if let Some(method_fn) = self.global_method_access_expr(left.clone(), &method, obj.span)? {
1459 return Ok(Some(method_fn));
1460 }
1461 Ok(Some(self.literal_field_access_expr(left, &method, obj.span)))
1462 }
1463
1464 pub fn compile_fn(&mut self, args: &[SmolStr], tys: &mut Vec<Type>, body: Stmt, cap: &mut Capture) -> Result<Vec<Stmt>> {
1465 let top = self.sym_tab.tys.len();
1466 self.sym_tab.frames.push(top);
1467 self.type_ctx.arg_counts.push(args.len());
1468 let result = (|| -> Result<Vec<Stmt>> {
1469 for (arg, ty) in args.iter().zip(tys.iter_mut()) {
1470 *ty = self.sym_tab.symbols.get_type(ty)?;
1471 self.add_name(arg.clone());
1472 self.add_ty(ty.clone());
1473 }
1474 if cap.names.is_empty() && tys.iter().all(|ty| !ty.is_any()) {
1475 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());
1476 let result = self.check_return_type(&body);
1477 self.restore_local_state(saved_state);
1478 result?;
1479 }
1480 let mut compiled = Vec::new();
1481 self.compile_stmt(body, &mut compiled, cap)?;
1482 if !compiled.last_mut().map(|stmt| stmt.last_return()).unwrap_or(false) {
1483 compiled.push(Stmt::new(StmtKind::Return(None), Span::default()));
1484 }
1485 Ok(compiled)
1486 })();
1487 if let Some(top) = self.sym_tab.frames.pop() {
1488 self.sym_tab.tys.truncate(top);
1489 self.sym_tab.names.truncate(top);
1490 self.type_ctx.list_elem_states.truncate(top);
1491 }
1492 self.type_ctx.arg_counts.pop();
1493 result
1494 }
1495
1496 pub fn compile(&mut self, mod_name: SmolStr, stmts: Vec<Stmt>) -> Result<Vec<u32>> {
1497 self.sym_tab.symbols.add_module(mod_name.clone());
1498 for stmt in stmts {
1499 match stmt.kind {
1500 StmtKind::Struct { name, def, is_pub } => {
1501 self.sym_tab.symbols.add(name, Symbol::Struct(def, is_pub));
1502 }
1503 StmtKind::Static { name, ty, value, is_pub } => {
1504 let value = value.map(|value| self.const_expr_value(&value)).transpose()?;
1505 self.sym_tab.symbols.add(name, Symbol::Static { value, ty, is_pub });
1506 }
1507 StmtKind::Const { name, ty, value, is_pub } => {
1508 let value = self.const_expr_value(&value)?;
1509 let ty = if ty.is_any() { value.get_type() } else { ty };
1510 self.sym_tab.symbols.add(name, Symbol::Const { value, ty, is_pub });
1511 }
1512 StmtKind::Fn { name, generic_params, args, body, is_pub } => {
1513 let (ty, args) = Type::from_args(args);
1514 self.sym_tab.symbols.add(name, Symbol::Fn { ty, args, generic_params, cap: Capture::default(), body: Arc::new(*body), is_pub });
1515 }
1516 StmtKind::Impl { target, body } => {
1517 let name = impl_target_name(&target)?;
1518 let def_id = match self.sym_tab.symbols.get_id(&name) {
1519 Ok(id) => id,
1520 Err(_) if name.as_str() == "Vec" => self.sym_tab.symbols.add(name.clone(), Symbol::Struct(Type::Struct { params: Vec::new(), fields: Vec::new() }, true)),
1521 Err(err) => return Err(err),
1522 };
1523 if let StmtKind::Block(fns) = body.kind {
1524 for f in fns {
1525 if let StmtKind::Fn { name: fn_name, generic_params: fn_generic_params, args, body, is_pub } = f.kind {
1526 let (ty, args) = Type::from_args(args);
1527 let target_generics: Vec<Type> = match &target {
1531 Type::Ident { params, .. } => params.clone(),
1532 _ => Vec::new(),
1533 };
1534 let mut generic_params = if !target_generics.is_empty() && has_unresolved_generic_param(&target, &target_generics) {
1535 target_generics.clone()
1536 } else {
1537 Vec::new()
1538 };
1539 for param in fn_generic_params {
1540 if !generic_params.contains(¶m) {
1541 generic_params.push(param);
1542 }
1543 }
1544 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 });
1545 if let Symbol::Struct(ty, _) = &mut self.sym_tab.symbols.symbols[def_id as usize] {
1546 ty.add_field(fn_name.into(), Type::Symbol { id: fn_id, params: Vec::new() })?;
1547 }
1548 } else {
1549 log::debug!("impl 包含非函数语句 {:?}", f);
1550 }
1551 }
1552 }
1553 }
1554 StmtKind::Expr(expr, _) if is_top_level_import_expr(&expr) => {}
1555 StmtKind::Import { .. } => {}
1556 _ => return Err(Self::semantic_error(stmt.span, format!("不支持的顶层语句: {:?}", stmt.kind))),
1557 }
1558 }
1559 let mut fn_ids = Vec::new();
1560 for (name, id) in self.sym_tab.symbols.symbol(&mod_name) {
1561 log::debug!("compile symbol {:?}[{}]", name, id);
1562 if let Some((_, Symbol::Fn { ty, generic_params, .. })) = self.sym_tab.symbols.get_symbol(id).ok() {
1563 let resolved_ty = self.sym_tab.symbols.get_type(ty).unwrap_or_else(|_| ty.clone());
1564 if has_unresolved_generic_param(&resolved_ty, generic_params) || !generic_params.is_empty() {
1565 continue;
1566 }
1567 }
1568 if let Some(s) = self.sym_tab.symbols.get_symbol(id).ok().map(|(_, symbol)| symbol.clone()) {
1569 if let Symbol::Fn { ty, args, generic_params, mut cap, body, is_pub } = s {
1570 if let Type::Fn { mut tys, ret } = ty {
1571 let compiled = self.compile_fn(&args, &mut tys, body.as_ref().clone(), &mut cap)?;
1572 for s in compiled.iter() {
1573 log::debug!("{}", s);
1574 }
1575 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 };
1576 fn_ids.push(id);
1577 }
1578 }
1579 }
1580 }
1581 self.sym_tab.symbols.pop_module();
1582 Ok(fn_ids)
1583 }
1584
1585 fn pat_to_var(&mut self, pat: Pattern, expr_ty: Type) -> Result<Pattern> {
1586 match pat.kind {
1587 PatternKind::Var { idx, ty } => Ok(Pattern { kind: PatternKind::Var { idx, ty }, span: pat.span }),
1588 PatternKind::Ident { name, ty } => {
1589 let ty = self.sym_tab.symbols.get_type(&ty)?;
1590 let ty = if ty.is_any() { expr_ty } else { ty };
1591 self.add_ty(ty.clone());
1592 Ok(Pattern { kind: PatternKind::Var { idx: self.add_name(name), ty }, span: pat.span })
1593 }
1594 PatternKind::Tuple(pats) => {
1595 if let Type::Tuple(tys) = &expr_ty {
1596 if pats.len() != tys.len() {
1597 return Err(Self::semantic_error(pat.span, format!("模式与元组类型不匹配: {:?}", expr_ty)));
1598 }
1599 let pats: Vec<Pattern> = pats.into_iter().zip(tys).map(|p| self.pat_to_var(p.0, p.1.clone())).collect::<Result<_>>()?;
1600 Ok(Pattern { kind: PatternKind::Tuple(pats), span: pat.span })
1601 } else if expr_ty.is_any() {
1602 let pats = pats.into_iter().map(|p| self.pat_to_var(p, Type::Any)).collect::<Result<_>>()?;
1603 Ok(Pattern { kind: PatternKind::Tuple(pats), span: pat.span })
1604 } else {
1605 Err(Self::semantic_error(pat.span, format!("元组模式 {:?} 与类型 {:?} 不匹配", pats, expr_ty)))
1606 }
1607 }
1608 PatternKind::List { elems, has_rest } => {
1609 if expr_ty.is_any() {
1610 let elems: Vec<Pattern> = elems.into_iter().map(|p| self.pat_to_var(p, Type::Any)).collect::<Result<_>>()?;
1611 Ok(Pattern { kind: PatternKind::List { elems, has_rest }, span: pat.span })
1612 } else if let Type::List(elem_ty) | Type::Array(elem_ty, _) | Type::Vec(elem_ty, _) = &expr_ty {
1613 let elems: Vec<Pattern> = elems.into_iter().map(|p| self.pat_to_var(p, elem_ty.as_ref().clone())).collect::<Result<_>>()?;
1614 Ok(Pattern { kind: PatternKind::List { elems, has_rest }, span: pat.span })
1615 } else {
1616 Err(Self::semantic_error(pat.span, format!("列表模式 {:?} 与类型 {:?} 不匹配", elems, expr_ty)))
1617 }
1618 }
1619 PatternKind::Wildcard => {
1620 self.add_ty(expr_ty.clone());
1621 Ok(Pattern { kind: PatternKind::Var { idx: self.add_name(SmolStr::new_static("")), ty: expr_ty }, span: pat.span })
1622 }
1623 _ => Err(Self::semantic_error(pat.span, format!("未知的模式 {:?}", pat))),
1624 }
1625 }
1626
1627 fn infer_range_type(&self, range: &Expr) -> Type {
1628 if let ExprKind::Range { start, stop, .. } = &range.kind {
1629 let start_ty = start.get_type();
1630 let stop_ty = stop.get_type();
1631 if start_ty.is_any() {
1632 stop_ty
1633 } else if stop_ty.is_any() {
1634 start_ty
1635 } else if start_ty == Type::I32 && stop_ty.is_uint() {
1636 stop_ty
1637 } else if stop_ty == Type::I32 && start_ty.is_uint() {
1638 start_ty
1639 } else {
1640 start_ty + stop_ty
1641 }
1642 } else {
1643 range.get_type()
1644 }
1645 }
1646
1647 fn dyn_init(&mut self, expr: Expr, stmts: &mut Vec<Stmt>, items: Vec<(Expr, Expr)>, ty: Type) -> Expr {
1648 self.add_name("".into());
1649 let temp = self.add_ty(ty);
1650 let span = expr.span;
1651 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));
1652 for (idx, item) in items {
1653 let item_span = idx.span.merge(item.span);
1654 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);
1655 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));
1656 }
1657 Expr::new(ExprKind::Var(temp), span)
1658 }
1659
1660 fn is_spawn_closure_call(obj: &Expr, params: &[Expr]) -> bool {
1661 params.len() == 2 && matches!(&obj.kind, ExprKind::Ident(name) if name.as_str() == "spawn") && matches!(¶ms[0].kind, ExprKind::Closure { .. })
1662 }
1663
1664 fn eval_spawn_arg_pack(&mut self, expr: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Expr> {
1665 match &expr.kind {
1666 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)),
1667 _ => Err(Self::semantic_error(expr.span, "spawn closure args must be tuple")),
1668 }
1669 }
1670
1671 fn is_multi_assign_target(expr: &Expr) -> bool {
1672 matches!(expr.kind, ExprKind::Tuple(_) | ExprKind::List(_))
1673 }
1674
1675 fn push_assign(stmts: &mut Vec<Stmt>, left: Expr, right: Expr, span: Span) {
1676 stmts.push(Stmt::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Assign, right: Box::new(right) }, span), true), span));
1677 }
1678
1679 fn temp_var(&mut self, ty: Type, span: Span) -> Expr {
1680 self.add_name("".into());
1681 let idx = self.add_ty(ty);
1682 Expr::new(ExprKind::Var(idx), span)
1683 }
1684
1685 fn typed_expr(value: Expr, ty: &Type) -> Expr {
1686 if ty.is_any() {
1687 value
1688 } else {
1689 let span = value.span;
1690 Expr::new(ExprKind::Typed { value: Box::new(value), ty: ty.clone() }, span)
1691 }
1692 }
1693
1694 fn lower_multi_assign(&mut self, left: &Expr, right: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture, span: Span) -> Result<Expr> {
1695 let left_items = match &left.kind {
1696 ExprKind::Tuple(items) | ExprKind::List(items) => items,
1697 _ => return Err(Self::semantic_error(left.span, "多重赋值左侧必须是 tuple 或 list")),
1698 };
1699 if left_items.is_empty() {
1700 return Err(Self::semantic_error(left.span, "多重赋值左侧不能为空"));
1701 }
1702
1703 let mut temps = Vec::with_capacity(left_items.len());
1704 if let ExprKind::Tuple(right_items) | ExprKind::List(right_items) = &right.kind {
1705 if left_items.len() != right_items.len() {
1706 return Err(Self::semantic_error(span, format!("多重赋值数量不匹配: 左侧 {} 个,右侧 {} 个", left_items.len(), right_items.len())));
1707 }
1708 for item in right_items {
1709 let value = self.eval(item, stmts, cap)?;
1710 let ty = self.infer_expr(&value)?;
1711 let temp = self.temp_var(ty.clone(), item.span);
1712 Self::push_assign(stmts, temp.clone(), Self::typed_expr(value, &ty), item.span);
1713 temps.push((temp, ty));
1714 }
1715 } else {
1716 let value = self.eval(right, stmts, cap)?;
1717 let ty = self.infer_expr(&value)?;
1718 let source = self.temp_var(ty.clone(), right.span);
1719 Self::push_assign(stmts, source.clone(), Self::typed_expr(value, &ty), right.span);
1720 for idx in 0..left_items.len() {
1721 let item_span = left_items[idx].span;
1722 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);
1723 let value = self.eval(&item, stmts, cap)?;
1724 let ty = self.infer_expr(&value)?;
1725 let temp = self.temp_var(ty.clone(), item_span);
1726 Self::push_assign(stmts, temp.clone(), Self::typed_expr(value, &ty), item_span);
1727 temps.push((temp, ty));
1728 }
1729 }
1730
1731 for (target, (temp, ty)) in left_items.iter().zip(temps.iter()) {
1732 let target = self.eval(target, stmts, cap)?;
1733 let assign_span = target.span.merge(temp.span);
1734 Self::push_assign(stmts, target, Self::typed_expr(temp.clone(), ty), assign_span);
1735 }
1736
1737 Ok(temps.last().map(|(temp, ty)| Self::typed_expr(temp.clone(), ty)).unwrap_or_else(|| Expr::new(ExprKind::Value(Dynamic::Null), span)))
1738 }
1739
1740 fn static_composite_literal(&self, expr: &Expr) -> Result<Option<Dynamic>> {
1741 match &expr.kind {
1742 ExprKind::List(items) | ExprKind::Tuple(items) => {
1743 let mut values = Vec::with_capacity(items.len());
1744 for item in items {
1745 let Some(value) = self.static_literal_value(item)? else {
1746 return Ok(None);
1747 };
1748 values.push(value);
1749 }
1750 Ok(Some(Dynamic::list(values)))
1751 }
1752 ExprKind::Dict(items) => {
1753 let mut values = BTreeMap::new();
1754 for (key, item) in items {
1755 let Some(value) = self.static_literal_value(item)? else {
1756 return Ok(None);
1757 };
1758 values.insert(key.clone(), value);
1759 }
1760 Ok(Some(Dynamic::map(values)))
1761 }
1762 _ => Ok(None),
1763 }
1764 }
1765
1766 fn static_literal_value(&self, expr: &Expr) -> Result<Option<Dynamic>> {
1767 match &expr.kind {
1768 ExprKind::Value(value) => Ok(Some(value.clone())),
1769 ExprKind::Const(idx) => Ok(self.sym_tab.consts.get_index(*idx).map(|(_, v)| v.clone())),
1770 ExprKind::Typed { value, ty } if ty.is_native() => Ok(self.static_literal_value(value)?.map(|value| ty.force(value)).transpose()?),
1771 _ => self.static_composite_literal(expr),
1772 }
1773 }
1774
1775 fn const_expr_value(&self, expr: &Expr) -> Result<Dynamic> {
1776 match &expr.kind {
1777 ExprKind::Value(value) => Ok(value.clone()),
1778 ExprKind::Const(idx) => self.sym_tab.consts.get_index(*idx).map(|(_, v)| v.clone()).ok_or_else(|| Self::semantic_error(expr.span, format!("常量索引 {} 不存在", idx))),
1779 ExprKind::Ident(ident) => {
1780 let id = self.sym_tab.symbols.get_id(ident).map_err(|_| Self::semantic_error(expr.span, format!("未找到常量 {}", ident)))?;
1781 match self.sym_tab.symbols.get_symbol(id).map(|(_, symbol)| symbol) {
1782 Ok(Symbol::Const { value, .. }) => Ok(value.clone()),
1783 Ok(Symbol::Static { value: Some(value), .. }) => Ok(value.clone()),
1784 _ => Err(Self::semantic_error(expr.span, format!("{} 不是可用于 const 的静态值", ident))),
1785 }
1786 }
1787 ExprKind::Typed { value, ty } if ty.is_native() => Ok(ty.force(self.const_expr_value(value)?)?),
1788 ExprKind::Typed { value, .. } => self.const_expr_value(value),
1789 ExprKind::List(items) | ExprKind::Tuple(items) => {
1790 let values = items.iter().map(|item| self.const_expr_value(item)).collect::<Result<Vec<_>>>()?;
1791 Ok(Dynamic::list(values))
1792 }
1793 ExprKind::Dict(items) => {
1794 let mut values = BTreeMap::new();
1795 for (key, item) in items {
1796 values.insert(key.clone(), self.const_expr_value(item)?);
1797 }
1798 Ok(Dynamic::map(values))
1799 }
1800 ExprKind::Unary { op, value } => {
1801 let value = self.const_expr_value(value)?;
1802 match op {
1803 parser::UnaryOp::Neg => Ok(-value),
1804 parser::UnaryOp::Not => Ok(!value),
1805 parser::UnaryOp::Unknow => Err(Self::semantic_error(expr.span, "const 一元表达式无法在编译期求值")),
1806 }
1807 }
1808 ExprKind::Binary { left, op, right } => {
1809 let left = Expr::new(ExprKind::Value(self.const_expr_value(left)?), left.span);
1810 let right = Expr::new(ExprKind::Value(self.const_expr_value(right)?), right.span);
1811 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 二元表达式无法在编译期求值"))
1812 }
1813 _ => Err(Self::semantic_error(expr.span, "const 只能使用字面量、已声明常量和静态 composite literal")),
1814 }
1815 }
1816
1817 fn eval_stmt_expr(&mut self, stmt: &Stmt, stmts: &mut Vec<Stmt>, cap: &mut Capture, span: Span) -> Result<Expr> {
1818 self.compile_stmt(stmt.clone(), stmts, cap)?;
1819 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 };
1820 self.add_name("".into());
1821 let temp = self.add_ty(expr_ty.clone());
1822 let pat = Pattern { kind: PatternKind::Var { idx: temp, ty: expr_ty }, span };
1823 stmts.last_mut().ok_or_else(|| Self::semantic_error(span, "没有生成可求值语句表达式")).and_then(|stmt| stmt.bind_pattern(pat))?;
1824 Ok(Expr::new(ExprKind::Var(temp), span))
1825 }
1826
1827 fn eval(&mut self, expr: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Expr> {
1828 match &expr.kind {
1829 ExprKind::Stmt(stmt) => self.eval_stmt_expr(stmt, stmts, cap, expr.span),
1830 ExprKind::Closure { args, body } => {
1831 let (mut names, mut tys): (Vec<SmolStr>, Vec<Type>) = args.clone().into_iter().unzip();
1832 let top = self.top();
1833 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();
1834 let parent_cap_start = cap_vars.len();
1835 cap_vars.extend(cap.names.iter().cloned());
1836 let mut local_cap = Capture::new(cap_vars);
1837 let _ = self.compile_fn(names.as_slice(), &mut tys.clone(), *body.clone(), &mut local_cap)?;
1838 for cap_idx in local_cap.vars.iter() {
1839 if *cap_idx >= parent_cap_start {
1840 let _ = cap.get(&local_cap.names[*cap_idx].0);
1841 }
1842 names.push(local_cap.names[*cap_idx].0.clone());
1843 tys.push(local_cap.names[*cap_idx].1.clone());
1844 }
1845 let mut compiled = self.compile_fn(names.as_slice(), &mut tys.clone(), *body.clone(), &mut Capture::default())?;
1846 let (ty, args) = Type::from_args(args.clone());
1847 let body_stmt = if compiled.len() == 1 { compiled.pop().unwrap() } else { Stmt::new(StmtKind::Block(compiled), expr.span) };
1848 let name = SmolStr::from(format!("__closure_{}_{}", expr.span.start, expr.span.end));
1849 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 });
1850 Ok(Expr::new(ExprKind::Id(fn_id, None), expr.span))
1851 }
1852 ExprKind::Value(v) => {
1853 if v.is_native() {
1854 Ok(Expr::new(ExprKind::Value(v.clone()), expr.span))
1855 } else {
1856 Ok(Expr::new(ExprKind::Const(self.get_const(v.clone())), expr.span))
1857 }
1858 }
1859 ExprKind::Typed { value, ty } => {
1860 let ty = self.sym_tab.symbols.get_type(ty)?;
1861 if let Type::Struct { fields, .. } = &ty
1862 && let ExprKind::Dict(dict) = &value.kind
1863 {
1864 let mut items = Vec::new();
1865 for field in fields {
1866 if let Some((_, v)) = dict.iter().find(|(name, _)| name == &field.0) {
1867 items.push(self.eval(v, stmts, cap)?);
1868 }
1869 }
1870 Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty }, expr.span))
1871 } else if let Type::Struct { .. } = &ty
1872 && let ExprKind::List(list) = &value.kind
1873 {
1874 let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1875 Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty }, expr.span))
1876 } else if let Type::Array(elem_ty, _) = &ty
1877 && let ExprKind::List(list) = &value.kind
1878 {
1879 let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1880 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))
1881 } else if let Type::Vec(elem_ty, _) = &ty
1882 && let ExprKind::List(list) = &value.kind
1883 {
1884 let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1885 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))
1886 } else if let Type::Array(elem_ty, _) | Type::Vec(elem_ty, _) = &ty
1887 && let ExprKind::Value(Dynamic::List(items)) = &value.kind
1888 {
1889 let items = items.read();
1896 let exprs = items
1897 .iter()
1898 .map(|v| {
1899 let coerced = elem_ty.force(v.clone()).unwrap_or_else(|_| v.clone());
1900 Expr::new(ExprKind::Value(coerced), expr.span)
1901 })
1902 .collect::<Vec<_>>();
1903 let len = exprs.len() as u32;
1904 let new_ty = match &ty {
1905 Type::Array(_, _) => Type::Array(elem_ty.clone(), len),
1906 Type::Vec(_, _) => Type::Vec(elem_ty.clone(), len),
1907 _ => unreachable!(),
1908 };
1909 Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(exprs), expr.span)), ty: new_ty }, expr.span))
1910 } else if value.is_value() {
1911 let value = value.clone().value()?;
1912 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)) }
1916 } else {
1917 Ok(Expr::new(ExprKind::Typed { value: Box::new(self.eval(value, stmts, cap)?), ty }, expr.span))
1918 }
1919 }
1920 ExprKind::Ident(ident) => {
1921 for idx in (self.top()..self.sym_tab.names.len()).rev() {
1923 if self.sym_tab.names[idx].eq(ident) {
1924 return Ok(Expr::new(ExprKind::Var((idx - self.top()) as u32), expr.span));
1925 }
1926 }
1927 if let Some(idx) = cap.get(ident) {
1928 return Ok(Expr::new(ExprKind::Capture(idx as u32), expr.span));
1929 }
1930 self.get_ident(ident, expr.span)
1931 }
1932 ExprKind::Generic { obj, params } => {
1933 let obj = self.eval(obj, stmts, cap)?;
1934 let params = params.iter().map(|param| self.sym_tab.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect();
1935 match obj.kind {
1936 ExprKind::Id(id, None) | ExprKind::AssocId { id, .. } => Ok(Expr::new(ExprKind::AssocId { id, params }, expr.span)),
1937 _ => Err(Self::semantic_error(expr.span, format!("范型参数只能用于函数或关联函数调用: {:?}", obj))),
1938 }
1939 }
1940 ExprKind::Assoc { ty, name } => {
1941 let base_name = match ty {
1942 Type::Ident { name, .. } => name.clone(),
1943 Type::Symbol { id, .. } => self.sym_tab.symbols.get_symbol(*id)?.0.clone(),
1944 _ => return Err(Self::semantic_error(expr.span, format!("关联函数目标必须是类型: {:?}", ty))),
1945 };
1946 let id = self.sym_tab.symbols.get_id(&format!("{}::{}", base_name, name)).map_err(|_| Self::semantic_error(expr.span, format!("未找到关联函数 {}::{}", base_name, name)))?;
1947 let params = match ty {
1948 Type::Ident { params, .. } | Type::Symbol { params, .. } => params.iter().map(|param| self.sym_tab.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect(),
1949 _ => Vec::new(),
1950 };
1951 Ok(Expr::new(ExprKind::AssocId { id, params }, expr.span))
1952 }
1953 ExprKind::Unary { op, value } => {
1954 let value = Expr::new(ExprKind::Unary { op: op.clone(), value: Box::new(self.eval(value, stmts, cap)?) }, expr.span);
1955 if let Some(v) = value.compact() { Ok(Expr::new(ExprKind::Value(v), expr.span)) } else { Ok(value) }
1956 }
1957 ExprKind::Binary { left, op, right } => {
1958 if *op == BinaryOp::Assign && Self::is_multi_assign_target(left) {
1959 return self.lower_multi_assign(left, right, stmts, cap, expr.span);
1960 }
1961 let left = self.eval(left, stmts, cap)?;
1962 if *op == BinaryOp::Idx {
1963 if let Some(key) = self.get_value(right).and_then(|v| if v.is_str() { Some(v.as_str().to_string()) } else { None }) {
1964 if let Some(field) = self.type_field_access_expr(left.clone(), &key, expr.span, true) {
1965 return Ok(field);
1966 }
1967 return Ok(self.literal_field_access_expr(left, &key, expr.span));
1968 } else if let Ok(ident) = right.ident() {
1969 if let Ok(found) = self.get_ident(ident, right.span) {
1970 return Ok(if let Some(id) = found.id() {
1971 Expr::new(ExprKind::Id(id, Some(Box::new(left))), expr.span)
1972 } else {
1973 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(found) }, expr.span)
1974 });
1975 }
1976 if let Ok(ty) = self.infer_expr(&left)
1977 && let Ok((idx, ty)) = self.get_field(&ty, ident)
1978 {
1979 return Ok(if let Type::Symbol { id, .. } = ty {
1980 Expr::new(ExprKind::Id(id, Some(Box::new(left))), expr.span)
1981 } else if ty.is_bool() && idx == usize::MAX {
1982 Expr::new(ExprKind::Value(Dynamic::Bool(false)), expr.span)
1983 } else if ty.is_any() && idx == usize::MAX {
1984 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(ident.into()))), expr.span);
1985 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, expr.span)
1986 } else {
1987 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)
1988 });
1989 } else {
1990 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(ident.into()))), expr.span);
1991 return Ok(Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, expr.span));
1992 }
1993 }
1994 }
1995 let right = self.eval(right, stmts, cap)?;
1996 let value = Self::normalize_self_assign(left, op.clone(), right, expr.span, self.type_ctx.arg_counts.last().copied().unwrap_or(0));
1997 if let Some(v) = value.compact() { Ok(Expr::new(ExprKind::Value(v), expr.span)) } else { Ok(value) }
1998 }
1999 ExprKind::Call { obj, params } => {
2000 let params: Vec<Expr> = if Self::is_spawn_closure_call(obj, params) {
2001 vec![self.eval(¶ms[0], stmts, cap)?, self.eval_spawn_arg_pack(¶ms[1], stmts, cap)?]
2002 } else {
2003 params.iter().map(|p| self.eval(p, stmts, cap)).collect::<Result<Vec<_>>>()?
2004 };
2005 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) };
2006 match obj_result {
2007 Ok(obj) if obj.is_value() && params.is_empty() => Ok(obj),
2008 Ok(obj) => Ok(Expr::new(ExprKind::Call { obj: Box::new(obj), params }, expr.span)),
2009 Err(e) => {
2010 Err(Self::semantic_error(obj.span, format!("未注册函数 {:?}: {}", obj.kind, e)))
2013 }
2014 }
2015 }
2016 ExprKind::Range { start, stop, inclusive } => {
2017 let start = Box::new(self.eval(start, stmts, cap)?);
2018 let stop = Box::new(self.eval(stop, stmts, cap)?);
2019 Ok(Expr::new(ExprKind::Range { start, stop, inclusive: *inclusive }, expr.span))
2020 }
2021 ExprKind::List(list) | ExprKind::Tuple(list) => {
2022 if let Some(value) = self.static_composite_literal(expr)? {
2023 let idx = self.get_const(value);
2024 return Ok(Expr::new(ExprKind::Const(idx), expr.span));
2025 }
2026 let mut v = Vec::new();
2027 let mut items = Vec::new();
2028 for (idx, item) in list.iter().enumerate() {
2029 if item.is_value() {
2030 v.push(item.clone().value().unwrap());
2031 } else {
2032 items.push((Expr::new(ExprKind::Value((idx as u32).into()), item.span), self.eval(item, stmts, cap)?));
2033 v.push(Dynamic::Null);
2034 }
2035 }
2036 let list = Expr::new(ExprKind::Const(self.get_const(Dynamic::list(v))), expr.span);
2037 Ok(self.dyn_init(list, stmts, items, Type::Any))
2038 }
2039 ExprKind::Repeat { value, len } => {
2040 let len = self.sym_tab.symbols.get_type(len)?;
2041 let Type::ConstInt(len) = len else {
2042 return Err(Self::semantic_error(expr.span, format!("重复数组长度必须是编译期整数: {:?}", len)));
2043 };
2044 if len < 0 {
2045 return Err(Self::semantic_error(expr.span, "重复数组长度不能为负数"));
2046 }
2047 Ok(Expr::new(ExprKind::Repeat { value: Box::new(self.eval(value, stmts, cap)?), len: Type::ConstInt(len) }, expr.span))
2048 }
2049 ExprKind::Dict(dict) => {
2050 if let Some(value) = self.static_composite_literal(expr)? {
2051 let idx = self.get_const(value);
2052 return Ok(Expr::new(ExprKind::Const(idx), expr.span));
2053 }
2054 let mut dyn_kv = Vec::new();
2055 let mut m = BTreeMap::new();
2056 for (k, v) in dict {
2057 if v.is_value() {
2058 m.insert(k.clone(), v.clone().value()?);
2059 } else {
2060 let key = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(k.clone()))), v.span);
2061 dyn_kv.push((key, self.eval(v, stmts, cap)?));
2062 m.insert(k.clone(), Dynamic::Null);
2063 }
2064 }
2065 let dict = Expr::new(ExprKind::Const(self.get_const(Dynamic::map(m))), expr.span);
2066 Ok(self.dyn_init(dict, stmts, dyn_kv, Type::Any))
2067 }
2068 ExprKind::Id(_, _) | ExprKind::AssocId { .. } => Ok(expr.clone()),
2069 _ => Ok(expr.clone()),
2070 }
2071 }
2072
2073 fn get_stmt(&mut self, stmt: Stmt, cap: &mut Capture) -> Result<Stmt> {
2074 let span = stmt.span;
2075 let mut stmts = Vec::new();
2076 self.compile_stmt(stmt, &mut stmts, cap)?;
2077 Ok(Stmt::new(StmtKind::Block(stmts), span))
2078 }
2079
2080 fn compile_stmt(&mut self, stmt: Stmt, compiled: &mut Vec<Stmt>, cap: &mut Capture) -> Result<()> {
2081 let stmt_span = stmt.span;
2082 match stmt.kind {
2083 StmtKind::Let { pat, value } => {
2084 if let PatternKind::Tuple(pats) = &pat.kind
2089 && let StmtKind::Expr(expr, _) = &value.kind
2090 && let ExprKind::Tuple(items) = &expr.kind
2091 {
2092 if pats.len() != items.len() {
2093 return Err(Self::semantic_error(stmt_span, format!("元组解构长度不匹配: 模式 {} 个,值 {} 个", pats.len(), items.len())));
2094 }
2095 for (p, item) in pats.iter().zip(items.iter()) {
2096 let inner = Stmt::new(StmtKind::Let { pat: p.clone(), value: Box::new(Stmt::new(StmtKind::Expr(item.clone(), false), item.span)) }, stmt_span);
2097 self.compile_stmt(inner, compiled, cap)?;
2098 }
2099 return Ok(());
2100 }
2101 let value = *value;
2102 let annotated_ty = if let PatternKind::Ident { ty, .. } = &pat.kind {
2103 let ty = self.sym_tab.symbols.get_type(ty)?;
2104 if ty.is_any() { None } else { Some(ty) }
2105 } else {
2106 None
2107 };
2108 let pattern_expr_ty = if matches!(pat.kind, PatternKind::List { .. } | PatternKind::Tuple(_)) {
2109 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 }
2110 } else {
2111 None
2112 };
2113 if let Some(ty) = annotated_ty {
2114 if let StmtKind::Expr(expr, close) = value.kind {
2115 let span = expr.span;
2116 let typed = Expr::new(ExprKind::Typed { value: Box::new(expr), ty }, span);
2117 self.compile_stmt(Stmt::new(StmtKind::Expr(typed, close), value.span), compiled, cap)?;
2118 } else {
2119 self.compile_stmt(value, compiled, cap)?;
2120 }
2121 } else {
2122 self.compile_stmt(value, compiled, cap)?;
2123 }
2124 let expr_ty = if let Some(ty) = pattern_expr_ty {
2125 ty
2126 } else if let Some(stmt) = compiled.last() {
2127 if let StmtKind::Expr(expr, _) = &stmt.kind { self.infer_expr(expr)? } else { self.infer_stmt(stmt)? }
2128 } else {
2129 Type::Any
2130 };
2131 let pat = self.pat_to_var(pat, expr_ty.clone())?;
2132 if matches!(pat.kind, PatternKind::Tuple(_) | PatternKind::List { .. }) {
2133 let temp = self.add_temp(expr_ty.clone());
2137 let temp_pat = Pattern { kind: PatternKind::Var { idx: temp, ty: expr_ty }, span: stmt_span };
2138 compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "没有生成可绑定模式的编译语句")).and_then(|stmt| stmt.bind_pattern(temp_pat))?;
2139 let temp_expr = Expr::new(ExprKind::Var(temp), stmt_span);
2140 compiled.push(Stmt::new(StmtKind::Expr(temp_expr, false), stmt_span));
2141 compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "临时变量 stmt 缺失")).and_then(|stmt| stmt.bind_pattern(pat))?;
2142 } else {
2143 compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "没有生成可绑定模式的编译语句")).and_then(|stmt| stmt.bind_pattern(pat))?;
2144 }
2145 }
2146 StmtKind::Expr(expr, close) => {
2147 if let ExprKind::Binary { left, op: BinaryOp::Assign, right } = &expr.kind
2148 && Self::is_multi_assign_target(left)
2149 {
2150 self.lower_multi_assign(left, right, compiled, cap, stmt_span)?;
2151 return Ok(());
2152 }
2153 let e = self.eval(&expr, compiled, cap)?;
2154 compiled.push(Stmt::new(StmtKind::Expr(e, close), stmt_span));
2155 }
2156 StmtKind::Block(stmts) => {
2157 let mut block = Vec::new();
2158 for stmt in stmts {
2159 self.compile_stmt(stmt, &mut block, cap)?;
2160 }
2161 compiled.push(Stmt::new(StmtKind::Block(block), stmt_span));
2162 }
2163 StmtKind::Fn { name, generic_params, args, body, is_pub } => {
2164 let (ty, args) = Type::from_args(args);
2165 if let Type::Fn { mut tys, ret } = ty {
2166 let mut fn_cap = Capture::default();
2167 let compiled_body = self.compile_fn(&args, &mut tys, *body, &mut fn_cap)?;
2168 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 });
2169 } else {
2170 panic!("nested functions are not supported here")
2171 }
2172 }
2173 StmtKind::Return(expr) => {
2174 let expr = expr.map(|e| self.eval(&e, compiled, cap)).transpose()?;
2175 compiled.push(Stmt::new(StmtKind::Return(expr), stmt_span));
2176 }
2177 StmtKind::If { cond, then_body, else_body } => {
2178 let cond = self.eval(&cond, compiled, cap)?;
2179 if let Some(cond_value) = cond.compact()
2180 && let Some(cond_bool) = cond_value.as_bool()
2181 {
2182 if cond_bool {
2183 self.compile_stmt(*then_body, compiled, cap)?;
2184 } else if let Some(body) = else_body {
2185 self.compile_stmt(*body, compiled, cap)?;
2186 }
2187 } else {
2188 let then_body = Box::new(self.get_stmt(*then_body, cap)?);
2189 let else_body = if let Some(body) = else_body { Some(Box::new(self.get_stmt(*body, cap)?)) } else { None };
2190 compiled.push(Stmt::new(StmtKind::If { cond, then_body, else_body }, stmt_span));
2191 }
2192 }
2193 StmtKind::Loop(body) => {
2194 compiled.push(Stmt::new(StmtKind::Loop(Box::new(self.get_stmt(*body, cap)?)), stmt_span));
2195 }
2196 StmtKind::While { cond, body } => {
2197 let cond = self.eval(&cond, compiled, cap)?;
2198 compiled.push(Stmt::new(StmtKind::While { cond, body: Box::new(self.get_stmt(*body, cap)?) }, stmt_span));
2199 }
2200 StmtKind::For { pat, range, body } => {
2201 let range = self.eval(&range, compiled, cap)?;
2202 let range_ty = self.infer_range_type(&range);
2203 let pat = self.pat_to_var(pat, range_ty)?;
2204 compiled.push(Stmt::new(StmtKind::For { pat, range, body: Box::new(self.get_stmt(*body, cap)?) }, stmt_span));
2205 }
2206 stmt_kind => {
2207 compiled.push(Stmt::new(stmt_kind, stmt_span));
2208 }
2209 }
2210 Ok(())
2211 }
2212}