118 lines
2.7 KiB
Rust
118 lines
2.7 KiB
Rust
|
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<dyn std::ops::Fn(Value<'src>) -> Result<Value<'src>, LudusError>>,
|
||
|
),
|
||
|
Binary(
|
||
|
&'src str,
|
||
|
Box<dyn std::ops::Fn(Value<'src>, Value<'src>) -> Result<Value<'src>, LudusError>>,
|
||
|
),
|
||
|
Ternary(
|
||
|
&'src str,
|
||
|
Box<
|
||
|
dyn std::ops::Fn(
|
||
|
Value<'src>,
|
||
|
Value<'src>,
|
||
|
Value<'src>,
|
||
|
) -> Result<Value<'src>, 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
|