diff --git a/src/lisp/expression.rs b/src/lisp/expression.rs index 6ceb650..fb7b088 100644 --- a/src/lisp/expression.rs +++ b/src/lisp/expression.rs @@ -56,10 +56,10 @@ impl From<(Expression, Expression)> for Expression { } } -impl TryInto for Expression { +impl TryFrom for i64 { type Error = EvalError; - fn try_into(self) -> Result { - match self { + fn try_from(value: Expression) -> Result { + match value { Expression::Integer(i) => Ok(i), _ => Err(EvalError::TypeError( "Expression is not an Integer".to_string(), @@ -68,10 +68,10 @@ impl TryInto for Expression { } } -impl TryInto for Expression { +impl TryFrom for f64 { type Error = EvalError; - fn try_into(self) -> Result { - match self { + fn try_from(value: Expression) -> Result { + match value { Expression::Float(f) => Ok(f), _ => Err(EvalError::TypeError( "Expression is not a Float".to_string(), @@ -80,10 +80,10 @@ impl TryInto for Expression { } } -impl TryInto for Expression { +impl TryFrom for String { type Error = EvalError; - fn try_into(self) -> Result { - match self { + fn try_from(value: Expression) -> Result { + match value { Expression::String(s) => Ok(s), _ => Err(EvalError::TypeError( "Expression is not a String".to_string(), @@ -92,19 +92,35 @@ impl TryInto for Expression { } } -impl TryInto> for Expression { +impl TryFrom for Vec { type Error = EvalError; - fn try_into(self) -> Result, Self::Error> { - CellIterator::new(self).collect() + fn try_from(value: Expression) -> Result, Self::Error> { + CellIterator::new(value).collect() } } -impl TryInto<[Expression; N]> for Expression { +impl TryFrom for Vec +where + ToExpr: TryFrom, +{ type Error = EvalError; - fn try_into(self) -> Result<[Expression; N], Self::Error> { - let buf: Vec = self.try_into()?; + fn try_from(value: Expression) -> Result, Self::Error> { + CellIterator::new(value) + .map(|x| x?.try_into() as Result) + .collect() + } +} + +impl TryFrom for [ToExpr; N] +where + ToExpr: TryFrom, +{ + type Error = EvalError; + + fn try_from(value: Expression) -> Result<[ToExpr; N], Self::Error> { + let buf: Vec = value.try_into()?; let n = buf.len(); buf.try_into() @@ -112,10 +128,22 @@ impl TryInto<[Expression; N]> for Expression { } } -impl TryInto<(Expression, Expression)> for Expression { +impl TryFrom for [Expression; N] { type Error = EvalError; - fn try_into(self) -> Result<(Expression, Expression), Self::Error> { - match self { + + fn try_from(value: Expression) -> Result<[Expression; N], Self::Error> { + let buf: Vec = value.try_into()?; + let n = buf.len(); + + buf.try_into() + .map_err(|_| EvalError::ArgumentError(format!("Expected {} arguments, got {}", N, n))) + } +} + +impl TryFrom for (Expression, Expression) { + type Error = EvalError; + fn try_from(value: Expression) -> Result<(Expression, Expression), Self::Error> { + match value { Expression::Cell(a, b) => Ok((*a, *b)), _ => Err(EvalError::TypeError( "Expression must be a Cell".to_string(), diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs index a740228..1e565cc 100644 --- a/src/lisp/prelude.rs +++ b/src/lisp/prelude.rs @@ -79,7 +79,7 @@ pub fn prelude_div(env: &Environment, expr: Expression) -> Result Result { - let [args, body] = expr.try_into()?; + let [args, body]: [Expression; 2] = expr.try_into()?; let mut arg_exprs: Vec = args.try_into()?; let argument_symbols: Vec = arg_exprs .iter_mut()