8efd12add6
Introduces `CallHooks` to enable extensions to the type inference and AST finalization process. This allows for more dynamic and configurable behavior without hardcoding symbol names in the compiler core. Specifically, this commit adds: - **`series_post_call`**: A hook for the `(series n)` function. It ensures that the return type is a fresh `TypeVar` when the element type is `Any`, allowing for proper type inference from subsequent `push` calls. - **`series_finalize`**: A hook for `(series n)` that rewrites the AST node. It replaces the generic `series` call with a pre-configured factory closure that allocates the correct series storage type (e.g., `ScalarSeries<f64>` for floats, `RecordSeries` for records). This avoids runtime dispatch and relies on type information captured during compilation. - **`push_post_call`**: A hook for the `(push series val)` function. It unifies the series element `TypeVar` with the pushed value's type. It also handles numeric and record field promotion and updates the `TypeVar` binding if a promotion occurs.
60 lines
1.4 KiB
Rust
60 lines
1.4 KiB
Rust
pub mod analyzer;
|
|
pub mod binder;
|
|
pub mod call_hooks;
|
|
pub mod module_loader;
|
|
pub mod captures;
|
|
pub mod dumper;
|
|
pub mod emitter;
|
|
pub mod lambda_collector;
|
|
pub mod macros;
|
|
pub mod optimizer;
|
|
pub mod specializer;
|
|
pub mod lowering;
|
|
pub mod type_checker;
|
|
|
|
pub use crate::ast::nodes::*;
|
|
pub use binder::*;
|
|
pub use captures::*;
|
|
pub use dumper::*;
|
|
pub use macros::*;
|
|
pub use optimizer::*;
|
|
pub use specializer::*;
|
|
pub use lowering::*;
|
|
pub use type_checker::*;
|
|
|
|
use crate::ast::diagnostics::Diagnostics;
|
|
|
|
/// The result of a compilation pass: either a typed AST or a set of diagnostics.
|
|
pub struct CompilationResult {
|
|
pub ast: Option<TypedNode>,
|
|
pub diagnostics: Diagnostics,
|
|
}
|
|
|
|
impl CompilationResult {
|
|
pub fn success(ast: TypedNode) -> Self {
|
|
Self {
|
|
ast: Some(ast),
|
|
diagnostics: Diagnostics::new(),
|
|
}
|
|
}
|
|
|
|
pub fn error(msg: impl Into<String>) -> Self {
|
|
let mut diag = Diagnostics::new();
|
|
diag.push_error(msg, None);
|
|
Self {
|
|
ast: None,
|
|
diagnostics: diag,
|
|
}
|
|
}
|
|
|
|
pub fn into_result(self) -> Result<TypedNode, String> {
|
|
if self.diagnostics.has_errors() {
|
|
Err(self.diagnostics.format_errors())
|
|
} else if let Some(ast) = self.ast {
|
|
Ok(ast)
|
|
} else {
|
|
Err("Compilation failed without diagnostics".to_string())
|
|
}
|
|
}
|
|
}
|