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