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,
15 Done(Type),
16}
17
18#[derive(Clone)]
19pub struct Compiler {
20 pub symbols: SymbolTable,
21 pub frames: Vec<usize>,
22 pub tys: Vec<Type>,
23 pub consts: Vec<Dynamic>,
24 names: Vec<SmolStr>,
25 fns: BTreeMap<u32, Vec<(Vec<Type>, Vec<Type>, FnInferRet)>>,
26 importing_paths: BTreeSet<PathBuf>,
27}
28
29fn impl_target_name(target: &Type) -> anyhow::Result<SmolStr> {
30 match target {
31 Type::Ident { name, .. } => Ok(name.clone()),
32 _ => anyhow::bail!("impl 目标类型暂不支持: {:?}", target),
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::{Compiler, Symbol};
39 use dynamic::Type;
40
41 #[test]
42 fn inferred_function_return_type_is_written_back_to_symbol() -> anyhow::Result<()> {
43 let mut compiler = Compiler::new();
44 compiler.import_code(
45 "compiler_infer_return",
46 br#"
47 pub fn is_alive() {
48 true
49 }
50
51 pub fn can_act() {
52 is_alive() && true && is_alive()
53 }
54 "#
55 .to_vec(),
56 )?;
57
58 let is_alive = compiler.symbols.get_id("compiler_infer_return::is_alive")?;
59 assert_eq!(compiler.infer_fn(is_alive, &[])?, Type::Bool);
60
61 let (_, symbol) = compiler.symbols.get_symbol(is_alive)?;
62 let Symbol::Fn { ty: Type::Fn { ret, .. }, .. } = symbol else {
63 panic!("is_alive should be a function symbol");
64 };
65 assert_eq!(ret.as_ref(), &Type::Bool);
66
67 let can_act = compiler.symbols.get_id("compiler_infer_return::can_act")?;
68 assert_eq!(compiler.infer_fn(can_act, &[])?, Type::Bool);
69 Ok(())
70 }
71
72 #[test]
73 fn top_level_const_composite_resolves_const_idents() -> anyhow::Result<()> {
74 let mut compiler = Compiler::new();
75 compiler.import_code(
76 "compiler_const_table",
77 br#"
78 pub const GEM_ATK = "atk";
79 pub const GEM_DEF = "def";
80 pub const GEM_TABLE = [
81 { key: GEM_ATK, score: 3i32 },
82 { key: GEM_DEF, score: 1i32 },
83 ];
84 "#
85 .to_vec(),
86 )?;
87
88 let table = compiler.symbols.get_id("compiler_const_table::GEM_TABLE")?;
89 let (_, symbol) = compiler.symbols.get_symbol(table)?;
90 let Symbol::Const { value, .. } = symbol else {
91 panic!("GEM_TABLE should be a const symbol");
92 };
93
94 let first = value.get_idx(0).expect("first table row");
95 assert_eq!(first.get_dynamic("key").expect("key").as_str(), "atk");
96 assert_eq!(first.get_dynamic("score").expect("score").as_int(), Some(3));
97 Ok(())
98 }
99
100 #[test]
101 fn const_unary_neg_handles_min_integer_literal() -> anyhow::Result<()> {
102 let mut compiler = Compiler::new();
103 compiler.import_code(
104 "compiler_const_min_int",
105 br#"
106 pub const MIN_I32: i32 = -2147483648i32;
107 "#
108 .to_vec(),
109 )?;
110
111 let id = compiler.symbols.get_id("compiler_const_min_int::MIN_I32")?;
112 let (_, symbol) = compiler.symbols.get_symbol(id)?;
113 let Symbol::Const { value, .. } = symbol else {
114 panic!("MIN_I32 should be a const symbol");
115 };
116 assert_eq!(value.as_int(), Some(i32::MIN as i64));
117 Ok(())
118 }
119
120 #[test]
121 fn return_check_resolves_function_args_before_body_compile() -> anyhow::Result<()> {
122 let mut compiler = Compiler::new();
123 compiler.import_code(
124 "compiler_return_check_args",
125 br#"
126 pub fn no_value_return(flag: bool) {
127 if flag {
128 return;
129 }
130 }
131
132 pub fn tail_if(flag: bool) {
133 if flag {
134 1
135 } else {
136 2
137 }
138 }
139
140 pub fn loop_index(low: i64, high: i64) {
141 let total = 0i64;
142 for i in low..high {
143 total += i;
144 }
145 total
146 }
147
148 pub fn closure_capture() {
149 let base = 10i32;
150 let add_base = |value: i32| {
151 value + base
152 };
153 add_base(1i32)
154 }
155
156 pub fn destructured_names() {
157 let (left, right) = (3i32, 4i32);
158 let [first, second] = [5i32, 6i32];
159 let _ = first;
160 left + right + second
161 }
162 "#
163 .to_vec(),
164 )?;
165
166 let no_value_return = compiler.symbols.get_id("compiler_return_check_args::no_value_return")?;
167 assert_eq!(compiler.infer_fn(no_value_return, &[Type::Bool])?, Type::Void);
168
169 let tail_if = compiler.symbols.get_id("compiler_return_check_args::tail_if")?;
170 assert_eq!(compiler.infer_fn(tail_if, &[Type::Bool])?, Type::I32);
171
172 let loop_index = compiler.symbols.get_id("compiler_return_check_args::loop_index")?;
173 assert_eq!(compiler.infer_fn(loop_index, &[Type::I64, Type::I64])?, Type::I64);
174
175 Ok(())
176 }
177
178 #[test]
179 fn forward_function_call_in_bool_condition_infers_callee_first() -> anyhow::Result<()> {
180 let mut compiler = Compiler::new();
181 compiler.import_code(
182 "compiler_forward_bool",
183 br#"
184 pub fn can_start() {
185 if is_ready() {
186 return true;
187 }
188 false
189 }
190
191 pub fn is_ready() {
192 true
193 }
194 "#
195 .to_vec(),
196 )?;
197
198 let can_start = compiler.symbols.get_id("compiler_forward_bool::can_start")?;
199 assert_eq!(compiler.infer_fn(can_start, &[])?, Type::Bool);
200
201 let is_ready = compiler.symbols.get_id("compiler_forward_bool::is_ready")?;
202 assert_eq!(compiler.infer_fn(is_ready, &[])?, Type::Bool);
203 Ok(())
204 }
205
206 #[test]
207 fn inferred_return_cache_keeps_pending_separate_from_any() -> anyhow::Result<()> {
208 let mut compiler = Compiler::new();
209 compiler.import_code(
210 "compiler_pending_any",
211 br#"
212 pub fn dynamic_value(value) {
213 value
214 }
215
216 pub fn bool_value() {
217 true
218 }
219 "#
220 .to_vec(),
221 )?;
222
223 let dynamic_value = compiler.symbols.get_id("compiler_pending_any::dynamic_value")?;
224 assert_eq!(compiler.infer_fn(dynamic_value, &[Type::Any])?, Type::Any);
225
226 let bool_value = compiler.symbols.get_id("compiler_pending_any::bool_value")?;
227 assert_eq!(compiler.infer_fn(bool_value, &[])?, Type::Bool);
228 Ok(())
229 }
230
231 #[test]
232 fn return_map_and_struct_is_type_error() -> anyhow::Result<()> {
233 let mut compiler = Compiler::new();
234 let err = match compiler.import_code(
235 "compiler_return_map_struct",
236 br#"
237 struct S {
238 hp: i32,
239 }
240
241 pub fn make_s_or_error(flag: i32) {
242 if flag == 0 {
243 return { error: "bad" };
244 }
245 S{hp: 123}
246 }
247 "#
248 .to_vec(),
249 ) {
250 Ok(_) => panic!("expected mismatched return types to fail"),
251 Err(err) => err,
252 };
253
254 assert!(format!("{err:#}").contains("返回类型不一致"));
255 Ok(())
256 }
257}
258
259fn has_unresolved_generic_param(ty: &Type) -> bool {
260 match ty {
261 Type::Ident { name, params } => {
262 if params.is_empty() {
263 name.chars().next().map(|ch| ch.is_ascii_uppercase()).unwrap_or(false)
264 } else {
265 params.iter().any(has_unresolved_generic_param)
266 }
267 }
268 Type::Struct { params, fields } => params.iter().any(has_unresolved_generic_param) || fields.iter().any(|(_, ty)| has_unresolved_generic_param(ty)),
269 Type::Tuple(items) => items.iter().any(has_unresolved_generic_param),
270 Type::Vec(elem, _) | Type::Array(elem, _) => has_unresolved_generic_param(elem),
271 Type::ArrayParam(elem, len) => has_unresolved_generic_param(elem) || has_unresolved_generic_param(len),
272 Type::Fn { tys, ret } => tys.iter().any(has_unresolved_generic_param) || has_unresolved_generic_param(ret),
273 Type::Symbol { params, .. } => params.iter().any(has_unresolved_generic_param),
274 Type::ConstBinary { left, right, .. } => has_unresolved_generic_param(left) || has_unresolved_generic_param(right),
275 _ => false,
276 }
277}
278
279fn is_top_level_import_expr(expr: &Expr) -> bool {
280 matches!(
281 &expr.kind,
282 ExprKind::Call { obj, .. } if matches!(&obj.kind, ExprKind::Ident(name) if name.as_str() == "import")
283 )
284}
285
286fn string_value(expr: &Expr) -> Option<&str> {
287 if let ExprKind::Value(Dynamic::String(value)) = &expr.kind { Some(value.as_str()) } else { None }
288}
289
290fn import_decl(stmt: &Stmt) -> Option<(SmolStr, SmolStr)> {
291 let StmtKind::Expr(expr, _) = &stmt.kind else {
292 return None;
293 };
294 let ExprKind::Call { obj, params } = &expr.kind else {
295 return None;
296 };
297 let ExprKind::Ident(name) = &obj.kind else {
298 return None;
299 };
300 if name.as_str() != "import" {
301 return None;
302 }
303
304 match params.as_slice() {
305 [module, path] => Some((string_value(module)?.into(), string_value(path)?.into())),
306 [module] => match &module.kind {
307 ExprKind::Value(Dynamic::String(value)) => Some((value.clone(), format!("{value}.zs").into())),
308 ExprKind::Ident(value) => Some((value.clone(), format!("{value}.zs").into())),
309 _ => None,
310 },
311 _ => None,
312 }
313}
314
315fn generic_arg_for_name<'a>(name: &str, params: &'a [Type], args: &'a [Type]) -> Option<&'a Type> {
316 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))
317}
318
319pub fn infer_generic_args_from_types(generic_params: &[Type], decl_tys: &[Type], arg_tys: &[Type]) -> Vec<Type> {
320 if generic_params.is_empty() {
321 return Vec::new();
322 }
323 let mut inferred = vec![None; generic_params.len()];
324 for (decl, actual) in decl_tys.iter().zip(arg_tys.iter()) {
325 infer_generic_arg_from_type(generic_params, decl, actual, &mut inferred);
326 }
327 if inferred.iter().all(|item| item.is_some()) {
328 return inferred.into_iter().map(Option::unwrap).collect();
329 }
330 if let Some(Type::Struct { params, .. }) = arg_tys.iter().find(|ty| matches!(ty, Type::Struct { params, .. } if params.len() == generic_params.len())) {
331 return params.clone();
332 }
333 for (decl, actual) in decl_tys.iter().zip(arg_tys.iter()) {
334 if let (Type::Ident { params: decl_params, .. }, Type::Ident { params: actual_params, .. }) = (decl, actual)
335 && decl_params.len() == actual_params.len()
336 && decl_params.iter().any(|param| generic_params.contains(param))
337 {
338 return actual_params.clone();
339 }
340 }
341 Vec::new()
342}
343
344fn infer_generic_arg_from_type(generic_params: &[Type], decl: &Type, actual: &Type, inferred: &mut [Option<Type>]) {
345 if let Some(idx) = generic_params.iter().position(|param| param == decl) {
346 inferred[idx] = Some(actual.clone());
347 return;
348 }
349
350 match (decl, actual) {
351 (Type::Vec(decl_elem, decl_len), Type::Vec(actual_elem, actual_len)) | (Type::Array(decl_elem, decl_len), Type::Array(actual_elem, actual_len)) => {
352 infer_generic_arg_from_type(generic_params, decl_elem, actual_elem, inferred);
353 infer_generic_arg_from_type(generic_params, &Type::ConstInt(*decl_len as i64), &Type::ConstInt(*actual_len as i64), inferred);
354 }
355 (Type::ArrayParam(decl_elem, decl_len), Type::Array(actual_elem, actual_len)) => {
356 infer_generic_arg_from_type(generic_params, decl_elem, actual_elem, inferred);
357 infer_generic_arg_from_type(generic_params, decl_len, &Type::ConstInt(*actual_len as i64), inferred);
358 }
359 (Type::Ident { params: decl_params, .. }, Type::Ident { params: actual_params, .. })
360 | (Type::Ident { params: decl_params, .. }, Type::Symbol { params: actual_params, .. })
361 | (Type::Symbol { params: decl_params, .. }, Type::Symbol { params: actual_params, .. })
362 | (Type::Symbol { params: decl_params, .. }, Type::Ident { params: actual_params, .. })
363 | (Type::Struct { params: decl_params, .. }, Type::Struct { params: actual_params, .. }) => {
364 for (decl, actual) in decl_params.iter().zip(actual_params.iter()) {
365 infer_generic_arg_from_type(generic_params, decl, actual, inferred);
366 }
367 }
368 _ => {}
369 }
370}
371
372fn substitute_pattern(pattern: &Pattern, params: &[Type], args: &[Type]) -> Pattern {
373 let kind = match &pattern.kind {
374 PatternKind::Ident { name, ty } => PatternKind::Ident { name: name.clone(), ty: substitute_type(ty, params, args) },
375 PatternKind::Var { idx, ty } => PatternKind::Var { idx: *idx, ty: substitute_type(ty, params, args) },
376 PatternKind::Tuple(items) => PatternKind::Tuple(items.iter().map(|item| substitute_pattern(item, params, args)).collect()),
377 PatternKind::List { elems, has_rest } => PatternKind::List { elems: elems.iter().map(|item| substitute_pattern(item, params, args)).collect(), has_rest: *has_rest },
378 other => other.clone(),
379 };
380 Pattern { kind, span: pattern.span }
381}
382
383fn substitute_expr(expr: &Expr, params: &[Type], args: &[Type]) -> Expr {
384 let kind = match &expr.kind {
385 ExprKind::Ident(name) => match generic_arg_for_name(name, params, args) {
386 Some(Type::ConstInt(value)) => ExprKind::Value(Dynamic::I32(*value as i32)),
387 Some(ty) => eval_const_int_type(ty).map(|value| ExprKind::Value(Dynamic::I32(value as i32))).unwrap_or_else(|| expr.kind.clone()),
388 _ => expr.kind.clone(),
389 },
390 ExprKind::Typed { value, ty } => ExprKind::Typed { value: Box::new(substitute_expr(value, params, args)), ty: substitute_type(ty, params, args) },
391 ExprKind::Unary { op, value } => ExprKind::Unary { op: op.clone(), value: Box::new(substitute_expr(value, params, args)) },
392 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)) },
393 ExprKind::Assoc { ty, name } => ExprKind::Assoc { ty: substitute_type(ty, params, args), name: name.clone() },
394 ExprKind::TypedMethod { obj, ty, name } => ExprKind::TypedMethod { obj: Box::new(substitute_expr(obj, params, args)), ty: substitute_type(ty, params, args), name: name.clone() },
395 ExprKind::AssocId { id, params: nested } => ExprKind::AssocId { id: *id, params: nested.iter().map(|param| substitute_type(param, params, args)).collect() },
396 ExprKind::Tuple(items) => ExprKind::Tuple(items.iter().map(|item| substitute_expr(item, params, args)).collect()),
397 ExprKind::List(items) => ExprKind::List(items.iter().map(|item| substitute_expr(item, params, args)).collect()),
398 ExprKind::Repeat { value, len } => ExprKind::Repeat { value: Box::new(substitute_expr(value, params, args)), len: substitute_type(len, params, args) },
399 ExprKind::Dict(items) => ExprKind::Dict(items.iter().map(|(name, value)| (name.clone(), substitute_expr(value, params, args))).collect()),
400 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 },
401 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() },
402 ExprKind::Stmt(stmt) => ExprKind::Stmt(Box::new(substitute_stmt(stmt, params, args))),
403 ExprKind::Closure { args: closure_args, body } => {
404 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)) }
405 }
406 _ => expr.kind.clone(),
407 };
408 Expr::new(kind, expr.span)
409}
410
411pub fn substitute_stmt(stmt: &Stmt, params: &[Type], args: &[Type]) -> Stmt {
412 let kind = match &stmt.kind {
413 StmtKind::Let { pat, value } => StmtKind::Let { pat: substitute_pattern(pat, params, args), value: Box::new(substitute_stmt(value, params, args)) },
414 StmtKind::Expr(expr, close) => StmtKind::Expr(substitute_expr(expr, params, args), *close),
415 StmtKind::Block(stmts) => StmtKind::Block(stmts.iter().map(|stmt| substitute_stmt(stmt, params, args)).collect()),
416 StmtKind::Return(expr) => StmtKind::Return(expr.as_ref().map(|expr| substitute_expr(expr, params, args))),
417 StmtKind::While { cond, body } => StmtKind::While { cond: substitute_expr(cond, params, args), body: Box::new(substitute_stmt(body, params, args)) },
418 StmtKind::Loop(body) => StmtKind::Loop(Box::new(substitute_stmt(body, params, args))),
419 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)) },
420 StmtKind::Fn { name, generic_params, args: fn_args, body, is_pub } => StmtKind::Fn {
421 name: name.clone(),
422 generic_params: generic_params.iter().map(|param| substitute_type(param, params, args)).collect(),
423 args: fn_args.iter().map(|(name, ty)| (name.clone(), substitute_type(ty, params, args))).collect(),
424 body: Box::new(substitute_stmt(body, params, args)),
425 is_pub: *is_pub,
426 },
427 StmtKind::Struct { name, def, is_pub } => StmtKind::Struct { name: name.clone(), def: substitute_type(def, params, args), is_pub: *is_pub },
428 StmtKind::Impl { target, body } => StmtKind::Impl { target: substitute_type(target, params, args), body: Box::new(substitute_stmt(body, params, args)) },
429 StmtKind::If { cond, then_body, else_body } => StmtKind::If {
430 cond: substitute_expr(cond, params, args),
431 then_body: Box::new(substitute_stmt(then_body, params, args)),
432 else_body: else_body.as_ref().map(|body| Box::new(substitute_stmt(body, params, args))),
433 },
434 StmtKind::Static { name, ty, value, is_pub } => {
435 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 }
436 }
437 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 },
438 other => other.clone(),
439 };
440 Stmt::new(kind, stmt.span)
441}
442
443#[derive(Debug, Clone, Default)]
444pub struct Capture {
445 pub names: Vec<(SmolStr, Type)>,
446 pub vars: Vec<usize>,
447}
448
449impl Capture {
450 pub fn new(names: Vec<(SmolStr, Type)>) -> Self {
451 Self { names, vars: Vec::new() }
452 }
453
454 pub fn get(&mut self, name: &str) -> Option<usize> {
455 if let Some(idx) = self.names.iter().position(|n| n.0 == name) {
456 if let Some(pos) = self.vars.iter().position(|v| *v == idx) {
457 Some(pos)
458 } else {
459 self.vars.push(idx);
460 Some(self.vars.len() - 1)
461 }
462 } else {
463 None
464 }
465 }
466
467 pub fn get_type(&self, idx: u32) -> Option<Type> {
468 self.names.get(idx as usize).map(|(_, ty)| ty.clone())
469 }
470}
471
472use anyhow::{Context, Result, anyhow};
473use smol_str::SmolStr;
474use thiserror::Error;
475
476#[derive(Debug, Error)]
477#[error("{message}")]
478pub struct SpannedCompilerError {
479 pub message: String,
480 pub span: Span,
481}
482
483#[derive(Debug, Clone)]
484pub struct CompilerDiagnostic {
485 pub message: String,
486 pub span: Span,
487}
488
489impl Compiler {
490 pub fn clear(&mut self) {
491 self.frames.clear();
492 self.names.clear();
493 self.tys.clear();
494 }
495
496 pub fn take_local_state(&mut self) -> (Vec<usize>, Vec<SmolStr>, Vec<Type>) {
497 (std::mem::take(&mut self.frames), std::mem::take(&mut self.names), std::mem::take(&mut self.tys))
498 }
499
500 pub fn restore_local_state(&mut self, state: (Vec<usize>, Vec<SmolStr>, Vec<Type>)) {
501 self.frames = state.0;
502 self.names = state.1;
503 self.tys = state.2;
504 }
505
506 pub fn get_value(&self, expr: &Expr) -> Option<Dynamic> {
507 match &expr.kind {
508 ExprKind::Value(v) => Some(v.clone()),
509 ExprKind::Const(idx) => self.consts.get(*idx).cloned(),
510 _ => None,
511 }
512 }
513
514 pub fn get_const(&mut self, value: Dynamic) -> usize {
515 self.consts.iter().position(|c| c == &value).unwrap_or_else(|| {
516 self.consts.push(value);
517 self.consts.len() - 1
518 })
519 }
520
521 pub fn top(&self) -> usize {
522 self.frames.last().copied().unwrap_or(0)
523 }
524
525 fn add_name(&mut self, name: SmolStr) -> u32 {
526 self.names.push(name);
527 (self.names.len() - self.top() - 1) as u32
528 }
529
530 fn add_ty(&mut self, ty: Type) -> u32 {
531 self.tys.push(ty);
532 (self.tys.len() - self.top() - 1) as u32
533 }
534
535 fn set_ty(&mut self, idx: u32, ty: Type) {
536 let pos = idx as usize + self.top();
537 if pos < self.tys.len() {
538 self.tys[pos] = ty;
539 } else if pos == self.tys.len() {
540 self.tys.push(ty);
541 } else {
542 self.tys.resize(pos + 1, Type::Any);
543 self.tys[pos] = ty;
544 }
545 }
546
547 pub fn add_symbol(&mut self, name: &str, s: Symbol) -> u32 {
548 self.symbols.add(name.into(), s)
549 }
550
551 pub fn new() -> Self {
552 let symbols = SymbolTable::default();
553 Self { symbols, tys: Vec::new(), names: Vec::new(), consts: Vec::with_capacity(10240), frames: Vec::new(), fns: BTreeMap::new(), importing_paths: BTreeSet::new() }
554 }
555
556 fn byte_to_line_col(src: &[u8], pos: usize) -> (usize, usize) {
557 let mut line = 1;
558 let mut col = 1;
559 for &b in src.iter().take(pos.min(src.len())) {
560 if b == b'\n' {
561 line += 1;
562 col = 1;
563 } else {
564 col += 1;
565 }
566 }
567 (line, col)
568 }
569
570 fn line_snippet(code: &[u8], span: Span) -> String {
571 let pos = span.start.min(code.len());
572 let line_start = code[..pos].iter().rposition(|&b| b == b'\n').map(|idx| idx + 1).unwrap_or(0);
573 let line_end = code[pos..].iter().position(|&b| b == b'\n').map(|idx| pos + idx).unwrap_or(code.len());
574 String::from_utf8_lossy(&code[line_start..line_end]).into_owned()
575 }
576
577 fn semantic_error(span: Span, message: impl Into<String>) -> anyhow::Error {
578 SpannedCompilerError { message: message.into(), span }.into()
579 }
580
581 fn format_compile_error(code: &[u8], err: anyhow::Error) -> anyhow::Error {
582 if let Some(err) = err.downcast_ref::<SpannedCompilerError>() {
583 let pos = err.span.start.min(code.len());
584 let (line, col) = Self::byte_to_line_col(code, pos);
585 let snippet = Self::line_snippet(code, err.span);
586 anyhow!("语义错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{}\n{}", err.message, snippet)
587 } else {
588 err
589 }
590 }
591
592 pub fn parse_code(code: Vec<u8>) -> Result<Vec<Stmt>> {
593 let mut p = Parser::new(code.clone());
594 let mut stmts = Vec::new();
595 loop {
596 match p.stmt(false) {
597 Ok(stmt) => stmts.push(stmt),
598 Err(e) => {
599 if p.is_eof() {
600 return Ok(stmts);
601 }
602 let pos = p.current_pos();
603 let (line, col) = Self::byte_to_line_col(&code, pos);
604 return Err(anyhow!("解析错误:第 {line} 行,第 {col} 列(字节偏移 {pos}):{e:#}\n{}", p.error_stmt()));
605 }
606 }
607 }
608 }
609
610 pub fn import_code(&mut self, name: &str, code: Vec<u8>) -> Result<Vec<u32>> {
611 self.import_code_with_base_dir(name, code, None)
612 }
613
614 pub fn import_code_from_path(&mut self, name: &str, code: Vec<u8>, path: impl AsRef<Path>) -> Result<Vec<u32>> {
615 self.import_code_with_base_dir(name, code, path.as_ref().parent())
616 }
617
618 pub fn import_file(&mut self, name: &str, path: impl AsRef<Path>) -> Result<Vec<u32>> {
619 let path = path.as_ref();
620 let canonical = std::fs::canonicalize(path).with_context(|| format!("failed to resolve import path {}", path.display()))?;
621 if !self.importing_paths.insert(canonical.clone()) {
622 return Ok(Vec::new());
623 }
624 let code = std::fs::read(&canonical).with_context(|| format!("failed to read import path {}", canonical.display()))?;
625 let result = self.import_code_from_path(name, code, &canonical);
626 self.importing_paths.remove(&canonical);
627 result
628 }
629
630 fn import_code_with_base_dir(&mut self, name: &str, code: Vec<u8>, base_dir: Option<&Path>) -> Result<Vec<u32>> {
631 let stmts = Self::parse_code(code.clone())?;
632 log::info!("func->{}", name);
633 for s in stmts.iter() {
634 log::info!("{}", s);
635 }
636 self.resolve_imports(&stmts, base_dir).map_err(|err| Self::format_compile_error(&code, err))?;
637 self.clear();
638 self.compile(name.into(), stmts).map_err(|err| Self::format_compile_error(&code, err))
639 }
640
641 fn resolve_imports(&mut self, stmts: &[Stmt], base_dir: Option<&Path>) -> Result<()> {
642 for stmt in stmts {
643 let Some((module, path)) = import_decl(stmt) else {
644 continue;
645 };
646 if !self.symbols.symbol(module.as_str()).is_empty() {
647 continue;
648 }
649 let path = Path::new(path.as_str());
650 let resolved = if path.is_absolute() {
651 path.to_path_buf()
652 } else if let Some(base_dir) = base_dir {
653 base_dir.join(path)
654 } else {
655 std::env::current_dir()?.join(path)
656 };
657 self.import_file(module.as_str(), &resolved).with_context(|| format!("failed to import {module} from {}", resolved.display()))?;
658 }
659 Ok(())
660 }
661
662 pub fn check_code(name: &str, code: Vec<u8>) -> Vec<CompilerDiagnostic> {
663 let mut parser = Parser::new(code.clone());
664 let mut stmts = Vec::new();
665 loop {
666 match parser.stmt(false) {
667 Ok(stmt) => stmts.push(stmt),
668 Err(err) => {
669 if parser.is_eof() {
670 break;
671 }
672 return vec![CompilerDiagnostic { message: format!("解析错误:{err:#}"), span: Span::empty(parser.current_pos()) }];
673 }
674 }
675 }
676
677 let mut compiler = Self::new();
678 compiler.clear();
679 match compiler.compile(name.into(), stmts) {
680 Ok(_) => Vec::new(),
681 Err(err) => {
682 if let Some(err) = err.downcast_ref::<SpannedCompilerError>() {
683 vec![CompilerDiagnostic { message: err.message.clone(), span: err.span }]
684 } else {
685 vec![CompilerDiagnostic { message: format!("{err:#}"), span: Span::default() }]
686 }
687 }
688 }
689 }
690
691 pub fn get_field(&self, ty: &Type, name: &str) -> Result<(usize, Type)> {
692 self.symbols.get_field(ty, name)
693 }
694
695 pub fn get_ident(&mut self, ident: &str, span: Span) -> Result<Expr> {
696 for idx in (self.top()..self.names.len()).rev() {
697 if self.names[idx].eq(ident) {
698 return Ok(Expr::new(ExprKind::Var((idx - self.top()) as u32), span));
699 }
700 }
701 let id = self.symbols.get_id(ident).map_err(|_| Self::semantic_error(span, format!("未找到标识符 {}", ident)))?;
702 let s = self.symbols.get_symbol(id).map(|(_, v)| v.clone()).unwrap();
703 if let Symbol::Const { value, ty, .. } = s {
704 let c = self.get_const(value);
705 return Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Const(c), span)), ty }, span));
706 } else if let Symbol::Static { value, ty, .. } = s
707 && let Some(v) = value
708 {
709 let c = self.get_const(v);
710 return Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::Const(c), span)), ty }, span));
711 }
712 Ok(Expr::new(ExprKind::Id(id, None), span))
713 }
714
715 fn field_access_expr(&mut self, left: Expr, idx: usize, ty: Type, key: &str, span: Span) -> Expr {
716 if let Type::Symbol { id, .. } = ty {
717 Expr::new(ExprKind::Id(id, Some(Box::new(left))), span)
718 } else if ty.is_bool() && idx == usize::MAX {
719 Expr::new(ExprKind::Value(Dynamic::Bool(false)), span)
720 } else if ty.is_any() && idx == usize::MAX {
721 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(key.into()))), span);
722 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, span)
723 } else {
724 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)
725 }
726 }
727
728 fn literal_field_access_expr(&mut self, left: Expr, key: &str, span: Span) -> Expr {
729 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(key.into()))), span);
730 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, span)
731 }
732
733 fn type_field_access_expr(&mut self, left: Expr, key: &str, span: Span, prefer_dynamic_field: bool) -> Option<Expr> {
734 let ty = self.infer_expr(&left).ok()?;
735 if prefer_dynamic_field && ty.is_any() {
736 return Some(self.literal_field_access_expr(left, key, span));
737 }
738 let (idx, field_ty) = self.get_field(&ty, key).ok()?;
739 Some(self.field_access_expr(left, idx, field_ty, key, span))
740 }
741
742 fn global_method_access_expr(&self, left: Expr, method: &str, span: Span) -> Result<Option<Expr>> {
743 let Ok(id) = self.symbols.get_id(method) else {
744 return Ok(None);
745 };
746 if self.symbols.get_symbol(id)?.1.is_fn() { Ok(Some(Expr::new(ExprKind::Id(id, Some(Box::new(left))), span))) } else { Ok(None) }
747 }
748
749 fn method_call_obj_expr(&mut self, obj: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Option<Expr>> {
750 if let ExprKind::TypedMethod { obj: left, ty, name } = &obj.kind {
751 let left = self.eval(left, stmts, cap)?;
752 let base_name = match ty {
753 Type::Ident { name, .. } => name.clone(),
754 Type::Symbol { id, .. } => self.symbols.get_symbol(*id)?.0.clone(),
755 _ => return Err(Self::semantic_error(obj.span, format!("方法调用类型提示必须是类型: {:?}", ty))),
756 };
757 let method = format!("{}::{}", base_name, name);
758 let id = self.symbols.get_id(&method).map_err(|_| Self::semantic_error(obj.span, format!("未找到类型方法 {}", method)))?;
759 return Ok(Some(Expr::new(ExprKind::Id(id, Some(Box::new(left))), obj.span)));
760 }
761
762 let ExprKind::Binary { left, op: BinaryOp::Idx, right } = &obj.kind else {
763 return Ok(None);
764 };
765 let Some(method) = self.get_value(right).and_then(|v| if v.is_str() { Some(v.as_str().to_string()) } else { None }) else {
766 return Ok(None);
767 };
768 let left = self.eval(left, stmts, cap)?;
769 if let Some(field) = self.type_field_access_expr(left.clone(), &method, obj.span, false) {
770 return Ok(Some(field));
771 }
772 if let Some(method_fn) = self.global_method_access_expr(left.clone(), &method, obj.span)? {
773 return Ok(Some(method_fn));
774 }
775 Ok(Some(self.literal_field_access_expr(left, &method, obj.span)))
776 }
777
778 pub fn compile_fn(&mut self, args: &[SmolStr], tys: &mut Vec<Type>, body: Stmt, cap: &mut Capture) -> Result<Vec<Stmt>> {
779 let top = self.tys.len();
780 self.frames.push(top);
781 let result = (|| -> Result<Vec<Stmt>> {
782 for (arg, ty) in args.iter().zip(tys.iter_mut()) {
783 *ty = self.symbols.get_type(ty)?;
784 self.add_name(arg.clone());
785 self.add_ty(ty.clone());
786 }
787 if cap.names.is_empty() && tys.iter().all(|ty| !ty.is_any()) {
788 let saved_state = (self.frames.clone(), self.names.clone(), self.tys.clone());
789 let result = self.check_return_type(&body);
790 self.restore_local_state(saved_state);
791 result?;
792 }
793 let mut compiled = Vec::new();
794 self.compile_stmt(body, &mut compiled, cap)?;
795 if !compiled.last_mut().map(|stmt| stmt.last_return()).unwrap_or(false) {
796 compiled.push(Stmt::new(StmtKind::Return(None), Span::default()));
797 }
798 Ok(compiled)
799 })();
800 if let Some(top) = self.frames.pop() {
801 self.tys.truncate(top);
802 self.names.truncate(top);
803 }
804 result
805 }
806
807 pub fn compile(&mut self, mod_name: SmolStr, stmts: Vec<Stmt>) -> Result<Vec<u32>> {
808 self.symbols.add_module(mod_name.clone());
809 for stmt in stmts {
810 match stmt.kind {
811 StmtKind::Struct { name, def, is_pub } => {
812 self.symbols.add(name, Symbol::Struct(def, is_pub));
813 }
814 StmtKind::Static { name, ty, value, is_pub } => {
815 self.symbols.add(name, Symbol::Static { value: value.and_then(|v| v.value().ok()), ty, is_pub });
816 }
817 StmtKind::Const { name, ty, value, is_pub } => {
818 let value = self.const_expr_value(&value)?;
819 self.symbols.add(name, Symbol::Const { value, ty, is_pub });
820 }
821 StmtKind::Fn { name, generic_params, args, body, is_pub } => {
822 let (ty, args) = Type::from_args(args);
823 self.symbols.add(name, Symbol::Fn { ty, args, generic_params, cap: Capture::default(), body: Arc::new(*body), is_pub });
824 }
825 StmtKind::Impl { target, body } => {
826 let name = impl_target_name(&target)?;
827 let def_id = match self.symbols.get_id(&name) {
828 Ok(id) => id,
829 Err(_) if name.as_str() == "Vec" => self.symbols.add(name.clone(), Symbol::Struct(Type::Struct { params: Vec::new(), fields: Vec::new() }, true)),
830 Err(err) => return Err(err),
831 };
832 if let StmtKind::Block(fns) = body.kind {
833 for f in fns {
834 if let StmtKind::Fn { name: fn_name, generic_params: fn_generic_params, args, body, is_pub } = f.kind {
835 let (ty, args) = Type::from_args(args);
836 let mut generic_params = if has_unresolved_generic_param(&target) {
837 match &target {
838 Type::Ident { params, .. } => params.clone(),
839 _ => Vec::new(),
840 }
841 } else {
842 Vec::new()
843 };
844 for param in fn_generic_params {
845 if !generic_params.contains(¶m) {
846 generic_params.push(param);
847 }
848 }
849 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 });
850 if let Symbol::Struct(ty, _) = &mut self.symbols.symbols[def_id as usize] {
851 ty.add_field(fn_name.into(), Type::Symbol { id: fn_id, params: Vec::new() })?;
852 }
853 } else {
854 println!("impl 包含非函数语句 {:?}", f);
855 }
856 }
857 }
858 }
859 StmtKind::Expr(expr, _) if is_top_level_import_expr(&expr) => {}
860 _ => {
861 println!("未知的顶层语句 {:?}", stmt);
862 }
863 }
864 }
865 let mut fn_ids = Vec::new();
866 for (name, id) in self.symbols.symbol(&mod_name) {
867 log::info!("compile symbol {:?}[{}]", name, id);
868 if let Some((_, Symbol::Fn { ty, generic_params, .. })) = self.symbols.get_symbol(id).ok() {
869 let resolved_ty = self.symbols.get_type(ty).unwrap_or_else(|_| ty.clone());
870 if has_unresolved_generic_param(&resolved_ty) || !generic_params.is_empty() {
871 continue;
872 }
873 }
874 if let Some(s) = self.symbols.get_symbol(id).ok().map(|(_, symbol)| symbol.clone()) {
875 if let Symbol::Fn { ty, args, generic_params, mut cap, body, is_pub } = s {
876 if let Type::Fn { mut tys, ret } = ty {
877 let compiled = self.compile_fn(&args, &mut tys, body.as_ref().clone(), &mut cap)?;
878 for s in compiled.iter() {
879 log::info!("{}", s);
880 }
881 self.symbols.symbols[id as usize] = Symbol::Fn {
882 ty: Type::Fn { tys, ret },
883 args,
884 generic_params,
885 cap,
886 body: Arc::new(Stmt::new(StmtKind::Block(compiled), Span::default())),
887 is_pub,
888 };
889 fn_ids.push(id);
890 }
891 }
892 }
893 }
894 self.symbols.pop_module();
895 Ok(fn_ids)
896 }
897
898 fn pat_to_var(&mut self, pat: Pattern, expr_ty: Type) -> Result<Pattern> {
899 match pat.kind {
900 PatternKind::Var { idx, ty } => Ok(Pattern { kind: PatternKind::Var { idx, ty }, span: pat.span }),
901 PatternKind::Ident { name, ty } => {
902 let ty = self.symbols.get_type(&ty)?;
903 let ty = if ty.is_any() { expr_ty } else { ty };
904 self.add_ty(ty.clone());
905 Ok(Pattern { kind: PatternKind::Var { idx: self.add_name(name), ty }, span: pat.span })
906 }
907 PatternKind::Tuple(pats) => {
908 if let Type::Tuple(tys) = &expr_ty {
909 let pats: Vec<Pattern> = pats.into_iter().zip(tys).filter_map(|p| self.pat_to_var(p.0, p.1.clone()).ok()).collect();
910 if pats.len() == tys.len() { Ok(Pattern { kind: PatternKind::Tuple(pats), span: pat.span }) } else { Err(Self::semantic_error(pat.span, format!("模式与元组类型不匹配: {:?}", expr_ty))) }
911 } else {
912 let pats = pats.into_iter().filter_map(|p| self.pat_to_var(p, Type::Any).ok()).collect();
913 Ok(Pattern { kind: PatternKind::Tuple(pats), span: pat.span })
914 }
915 }
916 PatternKind::List { elems, has_rest } => {
917 if expr_ty.is_any() {
918 let elems: Vec<Pattern> = elems.into_iter().filter_map(|p| self.pat_to_var(p, Type::Any).ok()).collect();
919 Ok(Pattern { kind: PatternKind::List { elems, has_rest }, span: pat.span })
920 } else {
921 Err(Self::semantic_error(pat.span, format!("列表模式 {:?} 与类型 {:?} 不匹配", elems, expr_ty)))
922 }
923 }
924 PatternKind::Wildcard => {
925 self.add_ty(expr_ty.clone());
926 Ok(Pattern { kind: PatternKind::Var { idx: self.add_name(SmolStr::new_static("")), ty: expr_ty }, span: pat.span })
927 }
928 _ => panic!("未知的模式 {:?}", pat),
929 }
930 }
931
932 fn infer_range_type(&self, range: &Expr) -> Type {
933 if let ExprKind::Range { start, stop, .. } = &range.kind {
934 let start_ty = start.get_type();
935 let stop_ty = stop.get_type();
936 if start_ty.is_any() {
937 stop_ty
938 } else if stop_ty.is_any() {
939 start_ty
940 } else {
941 stop_ty
942 }
943 } else {
944 range.get_type()
945 }
946 }
947
948 fn dyn_init(&mut self, expr: Expr, stmts: &mut Vec<Stmt>, items: Vec<(Expr, Expr)>, ty: Type) -> Expr {
949 self.add_name("".into());
950 let temp = self.add_ty(ty);
951 let span = expr.span;
952 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));
953 for (idx, item) in items {
954 let item_span = idx.span.merge(item.span);
955 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);
956 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));
957 }
958 Expr::new(ExprKind::Var(temp), span)
959 }
960
961 fn static_composite_literal(&self, expr: &Expr) -> Result<Option<Dynamic>> {
962 match &expr.kind {
963 ExprKind::List(items) | ExprKind::Tuple(items) => {
964 let mut values = Vec::with_capacity(items.len());
965 for item in items {
966 let Some(value) = self.static_literal_value(item)? else {
967 return Ok(None);
968 };
969 values.push(value);
970 }
971 Ok(Some(Dynamic::list(values)))
972 }
973 ExprKind::Dict(items) => {
974 let mut values = BTreeMap::new();
975 for (key, item) in items {
976 let Some(value) = self.static_literal_value(item)? else {
977 return Ok(None);
978 };
979 values.insert(key.clone(), value);
980 }
981 Ok(Some(Dynamic::map(values)))
982 }
983 _ => Ok(None),
984 }
985 }
986
987 fn static_literal_value(&self, expr: &Expr) -> Result<Option<Dynamic>> {
988 match &expr.kind {
989 ExprKind::Value(value) => Ok(Some(value.clone())),
990 ExprKind::Const(idx) => Ok(self.consts.get(*idx).cloned()),
991 ExprKind::Typed { value, ty } if ty.is_native() => Ok(self.static_literal_value(value)?.map(|value| ty.force(value)).transpose()?),
992 _ => self.static_composite_literal(expr),
993 }
994 }
995
996 fn const_expr_value(&self, expr: &Expr) -> Result<Dynamic> {
997 match &expr.kind {
998 ExprKind::Value(value) => Ok(value.clone()),
999 ExprKind::Const(idx) => self.consts.get(*idx).cloned().ok_or_else(|| Self::semantic_error(expr.span, format!("常量索引 {} 不存在", idx))),
1000 ExprKind::Ident(ident) => {
1001 let id = self.symbols.get_id(ident).map_err(|_| Self::semantic_error(expr.span, format!("未找到常量 {}", ident)))?;
1002 match self.symbols.get_symbol(id).map(|(_, symbol)| symbol) {
1003 Ok(Symbol::Const { value, .. }) => Ok(value.clone()),
1004 Ok(Symbol::Static { value: Some(value), .. }) => Ok(value.clone()),
1005 _ => Err(Self::semantic_error(expr.span, format!("{} 不是可用于 const 的静态值", ident))),
1006 }
1007 }
1008 ExprKind::Typed { value, ty } if ty.is_native() => Ok(ty.force(self.const_expr_value(value)?)?),
1009 ExprKind::Typed { value, .. } => self.const_expr_value(value),
1010 ExprKind::List(items) | ExprKind::Tuple(items) => {
1011 let values = items.iter().map(|item| self.const_expr_value(item)).collect::<Result<Vec<_>>>()?;
1012 Ok(Dynamic::list(values))
1013 }
1014 ExprKind::Dict(items) => {
1015 let mut values = BTreeMap::new();
1016 for (key, item) in items {
1017 values.insert(key.clone(), self.const_expr_value(item)?);
1018 }
1019 Ok(Dynamic::map(values))
1020 }
1021 ExprKind::Unary { op, value } => {
1022 let value = self.const_expr_value(value)?;
1023 match op {
1024 parser::UnaryOp::Neg => Ok(-value),
1025 parser::UnaryOp::Not => Ok(!value),
1026 parser::UnaryOp::Unknow => Err(Self::semantic_error(expr.span, "const 一元表达式无法在编译期求值")),
1027 }
1028 }
1029 ExprKind::Binary { left, op, right } => {
1030 let left = Expr::new(ExprKind::Value(self.const_expr_value(left)?), left.span);
1031 let right = Expr::new(ExprKind::Value(self.const_expr_value(right)?), right.span);
1032 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 二元表达式无法在编译期求值"))
1033 }
1034 _ => Err(Self::semantic_error(expr.span, "const 只能使用字面量、已声明常量和静态 composite literal")),
1035 }
1036 }
1037
1038 fn eval_stmt_expr(&mut self, stmt: &Stmt, stmts: &mut Vec<Stmt>, cap: &mut Capture, span: Span) -> Result<Expr> {
1039 self.compile_stmt(stmt.clone(), stmts, cap)?;
1040 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 };
1041 self.add_name("".into());
1042 let temp = self.add_ty(expr_ty.clone());
1043 let pat = Pattern { kind: PatternKind::Var { idx: temp, ty: expr_ty }, span };
1044 stmts.last_mut().ok_or_else(|| Self::semantic_error(span, "没有生成可求值语句表达式")).and_then(|stmt| stmt.bind_pattern(pat))?;
1045 Ok(Expr::new(ExprKind::Var(temp), span))
1046 }
1047
1048 fn eval(&mut self, expr: &Expr, stmts: &mut Vec<Stmt>, cap: &mut Capture) -> Result<Expr> {
1049 match &expr.kind {
1050 ExprKind::Stmt(stmt) => self.eval_stmt_expr(stmt, stmts, cap, expr.span),
1051 ExprKind::Closure { args, body } => {
1052 let (mut names, mut tys): (Vec<SmolStr>, Vec<Type>) = args.clone().into_iter().unzip();
1053 let cap_vars: Vec<(SmolStr, Type)> = self.names.iter().zip(self.tys.iter()).map(|(n, ty)| (n.clone(), ty.clone())).collect();
1054 let mut local_cap = Capture::new(cap_vars);
1055 let _ = self.compile_fn(names.as_slice(), &mut tys.clone(), *body.clone(), &mut local_cap)?;
1056 for cap_idx in local_cap.vars.iter() {
1057 names.push(local_cap.names[*cap_idx].0.clone());
1058 tys.push(local_cap.names[*cap_idx].1.clone());
1059 }
1060 let mut compiled = self.compile_fn(names.as_slice(), &mut tys.clone(), *body.clone(), &mut Capture::default())?;
1061 let (ty, args) = Type::from_args(args.clone());
1062 let body_stmt = if compiled.len() == 1 { compiled.pop().unwrap() } else { Stmt::new(StmtKind::Block(compiled), expr.span) };
1063 let name = SmolStr::from(format!("__closure_{}_{}", expr.span.start, expr.span.end));
1064 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 });
1065 Ok(Expr::new(ExprKind::Id(fn_id, None), expr.span))
1066 }
1067 ExprKind::Value(v) => {
1068 if v.is_native() {
1069 Ok(Expr::new(ExprKind::Value(v.clone()), expr.span))
1070 } else {
1071 Ok(Expr::new(ExprKind::Const(self.get_const(v.clone())), expr.span))
1072 }
1073 }
1074 ExprKind::Typed { value, ty } => {
1075 let ty = self.symbols.get_type(ty)?;
1076 if let Type::Struct { fields, .. } = &ty
1077 && let ExprKind::Dict(dict) = &value.kind
1078 {
1079 let mut items = Vec::new();
1080 for field in fields {
1081 if let Some((_, v)) = dict.iter().find(|(name, _)| name == &field.0) {
1082 items.push(self.eval(v, stmts, cap)?);
1083 }
1084 }
1085 Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty }, expr.span))
1086 } else if let Type::Struct { .. } = &ty
1087 && let ExprKind::List(list) = &value.kind
1088 {
1089 let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1090 Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty }, expr.span))
1091 } else if let Type::Array(_, _) = &ty
1092 && let ExprKind::List(list) = &value.kind
1093 {
1094 let items = list.iter().map(|item| self.eval(item, stmts, cap)).collect::<Result<Vec<_>>>()?;
1095 Ok(Expr::new(ExprKind::Typed { value: Box::new(Expr::new(ExprKind::List(items), expr.span)), ty }, expr.span))
1096 } else if value.is_value() {
1097 let value = value.clone().value()?;
1098 if ty.is_str() && value.is_str() {
1099 log::warn!("常量 String 只能作为动态值使用,已忽略 string 类型约束");
1100 Ok(Expr::new(ExprKind::Const(self.get_const(value)), expr.span))
1101 } else {
1102 Ok(Expr::new(ExprKind::Value(ty.force(value)?), expr.span))
1103 }
1104 } else {
1105 Ok(Expr::new(ExprKind::Typed { value: Box::new(self.eval(value, stmts, cap)?), ty }, expr.span))
1106 }
1107 }
1108 ExprKind::Ident(ident) => match self.get_ident(ident, expr.span) {
1109 Ok(id) => Ok(id),
1110 Err(_) => {
1111 if let Some(idx) = cap.get(ident) {
1112 Ok(Expr::new(ExprKind::Capture(idx as u32), expr.span))
1113 } else {
1114 Err(Self::semantic_error(expr.span, format!("未找到标识符 {}", ident)))
1115 }
1116 }
1117 },
1118 ExprKind::Assoc { ty, name } => {
1119 let base_name = match ty {
1120 Type::Ident { name, .. } => name.clone(),
1121 Type::Symbol { id, .. } => self.symbols.get_symbol(*id)?.0.clone(),
1122 _ => return Err(Self::semantic_error(expr.span, format!("关联函数目标必须是类型: {:?}", ty))),
1123 };
1124 let id = self.symbols.get_id(&format!("{}::{}", base_name, name)).map_err(|_| Self::semantic_error(expr.span, format!("未找到关联函数 {}::{}", base_name, name)))?;
1125 let params = match ty {
1126 Type::Ident { params, .. } | Type::Symbol { params, .. } => params.iter().map(|param| self.symbols.get_type(param).unwrap_or_else(|_| param.clone())).collect(),
1127 _ => Vec::new(),
1128 };
1129 Ok(Expr::new(ExprKind::AssocId { id, params }, expr.span))
1130 }
1131 ExprKind::Unary { op, value } => {
1132 let value = Expr::new(ExprKind::Unary { op: op.clone(), value: Box::new(self.eval(value, stmts, cap)?) }, expr.span);
1133 if let Some(v) = value.compact() { Ok(Expr::new(ExprKind::Value(v), expr.span)) } else { Ok(value) }
1134 }
1135 ExprKind::Binary { left, op, right } => {
1136 let left = self.eval(left, stmts, cap)?;
1137 if *op == BinaryOp::Idx {
1138 if let Some(key) = self.get_value(right).and_then(|v| if v.is_str() { Some(v.as_str().to_string()) } else { None }) {
1139 if let Some(field) = self.type_field_access_expr(left.clone(), &key, expr.span, true) {
1140 return Ok(field);
1141 }
1142 return Ok(self.literal_field_access_expr(left, &key, expr.span));
1143 } else if let Ok(ident) = right.ident() {
1144 if let Ok(found) = self.get_ident(ident, right.span) {
1145 return Ok(if let Some(id) = found.id() {
1146 Expr::new(ExprKind::Id(id, Some(Box::new(left))), expr.span)
1147 } else {
1148 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(found) }, expr.span)
1149 });
1150 }
1151 if let Ok(ty) = self.infer_expr(&left)
1152 && let Ok((idx, ty)) = self.get_field(&ty, ident)
1153 {
1154 return Ok(if let Type::Symbol { id, .. } = ty {
1155 Expr::new(ExprKind::Id(id, Some(Box::new(left))), expr.span)
1156 } else if ty.is_bool() && idx == usize::MAX {
1157 Expr::new(ExprKind::Value(Dynamic::Bool(false)), expr.span)
1158 } else if ty.is_any() && idx == usize::MAX {
1159 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(ident.into()))), expr.span);
1160 Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, expr.span)
1161 } else {
1162 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)
1163 });
1164 } else {
1165 let right = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(ident.into()))), expr.span);
1166 return Ok(Expr::new(ExprKind::Binary { left: Box::new(left), op: BinaryOp::Idx, right: Box::new(right) }, expr.span));
1167 }
1168 }
1169 }
1170 let right = Box::new(self.eval(right, stmts, cap)?);
1171 let value = Expr::new(ExprKind::Binary { left: Box::new(left), op: op.clone(), right }, expr.span);
1172 if let Some(v) = value.compact() { Ok(Expr::new(ExprKind::Value(v), expr.span)) } else { Ok(value) }
1173 }
1174 ExprKind::Call { obj, params } => {
1175 let params: Vec<Expr> = params.iter().map(|p| self.eval(p, stmts, cap)).collect::<Result<Vec<_>>>()?;
1176 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) };
1177 match obj_result {
1178 Ok(obj) if obj.is_value() && params.is_empty() => Ok(obj),
1179 Ok(obj) => Ok(Expr::new(ExprKind::Call { obj: Box::new(obj), params }, expr.span)),
1180 Err(e) => {
1181 if let ExprKind::Ident(ident) = &obj.kind {
1182 let fn_id = if ident.contains("::") { self.symbols.add_global(ident.clone(), Symbol::Null) } else { self.symbols.add(ident.clone(), Symbol::Null) };
1183 Ok(Expr::new(ExprKind::Call { obj: Box::new(Expr::new(ExprKind::Id(fn_id, None), obj.span)), params }, expr.span))
1184 } else {
1185 Err(e)
1186 }
1187 }
1188 }
1189 }
1190 ExprKind::Range { start, stop, inclusive } => {
1191 let start = Box::new(self.eval(start, stmts, cap)?);
1192 let stop = Box::new(self.eval(stop, stmts, cap)?);
1193 Ok(Expr::new(ExprKind::Range { start, stop, inclusive: *inclusive }, expr.span))
1194 }
1195 ExprKind::List(list) | ExprKind::Tuple(list) => {
1196 if let Some(value) = self.static_composite_literal(expr)? {
1197 let idx = self.get_const(value);
1198 return Ok(Expr::new(ExprKind::Const(idx), expr.span));
1199 }
1200 let mut v = Vec::new();
1201 let mut items = Vec::new();
1202 for (idx, item) in list.iter().enumerate() {
1203 if item.is_value() {
1204 v.push(item.clone().value().unwrap());
1205 } else {
1206 items.push((Expr::new(ExprKind::Value((idx as u32).into()), item.span), self.eval(item, stmts, cap)?));
1207 v.push(Dynamic::Null);
1208 }
1209 }
1210 let list = Expr::new(ExprKind::Const(self.get_const(Dynamic::list(v))), expr.span);
1211 Ok(self.dyn_init(list, stmts, items, Type::Any))
1212 }
1213 ExprKind::Repeat { value, len } => {
1214 let len = self.symbols.get_type(len)?;
1215 let Type::ConstInt(len) = len else {
1216 return Err(Self::semantic_error(expr.span, format!("重复数组长度必须是编译期整数: {:?}", len)));
1217 };
1218 if len < 0 {
1219 return Err(Self::semantic_error(expr.span, "重复数组长度不能为负数"));
1220 }
1221 Ok(Expr::new(ExprKind::Repeat { value: Box::new(self.eval(value, stmts, cap)?), len: Type::ConstInt(len) }, expr.span))
1222 }
1223 ExprKind::Dict(dict) => {
1224 if let Some(value) = self.static_composite_literal(expr)? {
1225 let idx = self.get_const(value);
1226 return Ok(Expr::new(ExprKind::Const(idx), expr.span));
1227 }
1228 let mut dyn_kv = Vec::new();
1229 let mut m = BTreeMap::new();
1230 for (k, v) in dict {
1231 if v.is_value() {
1232 m.insert(k.clone(), v.clone().value()?);
1233 } else {
1234 let key = Expr::new(ExprKind::Const(self.get_const(Dynamic::String(k.clone()))), v.span);
1235 dyn_kv.push((key, self.eval(v, stmts, cap)?));
1236 m.insert(k.clone(), Dynamic::Null);
1237 }
1238 }
1239 let dict = Expr::new(ExprKind::Const(self.get_const(Dynamic::map(m))), expr.span);
1240 Ok(self.dyn_init(dict, stmts, dyn_kv, Type::Any))
1241 }
1242 ExprKind::Id(_, _) | ExprKind::AssocId { .. } => Ok(expr.clone()),
1243 _ => Ok(expr.clone()),
1244 }
1245 }
1246
1247 fn get_stmt(&mut self, stmt: Stmt, cap: &mut Capture) -> Result<Stmt> {
1248 let span = stmt.span;
1249 let mut stmts = Vec::new();
1250 self.compile_stmt(stmt, &mut stmts, cap)?;
1251 Ok(Stmt::new(StmtKind::Block(stmts), span))
1252 }
1253
1254 fn compile_stmt(&mut self, stmt: Stmt, compiled: &mut Vec<Stmt>, cap: &mut Capture) -> Result<()> {
1255 let stmt_span = stmt.span;
1256 match stmt.kind {
1257 StmtKind::Let { mut pat, value } => {
1258 let value = *value;
1259 let string_literal_constraint = matches!(
1260 (&pat.kind, &value.kind),
1261 (
1262 PatternKind::Ident { ty: Type::Str, .. },
1263 StmtKind::Expr(
1264 Expr {
1265 kind: ExprKind::Value(value),
1266 ..
1267 },
1268 _
1269 )
1270 ) if value.is_str()
1271 );
1272 if string_literal_constraint {
1273 log::warn!("常量 String 只能作为动态值使用,已忽略 string 类型约束");
1274 if let PatternKind::Ident { ty, .. } = &mut pat.kind {
1275 *ty = Type::Any;
1276 }
1277 }
1278 let annotated_ty = if let PatternKind::Ident { ty, .. } = &pat.kind {
1279 let ty = self.symbols.get_type(ty)?;
1280 if ty.is_any() { None } else { Some(ty) }
1281 } else {
1282 None
1283 };
1284 if let Some(ty) = annotated_ty {
1285 if let StmtKind::Expr(expr, close) = value.kind {
1286 let span = expr.span;
1287 let typed = Expr::new(ExprKind::Typed { value: Box::new(expr), ty }, span);
1288 self.compile_stmt(Stmt::new(StmtKind::Expr(typed, close), value.span), compiled, cap)?;
1289 } else {
1290 self.compile_stmt(value, compiled, cap)?;
1291 }
1292 } else {
1293 self.compile_stmt(value, compiled, cap)?;
1294 }
1295 let expr_ty = if let Some(stmt) = compiled.last() { if let StmtKind::Expr(expr, _) = &stmt.kind { self.infer_expr(expr)? } else { self.infer_stmt(stmt)? } } else { Type::Any };
1296 let pat = self.pat_to_var(pat, expr_ty)?;
1297 compiled.last_mut().ok_or_else(|| Self::semantic_error(stmt_span, "没有生成可绑定模式的编译语句")).and_then(|stmt| stmt.bind_pattern(pat))?;
1298 }
1299 StmtKind::Expr(expr, close) => {
1300 let e = self.eval(&expr, compiled, cap)?;
1301 compiled.push(Stmt::new(StmtKind::Expr(e, close), stmt_span));
1302 }
1303 StmtKind::Block(stmts) => {
1304 let mut block = Vec::new();
1305 for stmt in stmts {
1306 self.compile_stmt(stmt, &mut block, cap)?;
1307 }
1308 compiled.push(Stmt::new(StmtKind::Block(block), stmt_span));
1309 }
1310 StmtKind::Fn { name, generic_params, args, body, is_pub } => {
1311 let (ty, args) = Type::from_args(args);
1312 if let Type::Fn { mut tys, ret } = ty {
1313 let mut fn_cap = Capture::default();
1314 let compiled_body = self.compile_fn(&args, &mut tys, *body, &mut fn_cap)?;
1315 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 });
1316 } else {
1317 panic!("nested functions are not supported here")
1318 }
1319 }
1320 StmtKind::Return(expr) => {
1321 let expr = expr.and_then(|e| self.eval(&e, compiled, cap).ok());
1322 compiled.push(Stmt::new(StmtKind::Return(expr), stmt_span));
1323 }
1324 StmtKind::If { cond, then_body, else_body } => {
1325 let cond = self.eval(&cond, compiled, cap)?;
1326 if let Some(cond_value) = cond.compact()
1327 && let Some(cond_bool) = cond_value.as_bool()
1328 {
1329 if cond_bool {
1330 self.compile_stmt(*then_body, compiled, cap)?;
1331 } else if let Some(body) = else_body {
1332 self.compile_stmt(*body, compiled, cap)?;
1333 }
1334 } else {
1335 let then_body = Box::new(self.get_stmt(*then_body, cap)?);
1336 let else_body = if let Some(body) = else_body { Some(Box::new(self.get_stmt(*body, cap)?)) } else { None };
1337 compiled.push(Stmt::new(StmtKind::If { cond, then_body, else_body }, stmt_span));
1338 }
1339 }
1340 StmtKind::Loop(body) => {
1341 compiled.push(Stmt::new(StmtKind::Loop(Box::new(self.get_stmt(*body, cap)?)), stmt_span));
1342 }
1343 StmtKind::While { cond, body } => {
1344 let cond = self.eval(&cond, compiled, cap)?;
1345 compiled.push(Stmt::new(StmtKind::While { cond, body: Box::new(self.get_stmt(*body, cap)?) }, stmt_span));
1346 }
1347 StmtKind::For { pat, range, body } => {
1348 let range = self.eval(&range, compiled, cap)?;
1349 let range_ty = self.infer_range_type(&range);
1350 let pat = self.pat_to_var(pat, range_ty)?;
1351 compiled.push(Stmt::new(StmtKind::For { pat, range, body: Box::new(self.get_stmt(*body, cap)?) }, stmt_span));
1352 }
1353 stmt_kind => {
1354 compiled.push(Stmt::new(stmt_kind, stmt_span));
1355 }
1356 }
1357 Ok(())
1358 }
1359}