Skip to main content

compiler/
lib.rs

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