pull out libm. pow and sqrt to be implemented in userlib maybe?
Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
parent
a93fb512aa
commit
48178b5a48
3 changed files with 2 additions and 126 deletions
|
|
@ -4,10 +4,6 @@ version = "0.4.0"
|
||||||
authors = ["Ava <ava@sunnypup.io>"]
|
authors = ["Ava <ava@sunnypup.io>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
# cant have math without libc I guess...
|
|
||||||
libm = "0.2.8"
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "flesh"
|
name = "flesh"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,16 @@ use crate::segment::{Ctr, Seg};
|
||||||
use crate::sym::{SymTable, ValueType, Symbol, Args};
|
use crate::sym::{SymTable, ValueType, Symbol, Args};
|
||||||
use crate::error::{Traceback, start_trace};
|
use crate::error::{Traceback, start_trace};
|
||||||
|
|
||||||
use libm::pow;
|
|
||||||
|
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn isnumeric(arg: &Ctr) -> bool {
|
fn isnumeric(arg: &Ctr) -> bool {
|
||||||
matches!(arg, Ctr::Integer(_) | Ctr::Float(_))
|
matches!(arg, Ctr::Integer(_) | Ctr::Float(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ADD_DOCSTRING: &str =
|
const ADD_DOCSTRING: &str =
|
||||||
"traverses over N args, which must all evaluate to an Integer or Float.
|
"traverses over N args, which must all evaluate to an Integer or Float.
|
||||||
Adds each arg up to a final result. WARNING: does not acocunt for under/overflows.
|
Adds each arg up to a final result. WARNING: does not acocunt for under/overflows.
|
||||||
|
|
@ -192,52 +192,6 @@ fn floatcast_callback(ast: &Seg, _: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const EXP_DOCSTRING: &str = "Takes two args, both expected to be numeric.
|
|
||||||
Returns the first arg to the power of the second arg.
|
|
||||||
Does not handle overflow or underflow.";
|
|
||||||
fn exp_callback(ast: &Seg, _: &mut SymTable) -> Result<Ctr, Traceback> {
|
|
||||||
let first = *ast.car.clone();
|
|
||||||
if !isnumeric(&first) {
|
|
||||||
return Err(start_trace(
|
|
||||||
("exp", format!("{} is not a number!", first))
|
|
||||||
.into()))
|
|
||||||
}
|
|
||||||
let second: Ctr;
|
|
||||||
if let Ctr::Seg(ref s) = *ast.cdr {
|
|
||||||
second = *s.car.clone();
|
|
||||||
} else {
|
|
||||||
return Err(start_trace(
|
|
||||||
("exp", "expected at least two inputs")
|
|
||||||
.into()))
|
|
||||||
}
|
|
||||||
if !isnumeric(&second) {
|
|
||||||
return Err(start_trace(
|
|
||||||
("exp", format!("{} is not a number!", second))
|
|
||||||
.into()))
|
|
||||||
}
|
|
||||||
|
|
||||||
match first {
|
|
||||||
Ctr::Float(lf) => match second {
|
|
||||||
Ctr::Float(rf) => Ok(Ctr::Float(pow(lf, rf))),
|
|
||||||
Ctr::Integer(ri) => Ok(Ctr::Float(pow(lf as f64, ri as f64))),
|
|
||||||
_ => Err(start_trace(
|
|
||||||
("exp", "not implemented for these input types")
|
|
||||||
.into())),
|
|
||||||
},
|
|
||||||
Ctr::Integer(li) => match second {
|
|
||||||
Ctr::Float(rf) => Ok(Ctr::Float(pow(li as f64, rf))),
|
|
||||||
Ctr::Integer(ri) => Ok(Ctr::Float(pow(li as f64, ri as f64))),
|
|
||||||
_ => Err(start_trace(
|
|
||||||
("exp", "not implemented for these input types")
|
|
||||||
.into())),
|
|
||||||
},
|
|
||||||
|
|
||||||
_ => Err(start_trace(
|
|
||||||
("exp", "not implemented for these input types")
|
|
||||||
.into())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const MOD_DOCSTRING: &str = "Takes two args, both expected to be numeric.
|
const MOD_DOCSTRING: &str = "Takes two args, both expected to be numeric.
|
||||||
Returns a list of two values: the modulus and the remainder.
|
Returns a list of two values: the modulus and the remainder.
|
||||||
Example: (mod 5 3) -> (1 2)
|
Example: (mod 5 3) -> (1 2)
|
||||||
|
|
@ -602,19 +556,6 @@ pub fn add_math_lib(syms: &mut SymTable) {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
syms.insert(
|
|
||||||
"exp".to_string(),
|
|
||||||
Symbol {
|
|
||||||
name: String::from("exp"),
|
|
||||||
args: Args::Lazy(2),
|
|
||||||
conditional_branches: false,
|
|
||||||
docs: EXP_DOCSTRING.to_string(),
|
|
||||||
optimizable: true,
|
|
||||||
value: ValueType::Internal(Rc::new(exp_callback)),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
syms.insert(
|
syms.insert(
|
||||||
"mod".to_string(),
|
"mod".to_string(),
|
||||||
Symbol {
|
Symbol {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
mod math_lib_tests {
|
mod math_lib_tests {
|
||||||
use flesh::ast::{eval, lex, Ctr, SymTable};
|
use flesh::ast::{eval, lex, Ctr, SymTable};
|
||||||
use flesh::stdlib::static_stdlib;
|
use flesh::stdlib::static_stdlib;
|
||||||
use libm::pow;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_chain() {
|
fn test_add_chain() {
|
||||||
|
|
@ -138,66 +137,6 @@ mod math_lib_tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_ii_exp() {
|
|
||||||
let document = "(exp 7 20)";
|
|
||||||
let result = pow(7 as f64, 20 as f64);
|
|
||||||
|
|
||||||
let mut syms = SymTable::new();
|
|
||||||
static_stdlib(&mut syms, |_: &String| (), || String::new());
|
|
||||||
assert_eq!(
|
|
||||||
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
|
|
||||||
.unwrap()
|
|
||||||
.to_string(),
|
|
||||||
result.to_string(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_if_exp() {
|
|
||||||
let document = "(exp 1 10.2)";
|
|
||||||
let result = f64::powf(1f64, 10.2);
|
|
||||||
|
|
||||||
let mut syms = SymTable::new();
|
|
||||||
static_stdlib(&mut syms, |_: &String| (), || String::new());
|
|
||||||
assert_eq!(
|
|
||||||
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
|
|
||||||
.unwrap()
|
|
||||||
.to_string(),
|
|
||||||
result.to_string(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_fi_exp() {
|
|
||||||
let document = "(exp 10.2 1)";
|
|
||||||
let result = pow(10.2 as f64, 1 as f64);
|
|
||||||
|
|
||||||
let mut syms = SymTable::new();
|
|
||||||
static_stdlib(&mut syms, |_: &String| (), || String::new());
|
|
||||||
assert_eq!(
|
|
||||||
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
|
|
||||||
.unwrap()
|
|
||||||
.to_string(),
|
|
||||||
result.to_string(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_ff_exp() {
|
|
||||||
let document = "(exp 1.4 1.5)";
|
|
||||||
let result = pow(1.4, 1.5);
|
|
||||||
|
|
||||||
let mut syms = SymTable::new();
|
|
||||||
static_stdlib(&mut syms, |_: &String| (), || String::new());
|
|
||||||
assert_eq!(
|
|
||||||
*eval(&lex(&document.to_string()).unwrap(), &mut syms)
|
|
||||||
.unwrap()
|
|
||||||
.to_string(),
|
|
||||||
result.to_string(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ii_mod() {
|
fn test_ii_mod() {
|
||||||
let document = "(def test \"\" (mod 7 3))";
|
let document = "(def test \"\" (mod 7 3))";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue