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
677fn has_unresolved_generic_param(ty: &Type) -> bool {
678 match ty {
679 Type::Ident { name, params } => {
680 if params.is_empty() {
681 name.chars().next().map(|ch| ch.is_ascii_uppercase()).unwrap_or(false)
682 } else {
683 params.iter().any(has_unresolved_generic_param)
684 }
685 }
686 Type::Struct { params, fields } => params.iter().any(has_unresolved_generic_param) || fields.iter().any(|(_, ty)| has_unresolved_generic_param(ty)),
687 Type::Tuple(items) => items.iter().any(has_unresolved_generic_param),
688 Type::List(elem) | Type::Vec(elem, _) | Type::Array(elem, _) => has_unresolved_generic_param(elem),
689 Type::ArrayParam(elem, len) => has_unresolved_generic_param(elem) || has_unresolved_generic_param(len),
690 Type::Fn { tys, ret } => tys.iter().any(has_unresolved_generic_param) || has_unresolved_generic_param(ret),
691 Type::Symbol { params, .. } => params.iter().any(has_unresolved_generic_param),
692 Type::ConstBinary { left, right, .. } => has_unresolved_generic_param(left) || has_unresolved_generic_param(right),
693 _ => false,
694 }
695}
696
697fn is_top_level_import_expr(expr: &Expr) -> bool {
698 matches!(
699 &expr.kind,
700 ExprKind::Call { obj, .. } if matches!(&obj.kind, ExprKind::Ident(name) if name.as_str() == "import")
701 )
702}
703
704fn string_value(expr: &Expr) -> Option<&str> {
705 if let ExprKind::Value(Dynamic::String(value)) = &expr.kind { Some(value.as_str()) } else { None }
706}
707
708fn import_decl(stmt: &Stmt) -> Option<(SmolStr, SmolStr)> {
709 match &stmt.kind {
710 StmtKind::Import { module, path, .. } => Some((module.clone(), path.clone())),
711 StmtKind::Expr(expr, _) => {
712 let ExprKind::Call { obj, params } = &expr.kind else {
714 return None;
715 };
716 let ExprKind::Ident(name) = &obj.kind else {
717 return None;
718 };
719 if name.as_str() != "import" {
720 return None;
721 }
722 match params.as_slice() {
723 [module, path] => Some((string_value(module)?.into(), string_value(path)?.into())),
724 [module] => match &module.kind {
725 ExprKind::Value(Dynamic::String(value)) => Some((value.clone(), format!("{value}.zs").into())),
726 ExprKind::Ident(value) => Some((value.clone(), format!("{value}.zs").into())),
727 _ => None,
728 },
729 _ => None,
730 }
731 }
732 _ => None,
733 }
734}
735
736fn generic_arg_for_name<'a>(name: &str, params: &'a [Type], args: &'a [Type]) -> Option<&'a Type> {
737 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))
738}
739
740pub fn infer_generic_args_from_types(generic_params: &[Type], decl_tys: &[Type], arg_tys: &[Type]) -> Vec<Type> {
741 if generic_params.is_empty() {
742 return Vec::new();
743 }
744 let mut inferred = vec![None; generic_params.len()];
745 for (decl, actual) in decl_tys.iter().zip(arg_tys.iter()) {
746 infer_generic_arg_from_type(generic_params, decl, actual, &mut inferred);
747 }
748 if inferred.iter().all(|item| item.is_some()) {
749 return inferred.into_iter().map(Option::unwrap).collect();
750 }
751 if let Some(Type::Struct { params, .. }) = arg_tys.iter().find(|ty| matches!(ty, Type::Struct { params, .. } if params.len() == generic_params.len())) {
752 return params.clone();
753 }
754 for (decl, actual) in decl_tys.iter().zip(arg_tys.iter()) {
755 if let (Type::Ident { params: decl_params, .. }, Type::Ident { params: actual_params, .. }) = (decl, actual)
756 && decl_params.len() == actual_params.len()
757 && decl_params.iter().any(|param| generic_params.contains(param))
758 {
759 return actual_params.clone();
760 }
761 }
762 Vec::new()
763}
764
765pub fn resolve_generic_args_from_types(generic_params: &[Type], decl_tys: &[Type], arg_tys: &[Type], explicit_args: &[Type]) -> Result<Vec<Type>> {
766 if generic_params.is_empty() {
767 if explicit_args.is_empty() {
768 return Ok(Vec::new());
769 }
770 return Err(anyhow!("函数不接受范型参数,但传入了 {}", explicit_args.len()));
771 }
772 if !explicit_args.is_empty() {
773 if explicit_args.len() == generic_params.len() {
774 return Ok(explicit_args.to_vec());
775 }
776 return Err(anyhow!("函数范型参数数量不匹配,期望 {} 个,实际 {} 个", generic_params.len(), explicit_args.len()));
777 }
778
779 let inferred = infer_generic_args_from_types(generic_params, decl_tys, arg_tys);
780 if inferred.len() == generic_params.len() {
781 Ok(inferred)
782 } else if generic_params.len() == 1
783 && let Some(Type::List(elem) | Type::Vec(elem, _) | Type::Array(elem, _)) = arg_tys.first()
784 {
785 Ok(vec![elem.as_ref().clone()])
786 } else {
787 Err(anyhow!("无法从实参类型推断函数范型参数 {:?}", generic_params))
788 }
789}
790
791fn infer_generic_arg_from_type(generic_params: &[Type], decl: &Type, actual: &Type, inferred: &mut [Option<Type>]) {
792 if let Some(idx) = generic_params.iter().position(|param| param == decl) {
793 inferred[idx] = Some(actual.clone());
794 return;
795 }
796
797 match (decl, actual) {
798 (Type::List(decl_elem), Type::List(actual_elem)) => {
799 infer_generic_arg_from_type(generic_params, decl_elem, actual_elem, inferred);
800 }
801 (Type::Vec(decl_elem, decl_len), Type::Vec(actual_elem, actual_len)) | (Type::Array(decl_elem, decl_len), Type::Array(actual_elem, actual_len)) => {
802 infer_generic_arg_from_type(generic_params, decl_elem, actual_elem, inferred);
803 infer_generic_arg_from_type(generic_params, &Type::ConstInt(*decl_len as i64), &Type::ConstInt(*actual_len as i64), inferred);
804 }
805 (Type::ArrayParam(decl_elem, decl_len), Type::Array(actual_elem, actual_len)) => {
806 infer_generic_arg_from_type(generic_params, decl_elem, actual_elem, inferred);
807 infer_generic_arg_from_type(generic_params, decl_len, &Type::ConstInt(*actual_len as i64), inferred);
808 }
809 (Type::Ident { params: decl_params, .. }, Type::Ident { params: actual_params, .. })
810 | (Type::Ident { params: decl_params, .. }, Type::Symbol { params: actual_params, .. })
811 | (Type::Symbol { params: decl_params, .. }, Type::Symbol { params: actual_params, .. })
812 | (Type::Symbol { params: decl_params, .. }, Type::Ident { params: actual_params, .. })
813 | (Type::Struct { params: decl_params, .. }, Type::Struct { params: actual_params, .. }) => {
814 for (decl, actual) in decl_params.iter().zip(actual_params.iter()) {
815 infer_generic_arg_from_type(generic_params, decl, actual, inferred);
816 }
817 }
818 _ => {}
819 }
820}
821
822fn substitute_pattern(pattern: &Pattern, params: &[Type], args: &[Type]) -> Pattern {
823 let kind = match &pattern.kind {
824 PatternKind::Ident { name, ty } => PatternKind::Ident { name: name.clone(), ty: substitute_type(ty, params, args) },
825 PatternKind::Var { idx, ty } => PatternKind::Var { idx: *idx, ty: substitute_type(ty, params, args) },
826 PatternKind::Tuple(items) => PatternKind::Tuple(items.iter().map(|item| substitute_pattern(item, params, args)).collect()),
827 PatternKind::List { elems, has_rest } => PatternKind::List { elems: elems.iter().map(|item| substitute_pattern(item, params, args)).collect(), has_rest: *has_rest },
828 other => other.clone(),
829 };
830 Pattern { kind, span: pattern.span }
831}
832
833fn substitute_expr(expr: &Expr, params: &[Type], args: &[Type]) -> Expr {
834 let kind = match &expr.kind {
835 ExprKind::Ident(name) => match generic_arg_for_name(name, params, args) {
836 Some(Type::ConstInt(value)) => ExprKind::Value(Dynamic::I32(*value as i32)),
837 Some(ty) => eval_const_int_type(ty).map(|value| ExprKind::Value(Dynamic::I32(value as i32))).unwrap_or_else(|| expr.kind.clone()),
838 _ => expr.kind.clone(),
839 },
840 ExprKind::Typed { value, ty } => ExprKind::Typed { value: Box::new(substitute_expr(value, params, args)), ty: substitute_type(ty, params, args) },
841 ExprKind::Unary { op, value } => ExprKind::Unary { op: op.clone(), value: Box::new(substitute_expr(value, params, args)) },
842 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)) },
843 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() },
844 ExprKind::Assoc { ty, name } => ExprKind::Assoc { ty: substitute_type(ty, params, args), name: name.clone() },
845 ExprKind::TypedMethod { obj, ty, name } => ExprKind::TypedMethod { obj: Box::new(substitute_expr(obj, params, args)), ty: substitute_type(ty, params, args), name: name.clone() },
846 ExprKind::AssocId { id, params: nested } => ExprKind::AssocId { id: *id, params: nested.iter().map(|param| substitute_type(param, params, args)).collect() },
847 ExprKind::Tuple(items) => ExprKind::Tuple(items.iter().map(|item| substitute_expr(item, params, args)).collect()),
848 ExprKind::List(items) => ExprKind::List(items.iter().map(|item| substitute_expr(item, params, args)).collect()),
849 ExprKind::Repeat { value, len } => ExprKind::Repeat { value: Box::new(substitute_expr(value, params, args)), len: substitute_type(len, params, args) },
850 ExprKind::Dict(items) => ExprKind::Dict(items.iter().map(|(name, value)| (name.clone(), substitute_expr(value, params, args))).collect()),
851 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 },
852 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() },
853 ExprKind::Stmt(stmt) => ExprKind::Stmt(Box::new(substitute_stmt(stmt, params, args))),
854 ExprKind::Closure { args: closure_args, body } => {
855 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)) }
856 }
857 _ => expr.kind.clone(),
858 };
859 Expr::new(kind, expr.span)
860}
861
862pub fn substitute_stmt(stmt: &Stmt, params: &[Type], args: &[Type]) -> Stmt {
863 let kind = match &stmt.kind {
864 StmtKind::Let { pat, value } => StmtKind::Let { pat: substitute_pattern(pat, params, args), value: Box::new(substitute_stmt(value, params, args)) },
865 StmtKind::Expr(expr, close) => StmtKind::Expr(substitute_expr(expr, params, args), *close),
866 StmtKind::Block(stmts) => StmtKind::Block(stmts.iter().map(|stmt| substitute_stmt(stmt, params, args)).collect()),
867 StmtKind::Return(expr) => StmtKind::Return(expr.as_ref().map(|expr| substitute_expr(expr, params, args))),
868 StmtKind::While { cond, body } => StmtKind::While { cond: substitute_expr(cond, params, args), body: Box::new(substitute_stmt(body, params, args)) },
869 StmtKind::Loop(body) => StmtKind::Loop(Box::new(substitute_stmt(body, params, args))),
870 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)) },
871 StmtKind::Fn { name, generic_params, args: fn_args, body, is_pub } => StmtKind::Fn {
872 name: name.clone(),
873 generic_params: generic_params.iter().map(|param| substitute_type(param, params, args)).collect(),
874 args: fn_args.iter().map(|(name, ty)| (name.clone(), substitute_type(ty, params, args))).collect(),
875 body: Box::new(substitute_stmt(body, params, args)),
876 is_pub: *is_pub,
877 },
878 StmtKind::Struct { name, def, is_pub } => StmtKind::Struct { name: name.clone(), def: substitute_type(def, params, args), is_pub: *is_pub },
879 StmtKind::Impl { target, body } => StmtKind::Impl { target: substitute_type(target, params, args), body: Box::new(substitute_stmt(body, params, args)) },
880 StmtKind::If { cond, then_body, else_body } => StmtKind::If {
881 cond: substitute_expr(cond, params, args),
882 then_body: Box::new(substitute_stmt(then_body, params, args)),
883 else_body: else_body.as_ref().map(|body| Box::new(substitute_stmt(body, params, args))),
884 },
885 StmtKind::Static { name, ty, value, is_pub } => {
886 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 }
887 }
888 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 },
889 other => other.clone(),
890 };
891 Stmt::new(kind, stmt.span)
892}
893
894#[derive(Debug, Clone, Default)]
895pub struct Capture {
896 pub names: Vec<(SmolStr, Type)>,
897 pub vars: Vec<usize>,
898}
899
900impl Capture {
901 pub fn new(names: Vec<(SmolStr, Type)>) -> Self {
902 Self { names, vars: Vec::new() }
903 }
904
905 pub fn get(&mut self, name: &str) -> Option<usize> {
906 if let Some(idx) = self.names.iter().position(|n| n.0 == name) {
907 if let Some(pos) = self.vars.iter().position(|v| *v == idx) {
908 Some(pos)
909 } else {
910 self.vars.push(idx);
911 Some(self.vars.len() - 1)
912 }
913 } else {
914 None
915 }
916 }
917
918 pub fn get_type(&self, idx: u32) -> Option<Type> {
919 self.names.get(idx as usize).map(|(_, ty)| ty.clone())
920 }
921}
922
923use anyhow::{Context, Result, anyhow};
924use thiserror::Error;
925
926#[derive(Debug, Error)]
927#[error("{message}")]
928pub struct SpannedCompilerError {
929 pub message: String,
930 pub span: Span,
931}
932
933#[derive(Debug, Clone)]
934pub struct CompilerDiagnostic {
935 pub message: String,
936 pub span: Span,
937}
938
939impl Compiler {
940 pub fn clear(&mut self) {
941 self.sym_tab.frames.clear();
942 self.sym_tab.names.clear();
943 self.sym_tab.tys.clear();
944 self.type_ctx.list_elem_states.clear();
945 self.type_ctx.arg_counts.clear();
946 }
947
948 pub fn take_local_state(&mut self) -> (Vec<usize>, Vec<SmolStr>, Vec<Type>, Vec<Option<ListElemState>>, Vec<usize>) {
949 (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))
950 }
951
952 pub fn restore_local_state(&mut self, state: (Vec<usize>, Vec<SmolStr>, Vec<Type>, Vec<Option<ListElemState>>, Vec<usize>)) {
953 self.sym_tab.frames = state.0;
954 self.sym_tab.names = state.1;
955 self.sym_tab.tys = state.2;
956 self.type_ctx.list_elem_states = state.3;
957 self.type_ctx.arg_counts = state.4;
958 }
959
960 pub fn get_value(&self, expr: &Expr) -> Option<Dynamic> {
961 match &expr.kind {
962 ExprKind::Value(v) => Some(v.clone()),
963 ExprKind::Const(idx) => self.sym_tab.consts.get_index(*idx).map(|(_, v)| v.clone()),
964 _ => None,
965 }
966 }
967
968 pub fn get_const(&mut self, value: Dynamic) -> usize {
969 let key: SmolStr = if value.is_str() {
970 format!("str:{}", value.as_str()).into()
971 } else if value.is_null() {
972 "null".into()
973 } else {
974 format!("{value:?}").into()
975 };
976 if let Some((idx, _, _)) = self.sym_tab.consts.get_full(&key) {
977 return idx;
978 }
979 self.sym_tab.consts.insert_full(key, value).0
980 }
981
982 fn normalize_self_assign(left: Expr, op: BinaryOp, right: Expr, span: Span, arg_count: usize) -> Expr {
983 if let Some(idx) = left.var()
984 && (idx as usize) < arg_count
985 {
986 let base_op = match op {
987 BinaryOp::AddAssign => Some(BinaryOp::Add),
988 BinaryOp::SubAssign => Some(BinaryOp::Sub),
989 BinaryOp::MulAssign => Some(BinaryOp::Mul),
990 BinaryOp::DivAssign => Some(BinaryOp::Div),
991 BinaryOp::ModAssign => Some(BinaryOp::Mod),
992 BinaryOp::ShlAssign => Some(BinaryOp::Shl),
993 BinaryOp::ShrAssign => Some(BinaryOp::Shr),
994 BinaryOp::BitAndAssign => Some(BinaryOp::BitAnd),
995 BinaryOp::BitOrAssign => Some(BinaryOp::BitOr),
996 BinaryOp::BitXorAssign => Some(BinaryOp::BitXor),
997 _ => None,
998 };
999 if let Some(op) = base_op {
1000 let right = Expr::new(ExprKind::Binary { left: Box::new(left.clone()), op, right: Box::new(right) }, span);
1001 return Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Assign, right: Box::new(right) }, span);
1002 }
1003 }
1004 if op == BinaryOp::Assign
1005 && let Some(idx) = left.var()
1006 && idx as usize >= arg_count
1007 && let ExprKind::Binary { left: rhs_left, op: rhs_op, right: rhs_right } = &right.kind
1008 && rhs_left.var() == Some(idx)
1009 {
1010 let compound_op = match rhs_op {
1011 BinaryOp::Add => Some(BinaryOp::AddAssign),
1012 BinaryOp::Sub => Some(BinaryOp::SubAssign),
1013 BinaryOp::Mul => Some(BinaryOp::MulAssign),
1014 BinaryOp::Div => Some(BinaryOp::DivAssign),
1015 BinaryOp::Mod => Some(BinaryOp::ModAssign),
1016 BinaryOp::Shl => Some(BinaryOp::ShlAssign),
1017 BinaryOp::Shr => Some(BinaryOp::ShrAssign),
1018 BinaryOp::BitAnd => Some(BinaryOp::BitAndAssign),
1019 BinaryOp::BitOr => Some(BinaryOp::BitOrAssign),
1020 BinaryOp::BitXor => Some(BinaryOp::BitXorAssign),
1021 _ => None,
1022 };
1023 if let Some(op) = compound_op {
1024 return Expr::new(ExprKind::Binary { left: Box::new(left), op, right: Box::new((**rhs_right).clone()) }, span);
1025 }
1026 }
1027 Expr::new(ExprKind::Binary { left: Box::new(left), op, right: Box::new(right) }, span)
1028 }
1029
1030 pub fn top(&self) -> usize {
1031 self.sym_tab.frames.last().copied().unwrap_or(0)
1032 }
1033
1034 fn add_name(&mut self, name: SmolStr) -> u32 {
1035 self.sym_tab.names.push(name);
1036 (self.sym_tab.names.len() - self.top() - 1) as u32
1037 }
1038
1039 fn list_elem_state_for_ty(ty: &Type) -> Option<ListElemState> {
1040 match ty {
1041 Type::List(elem) if elem.is_any() => Some(ListElemState::Unknown),
1042 Type::List(elem) => Some(ListElemState::Known(elem.as_ref().clone())),
1043 _ => None,
1044 }
1045 }
1046
1047 pub(crate) fn list_elem_state(&self, idx: u32) -> Option<ListElemState> {
1048 self.type_ctx.list_elem_states.get(self.top() + idx as usize).cloned().flatten()
1049 }
1050
1051 pub(crate) fn set_list_elem_state(&mut self, idx: u32, state: Option<ListElemState>) {
1052 let pos = idx as usize + self.top();
1053 if self.type_ctx.list_elem_states.len() <= pos {
1054 self.type_ctx.list_elem_states.resize(pos + 1, None);
1055 }
1056 self.type_ctx.list_elem_states[pos] = state;
1057 }
1058
1059 fn add_ty(&mut self, ty: Type) -> u32 {
1060 self.type_ctx.list_elem_states.push(Self::list_elem_state_for_ty(&ty));
1061 self.sym_tab.tys.push(ty);
1062 (self.sym_tab.tys.len() - self.top() - 1) as u32
1063 }
1064
1065 fn add_temp(&mut self, ty: Type) -> u32 {
1074 self.sym_tab.names.push(SmolStr::new_static(""));
1075 self.type_ctx.list_elem_states.push(Self::list_elem_state_for_ty(&ty));
1076 self.sym_tab.tys.push(ty);
1077 (self.sym_tab.tys.len() - self.top() - 1) as u32
1078 }
1079
1080 fn set_ty(&mut self, idx: u32, ty: Type) {
1081 let pos = idx as usize + self.top();
1082 if self.type_ctx.list_elem_states.len() <= pos {
1083 self.type_ctx.list_elem_states.resize(pos + 1, None);
1084 }
1085 self.type_ctx.list_elem_states[pos] = Self::list_elem_state_for_ty(&ty);
1086 if pos < self.sym_tab.tys.len() {
1087 self.sym_tab.tys[pos] = ty;
1088 } else if pos == self.sym_tab.tys.len() {
1089 self.sym_tab.tys.push(ty);
1090 } else {
1091 self.sym_tab.tys.resize(pos + 1, Type::Any);
1092 self.sym_tab.tys[pos] = ty;
1093 }
1094 }
1095
1096 pub fn add_symbol(&mut self, name: &str, s: Symbol) -> u32 {
1097 self.sym_tab.symbols.add(name.into(), s)
1098 }
1099
1100 pub fn new() -> Self {
1101 Self::default()
1102 }
1103
1104 fn byte_to_line_col(src: &[u8], pos: usize) -> (usize, usize) {
1105 let mut line = 1;
1106 let mut col = 1;
1107 for &b in src.iter().take(pos.min(src.len())) {
1108 if b == b'\n' {
1109 line += 1;
1110 col = 1;
1111 } else {
1112 col += 1;
1113 }
1114 }
1115 (line, col)
1116 }
1117
1118 fn line_snippet(code: &[u8], span: Span) -> String {
1119 let pos = span.start.min(code.len());
1120 let line_start = code[..pos].iter().rposition(|&b| b == b'\n').map(|idx| idx + 1).unwrap_or(0);
1121 let line_end = code[pos..].iter().position(|&b| b == b'\n').map(|idx| pos + idx).unwrap_or(code.len());
1122 String::from_utf8_lossy(&code[line_start..line_end]).into_owned()
1123 }
1124
1125 fn semantic_error(span: Span, message: impl Into<String>) -> anyhow::Error {
1126 SpannedCompilerError { message: message.into(), span }.into()
1127 }
1128
1129 fn format_compile_error(code: &[u8], err: anyhow::Error) -> anyhow::Error {
1130 if let Some(err) = err.downcast_ref::<SpannedCompilerError>() {
1131 return Self::format_span_error(code, err.span, &err.message);
1132 }
1133 if let Some(err) = err.downcast_ref::<parser::ParserErr>() {
1134 return Self::format_span_error(code, err.span(), err.message());
1135 }
1136 if let Some(err) = err.downcast_ref::<parser::SpannedParseError>() {
1137 let pos = err.pos.min(code.len());
1138 let (line, col) = Self::byte_to_line_col(code, pos);
1139 let snippet = Self::line_snippet(code, Span::new(pos, pos));
1140 return anyhow!("解析错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{}\n{}", err.err, snippet);
1141 }
1142 err
1143 }
1144
1145 fn format_span_error(code: &[u8], span: Span, message: &str) -> anyhow::Error {
1146 let pos = span.start.min(code.len());
1147 let (line, col) = Self::byte_to_line_col(code, pos);
1148 let snippet = Self::line_snippet(code, span);
1149 anyhow!("语义错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{}\n{}", message, snippet)
1150 }
1151
1152 pub fn format_source_span(&self, fn_name: &str, span: Span, message: &str) -> String {
1153 let module = fn_name.split_once("::").map(|(module, _)| module).unwrap_or(fn_name);
1154 let Some(source) = self.io.source_files.get(module) else {
1155 return format!("{fn_name}: 字节偏移 {}:{message}", span.start);
1156 };
1157 let code = source.code.as_ref();
1158 let pos = span.start.min(code.len());
1159 let (line, col) = Self::byte_to_line_col(code, pos);
1160 let snippet = Self::line_snippet(code, span);
1161 let location = source.path.as_ref().map(|path| path.display().to_string()).unwrap_or_else(|| module.to_string());
1162 format!("{location}:{line}:{col}: {message}\n{snippet}")
1163 }
1164
1165 pub fn parse_code(code: Vec<u8>) -> Result<Vec<Stmt>> {
1166 let mut p = Parser::new(code.clone());
1167 let mut stmts = Vec::new();
1168 loop {
1169 match p.stmt(false) {
1170 Ok(stmt) => stmts.push(stmt),
1171 Err(e) => {
1172 if p.is_eof() {
1173 return Ok(stmts);
1174 }
1175 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());
1178 let (line, col) = Self::byte_to_line_col(&code, pos);
1179 return Err(anyhow!("解析错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{e:#}\n{}", p.error_stmt()));
1180 }
1181 }
1182 }
1183 }
1184
1185 pub fn parse_code_strict(code: Vec<u8>) -> Result<Vec<Stmt>> {
1189 let mut p = Parser::new(code.clone());
1190 let mut stmts = Vec::new();
1191 loop {
1192 match p.stmt(false) {
1193 Ok(stmt) => stmts.push(stmt),
1194 Err(e) => {
1195 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());
1197 let (line, col) = Self::byte_to_line_col(&code, pos);
1198 let raw = format!("{e:#}");
1199 if p.is_eof() {
1200 if raw.contains("未关闭") || raw.contains("unclosed") {
1206 return Err(anyhow!("解析错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{raw}\n{}", p.error_stmt()));
1207 }
1208 if raw.contains("输入结束") && !stmts.is_empty() {
1209 return Ok(stmts);
1211 }
1212 return Err(anyhow!("解析错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):文件末尾有未关闭或截断的语法结构 (原始错误: {raw})\n{}", p.error_stmt()));
1214 }
1215 return Err(anyhow!("解析错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{raw}\n{}", p.error_stmt()));
1216 }
1217 }
1218 }
1219 }
1220
1221 pub fn parse_source(source: &str) -> Result<Vec<Stmt>> {
1222 Self::parse_code(source.as_bytes().to_vec())
1223 }
1224
1225 pub fn import_code(&mut self, name: &str, code: Vec<u8>) -> Result<Vec<u32>> {
1226 self.import_code_with_source(name, code, None, None, false)
1227 }
1228
1229 pub fn import_source(&mut self, name: &str, source: &str) -> Result<Vec<u32>> {
1230 self.import_code(name, source.as_bytes().to_vec())
1231 }
1232
1233 pub fn import_code_from_path(&mut self, name: &str, code: Vec<u8>, path: impl AsRef<Path>) -> Result<Vec<u32>> {
1234 let path = path.as_ref();
1235 self.import_code_with_source(name, code, path.parent(), Some(path), true)
1236 }
1237
1238 pub fn import_file(&mut self, name: &str, path: impl AsRef<Path>) -> Result<Vec<u32>> {
1239 let path = path.as_ref();
1240 let canonical = std::fs::canonicalize(path).with_context(|| format!("failed to resolve import path {}", path.display()))?;
1241 if !self.io.importing_paths.insert(canonical.clone()) {
1242 return Ok(Vec::new());
1243 }
1244 let code = std::fs::read(&canonical).with_context(|| format!("failed to read import path {}", canonical.display()))?;
1245 let result = self.import_code_from_path(name, code, &canonical);
1246 self.io.importing_paths.remove(&canonical);
1247 result
1248 }
1249
1250 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>> {
1251 self.io.source_files.insert(name.into(), SourceFile { path: source_path.map(Path::to_path_buf), code: Arc::new(code.clone()) });
1252 let stmts = if strict { Self::parse_code_strict(code.clone())? } else { Self::parse_code(code.clone())? };
1253 log::debug!("func->{}", name);
1254 for s in stmts.iter() {
1255 log::debug!("{}", s);
1256 }
1257 self.resolve_imports(&stmts, base_dir).map_err(|err| Self::format_compile_error(&code, err))?;
1258 self.clear();
1259 self.compile(name.into(), stmts).map_err(|err| Self::format_compile_error(&code, err))
1260 }
1261
1262 pub fn resolve_imports(&mut self, stmts: &[Stmt], base_dir: Option<&Path>) -> Result<()> {
1263 for stmt in stmts {
1264 let Some((module, path)) = import_decl(stmt) else {
1265 continue;
1266 };
1267 if !self.sym_tab.symbols.symbol(module.as_str()).is_empty() {
1268 continue;
1269 }
1270 let path = Path::new(path.as_str());
1271 let resolved = if path.is_absolute() {
1272 path.to_path_buf()
1273 } else if let Some(base_dir) = base_dir {
1274 base_dir.join(path)
1275 } else {
1276 std::env::current_dir()?.join(path)
1277 };
1278 self.import_file(module.as_str(), &resolved).with_context(|| format!("failed to import {module} from {}", resolved.display()))?;
1279 }
1280 Ok(())
1281 }
1282
1283 pub fn check_code(name: &str, code: Vec<u8>) -> Vec<CompilerDiagnostic> {
1284 let mut parser = Parser::new(code.clone());
1285 let mut stmts = Vec::new();
1286 loop {
1287 match parser.stmt(false) {
1288 Ok(stmt) => stmts.push(stmt),
1289 Err(err) => {
1290 if parser.is_eof() {
1291 break;
1292 }
1293 return vec![CompilerDiagnostic { message: format!("解析错误:{err:#}"), span: Span::empty(parser.current_pos()) }];
1294 }
1295 }
1296 }
1297
1298 let mut compiler = Self::new();
1299 compiler.clear();
1300 match compiler.compile(name.into(), stmts) {
1301 Ok(_) => Vec::new(),
1302 Err(err) => {
1303 if let Some(err) = err.downcast_ref::<SpannedCompilerError>() {
1304 vec![CompilerDiagnostic { message: err.message.clone(), span: err.span }]
1305 } else {
1306 vec![CompilerDiagnostic { message: format!("{err:#}"), span: Span::default() }]
1307 }
1308 }
1309 }
1310 }
1311
1312 pub fn get_field(&self, ty: &Type, name: &str) -> Result<(usize, Type)> {
1313 self.sym_tab.symbols.get_field(ty, name)
1314 }
1315
1316 pub fn get_ident(&mut self, ident: &str, span: Span) -> Result<Expr> {
1317 for idx in (self.top()..self.sym_tab.names.len()).rev() {
1318 if self.sym_tab.names[idx].eq(ident) {
1319 return Ok(Expr::new(ExprKind::Var((idx - self.top()) as u32), span));
1320 }
1321 }
1322 let id = self.sym_tab.symbols.get_id(ident).map_err(|_| Self::semantic_error(span, format!("未找到标识符 {}", ident)))?;
1323 let s = self.sym_tab.symbols.get_symbol(id).map(|(_, v)| v.clone()).unwrap();
1324 if let Symbol::Const { value, ty, .. } = s {
1325 let c = self.get_const(value);
1326 return Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Const(c), span)), ty }, span));
1327 } else if let Symbol::Static { value, ty, .. } = s
1328 && let Some(v) = value
1329 {
1330 let c = self.get_const(v);
1331 return Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Const(c), span)), ty }, span));
1332 }
1333 Ok(Expr::new(ExprKind::Id(id, None), span))
1334 }
1335
1336 fn field_access_expr(&mut self, left: Expr, idx: usize, ty: Type, key: &str, span: Span) -> Expr {
1337 if let Type::Symbol { id, .. } = ty {
1338 Expr::new(ExprKind::Id(id, Some(Box::new(left))), span)
1339 } else if ty.is_bool() && idx == usize::MAX {
1340 Expr::new(ExprKind::Value(Dynamic::Bool(false)), span)
1341 } else if ty.is_any() && idx == usize::MAX {
1342 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(key.into()))), span);
1343 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, span)
1344 } else {
1345 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)
1346 }
1347 }
1348
1349 fn literal_field_access_expr(&mut self, left: Expr, key: &str, span: Span) -> Expr {
1350 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(key.into()))), span);
1351 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, span)
1352 }
1353
1354 fn type_field_access_expr(&mut self, left: Expr, key: &str, span: Span, prefer_dynamic_field: bool) -> Option<Expr> {
1355 let ty = self.infer_expr(&left).ok()?;
1356 if prefer_dynamic_field && ty.is_any() {
1357 return Some(self.literal_field_access_expr(left, key, span));
1358 }
1359 let (idx, field_ty) = self.get_field(&ty, key).ok()?;
1360 Some(self.field_access_expr(left, idx, field_ty, key, span))
1361 }
1362
1363 fn global_method_access_expr(&self, left: Expr, method: &str, span: Span) -> Result<Option<Expr>> {
1364 let Ok(id) = self.sym_tab.symbols.get_id(method) else {
1365 return Ok(None);
1366 };
1367 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) }
1368 }
1369
1370 fn method_call_obj_expr(&mut self, obj: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Option<Expr>> {
1371 if let ExprKind::TypedMethod { obj: left, ty, name } = &obj.kind {
1372 let left = self.eval(left, stmts, cap)?;
1373 let base_name = match ty {
1374 Type::Ident { name, .. } => name.clone(),
1375 Type::Symbol { id, .. } => self.sym_tab.symbols.get_symbol(*id)?.0.clone(),
1376 _ => return Err(Self::semantic_error(obj.span, format!("方法调用类型提示必须是类型: {:?}", ty))),
1377 };
1378 let method = format!("{}::{}", base_name, name);
1379 let id = self.sym_tab.symbols.get_id(&method).map_err(|_| Self::semantic_error(obj.span, format!("未找到类型方法 {}", method)))?;
1380 return Ok(Some(Expr::new(ExprKind::Id(id, Some(Box::new(left))), obj.span)));
1381 }
1382
1383 let ExprKind::Binary { left, op: BinaryOp::Idx, right } = &obj.kind else {
1384 return Ok(None);
1385 };
1386 let Some(method) = self.get_value(right).and_then(|v| if v.is_str() { Some(v.as_str().to_string()) } else { None }) else {
1387 return Ok(None);
1388 };
1389 let left = self.eval(left, stmts, cap)?;
1390 if let Some(field) = self.type_field_access_expr(left.clone(), &method, obj.span, false) {
1391 return Ok(Some(field));
1392 }
1393 if let Some(method_fn) = self.global_method_access_expr(left.clone(), &method, obj.span)? {
1394 return Ok(Some(method_fn));
1395 }
1396 Ok(Some(self.literal_field_access_expr(left, &method, obj.span)))
1397 }
1398
1399 pub fn compile_fn(&mut self, args: &[SmolStr], tys: &mut Vec<Type>, body: Stmt, cap: &mut Capture) -> Result<Vec<Stmt>> {
1400 let top = self.sym_tab.tys.len();
1401 self.sym_tab.frames.push(top);
1402 self.type_ctx.arg_counts.push(args.len());
1403 let result = (|| -> Result<Vec<Stmt>> {
1404 for (arg, ty) in args.iter().zip(tys.iter_mut()) {
1405 *ty = self.sym_tab.symbols.get_type(ty)?;
1406 self.add_name(arg.clone());
1407 self.add_ty(ty.clone());
1408 }
1409 if cap.names.is_empty() && tys.iter().all(|ty| !ty.is_any()) {
1410 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());
1411 let result = self.check_return_type(&body);
1412 self.restore_local_state(saved_state);
1413 result?;
1414 }
1415 let mut compiled = Vec::new();
1416 self.compile_stmt(body, &mut compiled, cap)?;
1417 if !compiled.last_mut().map(|stmt| stmt.last_return()).unwrap_or(false) {
1418 compiled.push(Stmt::new(StmtKind::Return(None), Span::default()));
1419 }
1420 Ok(compiled)
1421 })();
1422 if let Some(top) = self.sym_tab.frames.pop() {
1423 self.sym_tab.tys.truncate(top);
1424 self.sym_tab.names.truncate(top);
1425 self.type_ctx.list_elem_states.truncate(top);
1426 }
1427 self.type_ctx.arg_counts.pop();
1428 result
1429 }
1430
1431 pub fn compile(&mut self, mod_name: SmolStr, stmts: Vec<Stmt>) -> Result<Vec<u32>> {
1432 self.sym_tab.symbols.add_module(mod_name.clone());
1433 for stmt in stmts {
1434 match stmt.kind {
1435 StmtKind::Struct { name, def, is_pub } => {
1436 self.sym_tab.symbols.add(name, Symbol::Struct(def, is_pub));
1437 }
1438 StmtKind::Static { name, ty, value, is_pub } => {
1439 let value = value.map(|value| self.const_expr_value(&value)).transpose()?;
1440 self.sym_tab.symbols.add(name, Symbol::Static { value, ty, is_pub });
1441 }
1442 StmtKind::Const { name, ty, value, is_pub } => {
1443 let value = self.const_expr_value(&value)?;
1444 let ty = if ty.is_any() { value.get_type() } else { ty };
1445 self.sym_tab.symbols.add(name, Symbol::Const { value, ty, is_pub });
1446 }
1447 StmtKind::Fn { name, generic_params, args, body, is_pub } => {
1448 let (ty, args) = Type::from_args(args);
1449 self.sym_tab.symbols.add(name, Symbol::Fn { ty, args, generic_params, cap: Capture::default(), body: Arc::new(*body), is_pub });
1450 }
1451 StmtKind::Impl { target, body } => {
1452 let name = impl_target_name(&target)?;
1453 let def_id = match self.sym_tab.symbols.get_id(&name) {
1454 Ok(id) => id,
1455 Err(_) if name.as_str() == "Vec" => self.sym_tab.symbols.add(name.clone(), Symbol::Struct(Type::Struct { params: Vec::new(), fields: Vec::new() }, true)),
1456 Err(err) => return Err(err),
1457 };
1458 if let StmtKind::Block(fns) = body.kind {
1459 for f in fns {
1460 if let StmtKind::Fn { name: fn_name, generic_params: fn_generic_params, args, body, is_pub } = f.kind {
1461 let (ty, args) = Type::from_args(args);
1462 let mut generic_params = if has_unresolved_generic_param(&target) {
1463 match &target {
1464 Type::Ident { params, .. } => params.clone(),
1465 _ => Vec::new(),
1466 }
1467 } else {
1468 Vec::new()
1469 };
1470 for param in fn_generic_params {
1471 if !generic_params.contains(¶m) {
1472 generic_params.push(param);
1473 }
1474 }
1475 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 });
1476 if let Symbol::Struct(ty, _) = &mut self.sym_tab.symbols.symbols[def_id as usize] {
1477 ty.add_field(fn_name.into(), Type::Symbol { id: fn_id, params: Vec::new() })?;
1478 }
1479 } else {
1480 log::debug!("impl 包含非函数语句 {:?}", f);
1481 }
1482 }
1483 }
1484 }
1485 StmtKind::Expr(expr, _) if is_top_level_import_expr(&expr) => {}
1486 StmtKind::Import { .. } => {}
1487 _ => return Err(Self::semantic_error(stmt.span, format!("不支持的顶层语句: {:?}", stmt.kind))),
1488 }
1489 }
1490 let mut fn_ids = Vec::new();
1491 for (name, id) in self.sym_tab.symbols.symbol(&mod_name) {
1492 log::debug!("compile symbol {:?}[{}]", name, id);
1493 if let Some((_, Symbol::Fn { ty, generic_params, .. })) = self.sym_tab.symbols.get_symbol(id).ok() {
1494 let resolved_ty = self.sym_tab.symbols.get_type(ty).unwrap_or_else(|_| ty.clone());
1495 if has_unresolved_generic_param(&resolved_ty) || !generic_params.is_empty() {
1496 continue;
1497 }
1498 }
1499 if let Some(s) = self.sym_tab.symbols.get_symbol(id).ok().map(|(_, symbol)| symbol.clone()) {
1500 if let Symbol::Fn { ty, args, generic_params, mut cap, body, is_pub } = s {
1501 if let Type::Fn { mut tys, ret } = ty {
1502 let compiled = self.compile_fn(&args, &mut tys, body.as_ref().clone(), &mut cap)?;
1503 for s in compiled.iter() {
1504 log::debug!("{}", s);
1505 }
1506 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 };
1507 fn_ids.push(id);
1508 }
1509 }
1510 }
1511 }
1512 self.sym_tab.symbols.pop_module();
1513 Ok(fn_ids)
1514 }
1515
1516 fn pat_to_var(&mut self, pat: Pattern, expr_ty: Type) -> Result<Pattern> {
1517 match pat.kind {
1518 PatternKind::Var { idx, ty } => Ok(Pattern { kind: PatternKind::Var { idx, ty }, span: pat.span }),
1519 PatternKind::Ident { name, ty } => {
1520 let ty = self.sym_tab.symbols.get_type(&ty)?;
1521 let ty = if ty.is_any() { expr_ty } else { ty };
1522 self.add_ty(ty.clone());
1523 Ok(Pattern { kind: PatternKind::Var { idx: self.add_name(name), ty }, span: pat.span })
1524 }
1525 PatternKind::Tuple(pats) => {
1526 if let Type::Tuple(tys) = &expr_ty {
1527 if pats.len() != tys.len() {
1528 return Err(Self::semantic_error(pat.span, format!("模式与元组类型不匹配: {:?}", expr_ty)));
1529 }
1530 let pats: Vec<Pattern> = pats.into_iter().zip(tys).map(|p| self.pat_to_var(p.0, p.1.clone())).collect::<Result<_>>()?;
1531 Ok(Pattern { kind: PatternKind::Tuple(pats), span: pat.span })
1532 } else if expr_ty.is_any() {
1533 let pats = pats.into_iter().map(|p| self.pat_to_var(p, Type::Any)).collect::<Result<_>>()?;
1534 Ok(Pattern { kind: PatternKind::Tuple(pats), span: pat.span })
1535 } else {
1536 Err(Self::semantic_error(pat.span, format!("元组模式 {:?} 与类型 {:?} 不匹配", pats, expr_ty)))
1537 }
1538 }
1539 PatternKind::List { elems, has_rest } => {
1540 if expr_ty.is_any() {
1541 let elems: Vec<Pattern> = elems.into_iter().map(|p| self.pat_to_var(p, Type::Any)).collect::<Result<_>>()?;
1542 Ok(Pattern { kind: PatternKind::List { elems, has_rest }, span: pat.span })
1543 } else if let Type::List(elem_ty) | Type::Array(elem_ty, _) | Type::Vec(elem_ty, _) = &expr_ty {
1544 let elems: Vec<Pattern> = elems.into_iter().map(|p| self.pat_to_var(p, elem_ty.as_ref().clone())).collect::<Result<_>>()?;
1545 Ok(Pattern { kind: PatternKind::List { elems, has_rest }, span: pat.span })
1546 } else {
1547 Err(Self::semantic_error(pat.span, format!("列表模式 {:?} 与类型 {:?} 不匹配", elems, expr_ty)))
1548 }
1549 }
1550 PatternKind::Wildcard => {
1551 self.add_ty(expr_ty.clone());
1552 Ok(Pattern { kind: PatternKind::Var { idx: self.add_name(SmolStr::new_static("")), ty: expr_ty }, span: pat.span })
1553 }
1554 _ => Err(Self::semantic_error(pat.span, format!("未知的模式 {:?}", pat))),
1555 }
1556 }
1557
1558 fn infer_range_type(&self, range: &Expr) -> Type {
1559 if let ExprKind::Range { start, stop, .. } = &range.kind {
1560 let start_ty = start.get_type();
1561 let stop_ty = stop.get_type();
1562 if start_ty.is_any() {
1563 stop_ty
1564 } else if stop_ty.is_any() {
1565 start_ty
1566 } else if start_ty == Type::I32 && stop_ty.is_uint() {
1567 stop_ty
1568 } else if stop_ty == Type::I32 && start_ty.is_uint() {
1569 start_ty
1570 } else {
1571 start_ty + stop_ty
1572 }
1573 } else {
1574 range.get_type()
1575 }
1576 }
1577
1578 fn dyn_init(&mut self, expr: Expr, stmts: &mut Vec<Stmt>, items: Vec<(Expr, Expr)>, ty: Type) -> Expr {
1579 self.add_name("".into());
1580 let temp = self.add_ty(ty);
1581 let span = expr.span;
1582 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));
1583 for (idx, item) in items {
1584 let item_span = idx.span.merge(item.span);
1585 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);
1586 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));
1587 }
1588 Expr::new(ExprKind::Var(temp), span)
1589 }
1590
1591 fn is_spawn_closure_call(obj: &Expr, params: &[Expr]) -> bool {
1592 params.len() == 2 && matches!(&obj.kind, ExprKind::Ident(name) if name.as_str() == "spawn") && matches!(¶ms[0].kind, ExprKind::Closure { .. })
1593 }
1594
1595 fn eval_spawn_arg_pack(&mut self, expr: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Expr> {
1596 match &expr.kind {
1597 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)),
1598 _ => Err(Self::semantic_error(expr.span, "spawn closure args must be tuple")),
1599 }
1600 }
1601
1602 fn is_multi_assign_target(expr: &Expr) -> bool {
1603 matches!(expr.kind, ExprKind::Tuple(_) | ExprKind::List(_))
1604 }
1605
1606 fn push_assign(stmts: &mut Vec<Stmt>, left: Expr, right: Expr, span: Span) {
1607 stmts.push(Stmt::new(StmtKind::Expr(Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Assign, right: Box::new(right) }, span), true), span));
1608 }
1609
1610 fn temp_var(&mut self, ty: Type, span: Span) -> Expr {
1611 self.add_name("".into());
1612 let idx = self.add_ty(ty);
1613 Expr::new(ExprKind::Var(idx), span)
1614 }
1615
1616 fn typed_expr(value: Expr, ty: &Type) -> Expr {
1617 if ty.is_any() {
1618 value
1619 } else {
1620 let span = value.span;
1621 Expr::new(ExprKind::Typed { value: Box::new(value), ty: ty.clone() }, span)
1622 }
1623 }
1624
1625 fn lower_multi_assign(&mut self, left: &Expr, right: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture, span: Span) -> Result<Expr> {
1626 let left_items = match &left.kind {
1627 ExprKind::Tuple(items) | ExprKind::List(items) => items,
1628 _ => return Err(Self::semantic_error(left.span, "多重赋值左侧必须是 tuple 或 list")),
1629 };
1630 if left_items.is_empty() {
1631 return Err(Self::semantic_error(left.span, "多重赋值左侧不能为空"));
1632 }
1633
1634 let mut temps = Vec::with_capacity(left_items.len());
1635 if let ExprKind::Tuple(right_items) | ExprKind::List(right_items) = &right.kind {
1636 if left_items.len() != right_items.len() {
1637 return Err(Self::semantic_error(span, format!("多重赋值数量不匹配: 左侧 {} 个,右侧 {} 个", left_items.len(), right_items.len())));
1638 }
1639 for item in right_items {
1640 let value = self.eval(item, stmts, cap)?;
1641 let ty = self.infer_expr(&value)?;
1642 let temp = self.temp_var(ty.clone(), item.span);
1643 Self::push_assign(stmts, temp.clone(), Self::typed_expr(value, &ty), item.span);
1644 temps.push((temp, ty));
1645 }
1646 } else {
1647 let value = self.eval(right, stmts, cap)?;
1648 let ty = self.infer_expr(&value)?;
1649 let source = self.temp_var(ty.clone(), right.span);
1650 Self::push_assign(stmts, source.clone(), Self::typed_expr(value, &ty), right.span);
1651 for idx in 0..left_items.len() {
1652 let item_span = left_items[idx].span;
1653 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);
1654 let value = self.eval(&item, stmts, cap)?;
1655 let ty = self.infer_expr(&value)?;
1656 let temp = self.temp_var(ty.clone(), item_span);
1657 Self::push_assign(stmts, temp.clone(), Self::typed_expr(value, &ty), item_span);
1658 temps.push((temp, ty));
1659 }
1660 }
1661
1662 for (target, (temp, ty)) in left_items.iter().zip(temps.iter()) {
1663 let target = self.eval(target, stmts, cap)?;
1664 let assign_span = target.span.merge(temp.span);
1665 Self::push_assign(stmts, target, Self::typed_expr(temp.clone(), ty), assign_span);
1666 }
1667
1668 Ok(temps.last().map(|(temp, ty)| Self::typed_expr(temp.clone(), ty)).unwrap_or_else(|| Expr::new(ExprKind::Value(Dynamic::Null), span)))
1669 }
1670
1671 fn static_composite_literal(&self, expr: &Expr) -> Result<Option<Dynamic>> {
1672 match &expr.kind {
1673 ExprKind::List(items) | ExprKind::Tuple(items) => {
1674 let mut values = Vec::with_capacity(items.len());
1675 for item in items {
1676 let Some(value) = self.static_literal_value(item)? else {
1677 return Ok(None);
1678 };
1679 values.push(value);
1680 }
1681 Ok(Some(Dynamic::list(values)))
1682 }
1683 ExprKind::Dict(items) => {
1684 let mut values = BTreeMap::new();
1685 for (key, item) in items {
1686 let Some(value) = self.static_literal_value(item)? else {
1687 return Ok(None);
1688 };
1689 values.insert(key.clone(), value);
1690 }
1691 Ok(Some(Dynamic::map(values)))
1692 }
1693 _ => Ok(None),
1694 }
1695 }
1696
1697 fn static_literal_value(&self, expr: &Expr) -> Result<Option<Dynamic>> {
1698 match &expr.kind {
1699 ExprKind::Value(value) => Ok(Some(value.clone())),
1700 ExprKind::Const(idx) => Ok(self.sym_tab.consts.get_index(*idx).map(|(_, v)| v.clone())),
1701 ExprKind::Typed { value, ty } if ty.is_native() => Ok(self.static_literal_value(value)?.map(|value| ty.force(value)).transpose()?),
1702 _ => self.static_composite_literal(expr),
1703 }
1704 }
1705
1706 fn const_expr_value(&self, expr: &Expr) -> Result<Dynamic> {
1707 match &expr.kind {
1708 ExprKind::Value(value) => Ok(value.clone()),
1709 ExprKind::Const(idx) => self.sym_tab.consts.get_index(*idx).map(|(_, v)| v.clone()).ok_or_else(|| Self::semantic_error(expr.span, format!("常量索引 {} 不存在", idx))),
1710 ExprKind::Ident(ident) => {
1711 let id = self.sym_tab.symbols.get_id(ident).map_err(|_| Self::semantic_error(expr.span, format!("未找到常量 {}", ident)))?;
1712 match self.sym_tab.symbols.get_symbol(id).map(|(_, symbol)| symbol) {
1713 Ok(Symbol::Const { value, .. }) => Ok(value.clone()),
1714 Ok(Symbol::Static { value: Some(value), .. }) => Ok(value.clone()),
1715 _ => Err(Self::semantic_error(expr.span, format!("{} 不是可用于 const 的静态值", ident))),
1716 }
1717 }
1718 ExprKind::Typed { value, ty } if ty.is_native() => Ok(ty.force(self.const_expr_value(value)?)?),
1719 ExprKind::Typed { value, .. } => self.const_expr_value(value),
1720 ExprKind::List(items) | ExprKind::Tuple(items) => {
1721 let values = items.iter().map(|item| self.const_expr_value(item)).collect::<Result<Vec<_>>>()?;
1722 Ok(Dynamic::list(values))
1723 }
1724 ExprKind::Dict(items) => {
1725 let mut values = BTreeMap::new();
1726 for (key, item) in items {
1727 values.insert(key.clone(), self.const_expr_value(item)?);
1728 }
1729 Ok(Dynamic::map(values))
1730 }
1731 ExprKind::Unary { op, value } => {
1732 let value = self.const_expr_value(value)?;
1733 match op {
1734 parser::UnaryOp::Neg => Ok(-value),
1735 parser::UnaryOp::Not => Ok(!value),
1736 parser::UnaryOp::Unknow => Err(Self::semantic_error(expr.span, "const 一元表达式无法在编译期求值")),
1737 }
1738 }
1739 ExprKind::Binary { left, op, right } => {
1740 let left = Expr::new(ExprKind::Value(self.const_expr_value(left)?), left.span);
1741 let right = Expr::new(ExprKind::Value(self.const_expr_value(right)?), right.span);
1742 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 二元表达式无法在编译期求值"))
1743 }
1744 _ => Err(Self::semantic_error(expr.span, "const 只能使用字面量、已声明常量和静态 composite literal")),
1745 }
1746 }
1747
1748 fn eval_stmt_expr(&mut self, stmt: &Stmt, stmts: &mut Vec<Stmt>, cap: &mut Capture, span: Span) -> Result<Expr> {
1749 self.compile_stmt(stmt.clone(), stmts, cap)?;
1750 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 };
1751 self.add_name("".into());
1752 let temp = self.add_ty(expr_ty.clone());
1753 let pat = Pattern { kind: PatternKind::Var { idx: temp, ty: expr_ty }, span };
1754 stmts.last_mut().ok_or_else(|| Self::semantic_error(span, "没有生成可求值语句表达式")).and_then(|stmt| stmt.bind_pattern(pat))?;
1755 Ok(Expr::new(ExprKind::Var(temp), span))
1756 }
1757
1758 fn eval(&mut self, expr: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Expr> {
1759 match &expr.kind {
1760 ExprKind::Stmt(stmt) => self.eval_stmt_expr(stmt, stmts, cap, expr.span),
1761 ExprKind::Closure { args, body } => {
1762 let (mut names, mut tys): (Vec<SmolStr>, Vec<Type>) = args.clone().into_iter().unzip();
1763 let top = self.top();
1764 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();
1765 let parent_cap_start = cap_vars.len();
1766 cap_vars.extend(cap.names.iter().cloned());
1767 let mut local_cap = Capture::new(cap_vars);
1768 let _ = self.compile_fn(names.as_slice(), &mut tys.clone(), *body.clone(), &mut local_cap)?;
1769 for cap_idx in local_cap.vars.iter() {
1770 if *cap_idx >= parent_cap_start {
1771 let _ = cap.get(&local_cap.names[*cap_idx].0);
1772 }
1773 names.push(local_cap.names[*cap_idx].0.clone());
1774 tys.push(local_cap.names[*cap_idx].1.clone());
1775 }
1776 let mut compiled = self.compile_fn(names.as_slice(), &mut tys.clone(), *body.clone(), &mut Capture::default())?;
1777 let (ty, args) = Type::from_args(args.clone());
1778 let body_stmt = if compiled.len() == 1 { compiled.pop().unwrap() } else { Stmt::new(StmtKind::Block(compiled), expr.span) };
1779 let name = SmolStr::from(format!("__closure_{}_{}", expr.span.start, expr.span.end));
1780 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 });
1781 Ok(Expr::new(ExprKind::Id(fn_id, None), expr.span))
1782 }
1783 ExprKind::Value(v) => {
1784 if v.is_native() {
1785 Ok(Expr::new(ExprKind::Value(v.clone()), expr.span))
1786 } else {
1787 Ok(Expr::new(ExprKind::Const(self.get_const(v.clone())), expr.span))
1788 }
1789 }
1790 ExprKind::Typed { value, ty } => {
1791 let ty = self.sym_tab.symbols.get_type(ty)?;
1792 if let Type::Struct { fields, .. } = &ty
1793 && let ExprKind::Dict(dict) = &value.kind
1794 {
1795 let mut items = Vec::new();
1796 for field in fields {
1797 if let Some((_, v)) = dict.iter().find(|(name, _)| name == &field.0) {
1798 items.push(self.eval(v, stmts, cap)?);
1799 }
1800 }
1801 Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty }, expr.span))
1802 } else if let Type::Struct { .. } = &ty
1803 && let ExprKind::List(list) = &value.kind
1804 {
1805 let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1806 Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty }, expr.span))
1807 } else if let Type::Array(elem_ty, _) = &ty
1808 && let ExprKind::List(list) = &value.kind
1809 {
1810 let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1811 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))
1812 } else if let Type::Vec(elem_ty, _) = &ty
1813 && let ExprKind::List(list) = &value.kind
1814 {
1815 let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1816 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))
1817 } else if let Type::Array(elem_ty, _) | Type::Vec(elem_ty, _) = &ty
1818 && let ExprKind::Value(Dynamic::List(items)) = &value.kind
1819 {
1820 let items = items.read();
1827 let exprs = items
1828 .iter()
1829 .map(|v| {
1830 let coerced = elem_ty.force(v.clone()).unwrap_or_else(|_| v.clone());
1831 Expr::new(ExprKind::Value(coerced), expr.span)
1832 })
1833 .collect::<Vec<_>>();
1834 let len = exprs.len() as u32;
1835 let new_ty = match &ty {
1836 Type::Array(_, _) => Type::Array(elem_ty.clone(), len),
1837 Type::Vec(_, _) => Type::Vec(elem_ty.clone(), len),
1838 _ => unreachable!(),
1839 };
1840 Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(exprs), expr.span)), ty: new_ty }, expr.span))
1841 } else if value.is_value() {
1842 let value = value.clone().value()?;
1843 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)) }
1847 } else {
1848 Ok(Expr::new(ExprKind::Typed { value: Box::new(self.eval(value, stmts, cap)?), ty }, expr.span))
1849 }
1850 }
1851 ExprKind::Ident(ident) => {
1852 for idx in (self.top()..self.sym_tab.names.len()).rev() {
1854 if self.sym_tab.names[idx].eq(ident) {
1855 return Ok(Expr::new(ExprKind::Var((idx - self.top()) as u32), expr.span));
1856 }
1857 }
1858 if let Some(idx) = cap.get(ident) {
1859 return Ok(Expr::new(ExprKind::Capture(idx as u32), expr.span));
1860 }
1861 self.get_ident(ident, expr.span)
1862 }
1863 ExprKind::Generic { obj, params } => {
1864 let obj = self.eval(obj, stmts, cap)?;
1865 let params = params.iter().map(|param| self.sym_tab.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect();
1866 match obj.kind {
1867 ExprKind::Id(id, None) | ExprKind::AssocId { id, .. } => Ok(Expr::new(ExprKind::AssocId { id, params }, expr.span)),
1868 _ => Err(Self::semantic_error(expr.span, format!("范型参数只能用于函数或关联函数调用: {:?}", obj))),
1869 }
1870 }
1871 ExprKind::Assoc { ty, name } => {
1872 let base_name = match ty {
1873 Type::Ident { name, .. } => name.clone(),
1874 Type::Symbol { id, .. } => self.sym_tab.symbols.get_symbol(*id)?.0.clone(),
1875 _ => return Err(Self::semantic_error(expr.span, format!("关联函数目标必须是类型: {:?}", ty))),
1876 };
1877 let id = self.sym_tab.symbols.get_id(&format!("{}::{}", base_name, name)).map_err(|_| Self::semantic_error(expr.span, format!("未找到关联函数 {}::{}", base_name, name)))?;
1878 let params = match ty {
1879 Type::Ident { params, .. } | Type::Symbol { params, .. } => params.iter().map(|param| self.sym_tab.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect(),
1880 _ => Vec::new(),
1881 };
1882 Ok(Expr::new(ExprKind::AssocId { id, params }, expr.span))
1883 }
1884 ExprKind::Unary { op, value } => {
1885 let value = Expr::new(ExprKind::Unary { op: op.clone(), value: Box::new(self.eval(value, stmts, cap)?) }, expr.span);
1886 if let Some(v) = value.compact() { Ok(Expr::new(ExprKind::Value(v), expr.span)) } else { Ok(value) }
1887 }
1888 ExprKind::Binary { left, op, right } => {
1889 if *op == BinaryOp::Assign && Self::is_multi_assign_target(left) {
1890 return self.lower_multi_assign(left, right, stmts, cap, expr.span);
1891 }
1892 let left = self.eval(left, stmts, cap)?;
1893 if *op == BinaryOp::Idx {
1894 if let Some(key) = self.get_value(right).and_then(|v| if v.is_str() { Some(v.as_str().to_string()) } else { None }) {
1895 if let Some(field) = self.type_field_access_expr(left.clone(), &key, expr.span, true) {
1896 return Ok(field);
1897 }
1898 return Ok(self.literal_field_access_expr(left, &key, expr.span));
1899 } else if let Ok(ident) = right.ident() {
1900 if let Ok(found) = self.get_ident(ident, right.span) {
1901 return Ok(if let Some(id) = found.id() {
1902 Expr::new(ExprKind::Id(id, Some(Box::new(left))), expr.span)
1903 } else {
1904 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(found) }, expr.span)
1905 });
1906 }
1907 if let Ok(ty) = self.infer_expr(&left)
1908 && let Ok((idx, ty)) = self.get_field(&ty, ident)
1909 {
1910 return Ok(if let Type::Symbol { id, .. } = ty {
1911 Expr::new(ExprKind::Id(id, Some(Box::new(left))), expr.span)
1912 } else if ty.is_bool() && idx == usize::MAX {
1913 Expr::new(ExprKind::Value(Dynamic::Bool(false)), expr.span)
1914 } else if ty.is_any() && idx == usize::MAX {
1915 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(ident.into()))), expr.span);
1916 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, expr.span)
1917 } else {
1918 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)
1919 });
1920 } else {
1921 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(ident.into()))), expr.span);
1922 return Ok(Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, expr.span));
1923 }
1924 }
1925 }
1926 let right = self.eval(right, stmts, cap)?;
1927 let value = Self::normalize_self_assign(left, op.clone(), right, expr.span, self.type_ctx.arg_counts.last().copied().unwrap_or(0));
1928 if let Some(v) = value.compact() { Ok(Expr::new(ExprKind::Value(v), expr.span)) } else { Ok(value) }
1929 }
1930 ExprKind::Call { obj, params } => {
1931 let params: Vec<Expr> = if Self::is_spawn_closure_call(obj, params) {
1932 vec![self.eval(¶ms[0], stmts, cap)?, self.eval_spawn_arg_pack(¶ms[1], stmts, cap)?]
1933 } else {
1934 params.iter().map(|p| self.eval(p, stmts, cap)).collect::<Result<Vec<_>>>()?
1935 };
1936 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) };
1937 match obj_result {
1938 Ok(obj) if obj.is_value() && params.is_empty() => Ok(obj),
1939 Ok(obj) => Ok(Expr::new(ExprKind::Call { obj: Box::new(obj), params }, expr.span)),
1940 Err(e) => {
1941 Err(Self::semantic_error(obj.span, format!("未注册函数 {:?}: {}", obj.kind, e)))
1944 }
1945 }
1946 }
1947 ExprKind::Range { start, stop, inclusive } => {
1948 let start = Box::new(self.eval(start, stmts, cap)?);
1949 let stop = Box::new(self.eval(stop, stmts, cap)?);
1950 Ok(Expr::new(ExprKind::Range { start, stop, inclusive: *inclusive }, expr.span))
1951 }
1952 ExprKind::List(list) | ExprKind::Tuple(list) => {
1953 if let Some(value) = self.static_composite_literal(expr)? {
1954 let idx = self.get_const(value);
1955 return Ok(Expr::new(ExprKind::Const(idx), expr.span));
1956 }
1957 let mut v = Vec::new();
1958 let mut items = Vec::new();
1959 for (idx, item) in list.iter().enumerate() {
1960 if item.is_value() {
1961 v.push(item.clone().value().unwrap());
1962 } else {
1963 items.push((Expr::new(ExprKind::Value((idx as u32).into()), item.span), self.eval(item, stmts, cap)?));
1964 v.push(Dynamic::Null);
1965 }
1966 }
1967 let list = Expr::new(ExprKind::Const(self.get_const(Dynamic::list(v))), expr.span);
1968 Ok(self.dyn_init(list, stmts, items, Type::Any))
1969 }
1970 ExprKind::Repeat { value, len } => {
1971 let len = self.sym_tab.symbols.get_type(len)?;
1972 let Type::ConstInt(len) = len else {
1973 return Err(Self::semantic_error(expr.span, format!("重复数组长度必须是编译期整数: {:?}", len)));
1974 };
1975 if len < 0 {
1976 return Err(Self::semantic_error(expr.span, "重复数组长度不能为负数"));
1977 }
1978 Ok(Expr::new(ExprKind::Repeat { value: Box::new(self.eval(value, stmts, cap)?), len: Type::ConstInt(len) }, expr.span))
1979 }
1980 ExprKind::Dict(dict) => {
1981 if let Some(value) = self.static_composite_literal(expr)? {
1982 let idx = self.get_const(value);
1983 return Ok(Expr::new(ExprKind::Const(idx), expr.span));
1984 }
1985 let mut dyn_kv = Vec::new();
1986 let mut m = BTreeMap::new();
1987 for (k, v) in dict {
1988 if v.is_value() {
1989 m.insert(k.clone(), v.clone().value()?);
1990 } else {
1991 let key = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(k.clone()))), v.span);
1992 dyn_kv.push((key, self.eval(v, stmts, cap)?));
1993 m.insert(k.clone(), Dynamic::Null);
1994 }
1995 }
1996 let dict = Expr::new(ExprKind::Const(self.get_const(Dynamic::map(m))), expr.span);
1997 Ok(self.dyn_init(dict, stmts, dyn_kv, Type::Any))
1998 }
1999 ExprKind::Id(_, _) | ExprKind::AssocId { .. } => Ok(expr.clone()),
2000 _ => Ok(expr.clone()),
2001 }
2002 }
2003
2004 fn get_stmt(&mut self, stmt: Stmt, cap: &mut Capture) -> Result<Stmt> {
2005 let span = stmt.span;
2006 let mut stmts = Vec::new();
2007 self.compile_stmt(stmt, &mut stmts, cap)?;
2008 Ok(Stmt::new(StmtKind::Block(stmts), span))
2009 }
2010
2011 fn compile_stmt(&mut self, stmt: Stmt, compiled: &mut Vec<Stmt>, cap: &mut Capture) -> Result<()> {
2012 let stmt_span = stmt.span;
2013 match stmt.kind {
2014 StmtKind::Let { pat, value } => {
2015 if let PatternKind::Tuple(pats) = &pat.kind
2020 && let StmtKind::Expr(expr, _) = &value.kind
2021 && let ExprKind::Tuple(items) = &expr.kind
2022 {
2023 if pats.len() != items.len() {
2024 return Err(Self::semantic_error(stmt_span, format!("元组解构长度不匹配: 模式 {} 个,值 {} 个", pats.len(), items.len())));
2025 }
2026 for (p, item) in pats.iter().zip(items.iter()) {
2027 let inner = Stmt::new(StmtKind::Let { pat: p.clone(), value: Box::new(Stmt::new(StmtKind::Expr(item.clone(), false), item.span)) }, stmt_span);
2028 self.compile_stmt(inner, compiled, cap)?;
2029 }
2030 return Ok(());
2031 }
2032 let value = *value;
2033 let annotated_ty = if let PatternKind::Ident { ty, .. } = &pat.kind {
2034 let ty = self.sym_tab.symbols.get_type(ty)?;
2035 if ty.is_any() { None } else { Some(ty) }
2036 } else {
2037 None
2038 };
2039 let pattern_expr_ty = if matches!(pat.kind, PatternKind::List { .. } | PatternKind::Tuple(_)) {
2040 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 }
2041 } else {
2042 None
2043 };
2044 if let Some(ty) = annotated_ty {
2045 if let StmtKind::Expr(expr, close) = value.kind {
2046 let span = expr.span;
2047 let typed = Expr::new(ExprKind::Typed { value: Box::new(expr), ty }, span);
2048 self.compile_stmt(Stmt::new(StmtKind::Expr(typed, close), value.span), compiled, cap)?;
2049 } else {
2050 self.compile_stmt(value, compiled, cap)?;
2051 }
2052 } else {
2053 self.compile_stmt(value, compiled, cap)?;
2054 }
2055 let expr_ty = if let Some(ty) = pattern_expr_ty {
2056 ty
2057 } else if let Some(stmt) = compiled.last() {
2058 if let StmtKind::Expr(expr, _) = &stmt.kind { self.infer_expr(expr)? } else { self.infer_stmt(stmt)? }
2059 } else {
2060 Type::Any
2061 };
2062 let pat = self.pat_to_var(pat, expr_ty.clone())?;
2063 if matches!(pat.kind, PatternKind::Tuple(_) | PatternKind::List { .. }) {
2064 let temp = self.add_temp(expr_ty.clone());
2068 let temp_pat = Pattern { kind: PatternKind::Var { idx: temp, ty: expr_ty }, span: stmt_span };
2069 compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "没有生成可绑定模式的编译语句")).and_then(|stmt| stmt.bind_pattern(temp_pat))?;
2070 let temp_expr = Expr::new(ExprKind::Var(temp), stmt_span);
2071 compiled.push(Stmt::new(StmtKind::Expr(temp_expr, false), stmt_span));
2072 compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "临时变量 stmt 缺失")).and_then(|stmt| stmt.bind_pattern(pat))?;
2073 } else {
2074 compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "没有生成可绑定模式的编译语句")).and_then(|stmt| stmt.bind_pattern(pat))?;
2075 }
2076 }
2077 StmtKind::Expr(expr, close) => {
2078 if let ExprKind::Binary { left, op: BinaryOp::Assign, right } = &expr.kind
2079 && Self::is_multi_assign_target(left)
2080 {
2081 self.lower_multi_assign(left, right, compiled, cap, stmt_span)?;
2082 return Ok(());
2083 }
2084 let e = self.eval(&expr, compiled, cap)?;
2085 compiled.push(Stmt::new(StmtKind::Expr(e, close), stmt_span));
2086 }
2087 StmtKind::Block(stmts) => {
2088 let mut block = Vec::new();
2089 for stmt in stmts {
2090 self.compile_stmt(stmt, &mut block, cap)?;
2091 }
2092 compiled.push(Stmt::new(StmtKind::Block(block), stmt_span));
2093 }
2094 StmtKind::Fn { name, generic_params, args, body, is_pub } => {
2095 let (ty, args) = Type::from_args(args);
2096 if let Type::Fn { mut tys, ret } = ty {
2097 let mut fn_cap = Capture::default();
2098 let compiled_body = self.compile_fn(&args, &mut tys, *body, &mut fn_cap)?;
2099 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 });
2100 } else {
2101 panic!("nested functions are not supported here")
2102 }
2103 }
2104 StmtKind::Return(expr) => {
2105 let expr = expr.map(|e| self.eval(&e, compiled, cap)).transpose()?;
2106 compiled.push(Stmt::new(StmtKind::Return(expr), stmt_span));
2107 }
2108 StmtKind::If { cond, then_body, else_body } => {
2109 let cond = self.eval(&cond, compiled, cap)?;
2110 if let Some(cond_value) = cond.compact()
2111 && let Some(cond_bool) = cond_value.as_bool()
2112 {
2113 if cond_bool {
2114 self.compile_stmt(*then_body, compiled, cap)?;
2115 } else if let Some(body) = else_body {
2116 self.compile_stmt(*body, compiled, cap)?;
2117 }
2118 } else {
2119 let then_body = Box::new(self.get_stmt(*then_body, cap)?);
2120 let else_body = if let Some(body) = else_body { Some(Box::new(self.get_stmt(*body, cap)?)) } else { None };
2121 compiled.push(Stmt::new(StmtKind::If { cond, then_body, else_body }, stmt_span));
2122 }
2123 }
2124 StmtKind::Loop(body) => {
2125 compiled.push(Stmt::new(StmtKind::Loop(Box::new(self.get_stmt(*body, cap)?)), stmt_span));
2126 }
2127 StmtKind::While { cond, body } => {
2128 let cond = self.eval(&cond, compiled, cap)?;
2129 compiled.push(Stmt::new(StmtKind::While { cond, body: Box::new(self.get_stmt(*body, cap)?) }, stmt_span));
2130 }
2131 StmtKind::For { pat, range, body } => {
2132 let range = self.eval(&range, compiled, cap)?;
2133 let range_ty = self.infer_range_type(&range);
2134 let pat = self.pat_to_var(pat, range_ty)?;
2135 compiled.push(Stmt::new(StmtKind::For { pat, range, body: Box::new(self.get_stmt(*body, cap)?) }, stmt_span));
2136 }
2137 stmt_kind => {
2138 compiled.push(Stmt::new(stmt_kind, stmt_span));
2139 }
2140 }
2141 Ok(())
2142 }
2143}