refactor: remove mutable reassignment

This commit is contained in:
Roman Godmaire 2024-05-14 11:50:01 -04:00
parent ed86c884ec
commit a7c6e1a07d
2 changed files with 31 additions and 46 deletions

View file

@ -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<String, Value> {
),
(
"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<String, Value> {
),
(
"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<String, Value> {
),
(
"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<String, Value> {
),
(
"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<String, Value> {
),
(
"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<String, Value> {
"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<String, Value> {
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<String, Value> {
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<String, Value> {
arg => {
Node::Error(format!("TypeError: expected list, got {}.", arg.get_type()))
}
}
}),
},
),
),
]
.into_iter()

View file

@ -3,10 +3,9 @@ use std::collections::VecDeque;
use crate::{Environment, Error, Result};
use mute_parser::Node;
pub fn eval(env: &Environment, ast: VecDeque<Node>) -> Result<VecDeque<Node>> {
pub fn eval(env: &Environment, mut ast: VecDeque<Node>) -> Result<VecDeque<Node>> {
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<Node>) -> Result<VecDeque<Node>> {
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::<VecDeque<Node>>();
@ -56,8 +54,7 @@ pub fn eval_node(env: &Environment, ast_node: Node) -> Result<Node> {
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> {
}
}
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> {
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<Node> {
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<Node> {
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() {