docs(compiler): explain compilation entry points and source examples

This commit is contained in:
2026-11-15 18:21:28 +08:00
parent 2ca839c0d8
commit 8937b8f8d2
6 changed files with 45 additions and 2 deletions
+22
View File
@@ -1,31 +1,46 @@
//! 宿主与集成测试使用的源码编译门面:输出不依赖 VM 堆的模板,显式加载后才得到代码对象。
//! Minimal source-to-wordcode compiler. Analysis and emission do not allocate
//! VM objects; a compiled unit can be loaded into independent VMs explicitly.
// 名称分析决定局部槽与全局名字表,供下一个字节码生成阶段使用。
mod analysis;
// 生成可跨 VM 复用的代码模板;仅显式 load 时才分配目标 VM 的对象。
mod codegen;
// 对宿主和测试公开名称解析结果,便于检查绑定与源码位置。
pub use analysis::{NameBinding, NameUse, Scope, ScopeKind, SymbolTable, analyze};
// 宿主取得模板后负责选择 VM 并调用 CompiledCode::load。
pub use codegen::CompiledCode;
use frontend::ast::{AstDocument, AstRoot};
use frontend::{Diagnostic, DiagnosticKind, ParseMode, SourceDiagnostic, SourceUnit, Span};
/// 宿主通过 compile_source/compile_ast 提供的编译选项;名称分析据此允许访问宿主全局或内置名。
/// 这里只声明名称,宿主仍需在执行前向 VM 的环境字典提供实际值。
/// Names supplied by the host's globals or builtins dictionary. These are
/// compile-time declarations only; loading code never injects their values.
#[derive(Debug, Clone, Default)]
pub struct CompileOptions {
// 编译期已知名称列表;analyze 与源码声明共同解析可用的全局名,不在此持有 VM 值。
pub globals: Vec<String>,
}
/// 宿主及 compiler 集成测试的源码编译入口:按指定模式解析,再校验 AST、解析名称并生成模板。
/// source 提供文件身份与原始文本;mode 决定模块、表达式或交互根;options 声明额外宿主名称。
/// 解析错误已有源码诊断;后续编译错误在这里附加同一源码的位置和片段,成功不执行任何 VM 指令。
pub fn compile_source(
source: &SourceUnit,
mode: ParseMode,
options: &CompileOptions,
) -> Result<CompiledCode, SourceDiagnostic> {
// 前端根据模式返回对应 AstRoot,解析失败立即把带源码信息的错误传给宿主。
let root = frontend::parse_source_ast(source, mode)?;
// AST 入口返回不含源码快照的 Diagnostic;在此统一补上 SourceUnit 上下文。
compile_ast(&root, source, options).map_err(|error| source.annotate(error))
}
/// compile_source 及已有 AST 的宿主/测试调用;先验证结构与跨度,再分析名称,最后输出代码模板。
/// 传入 source 必须是期望匹配的位置快照;跨度有效只说明位置在范围内,不能证明 AST 与文本语义相同。
/// Compile an AST against its original source snapshot. Span validation does
/// not prove the AST's semantic equivalence to the supplied text.
pub fn compile_ast(
@@ -33,8 +48,10 @@ pub fn compile_ast(
source: &SourceUnit,
options: &CompileOptions,
) -> Result<CompiledCode, Diagnostic> {
// 包装并校验 AST 文档结构,再检查节点跨度对当前 source 文本是否有效;不修改调用方的树。
AstDocument::new(root.clone())
.and_then(|document| document.validate_source(source.text()))
// 文档结构/跨度验证错误归入编译错误,尚无可靠单一节点位置,使用默认跨度。
.map_err(|error| {
diagnostic(
DiagnosticKind::Compilation,
@@ -42,11 +59,16 @@ pub fn compile_ast(
error.to_string(),
)
})?;
// 收集并解析所有作用域的绑定及代码布局;错误会阻止生成阶段继续。
let symbols = analyze(root, options)?;
// 生成器按解析后的槽/名字索引编码,不在此加载模板或分配 VM 堆对象。
codegen::generate(root, source, &symbols)
}
/// 本模块的 AST 验证及 analysis/codegen 的错误辅助函数共用,统一构造不带源码快照的诊断。
/// kind 区分语义/编译错误,span 标记位置,message 接受可转 String 的说明;语法期望项留空。
fn diagnostic(kind: DiagnosticKind, span: Span, message: impl Into<String>) -> Diagnostic {
// 编译器错误没有解析器的“期望 token”列表,源码上下文由上层 compile_source 统一附加。
Diagnostic {
kind,
span,