71 lines
2 KiB
Rust
71 lines
2 KiB
Rust
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<Parameter>,
|
|
pub(crate) return_type: TokenType,
|
|
pub(crate) function: FunctionFn,
|
|
}
|
|
|
|
impl Signature {
|
|
pub(crate) fn new(
|
|
parameters: Vec<Parameter>,
|
|
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<Value>) -> Result<Value, RuntimeError>;
|
|
pub(crate) type FunctionMap = HashMap<String, Signature>;
|
|
pub(crate) type FunctionTable = HashMap<String, FunctionMap>;
|
|
|
|
static METHODS: LazyLock<FunctionTable> = 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<Value>,
|
|
) -> Result<Value, RuntimeError> {
|
|
(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())
|
|
}
|