use super::*;
use crate::Kind;
#[derive(Debug, Default, Clone)]
pub struct FunctionOverloads<T>(Vec<FunctionKindOverload<T>>);
impl<T: FunctionTypeOverload> FunctionOverloads<T> {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn find(&self, member: bool, kinds: &[Kind]) -> Option<&FunctionKindOverload<T>> {
self.0
.iter()
.find(|overload| overload.member() == member && overload.argument_kinds() == kinds)
}
pub fn find_mut(&mut self, member: bool, kinds: &[Kind]) -> Option<&mut FunctionKindOverload<T>>
where
T: Send + Sync,
{
self.0
.iter_mut()
.find(|overload| overload.member() == member && overload.argument_kinds() == kinds)
}
pub fn entries(&self) -> impl Iterator<Item = &FunctionKindOverload<T>> {
self.0.iter()
}
pub fn entries_mut(&mut self) -> impl Iterator<Item = &mut FunctionKindOverload<T>> {
self.0.iter_mut()
}
pub fn clear(&mut self) {
self.0.clear()
}
pub fn remove<I, K>(&mut self, member: bool, args: I) -> Result<(), Error>
where
I: IntoIterator<Item = K>,
K: Into<Kind>,
{
let kinds = args.into_iter().map(|k| k.into()).collect::<Vec<_>>();
if let Some(index) = self
.0
.iter()
.position(|overload| overload.member() == member && overload.argument_kinds() == &kinds)
{
self.0.remove(index);
} else {
return Err(Error::not_found(format!(
"Overload [{}] ({}) not found",
if member { "member" } else { "global" },
kinds
.iter()
.map(|k| k.to_string())
.collect::<Vec<_>>()
.join(", "),
)));
}
Ok(())
}
}
impl<'f> FunctionOverloads<FunctionDeclOrImpl<'f>> {
pub fn add_impl(&mut self, member: bool, f: Function<'f>) -> Result<&mut Self, Error> {
if member && f.arguments_len() == 0 {
return Err(Error::invalid_argument("Member functions cannot have zero arguments"));
}
let kinds = f
.arguments()
.into_iter()
.map(|t| t.kind())
.collect::<Vec<_>>();
if let Some(overload) = self.find_mut(member, &kinds) {
overload.add_impl(f)?;
} else {
let mut overload = FunctionKindOverload::new(member, kinds);
overload.add_impl(f)?;
self.0.push(overload);
}
Ok(self)
}
pub fn add_decl(&mut self, member: bool, f: FunctionType) -> Result<&mut Self, Error> {
if member && f.arguments().is_empty() {
return Err(Error::invalid_argument("Member functions cannot have zero arguments"));
}
let kinds = f.arguments().iter().map(|t| t.kind()).collect::<Vec<_>>();
if let Some(overload) = self.find_mut(member, &kinds) {
overload.add_decl(f)?;
} else {
let mut overload = FunctionKindOverload::new(member, kinds);
overload.add_decl(f)?;
self.0.push(overload);
}
Ok(self)
}
}
impl<'f> FunctionOverloads<Function<'f>> {
pub fn add(&mut self, member: bool, f: Function<'f>) -> Result<&mut Self, Error> {
let kinds = f
.arguments()
.into_iter()
.map(|t| t.kind())
.collect::<Vec<_>>();
if let Some(overload) = self.find_mut(member, &kinds) {
overload.add(f)?;
} else {
let mut overload = FunctionKindOverload::new(member, kinds);
overload.add(f)?;
self.0.push(overload);
}
Ok(self)
}
}
pub trait FunctionTypeOverload {
fn arguments(&self) -> Vec<ValueType>;
}
impl FunctionTypeOverload for FunctionDeclOrImpl<'_> {
fn arguments(&self) -> Vec<ValueType> {
self.decl().arguments().to_vec()
}
}
impl FunctionTypeOverload for Function<'_> {
fn arguments(&self) -> Vec<ValueType> {
self.arguments()
}
}
#[derive(Debug, Clone)]
pub struct FunctionKindOverload<T> {
member: bool,
argument_kinds: Vec<Kind>,
entries: Vec<T>,
}
impl<T: FunctionTypeOverload> FunctionKindOverload<T> {
pub fn new(member: bool, argument_kinds: Vec<Kind>) -> Self {
Self {
member,
argument_kinds,
entries: Vec::new(),
}
}
pub fn member(&self) -> bool {
self.member
}
pub fn argument_kinds(&self) -> &Vec<Kind> {
&self.argument_kinds
}
pub fn find(&self, args: &[ValueType]) -> Option<&T> {
self.entries.iter().find(|entry| entry.arguments() == args)
}
pub fn entries(&self) -> impl Iterator<Item = &T> {
self.entries.iter()
}
pub fn entries_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.entries.iter_mut()
}
pub fn clear(&mut self) {
self.entries.clear();
}
pub fn remove(&mut self, args: &[ValueType]) -> Result<(), Error> {
if let Some(index) = self
.entries
.iter()
.position(|entry| entry.arguments() == args)
{
self.entries.remove(index);
} else {
return Err(Error::not_found(format!(
"Overload [{}] ({}) not found",
if self.member { "member" } else { "global" },
args.iter()
.map(|t| t.to_string())
.collect::<Vec<_>>()
.join(", "),
)));
}
Ok(())
}
}
impl<'f> FunctionKindOverload<FunctionDeclOrImpl<'f>> {
pub fn add_impl(&mut self, f: Function<'f>) -> Result<&mut Self, Error> {
if let Some(_entry) = self.find(&f.arguments()) {
return Err(Error::invalid_argument("Function already exists"));
}
self.entries.push(FunctionDeclOrImpl::new_impl(f));
Ok(self)
}
pub fn add_decl(&mut self, r#type: FunctionType) -> Result<&mut Self, Error> {
if let Some(_entry) = self.find(r#type.arguments()) {
return Err(Error::invalid_argument("Function already exists"));
}
self.entries.push(FunctionDeclOrImpl::new(r#type));
Ok(self)
}
}
impl<'f> FunctionKindOverload<Function<'f>> {
pub fn add(&mut self, f: Function<'f>) -> Result<&mut Self, Error> {
if let Some(_entry) = self.find(&f.arguments()) {
return Err(Error::invalid_argument("Function already exists"));
}
self.entries.push(f);
Ok(self)
}
}
#[derive(Debug, Clone)]
pub struct FunctionDeclOrImpl<'f> {
r#type: FunctionType,
r#impl: Option<Function<'f>>,
}
impl<'f> FunctionDeclOrImpl<'f> {
pub fn new_impl(r#impl: Function<'f>) -> Self {
Self {
r#type: r#impl.function_type(),
r#impl: Some(r#impl),
}
}
pub fn new(r#type: FunctionType) -> Self {
Self {
r#type,
r#impl: None,
}
}
pub fn is_impl(&self) -> bool {
self.r#impl.is_some()
}
pub fn decl(&self) -> &FunctionType {
&self.r#type
}
pub fn r#impl(&self) -> Option<&Function<'f>> {
self.r#impl.as_ref()
}
}