finish base, I think
This commit is contained in:
parent
5e10a87cbc
commit
13c14fd38f
|
@ -11,3 +11,4 @@ chumsky = { git = "https://github.com/zesterer/chumsky", features = ["label"] }
|
|||
imbl = "3.0.0"
|
||||
struct_scalpel = "0.1.1"
|
||||
tailcall = "1.0.1"
|
||||
ran = "2.0.1"
|
||||
|
|
309
src/base.rs
309
src/base.rs
|
@ -1,9 +1,11 @@
|
|||
use crate::value::*;
|
||||
use imbl::*;
|
||||
use ran::ran_f64;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Base<'src> {
|
||||
Nullary(fn() -> Value<'src>),
|
||||
Unary(fn(&Value<'src>) -> Value<'src>),
|
||||
Binary(fn(&Value<'src>, &Value<'src>) -> Value<'src>),
|
||||
Ternary(fn(&Value<'src>, &Value<'src>, &Value<'src>) -> Value<'src>),
|
||||
|
@ -384,72 +386,262 @@ pub fn r#type<'src>(x: &Value<'src>) -> Value<'src> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn split<'src>(source: &Value<'src>, splitter: &Value) -> Value<'src> {
|
||||
match (source, splitter) {
|
||||
(Value::AllocatedString(source), Value::AllocatedString(splitter)) => {
|
||||
let parts = source.split_terminator(splitter.as_str());
|
||||
let mut list = vector![];
|
||||
for part in parts {
|
||||
list.push_back(Value::AllocatedString(Rc::new(part.to_string())));
|
||||
}
|
||||
Value::List(list)
|
||||
}
|
||||
(Value::AllocatedString(source), Value::InternedString(splitter)) => {
|
||||
let parts = source.split_terminator(splitter);
|
||||
let mut list = vector![];
|
||||
for part in parts {
|
||||
list.push_back(Value::AllocatedString(Rc::new(part.to_string())));
|
||||
}
|
||||
Value::List(list)
|
||||
}
|
||||
(Value::InternedString(source), Value::AllocatedString(splitter)) => {
|
||||
let parts = source.split_terminator(splitter.as_str());
|
||||
let mut list = vector![];
|
||||
for part in parts {
|
||||
list.push_back(Value::AllocatedString(Rc::new(part.to_string())));
|
||||
}
|
||||
Value::List(list)
|
||||
}
|
||||
(Value::InternedString(source), Value::InternedString(splitter)) => {
|
||||
let parts = source.split_terminator(splitter);
|
||||
let mut list = vector![];
|
||||
for part in parts {
|
||||
list.push_back(Value::AllocatedString(Rc::new(part.to_string())));
|
||||
}
|
||||
Value::List(list)
|
||||
}
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn upcase<'src>(string: &Value<'src>) -> Value<'src> {
|
||||
match string {
|
||||
Value::AllocatedString(string) => Value::AllocatedString(Rc::new(string.to_uppercase())),
|
||||
Value::InternedString(string) => Value::AllocatedString(Rc::new(string.to_uppercase())),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn downcase<'src>(string: &Value<'src>) -> Value<'src> {
|
||||
match string {
|
||||
Value::AllocatedString(string) => Value::AllocatedString(Rc::new(string.to_lowercase())),
|
||||
Value::InternedString(string) => Value::AllocatedString(Rc::new(string.to_lowercase())),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trim<'src>(string: &Value<'src>) -> Value<'src> {
|
||||
match string {
|
||||
Value::AllocatedString(string) => {
|
||||
Value::AllocatedString(Rc::new(string.trim().to_string()))
|
||||
}
|
||||
Value::InternedString(string) => Value::AllocatedString(Rc::new(string.trim().to_string())),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn triml<'src>(string: &Value<'src>) -> Value<'src> {
|
||||
match string {
|
||||
Value::AllocatedString(string) => {
|
||||
Value::AllocatedString(Rc::new(string.trim_start().to_string()))
|
||||
}
|
||||
Value::InternedString(string) => {
|
||||
Value::AllocatedString(Rc::new(string.trim_start().to_string()))
|
||||
}
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trimr<'src>(string: &Value<'src>) -> Value<'src> {
|
||||
match string {
|
||||
Value::AllocatedString(string) => {
|
||||
Value::AllocatedString(Rc::new(string.trim_end().to_string()))
|
||||
}
|
||||
Value::InternedString(string) => {
|
||||
Value::AllocatedString(Rc::new(string.trim_end().to_string()))
|
||||
}
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn atan_2<'src>(x: &Value, y: &Value) -> Value<'src> {
|
||||
match (x, y) {
|
||||
(Value::Number(x), Value::Number(y)) => Value::Number(x.atan2(*y)),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ceil<'src>(x: &Value) -> Value<'src> {
|
||||
match x {
|
||||
Value::Number(x) => Value::Number(x.ceil()),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cos<'src>(x: &Value) -> Value<'src> {
|
||||
match x {
|
||||
Value::Number(x) => Value::Number(x.cos()),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn floor<'src>(x: &Value) -> Value<'src> {
|
||||
match x {
|
||||
Value::Number(x) => Value::Number(x.floor()),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random<'src>() -> Value<'src> {
|
||||
Value::Number(ran_f64())
|
||||
}
|
||||
|
||||
pub fn round<'src>(x: &Value) -> Value<'src> {
|
||||
match x {
|
||||
Value::Number(x) => Value::Number(x.round()),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sin<'src>(x: &Value) -> Value<'src> {
|
||||
match x {
|
||||
Value::Number(x) => Value::Number(x.sin()),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sqrt<'src>(x: &Value) -> Value<'src> {
|
||||
match x {
|
||||
Value::Number(x) => Value::Number(x.sqrt()),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tan<'src>(x: &Value) -> Value<'src> {
|
||||
match x {
|
||||
Value::Number(x) => Value::Number(x.tan()),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gt<'src>(x: &Value, y: &Value) -> Value<'src> {
|
||||
match (x, y) {
|
||||
(Value::Number(x), Value::Number(y)) => Value::Boolean(x > y),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gte<'src>(x: &Value, y: &Value) -> Value<'src> {
|
||||
match (x, y) {
|
||||
(Value::Number(x), Value::Number(y)) => Value::Boolean(x >= y),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lt<'src>(x: &Value, y: &Value) -> Value<'src> {
|
||||
match (x, y) {
|
||||
(Value::Number(x), Value::Number(y)) => Value::Boolean(x < y),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lte<'src>(x: &Value, y: &Value) -> Value<'src> {
|
||||
match (x, y) {
|
||||
(Value::Number(x), Value::Number(y)) => Value::Boolean(x <= y),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn r#mod<'src>(x: &Value, y: &Value) -> Value<'src> {
|
||||
match (x, y) {
|
||||
(Value::Number(x), Value::Number(y)) => Value::Number(x % y),
|
||||
_ => unreachable!("internal Ludus error"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn base<'src>() -> Vec<(&'src str, Value<'src>)> {
|
||||
vec![
|
||||
("eq?", Value::Base(Base::Binary(eq))),
|
||||
("add", Value::Base(Base::Binary(add))),
|
||||
("sub", Value::Base(Base::Binary(sub))),
|
||||
("unbox", Value::Base(Base::Unary(unbox))),
|
||||
("store!", Value::Base(Base::Binary(store))),
|
||||
("doc!", Value::Base(Base::Unary(doc))),
|
||||
("and", Value::Base(Base::Binary(and))),
|
||||
("append", Value::Base(Base::Binary(append))),
|
||||
("assoc", Value::Base(Base::Ternary(assoc))),
|
||||
("at", Value::Base(Base::Binary(at))),
|
||||
("atan_2", Value::Base(Base::Binary(atan_2))),
|
||||
("bool", Value::Base(Base::Unary(r#bool))),
|
||||
("ceil", Value::Base(Base::Unary(ceil))),
|
||||
("chars", Value::Base(Base::Unary(chars))),
|
||||
("concat", Value::Base(Base::Binary(concat))),
|
||||
("append", Value::Base(Base::Binary(append))),
|
||||
("dec", Value::Base(Base::Unary(dec))),
|
||||
("inc", Value::Base(Base::Unary(inc))),
|
||||
("div", Value::Base(Base::Binary(div))),
|
||||
("mult", Value::Base(Base::Binary(mult))),
|
||||
("dissoc", Value::Base(Base::Binary(dissoc))),
|
||||
("first", Value::Base(Base::Unary(first))),
|
||||
("at", Value::Base(Base::Binary(at))),
|
||||
("get", Value::Base(Base::Binary(get))),
|
||||
("last", Value::Base(Base::Unary(last))),
|
||||
("or", Value::Base(Base::Binary(or))),
|
||||
("print!", Value::Base(Base::Unary(print))),
|
||||
("show", Value::Base(Base::Unary(show))),
|
||||
("rest", Value::Base(Base::Unary(rest))),
|
||||
("cos", Value::Base(Base::Unary(cos))),
|
||||
("count", Value::Base(Base::Unary(count))),
|
||||
("range", Value::Base(Base::Binary(range))),
|
||||
("slice", Value::Base(Base::Ternary(slice))),
|
||||
("dec", Value::Base(Base::Unary(dec))),
|
||||
("dissoc", Value::Base(Base::Binary(dissoc))),
|
||||
("div", Value::Base(Base::Binary(div))),
|
||||
("doc!", Value::Base(Base::Unary(doc))),
|
||||
("downcase", Value::Base(Base::Unary(downcase))),
|
||||
("eq?", Value::Base(Base::Binary(eq))),
|
||||
("first", Value::Base(Base::Unary(first))),
|
||||
("floor", Value::Base(Base::Unary(floor))),
|
||||
("get", Value::Base(Base::Binary(get))),
|
||||
("gt?", Value::Base(Base::Binary(gt))),
|
||||
("gte?", Value::Base(Base::Binary(gte))),
|
||||
("inc", Value::Base(Base::Unary(inc))),
|
||||
("last", Value::Base(Base::Unary(last))),
|
||||
("list", Value::Base(Base::Unary(list))),
|
||||
("lt?", Value::Base(Base::Binary(lt))),
|
||||
("lte?", Value::Base(Base::Binary(lte))),
|
||||
("mod", Value::Base(Base::Binary(r#mod))),
|
||||
("mult", Value::Base(Base::Binary(mult))),
|
||||
("number", Value::Base(Base::Unary(number))),
|
||||
("or", Value::Base(Base::Binary(or))),
|
||||
("pi", Value::Number(std::f64::consts::PI)),
|
||||
("print!", Value::Base(Base::Unary(print))),
|
||||
("random", Value::Base(Base::Nullary(random))),
|
||||
("range", Value::Base(Base::Binary(range))),
|
||||
("rest", Value::Base(Base::Unary(rest))),
|
||||
("round", Value::Base(Base::Unary(round))),
|
||||
("show", Value::Base(Base::Unary(show))),
|
||||
("sin", Value::Base(Base::Unary(sin))),
|
||||
("slice", Value::Base(Base::Ternary(slice))),
|
||||
("split", Value::Base(Base::Binary(split))),
|
||||
("sqrt", Value::Base(Base::Unary(sqrt))),
|
||||
("sqrt_2", Value::Number(std::f64::consts::SQRT_2)),
|
||||
("store!", Value::Base(Base::Binary(store))),
|
||||
("sub", Value::Base(Base::Binary(sub))),
|
||||
("tan", Value::Base(Base::Unary(tan))),
|
||||
("trim", Value::Base(Base::Unary(trim))),
|
||||
("triml", Value::Base(Base::Unary(triml))),
|
||||
("trimr", Value::Base(Base::Unary(trimr))),
|
||||
("type", Value::Base(Base::Unary(r#type))),
|
||||
("unbox", Value::Base(Base::Unary(unbox))),
|
||||
("upcase", Value::Base(Base::Unary(upcase))),
|
||||
]
|
||||
}
|
||||
|
||||
// * [ ] atan_2 (x) -> number
|
||||
// * [ ] ceil (x) -> number
|
||||
// * [ ] cos (x) -> number
|
||||
// * [x] count (x) -> number
|
||||
// * [~] disj (x) -> set
|
||||
// * [ ] downcase (x) -> string
|
||||
// * [ ] floor (x) -> number
|
||||
// * [ ] gt (x, y) -> bool
|
||||
// * [ ] gte! (x, y) -> bool
|
||||
// * [ ] lt (x) -> bool
|
||||
// * [ ] lte (x) -> bool
|
||||
// * [ ] mod (x, y) -> number
|
||||
// * [ ] pi
|
||||
// * [ ] random () -> number
|
||||
// * [x] range () -> list
|
||||
// * [ ] round (x) -> number
|
||||
// * [ ] sin (x) -> number
|
||||
// * [x] slice (x, y, z) -> list
|
||||
// * [ ] split (x, y) -> list(string)
|
||||
// * [ ] sqrt (x) -> number
|
||||
// * [x] ~str_slice (x, y, z) -> string~
|
||||
// * [x] ~stringify (x) -> string~
|
||||
// * [ ] tan (x) -> number
|
||||
// * [x] to_list (x) -> list
|
||||
// * [ ] to_number (x) -> number
|
||||
// * [ ] trim (x) -> string
|
||||
// * [ ] triml (x) -> string
|
||||
// * [ ] trimr (x) -> string
|
||||
// * [ ] type (x) -> keyword
|
||||
// * [ ] upcase (x) -> string
|
||||
// * [x] atan_2 (x) -> number
|
||||
// * [x] ceil (x) -> number
|
||||
// * [x] cos (x) -> number
|
||||
// * [x] floor (x) -> number
|
||||
// * [x] gt (x, y) -> bool
|
||||
// * [x] gte! (x, y) -> bool
|
||||
// * [x] lt (x) -> bool
|
||||
// * [x] lte (x) -> bool
|
||||
// * [x] mod (x, y) -> number
|
||||
// * [x] pi
|
||||
// * [x] random () -> number
|
||||
// * [x] round (x) -> number
|
||||
// * [x] sin (x) -> number
|
||||
// * [x] sqrt (x) -> number
|
||||
// * [x] tan (x) -> number
|
||||
// * [x] add (x, y) -> number
|
||||
// * [x] and (x, y) -> value
|
||||
// * [x] append (x, y) -> list
|
||||
|
@ -457,10 +649,12 @@ pub fn base<'src>() -> Vec<(&'src str, Value<'src>)> {
|
|||
// * [x] bool (x) -> bool
|
||||
// * [x] chars (x) -> list
|
||||
// * [x] concat (x, y) -> value
|
||||
// * [x] count (x) -> number
|
||||
// * [x] dec (x) -> number
|
||||
// * [x] dissoc (x, y) -> dict
|
||||
// * [x] div (x, y) -> number
|
||||
// * [x] doc (x) -> string
|
||||
// * [x] downcase (x) -> string
|
||||
// * [x] eq (x, y) -> bool
|
||||
// * [x] first (x) -> value
|
||||
// * [x] get (x, y) -> value
|
||||
|
@ -468,10 +662,23 @@ pub fn base<'src>() -> Vec<(&'src str, Value<'src>)> {
|
|||
// * [x] last (x) -> value
|
||||
// * [x] or (x, y) -> value
|
||||
// * [x] print! (x) -> :ok
|
||||
// * [x] range () -> list
|
||||
// * [x] rest (x) -> coll
|
||||
// * [x] show (x) -> string
|
||||
// * [x] slice (x, y, z) -> list
|
||||
// * [x] split (x, y) -> list(string)
|
||||
// * [x] store! (x, y) -> value
|
||||
// * [x] sub (x, y) -> number
|
||||
// * [x] to_list (x) -> list
|
||||
// * [x] to_number (x) -> number
|
||||
// * [x] trim (x) -> string
|
||||
// * [x] triml (x) -> string
|
||||
// * [x] trimr (x) -> string
|
||||
// * [x] type (x) -> keyword
|
||||
// * [x] unbox (x) -> value
|
||||
// * [x] upcase (x) -> string
|
||||
// * [x] ~prn (x) -> value~
|
||||
// * [x] ~push (x) -> list~
|
||||
// * [x] ~str_slice (x, y, z) -> string~
|
||||
// * [x] ~stringify (x) -> string~
|
||||
// * [~] disj (x) -> set
|
||||
|
|
|
@ -58,8 +58,8 @@ use crate::base::*;
|
|||
|
||||
pub fn main() {
|
||||
let src = "
|
||||
let foo = 42
|
||||
type (\"{foo}\")
|
||||
let foo = \" fOobArbaz \"
|
||||
trimr (foo)
|
||||
";
|
||||
let (tokens, lex_errs) = lexer().parse(src).into_output_errors();
|
||||
if !lex_errs.is_empty() {
|
||||
|
|
|
@ -242,6 +242,15 @@ pub fn apply<'src>(
|
|||
msg: "you may only call a function".to_string(),
|
||||
}),
|
||||
(Value::Base(f), Value::Tuple(args)) => match f {
|
||||
Base::Nullary(f) => {
|
||||
if args.len() != 0 {
|
||||
Err(LudusError {
|
||||
msg: "wrong arity: expected 0 arguments".to_string(),
|
||||
})
|
||||
} else {
|
||||
Ok(f())
|
||||
}
|
||||
}
|
||||
Base::Unary(f) => {
|
||||
if args.len() != 1 {
|
||||
Err(LudusError {
|
||||
|
|
Loading…
Reference in New Issue
Block a user