parsley 0.10.0

An implementation of Scheme
Documentation
use std::fmt;
use std::string::String as CoreString;

use super::{proc::Proc, Ns, SExp};

use self::Primitive::{
    Boolean, Character, Env, Number, Procedure, String, Symbol, Undefined, Vector, Void,
};

pub use self::num::Num;

mod from;
mod num;

#[derive(Clone, PartialEq)]
pub enum Primitive {
    Void,
    Undefined,
    Boolean(bool),
    Character(char),
    Number(Num),
    String(CoreString),
    Symbol(CoreString),
    Env(Ns),
    Procedure(Proc),
    Vector(Vec<SExp>),
}

impl fmt::Debug for Primitive {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Void => f.write_str("#<void>"),
            Undefined => f.write_str("#<undefined>"),
            Boolean(b) => f.write_str(if *b { "#t" } else { "#f" }),
            Character(c) => write!(f, "#\\{}", c),
            Number(n) => write!(f, "{}", n),
            String(s) => write!(f, "\"{}\"", s),
            Symbol(s) => write!(f, "{}", s),
            Env(_) => write!(f, "#<environment>"),
            Procedure(p) => write!(f, "{}", p),
            Vector(v) => write!(
                f,
                "#({})",
                v.iter()
                    .map(|e| format!("{:?}", e))
                    .collect::<Vec<_>>()
                    .join(" ")
            ),
        }
    }
}

impl fmt::Display for Primitive {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Undefined | Void => Ok(()),
            Boolean(b) => f.write_str(if *b { "#t" } else { "#f" }),
            Character(c) => write!(f, "{}", c),
            Number(n) => write!(f, "{}", n),
            String(s) | Symbol(s) => f.write_str(s),
            Env(_) => write!(f, "#<environment>"),
            Procedure(p) => write!(f, "{}", p),
            Vector(v) => write!(
                f,
                "#({})",
                v.iter().map(SExp::to_string).collect::<Vec<_>>().join(" ")
            ),
        }
    }
}

impl Primitive {
    pub fn type_of(&self) -> &str {
        match self {
            Void => "void",
            Undefined => "undefined",
            Boolean(_) => "bool",
            Character(_) => "char",
            Number(_) => "number",
            String(_) => "string",
            Symbol(_) => "symbol",
            Env(_) => "environment",
            Procedure { .. } => "procedure",
            Vector(_) => "vector",
        }
    }
}