Skip to content

Instantly share code, notes, and snippets.

@Compro-Prasad
Created July 26, 2019 12:59
Show Gist options
  • Save Compro-Prasad/c00e4bfd6b4d777c671a1eefb884096a to your computer and use it in GitHub Desktop.
Save Compro-Prasad/c00e4bfd6b4d777c671a1eefb884096a to your computer and use it in GitHub Desktop.
Testing
use std::collections::HashMap;
type Defun = fn(LispType) -> LispType;
#[derive(Debug, Clone, PartialEq)]
pub enum LispType {
Symbol(String),
Str(String),
RealNumber(f64),
LispDefun(Defun),
List(Vec<LispType>),
Cons(Box<LispType>, Box<LispType>),
Error(String),
Nil,
}
enum Scope {
Cons(HashMap<String, LispType>, Box<Scope>),
Nil,
}
fn add(args: &Vec<LispType>) -> LispType {
let mut sum = 0.0;
for n in args {
match n {
LispType::RealNumber(num) => sum += num,
_ => return LispType::Error("Not a number".to_string()),
}
}
LispType::RealNumber(sum)
}
fn cons(a1: &LispType, a2: &LispType) -> LispType {
match a2 {
LispType::List(list) => {
let mut result = Vec::new();
result.push(a1.clone());
for obj in list {
result.push(obj.clone());
}
LispType::List(result)
}
LispType::Symbol(_) | LispType::RealNumber(_) | LispType::Str(_) => {
LispType::Cons(Box::new(a1.clone()), Box::new(a2.clone()))
}
LispType::Nil => LispType::List(vec![a1.clone()]),
_ => LispType::Error("Cons doesn't have support for that".to_string()),
}
}
fn car(a: &LispType) -> LispType {
match a {
LispType::List(list) => {
if list.is_empty() {
LispType::Nil
} else {
LispType::List(vec![list[0].clone()])
}
}
LispType::Nil => LispType::Nil,
_ => LispType::Error("Car accepts only list".to_string()),
}
}
fn cdr(a: &LispType) -> LispType {
match a {
LispType::List(list) => {
if list.len() < 2 {
LispType::Nil
} else {
LispType::List(list[1..].to_vec())
}
}
LispType::Nil => LispType::Nil,
_ => LispType::Error("Cdr accepts only list".to_string()),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(
add(&vec![
LispType::RealNumber(1.0),
LispType::RealNumber(2.0),
LispType::RealNumber(3.0)
]),
LispType::RealNumber(6.0)
);
}
#[test]
fn test_cons() {
assert_eq!(
cons(
&LispType::Symbol("a".to_string()),
&LispType::Symbol("b".to_string())
),
LispType::Cons(
Box::new(LispType::Symbol("a".to_string())),
Box::new(LispType::Symbol("b".to_string()))
)
);
assert_eq!(
cons(&LispType::Symbol("a".to_string()), &LispType::Nil),
LispType::List(vec![LispType::Symbol("a".to_string())])
);
assert_eq!(
cons(
&LispType::Symbol("a".to_string()),
&LispType::List(vec![LispType::Symbol("b".to_string())])
),
LispType::List(vec![
LispType::Symbol("a".to_string()),
LispType::Symbol("b".to_string())
])
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment