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