refactor: remove mutable reassignment
This commit is contained in:
parent
ed86c884ec
commit
a7c6e1a07d
2 changed files with 31 additions and 46 deletions
56
mute-interpreter/src/env/core.rs
vendored
56
mute-interpreter/src/env/core.rs
vendored
|
@ -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()
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue