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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
use std::ops::{Add, Div, Mul, Sub}; use colored::*; use itertools::Itertools; use env::Env; use std::fmt; #[derive(Clone, PartialEq)] pub enum Expr { Nil, Bool(bool), Int(i64), Float(f64), Str(String), Symbol(String), Quote(Box<Expr>), Fun(Function, Arguments), Special(Function, Arguments), List(Vec<Expr>), } use Expr::*; impl fmt::Debug for Expr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Nil => write!(f, "nil"), Bool(x) => write!(f, "{:?}", x), Int(x) => write!(f, "{:?}", x), Float(x) => write!(f, "{:?}", x), Str(x) => write!(f, "{:?}", x), Symbol(x) => write!(f, "{}", x), Quote(x) => write!(f, "'{:?}", x), Fun(_, _) => write!(f, "<function>"), Special(_, _) => write!(f, "<special>"), List(xs) => write!(f, "({})", xs.iter().map(|x| format!("{:?}", x)).join(" ")), } } } impl fmt::Display for Expr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Nil => write!(f, "{}", format!("{:?}", self).cyan()), Bool(_) => write!(f, "{}", format!("{:?}", self).green()), Int(_) => write!(f, "{}", format!("{:?}", self).blue()), Float(_) => write!(f, "{}", format!("{:?}", self).blue()), Str(_) => write!(f, "{}", format!("{:?}", self).yellow()), Symbol(_) => write!(f, "{}", format!("{:?}", self).white()), Quote(x) => write!(f, "'{}", x), Fun(_, _) => write!(f, "{}", format!("{:?}", self).magenta()), Special(_, _) => write!(f, "{}", format!("{:?}", self).magenta()), List(xs) => write!(f, "({})", xs.iter().map(|x| format!("{}", x)).join(" ")), } } } impl Add for Expr { type Output = Self; fn add(self, other: Self) -> Self { match (self, other) { (Int(a), Int(b)) => Int(a + b), (Int(a), Float(b)) => Float(a as f64 + b), (Float(a), Int(b)) => Float(a + b as f64), (Float(a), Float(b)) => Float(a + b), (Str(a), Str(b)) => Str(format!("{}{}", a, b)), (a, b) => panic!("Can't add {:?} and {:?}", a, b), } } } impl Sub for Expr { type Output = Self; fn sub(self, other: Self) -> Self { match (self, other) { (Int(a), Int(b)) => Int(a - b), (Int(a), Float(b)) => Float(a as f64 - b), (Float(a), Int(b)) => Float(a - b as f64), (Float(a), Float(b)) => Float(a - b), (a, b) => panic!("Can't subtract {:?} from {:?}", b, a), } } } impl Mul for Expr { type Output = Self; fn mul(self, other: Self) -> Self { match (self, other) { (Int(a), Int(b)) => Int(a * b), (Int(a), Float(b)) => Float(a as f64 * b), (Float(a), Int(b)) => Float(a * b as f64), (Float(a), Float(b)) => Float(a * b), (a, b) => panic!("Can't multiply {:?} with {:?}", a, b), } } } impl Div for Expr { type Output = Self; fn div(self, other: Self) -> Self { match (self, other) { (Int(a), Int(b)) => Int(a / b), (Int(a), Float(b)) => Float(a as f64 / b), (Float(a), Int(b)) => Float(a / b as f64), (Float(a), Float(b)) => Float(a / b), (a, b) => panic!("Can't divide {:?} a {:?}", a, b), } } } #[derive(Clone)] pub enum Function { Builtin(fn(&mut Env) -> Expr), Dynamic(Box<Expr>), } impl PartialEq for Function { fn eq(&self, _other: &Self) -> bool { false } } #[derive(Debug, Clone, PartialEq)] pub enum Arguments { Variadic, Fixed(Vec<String>), }