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