finish engram-lang: protocols, decorators, imports, Result, closures, stdlib, integration tests

This commit is contained in:
Will Anderson
2026-04-27 20:22:23 -05:00
parent 316c0a85ce
commit c427a0adc0
32 changed files with 2878 additions and 32 deletions
+113
View File
@@ -0,0 +1,113 @@
//! Engram language standard library.
//!
//! This crate defines function signatures for the built-in standard library
//! modules. Each module registers its functions into a [`TypeEnv`] so the
//! type checker can resolve calls to stdlib functions without an explicit
//! import.
//!
//! # Auto-imported modules
//! - `std::array` — array operations
//! - `std::string` — string operations
//! - `std::result` — Result<T, E> operations
//! - `std::optional`— T? operations
//! - `std::math` — numeric operations
//! - `std::map` — Map<K, V> operations
//! - `std::engram` — Engram graph operations
pub mod array;
pub mod engram;
pub mod map;
pub mod math;
pub mod optional;
pub mod result;
pub mod string;
use el_types::{Type, TypeEnv};
/// Register all automatically-imported stdlib modules into the given environment.
///
/// Call this from `TypeEnv::with_builtins()` or at the start of type checking.
pub fn register_builtins(env: &mut TypeEnv) {
array::register(env);
string::register(env);
result::register(env);
optional::register(env);
math::register(env);
map::register(env);
engram::register(env);
}
/// Helper: build a simple function type.
pub(crate) fn fn_type(params: Vec<Type>, ret: Type) -> Type {
Type::Fn { params, return_type: Box::new(ret) }
}
#[cfg(test)]
mod tests {
use super::*;
use el_types::TypeEnv;
fn stdlib_env() -> TypeEnv {
let mut env = TypeEnv::with_builtins();
register_builtins(&mut env);
env
}
#[test]
fn test_array_functions_registered() {
let env = stdlib_env();
assert!(env.lookup_fn("array_map").is_some(), "array_map should be registered");
assert!(env.lookup_fn("array_filter").is_some());
assert!(env.lookup_fn("array_length").is_some());
assert!(env.lookup_fn("array_push").is_some());
}
#[test]
fn test_string_functions_registered() {
let env = stdlib_env();
assert!(env.lookup_fn("string_len").is_some());
assert!(env.lookup_fn("string_trim").is_some());
assert!(env.lookup_fn("string_split").is_some());
assert!(env.lookup_fn("string_contains").is_some());
}
#[test]
fn test_math_functions_registered() {
let env = stdlib_env();
assert!(env.lookup_fn("math_abs").is_some());
assert!(env.lookup_fn("math_max").is_some());
assert!(env.lookup_fn("math_min").is_some());
assert!(env.lookup_fn("math_sqrt").is_some());
}
#[test]
fn test_result_functions_registered() {
let env = stdlib_env();
assert!(env.lookup_fn("result_unwrap_or").is_some());
assert!(env.lookup_fn("result_ok").is_some());
}
#[test]
fn test_optional_functions_registered() {
let env = stdlib_env();
assert!(env.lookup_fn("optional_unwrap_or").is_some());
assert!(env.lookup_fn("optional_is_some").is_some());
assert!(env.lookup_fn("optional_is_none").is_some());
}
#[test]
fn test_map_functions_registered() {
let env = stdlib_env();
assert!(env.lookup_fn("map_get").is_some());
assert!(env.lookup_fn("map_set").is_some());
assert!(env.lookup_fn("map_remove").is_some());
}
#[test]
fn test_engram_functions_registered() {
let env = stdlib_env();
assert!(env.lookup_fn("engram_activate").is_some());
assert!(env.lookup_fn("engram_relate").is_some());
assert!(env.lookup_fn("engram_neighbors").is_some());
}
}