use crate::value::*; use crate::vm::*; use imbl::*; use std::cell::RefCell; use std::fmt; use std::rc::Rc; pub enum Base<'src> { Unary( &'src str, Box) -> Result, LudusError>>, ), Binary( &'src str, Box, Value<'src>) -> Result, LudusError>>, ), Ternary( &'src str, Box< dyn std::ops::Fn( Value<'src>, Value<'src>, Value<'src>, ) -> Result, LudusError>, >, ), } impl<'src> Base<'src> { pub fn name(&self) -> &'src str { match self { Base::Unary(name, _) => name, Base::Binary(name, _) => name, Base::Ternary(name, _) => name, } } } impl<'src> fmt::Debug for Base<'src> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Base").field(&self.name()).finish() } } pub fn base<'src>() -> Vec<(&'src str, Value<'src>)> { let mut base = vec![]; let eq = Base::Binary("eq", Box::new(|x, y| Ok(Value::Boolean(x == y)))); base.push(("eq", Value::Base(&eq))); let add = Base::Binary( "add", Box::new(|x, y| match (x, y) { (Value::Number(x), Value::Number(y)) => Ok(Value::Number(x + y)), _ => Err(LudusError { msg: "I can only add numbers".to_string(), }), }), ); base.push(("add", Value::Base(&add))); base } // add (x, y) -> number // and (x, y) -> value // assoc (x, y) -> dict // atan_2 (x) -> number // bool (x) -> bool // ceil (x) -> number // chars (x) -> list // concat (x, y) -> value // conj (x, y) -> list // cos (x) -> number // dec (x) -> number // disj (x) -> set // dissoc (x, y) -> dict // div (x, y) -> number // doc (x) -> string // downcase (x) -> string // first (x) -> value // floor (x) -> number // get (x, y) -> value // gt (x, y) -> bool // gte! (x, y) -> bool // inc (x) -> number // last (x) -> value // lt (x) -> bool // lte (x) -> bool // mod (x, y) -> number // or (x, y) -> value // pi // print! (x) -> :ok // prn (x) -> value // push (x) -> list // random () -> number // range () -> list // rest (x) -> coll // round (x) -> number // show (x) -> string // sin (x) -> number // slice (x, y, z) -> list // split (x, y) -> list(string) // sqrt (x) -> number // store! (x, y) -> value // str_slice (x, y, z) -> string // stringify (x) -> string // sub (x, y) -> number // tan (x) -> number // to_list (x) -> list // to_number (x) -> number // trim (x) -> string // triml (x) -> string // trimr (x) -> string // type (x) -> keyword // unbox (x) -> value // upcase (x) -> string