Add call hooks for series and push
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.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::ast::diagnostics::Diagnostics;
|
||||
use crate::ast::nodes::{Address, NodeKind, TypedNode, TypedPhase, VirtualId};
|
||||
use crate::ast::types::StaticType;
|
||||
|
||||
/// Gives a call-hook read/write access to the current scope's slot types without
|
||||
/// exposing `TypeContext` internals.
|
||||
pub trait TypeSlotAccess {
|
||||
fn get_slot_type(&self, addr: Address<VirtualId>) -> StaticType;
|
||||
fn set_slot_type(&mut self, addr: Address<VirtualId>, ty: StaticType);
|
||||
}
|
||||
|
||||
/// Gives a call-hook access to the type-checker's core inference operations without
|
||||
/// depending on the concrete `TypeChecker` type (avoids a circular module dependency).
|
||||
pub trait TypeInferenceAccess {
|
||||
/// Allocate a fresh unique `TypeVar`.
|
||||
fn fresh_var(&self) -> StaticType;
|
||||
|
||||
/// Unify two types, recording the substitution. Emits a diagnostic on conflict.
|
||||
fn unify(&self, a: StaticType, b: StaticType, diag: &mut Diagnostics);
|
||||
|
||||
/// Directly bind a `TypeVar` ID to a resolved type in the substitution map.
|
||||
fn bind_typevar(&self, id: u32, ty: StaticType);
|
||||
|
||||
/// Apply the current substitution to a type, resolving all known `TypeVar`s.
|
||||
fn apply_subst_ty(&self, ty: StaticType) -> StaticType;
|
||||
|
||||
/// Int/Float numeric-widening rule. Returns the promoted type, or `None` if
|
||||
/// the combination is not a widening pair.
|
||||
fn try_numeric_widen(&self, a: &StaticType, b: &StaticType) -> Option<StaticType>;
|
||||
|
||||
/// Record-field promotion rule. Returns the promoted record type when one record
|
||||
/// is a strict widening of the other, or `None` otherwise.
|
||||
fn try_record_promote(&self, a: &StaticType, b: &StaticType) -> Option<StaticType>;
|
||||
}
|
||||
|
||||
/// Called after the call's return type is resolved.
|
||||
/// May replace the return type and/or perform unification side-effects (e.g. push).
|
||||
pub type PostCallHook = fn(
|
||||
args: &TypedNode,
|
||||
ret_ty: StaticType,
|
||||
inference: &dyn TypeInferenceAccess,
|
||||
ctx: &mut dyn TypeSlotAccess,
|
||||
diag: &mut Diagnostics,
|
||||
) -> StaticType;
|
||||
|
||||
/// Called during AST finalization.
|
||||
/// Returns `Some(new_kind)` to rewrite the node, or `None` to keep the original.
|
||||
pub type FinalizeHook = fn(
|
||||
callee: Rc<TypedNode>,
|
||||
args: Rc<TypedNode>,
|
||||
node_ty: &StaticType,
|
||||
subst: &HashMap<u32, StaticType>,
|
||||
) -> Option<NodeKind<TypedPhase>>;
|
||||
|
||||
/// Hooks attached to a specific RTL function slot.
|
||||
/// Enables type-inference extensions and AST rewrites without hardcoding symbol
|
||||
/// names anywhere in the compiler core.
|
||||
#[derive(Default)]
|
||||
pub struct CallHooks {
|
||||
pub post_call: Option<PostCallHook>,
|
||||
pub finalize: Option<FinalizeHook>,
|
||||
}
|
||||
Reference in New Issue
Block a user