diff --git a/mute-interpreter/src/env/core.rs b/mute-interpreter/src/env/core.rs index 12ef3fd..cc96452 100644 --- a/mute-interpreter/src/env/core.rs +++ b/mute-interpreter/src/env/core.rs @@ -26,12 +26,11 @@ macro_rules! arithmetic { macro_rules! ordering { ($operator:tt) => { - NativeFunc(|args| { + NativeFunc(|mut args| { arg_count!(2, args.len()); - let mut args = args.into_iter(); - let lhs = args.next().unwrap(); - let rhs = args.next().unwrap(); + let lhs = args.pop_front().unwrap(); + let rhs = args.pop_front().unwrap(); let res = match (lhs, rhs) { (Node::Int(lhs), Node::Int(rhs)) => lhs $operator rhs, @@ -232,9 +231,8 @@ pub(super) fn core() -> HashMap { ), ( "empty?", - NativeFunc(|args| { + NativeFunc(|mut args| { arg_count!(1, args.len()); - let mut args = args; match args.pop_front().expect("argument length checked above") { Node::List(list) => Node::Boolean(list.is_empty()), @@ -249,9 +247,8 @@ pub(super) fn core() -> HashMap { ), ( "count", - NativeFunc(|args| { + NativeFunc(|mut args| { arg_count!(1, args.len()); - let mut args = args; match args.pop_front().expect("argument length checked above") { Node::List(list) => Node::Int(list.len() as i64), @@ -294,10 +291,10 @@ pub(super) fn core() -> HashMap { ), ( "last", - NativeFunc(|args| { + NativeFunc(|mut args| { arg_count!(1, args.len()); - match args[0].borrow() { + match args.pop_front().expect("argument length checked above") { Node::List(list) if list.is_empty() => Node::Nil, Node::Vector(list) if list.is_empty() => Node::Nil, @@ -312,10 +309,9 @@ pub(super) fn core() -> HashMap { ), ( "nth", - NativeFunc(|args| { + NativeFunc(|mut args| { arg_count!(2, args.len()); - let mut args = args; let list = match args.pop_front().expect("argument length checked above") { Node::List(list) => list, Node::Vector(vec) => vec.into(), @@ -343,9 +339,8 @@ pub(super) fn core() -> HashMap { ), ( "push-back", - NativeFunc(|args| { - let mut args = args; - match args.pop_front().expect("argument length checked above") { + NativeFunc( + |mut args| match args.pop_front().expect("argument length checked above") { Node::List(mut list) => { while let Some(val) = args.pop_front() { list.push_back(val); @@ -364,14 +359,13 @@ pub(super) fn core() -> HashMap { "TypeError: expected list or vector, got {}.", arg.get_type() )), - } - }), + }, + ), ), ( "push-front", - NativeFunc(|args| { - let mut args = args; - match args.pop_front().expect("argument length checked above") { + NativeFunc( + |mut args| match args.pop_front().expect("argument length checked above") { Node::List(mut list) => { while let Some(val) = args.pop_back() { list.push_front(val); @@ -382,14 +376,13 @@ pub(super) fn core() -> HashMap { arg => { Node::Error(format!("TypeError: expected list, got {}.", arg.get_type())) } - } - }), + }, + ), ), ( "pop-front", - NativeFunc(|args| { - let mut args = args; - match args.pop_front().expect("argument length checked above") { + NativeFunc( + |mut args| match args.pop_front().expect("argument length checked above") { Node::List(mut list) => { list.pop_front(); Node::List(list) @@ -397,14 +390,13 @@ pub(super) fn core() -> HashMap { arg => { Node::Error(format!("TypeError: expected list, got {}.", arg.get_type())) } - } - }), + }, + ), ), ( "pop-back", - NativeFunc(|args| { - let mut args = args; - match args.pop_front().expect("argument length checked above") { + NativeFunc( + |mut args| match args.pop_front().expect("argument length checked above") { Node::List(mut list) => { list.pop_back(); Node::List(list) @@ -416,8 +408,8 @@ pub(super) fn core() -> HashMap { arg => { Node::Error(format!("TypeError: expected list, got {}.", arg.get_type())) } - } - }), + }, + ), ), ] .into_iter() diff --git a/mute-interpreter/src/evaluator.rs b/mute-interpreter/src/evaluator.rs index a8685cf..e44c698 100644 --- a/mute-interpreter/src/evaluator.rs +++ b/mute-interpreter/src/evaluator.rs @@ -3,10 +3,9 @@ use std::collections::VecDeque; use crate::{Environment, Error, Result}; use mute_parser::Node; -pub fn eval(env: &Environment, ast: VecDeque) -> Result> { +pub fn eval(env: &Environment, mut ast: VecDeque) -> Result> { let mut results = VecDeque::new(); - let mut ast = ast; while let Some(node) = ast.pop_front() { if let Node::List(list) = &node { let first = match list.front() { @@ -17,8 +16,7 @@ pub fn eval(env: &Environment, ast: VecDeque) -> Result> { node => node.cloned(), }; - if let Some(Node::Macro(body)) = first { - let mut body = body; + if let Some(Node::Macro(mut body)) = first { let parameters = body.pop_front().ok_or_else(|| todo!())?; let parameters = read_parameters(parameters.clone())?; let args = list.clone().into_iter().skip(1).collect::>(); @@ -56,8 +54,7 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result { let operator = eval_node(env, list.pop_front().ok_or(Error::InvalidOperator)?)?; match operator { - Node::Function(body) => { - let mut body = body; + Node::Function(mut body) => { let parameters = body.pop_front().ok_or_else(|| todo!())?; let parameters = read_parameters(parameters.clone())?; @@ -81,8 +78,7 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result { } } - Node::Macro(body) => { - let mut body = body; + Node::Macro(mut body) => { let parameters = body.pop_front().ok_or_else(|| todo!())?; let parameters = read_parameters(parameters.clone())?; @@ -135,8 +131,7 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result { Node::Void } - Node::Let(body) => { - let mut body = body; + Node::Let(mut body) => { let args = match body.pop_front().ok_or_else(|| todo!())? { Node::List(list) => list .into_iter() @@ -161,12 +156,11 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result { eval(&env, body)?.pop_back().unwrap() } - Node::If(body) => { + Node::If(mut body) => { if body.len() != 2 && body.len() != 3 { Err(Error::MismatchedArgCount(3, body.len()))? } - let mut body = body; let cond = body.pop_front().expect("arg count verified above").clone(); let consequence = body.pop_front().expect("arg count verified above").clone(); let alternative = match body.pop_front() { @@ -222,8 +216,7 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result { env, eval_node(env, body.pop_front().ok_or_else(|| todo!())?)?, )?, - Node::Apply(body) => { - let mut body = body; + Node::Apply(mut body) => { let operator = eval_node(env, body.pop_front().ok_or(Error::InvalidOperator)?)?; let mut args = match body.pop_front() {