refactor: use macro for arg counting

This commit is contained in:
Roman Godmaire 2024-02-17 22:16:51 -05:00
parent c2b95dfee4
commit 4a02f7cb95
3 changed files with 24 additions and 33 deletions

View file

@ -1,5 +1,6 @@
use std::{borrow::Borrow, cell::RefCell, collections::HashMap, rc::Rc}; use std::{borrow::Borrow, cell::RefCell, collections::HashMap, rc::Rc};
use super::macros::arg_count;
use super::{eval_ast_node, Error, Expression}; use super::{eval_ast_node, Error, Expression};
use crate::parser::Node; use crate::parser::Node;
@ -130,9 +131,7 @@ pub fn core_environment() -> Rc<Environment> {
( (
"eq?", "eq?",
Expression::NativeFunc(|args| { Expression::NativeFunc(|args| {
if args.len() != 2 { arg_count!(2, args.len());
Err(Error::MismatchedArgCount(2, args.len()))?
}
if args[0] == args[1] { if args[0] == args[1] {
return Ok(Expression::Boolean(true).into()); return Ok(Expression::Boolean(true).into());
@ -144,9 +143,7 @@ pub fn core_environment() -> Rc<Environment> {
( (
"not", "not",
Expression::NativeFunc(|args| { Expression::NativeFunc(|args| {
if args.len() != 1 { arg_count!(1, args.len());
Err(Error::MismatchedArgCount(1, args.len()))?
}
if *args[0] == Expression::Boolean(false) { if *args[0] == Expression::Boolean(false) {
return Ok(Expression::Boolean(true).into()); return Ok(Expression::Boolean(true).into());
@ -158,9 +155,7 @@ pub fn core_environment() -> Rc<Environment> {
( (
"<", "<",
Expression::NativeFunc(|args| { Expression::NativeFunc(|args| {
if args.len() != 2 { arg_count!(2, args.len());
Err(Error::MismatchedArgCount(2, args.len()))?
}
let less_than = match (args[0].borrow(), args[1].borrow()) { let less_than = match (args[0].borrow(), args[1].borrow()) {
(Expression::Int(lhs), Expression::Int(rhs)) => lhs < rhs, (Expression::Int(lhs), Expression::Int(rhs)) => lhs < rhs,
@ -173,9 +168,7 @@ pub fn core_environment() -> Rc<Environment> {
( (
">", ">",
Expression::NativeFunc(|args| { Expression::NativeFunc(|args| {
if args.len() != 2 { arg_count!(2, args.len());
Err(Error::MismatchedArgCount(2, args.len()))?
}
let greater_than = match (args[0].borrow(), args[1].borrow()) { let greater_than = match (args[0].borrow(), args[1].borrow()) {
(Expression::Int(lhs), Expression::Int(rhs)) => lhs > rhs, (Expression::Int(lhs), Expression::Int(rhs)) => lhs > rhs,
@ -188,9 +181,7 @@ pub fn core_environment() -> Rc<Environment> {
( (
"<=", "<=",
Expression::NativeFunc(|args| { Expression::NativeFunc(|args| {
if args.len() != 2 { arg_count!(2, args.len());
Err(Error::MismatchedArgCount(2, args.len()))?
}
let less_than_equal = match (args[0].borrow(), args[1].borrow()) { let less_than_equal = match (args[0].borrow(), args[1].borrow()) {
(Expression::Int(lhs), Expression::Int(rhs)) => lhs <= rhs, (Expression::Int(lhs), Expression::Int(rhs)) => lhs <= rhs,
@ -203,9 +194,7 @@ pub fn core_environment() -> Rc<Environment> {
( (
">=", ">=",
Expression::NativeFunc(|args| { Expression::NativeFunc(|args| {
if args.len() != 2 { arg_count!(2, args.len());
Err(Error::MismatchedArgCount(2, args.len()))?
}
let greater_than_equal = match (args[0].borrow(), args[1].borrow()) { let greater_than_equal = match (args[0].borrow(), args[1].borrow()) {
(Expression::Int(lhs), Expression::Int(rhs)) => lhs >= rhs, (Expression::Int(lhs), Expression::Int(rhs)) => lhs >= rhs,
@ -219,9 +208,7 @@ pub fn core_environment() -> Rc<Environment> {
( (
"if", "if",
Expression::NativeFunc(|args| { Expression::NativeFunc(|args| {
if args.len() != 3 { arg_count!(3, args.len());
Err(Error::MismatchedArgCount(3, args.len()))?
}
let (cond, consequence, alternative) = let (cond, consequence, alternative) =
(args[0].clone(), args[1].clone(), args[2].clone()); (args[0].clone(), args[1].clone(), args[2].clone());
@ -239,9 +226,7 @@ pub fn core_environment() -> Rc<Environment> {
"define!", "define!",
Expression::Special(|env, args| { Expression::Special(|env, args| {
let mut args = args.into_iter(); let mut args = args.into_iter();
if args.len() != 2 { arg_count!(2, args.len());
Err(Error::MismatchedArgCount(2, args.len()))?
}
let key = match args.next().unwrap() { let key = match args.next().unwrap() {
Node::Symbol(name) => name, Node::Symbol(name) => name,
@ -258,9 +243,7 @@ pub fn core_environment() -> Rc<Environment> {
( (
"let*", "let*",
Expression::Special(|env, args| { Expression::Special(|env, args| {
if args.len() != 2 { arg_count!(2, args.len());
Err(Error::MismatchedArgCount(2, args.len()))?
}
let mut args = args.into_iter(); let mut args = args.into_iter();
let new_env = match args.next().unwrap() { let new_env = match args.next().unwrap() {
@ -288,9 +271,7 @@ pub fn core_environment() -> Rc<Environment> {
"fn*", "fn*",
Expression::Special(|env, args| { Expression::Special(|env, args| {
let mut args = args; let mut args = args;
if args.len() != 2 { arg_count!(2, args.len());
Err(Error::MismatchedArgCount(2, args.len()))?
}
let arg_list = args.remove(0); let arg_list = args.remove(0);
let body = args.remove(0); let body = args.remove(0);
@ -317,9 +298,7 @@ pub fn core_environment() -> Rc<Environment> {
( (
"display", "display",
Expression::NativeFunc(|args| { Expression::NativeFunc(|args| {
if args.len() != 1 { arg_count!(1, args.len());
Err(Error::MismatchedArgCount(1, args.len()))?
}
print!("{}", args[0]); print!("{}", args[0]);

10
src/evaluator/macros.rs Normal file
View file

@ -0,0 +1,10 @@
#[macro_export]
macro_rules! arg_count {
($expected:expr, $given:expr) => {
if $expected != $given {
Err(Error::MismatchedArgCount($expected, $given))?
}
};
}
pub(crate) use arg_count;

View file

@ -6,6 +6,8 @@ use thiserror::Error;
use crate::parser::Node; use crate::parser::Node;
mod env; mod env;
mod macros;
pub use env::{core_environment, Environment}; pub use env::{core_environment, Environment};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]