refactor: use macro for arg counting
This commit is contained in:
parent
c2b95dfee4
commit
4a02f7cb95
3 changed files with 24 additions and 33 deletions
|
@ -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
10
src/evaluator/macros.rs
Normal 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;
|
|
@ -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)]
|
||||||
|
|
Loading…
Reference in a new issue