add libm math functions to haku
This commit is contained in:
parent
e12573566e
commit
4bf3d685b8
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -590,6 +590,7 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
name = "haku"
|
name = "haku"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"libm",
|
||||||
"log",
|
"log",
|
||||||
"tiny-skia",
|
"tiny-skia",
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
tiny-skia = { version = "0.11.4", default-features = false, features = ["no-std-float"] }
|
tiny-skia = { version = "0.11.4", default-features = false, features = ["no-std-float"] }
|
||||||
|
libm = "0.2.8"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|
|
@ -106,7 +106,7 @@ impl Display for ChunkError {
|
||||||
impl Error for ChunkError {}
|
impl Error for ChunkError {}
|
||||||
|
|
||||||
pub mod fns {
|
pub mod fns {
|
||||||
use alloc::vec::Vec;
|
use alloc::{format, vec::Vec};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
value::{Fill, List, Ref, Rgba, Scribble, Shape, Stroke, Value, Vec2, Vec4},
|
value::{Fill, List, Ref, Rgba, Scribble, Shape, Stroke, Value, Vec2, Vec4},
|
||||||
|
@ -123,6 +123,36 @@ pub mod fns {
|
||||||
0x03 Binary "/" => div,
|
0x03 Binary "/" => div,
|
||||||
0x04 Unary "-" => neg,
|
0x04 Unary "-" => neg,
|
||||||
|
|
||||||
|
0x10 Nary "floor" => floorf,
|
||||||
|
0x11 Nary "ceil" => ceilf,
|
||||||
|
0x12 Nary "round" => roundf,
|
||||||
|
0x13 Nary "abs" => fabsf,
|
||||||
|
0x14 Nary "mod" => fmodf,
|
||||||
|
0x15 Nary "pow" => powf,
|
||||||
|
0x16 Nary "sqrt" => sqrtf,
|
||||||
|
0x17 Nary "cbrt" => cbrtf,
|
||||||
|
0x18 Nary "exp" => expf,
|
||||||
|
0x19 Nary "exp2" => exp2f,
|
||||||
|
0x1A Nary "ln" => logf,
|
||||||
|
0x1B Nary "log2" => log2f,
|
||||||
|
0x1C Nary "log10" => log10f,
|
||||||
|
0x1D Nary "hypot" => hypotf,
|
||||||
|
0x1E Nary "sin" => sinf,
|
||||||
|
0x1F Nary "cos" => cosf,
|
||||||
|
0x20 Nary "tan" => tanf,
|
||||||
|
0x21 Nary "asin" => asinf,
|
||||||
|
0x22 Nary "acos" => acosf,
|
||||||
|
0x23 Nary "atan" => atanf,
|
||||||
|
0x24 Nary "atan2" => atan2f,
|
||||||
|
0x25 Nary "expMinus1" => expm1f,
|
||||||
|
0x26 Nary "ln1Plus" => log1pf,
|
||||||
|
0x27 Nary "sinh" => sinhf,
|
||||||
|
0x28 Nary "cosh" => coshf,
|
||||||
|
0x29 Nary "tanh" => tanhf,
|
||||||
|
0x2A Nary "asinh" => asinhf,
|
||||||
|
0x2B Nary "acosh" => acoshf,
|
||||||
|
0x2C Nary "atanh" => atanhf,
|
||||||
|
|
||||||
0x40 Unary "!" => not,
|
0x40 Unary "!" => not,
|
||||||
0x41 Binary "==" => eq,
|
0x41 Binary "==" => eq,
|
||||||
0x42 Binary "!=" => neq,
|
0x42 Binary "!=" => neq,
|
||||||
|
@ -185,6 +215,85 @@ pub mod fns {
|
||||||
Ok(Value::Number(-x))
|
Ok(Value::Number(-x))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn math1(vm: &mut Vm, args: FnArgs, name: &str, f: fn(f32) -> f32) -> Result<Value, Exception> {
|
||||||
|
if args.num() != 1 {
|
||||||
|
return Err(
|
||||||
|
vm.create_exception(format!("`{name}` expects a single argument ({name} x)"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = args
|
||||||
|
.get(vm, 0)
|
||||||
|
.to_number()
|
||||||
|
.ok_or_else(|| vm.create_exception(format!("`{name}` argument must be a number")))?;
|
||||||
|
Ok(Value::Number(f(x)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn math2(
|
||||||
|
vm: &mut Vm,
|
||||||
|
args: FnArgs,
|
||||||
|
name: &str,
|
||||||
|
f: fn(f32, f32) -> f32,
|
||||||
|
) -> Result<Value, Exception> {
|
||||||
|
if args.num() != 2 {
|
||||||
|
return Err(vm.create_exception(format!("`{name}` expects two arguments ({name} x y)")));
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = args
|
||||||
|
.get(vm, 0)
|
||||||
|
.to_number()
|
||||||
|
.ok_or_else(|| vm.create_exception(format!("`{name}` arguments must be numbers")))?;
|
||||||
|
let y = args
|
||||||
|
.get(vm, 1)
|
||||||
|
.to_number()
|
||||||
|
.ok_or_else(|| vm.create_exception(format!("`{name}` arguments must be numbers")))?;
|
||||||
|
Ok(Value::Number(f(x, y)))
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! math_fns {
|
||||||
|
($($arity:tt $sysname:tt $name:tt),* $(,)?) => {
|
||||||
|
$(
|
||||||
|
pub fn $name(vm: &mut Vm, args: FnArgs) -> Result<Value, Exception> {
|
||||||
|
$arity(vm, args, $sysname, libm::$name)
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
math_fns! {
|
||||||
|
math1 "floor" floorf,
|
||||||
|
math1 "ceil" ceilf,
|
||||||
|
math1 "round" roundf,
|
||||||
|
math1 "abs" fabsf,
|
||||||
|
math2 "mod" fmodf,
|
||||||
|
math2 "pow" powf,
|
||||||
|
math1 "sqrt" sqrtf,
|
||||||
|
math1 "cbrt" cbrtf,
|
||||||
|
math1 "exp" expf,
|
||||||
|
math1 "exp2" exp2f,
|
||||||
|
math1 "ln" logf,
|
||||||
|
math1 "log2" log2f,
|
||||||
|
math1 "log10" log10f,
|
||||||
|
math2 "hypot" hypotf,
|
||||||
|
math1 "sin" sinf,
|
||||||
|
math1 "cos" cosf,
|
||||||
|
math1 "tan" tanf,
|
||||||
|
math1 "asin" asinf,
|
||||||
|
math1 "acos" acosf,
|
||||||
|
math1 "atan" atanf,
|
||||||
|
math2 "atan2" atan2f,
|
||||||
|
math1 "expMinus1" expm1f,
|
||||||
|
math1 "ln1Plus" log1pf,
|
||||||
|
math1 "sinh" sinhf,
|
||||||
|
math1 "cosh" coshf,
|
||||||
|
math1 "tanh" tanhf,
|
||||||
|
math1 "asinh" asinhf,
|
||||||
|
math1 "acosh" acoshf,
|
||||||
|
math1 "atanh" atanhf,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn not(vm: &mut Vm, args: FnArgs) -> Result<Value, Exception> {
|
pub fn not(vm: &mut Vm, args: FnArgs) -> Result<Value, Exception> {
|
||||||
let value = args.get(vm, 0);
|
let value = args.get(vm, 0);
|
||||||
Ok(Value::from(value.is_falsy()))
|
Ok(Value::from(value.is_falsy()))
|
||||||
|
|
Loading…
Reference in a new issue