1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use std::rc::Rc;
mod tokenizer;
mod eval;
pub mod stdlib;
pub use tokenizer::parse;
pub use eval::{Procedure, Environment, eval, ForeignFunction};
#[derive(Debug, Clone)]
pub enum Value {
List(Rc<Vec<Value>>),
String(Rc<String>),
Float(f64),
Int(i64),
Bool(bool),
Ident(Rc<String>),
ForeignFn(ForeignFunction),
Lambda(Procedure)
}
impl PartialEq for Value {
fn eq(&self, other: &Value) -> bool {
use ::Value::*;
fn rc_to_usize<T: ?Sized>(rc: &Rc<T>) -> usize {
use std::mem::transmute;
unsafe {transmute(&*rc)}
}
match (self, other) {
(&List(ref rc1), &List(ref rc2)) =>
rc_to_usize(rc1) == rc_to_usize(rc2),
(&String(ref rc1), &String(ref rc2)) =>
rc_to_usize(rc1) == rc_to_usize(rc2) || rc1 == rc2,
(&Float(f1), &Float(f2)) => f1 == f2,
(&Int(i1), &Int(i2)) => i1 == i2,
(&Bool(b1), &Bool(b2)) => b1 == b2,
(&Ident(ref id1), &Ident(ref id2)) =>
rc_to_usize(id1) == rc_to_usize(id2) || id1 == id2,
(&ForeignFn(ref ff1), &ForeignFn(ref ff2)) => ff1 == ff2,
(&Lambda(ref l1), &Lambda(ref l2)) => l1 == l2,
_ => false
}
}
}
impl Eq for Value {}
#[derive(Debug)]
pub enum Error {
UnexpectedType{expected: String, found: String},
UnexpectedArity{expected: u16, found: u16}
}