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