use crate::interpreter::{interpret_function, interpret_lambda, Customs, Frame};
use crate::{CustomType, InterpretError, InterpretVal};
pub fn built_in<C: CustomType>(
name: &str,
arg: InterpretVal<C>,
frame: &mut Frame<C>,
customs: &Customs<C>,
) -> Option<Result<InterpretVal<C>, InterpretError>> {
match name {
"list" => Some(list_func(arg)),
"get" => Some(get_func(arg)),
"map" => Some(map_func(arg, frame, customs)),
"filter" => Some(filter_func(arg, frame, customs)),
"len" => Some(length_func(arg)),
"any" => Some(any_func(arg, frame, customs)),
"all" => Some(all_func(arg, frame, customs)),
"fold" => Some(fold_func(arg, frame, customs)),
n => customs.built_ins.get(n).map(|f| f.call_func(&arg)),
}
}
fn list_func<C: CustomType>(arg: InterpretVal<C>) -> Result<InterpretVal<C>, InterpretError> {
let a = arg.unwrap_tuple();
if let InterpretVal::Tuple(v) = a {
Ok(InterpretVal::List(v))
} else {
Ok(InterpretVal::List(vec![a]))
}
}
fn length_func<C: CustomType>(arg: InterpretVal<C>) -> Result<InterpretVal<C>, InterpretError> {
if let InterpretVal::List(t) = arg.unwrap_tuple() {
Ok(InterpretVal::Int(t.len() as i32))
} else {
Err(InterpretError::new(
"Wrong argument type for `len` function.",
))
}
}
fn get_func<C: CustomType>(arg: InterpretVal<C>) -> Result<InterpretVal<C>, InterpretError> {
let a = arg.unwrap_tuple();
if let InterpretVal::Tuple(v) = a {
if v.len() == 2 {
if let (InterpretVal::List(l), InterpretVal::Int(i)) = (v[0].clone(), v[1].clone()) {
if i < l.len() as i32 || i < 0 {
Ok(l[i as usize].clone())
} else {
Err(InterpretError::new("Index out of range."))
}
} else {
Err(InterpretError::new(
format!("Wrong arguments for `get` ({:?}, {:?})", v[0], v[1]).as_str(),
))
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided for `get`.",
))
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided for `get`.",
))
}
}
fn map_func<C: CustomType>(
arg: InterpretVal<C>,
frame: &mut Frame<C>,
customs: &Customs<C>,
) -> Result<InterpretVal<C>, InterpretError> {
if let InterpretVal::Tuple(t) = arg {
if t.len() == 2 {
match (t.get(0).unwrap(), t.get(1).unwrap()) {
(InterpretVal::List(v), InterpretVal::Function(f)) => Ok(InterpretVal::List(
v.iter()
.map(|i| interpret_function(f, frame, i.clone(), customs))
.collect::<Result<Vec<InterpretVal<C>>, InterpretError>>()?,
)),
(InterpretVal::List(v), InterpretVal::Lambda(f, e)) => {
let mut env = e.clone();
env.set_next(frame);
Ok(InterpretVal::List(
v.iter()
.map(|i| interpret_lambda(f.clone(), &mut env, i.clone(), customs))
.collect::<Result<Vec<InterpretVal<C>>, InterpretError>>()?,
))
}
_ => Err(InterpretError::new(
format!(
"Wrong argument types provided to map: {:?}, {:?}",
t.get(0),
t.get(1)
)
.as_str(),
)),
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to map.",
))
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to map.",
))
}
}
fn filter_func<C: CustomType>(
arg: InterpretVal<C>,
frame: &mut Frame<C>,
customs: &Customs<C>,
) -> Result<InterpretVal<C>, InterpretError> {
if let InterpretVal::Tuple(t) = arg {
if t.len() == 2 {
match (t.get(0).unwrap(), t.get(1).unwrap()) {
(InterpretVal::List(v), InterpretVal::Function(f)) => Ok(InterpretVal::List(
v.iter()
.map(|v| {
if let InterpretVal::Bool(b) = interpret_function(f, frame, v.clone(), customs)? {
Ok((v.clone(), b))
} else {
Err(InterpretError::new("Filter function was not a bool."))
}
})
.collect::<Result<Vec<(InterpretVal<C>, bool)>, InterpretError>>()?
.iter()
.filter(|(_, b)| *b)
.map(|(v, _)| v.clone())
.collect(),
)),
(InterpretVal::List(v), InterpretVal::Lambda(f, e)) => {
let mut env = e.clone();
env.set_next(frame);
Ok(InterpretVal::List(
v.iter()
.map(|v| {
if let InterpretVal::Bool(b) =
interpret_lambda(f.clone(), &mut env, v.clone(), customs)?
{
Ok((v.clone(), b))
} else {
Err(InterpretError::new("Filter function was not a bool."))
}
})
.collect::<Result<Vec<(InterpretVal<C>, bool)>, InterpretError>>()?
.iter()
.filter(|(_, b)| *b)
.map(|(v, _)| v.clone())
.collect(),
))
}
_ => Err(InterpretError::new(
format!(
"Wrong argument types provided to filter: {:?}, {:?}",
t.get(0),
t.get(1)
)
.as_str(),
)),
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to filter.",
))
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to filter.",
))
}
}
fn any_func<C: CustomType>(
arg: InterpretVal<C>,
frame: &mut Frame<C>,
customs: &Customs<C>,
) -> Result<InterpretVal<C>, InterpretError> {
if let InterpretVal::Tuple(t) = arg {
if t.len() == 2 {
match (t.get(0).unwrap(), t.get(1).unwrap()) {
(InterpretVal::List(v), InterpretVal::Function(f)) => Ok(InterpretVal::Bool(
v.iter()
.map(|v| {
if let InterpretVal::Bool(b) = interpret_function(f, frame, v.clone(), customs)? {
Ok(b)
} else {
Err(InterpretError::new("Any function result was not a bool."))
}
})
.collect::<Result<Vec<bool>, InterpretError>>()?
.iter()
.any(|v| *v),
)),
(InterpretVal::List(v), InterpretVal::Lambda(f, e)) => {
let mut env = e.clone();
env.set_next(frame);
Ok(InterpretVal::Bool(
v.iter()
.map(|v| {
if let InterpretVal::Bool(b) =
interpret_lambda(f.clone(), &mut env, v.clone(), customs)?
{
Ok(b)
} else {
Err(InterpretError::new("Any function result was not a bool."))
}
})
.collect::<Result<Vec<bool>, InterpretError>>()?
.iter()
.any(|v| *v),
))
}
_ => Err(InterpretError::new(
format!(
"Wrong argument types provided to any: {:?}, {:?}",
t.get(0),
t.get(1)
)
.as_str(),
)),
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to any.",
))
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to any.",
))
}
}
fn all_func<C: CustomType>(
arg: InterpretVal<C>,
frame: &mut Frame<C>,
customs: &Customs<C>,
) -> Result<InterpretVal<C>, InterpretError> {
if let InterpretVal::Tuple(t) = arg {
if t.len() == 2 {
match (t.get(0).unwrap(), t.get(1).unwrap()) {
(InterpretVal::List(v), InterpretVal::Function(f)) => Ok(InterpretVal::Bool(
v.iter()
.map(|v| {
if let InterpretVal::Bool(b) = interpret_function(f, frame, v.clone(), customs)? {
Ok(b)
} else {
Err(InterpretError::new("Any function result was not a bool."))
}
})
.collect::<Result<Vec<bool>, InterpretError>>()?
.iter()
.all(|v| *v),
)),
(InterpretVal::List(v), InterpretVal::Lambda(f, e)) => {
let mut env = e.clone();
env.set_next(frame);
Ok(InterpretVal::Bool(
v.iter()
.map(|v| {
if let InterpretVal::Bool(b) =
interpret_lambda(f.clone(), &mut env, v.clone(), customs)?
{
Ok(b)
} else {
Err(InterpretError::new("Any function result was not a bool."))
}
})
.collect::<Result<Vec<bool>, InterpretError>>()?
.iter()
.all(|v| *v),
))
}
_ => Err(InterpretError::new(
format!(
"Wrong argument types provided to any: {:?}, {:?}",
t.get(0),
t.get(1)
)
.as_str(),
)),
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to any.",
))
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to any.",
))
}
}
fn fold_func<C: CustomType>(
arg: InterpretVal<C>,
frame: &mut Frame<C>,
customs: &Customs<C>,
) -> Result<InterpretVal<C>, InterpretError> {
if let InterpretVal::Tuple(t) = arg {
if t.len() == 3 {
match (t.get(0).unwrap(), t.get(1).unwrap(), t.get(2).unwrap()) {
(InterpretVal::List(v), s, InterpretVal::Function(f)) => {
v.iter().fold(Ok(s.clone()), |acc, x| {
interpret_function(
f,
frame,
InterpretVal::Tuple(vec![acc?, x.clone()]),
customs,
)
})
}
(InterpretVal::List(v), s, InterpretVal::Lambda(f, e)) => {
v.iter().fold(Ok(s.clone()), |acc, x| {
let mut l = e.clone();
l.set_next(frame);
interpret_lambda(
f.clone(),
&mut l,
InterpretVal::Tuple(vec![acc?, x.clone()]),
customs,
)
})
}
_ => Err(InterpretError::new(
"Wrong arguments types provided to fold.",
)),
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to fold.",
))
}
} else {
Err(InterpretError::new(
"Wrong number of arguments provided to fold.",
))
}
}