mod string; mod list; use crate::builtins::string::string_functions; use crate::errors::{CompilerError, RuntimeError}; use crate::tokens::TokenType; use crate::value::Value; use std::collections::HashMap; use std::sync::LazyLock; use crate::compiler::ast_pass::Parameter; use crate::builtins::list::list_functions; pub(crate) struct Signature { pub(crate) parameters: Vec, pub(crate) return_type: TokenType, pub(crate) function: FunctionFn, } impl Signature { pub(crate) fn new( parameters: Vec, return_type: TokenType, function: FunctionFn, ) -> Self { Self { parameters, return_type, function, } } pub(crate) fn arity(&self) -> usize { self.parameters.len() } } pub(crate) type FunctionFn = fn(Value, Vec) -> Result; pub(crate) type FunctionMap = HashMap; pub(crate) type FunctionTable = HashMap; static METHODS: LazyLock = LazyLock::new(|| { let mut table: FunctionTable = HashMap::new(); table.insert("string".to_string(), string_functions()); table.insert("list".to_string(), list_functions()); table }); pub(crate) fn add(m: &mut FunctionMap, name: &str, method: Signature) { m.insert(name.to_string(), method); } pub(crate) fn lookup(type_name: &str, method_name: &str) -> Result<&'static Signature, CompilerError> { METHODS .get(type_name) .and_then(|methods| methods.get(method_name)) .ok_or_else(|| CompilerError::FunctionNotFound(format!("{}.{}", type_name, method_name))) } pub(crate) fn call( type_name: &str, method_name: &str, self_val: Value, args: Vec, ) -> Result { (lookup(type_name,method_name).map_err(|e|RuntimeError::FunctionNotFound(e.to_string()))?.function)(self_val, args) } pub(crate) fn expected(expected_type: &str) -> RuntimeError { RuntimeError::ExpectedType(expected_type.to_string()) }