Add documentation infrastructure for RTL symbols

Introduces `RtlDocEntry` and `RtlRegistration` structs to store and
manage documentation for native functions and constants. The
`Environment` struct is updated to include a registry for these
documentation entries.

The `register_native_fn` and `register_constant` methods now return an
`RtlRegistration` builder, allowing for optional chaining of `.doc()`,
`.description()`, and `.examples()` methods before the registration is
finalized when the builder is dropped.

Macros `rtl_fn!` and `rtl_const!` are introduced to simplify the
registration process with documentation.

The MCP server is extended with `get_rtl_docs` and `get_symbol_doc`
tools to expose this documentation externally.

Specific RTL functions and constants (e.g., `+`, `-`, `*`, `/`, `NaN`,
`true`, `false`, `date`, `now`, math functions, `series`, `push`, `len`,
`create-random-ohlc`, `create-ticker`, `pipe`) have been updated to
include their respective documentation using the new infrastructure.

The `Signature` and `StaticType` types have gained `to_doc_string`
methods for generating human-readable documentation strings.
This commit is contained in:
2026-03-25 15:02:19 +01:00
parent 446bdcd42d
commit b436e09840
9 changed files with 400 additions and 69 deletions
+34
View File
@@ -422,6 +422,40 @@ impl fmt::Display for StaticType {
}
}
impl Signature {
/// Returns a human-readable signature string for documentation purposes.
/// Format: `(param_types) → return_type`
pub fn to_doc_string(&self) -> String {
let params = match &self.params {
StaticType::Tuple(elems) => elems
.iter()
.map(|t| t.to_string())
.collect::<Vec<_>>()
.join(", "),
other => other.to_string(),
};
format!("({}) → {}", params, self.ret)
}
}
impl StaticType {
/// Returns a human-readable type signature for documentation purposes.
/// Unlike `Display`, this expands `FunctionOverloads` into individual signatures
/// and labels polymorphic functions explicitly.
pub fn to_doc_string(&self) -> String {
match self {
StaticType::Function(sig) => sig.to_doc_string(),
StaticType::FunctionOverloads(sigs) => sigs
.iter()
.map(|s| s.to_doc_string())
.collect::<Vec<_>>()
.join(" | "),
StaticType::PolymorphicFn { .. } => "(any) → any [polymorphic]".to_string(),
other => other.to_string(),
}
}
}
impl StaticType {
/// Returns true if `other` can be assigned to a location of type `self`.
pub fn is_assignable_from(&self, other: &StaticType) -> bool {