implement builtin function math.log
This commit is contained in:
parent
313913734a
commit
458fcf0fd8
@ -1,6 +1,6 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use num_traits::{One, Zero};
|
use num_traits::{One, Signed, Zero};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
args::CallArgs,
|
args::CallArgs,
|
||||||
@ -107,7 +107,69 @@ fn hypot(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
|
|
||||||
fn log(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
fn log(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(2)?;
|
args.max_args(2)?;
|
||||||
|
|
||||||
|
let number = match args.get_err(0, "number")? {
|
||||||
|
Value::Dimension(Some(n), Unit::None, ..) => n,
|
||||||
|
v @ Value::Dimension(Some(..), ..) => {
|
||||||
|
return Err((
|
||||||
|
format!(
|
||||||
|
"$number: Expected {} to be unitless.",
|
||||||
|
v.inspect(args.span())?
|
||||||
|
),
|
||||||
|
args.span(),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
|
}
|
||||||
|
v @ Value::Dimension(None, ..) => return Ok(v),
|
||||||
|
v => {
|
||||||
|
return Err((
|
||||||
|
format!("$number: {} is not a number.", v.inspect(args.span())?),
|
||||||
|
args.span(),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let base = match args.default_arg(1, "base", Value::Null)? {
|
||||||
|
Value::Null => None,
|
||||||
|
Value::Dimension(Some(n), Unit::None, ..) => Some(n),
|
||||||
|
v @ Value::Dimension(Some(..), ..) => {
|
||||||
|
return Err((
|
||||||
|
format!(
|
||||||
|
"$number: Expected {} to be unitless.",
|
||||||
|
v.inspect(args.span())?
|
||||||
|
),
|
||||||
|
args.span(),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
|
}
|
||||||
|
v @ Value::Dimension(None, ..) => return Ok(v),
|
||||||
|
v => {
|
||||||
|
return Err((
|
||||||
|
format!("$base: {} is not a number.", v.inspect(args.span())?),
|
||||||
|
args.span(),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Value::Dimension(
|
||||||
|
if let Some(base) = base {
|
||||||
|
if base.is_zero() {
|
||||||
|
Some(Number::zero())
|
||||||
|
} else {
|
||||||
|
(|| Some(number.ln()? / base.ln()?))()
|
||||||
|
}
|
||||||
|
} else if number.is_negative() {
|
||||||
|
None
|
||||||
|
} else if number.is_zero() {
|
||||||
todo!()
|
todo!()
|
||||||
|
} else {
|
||||||
|
number.ln()
|
||||||
|
},
|
||||||
|
Unit::None,
|
||||||
|
true,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pow(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
fn pow(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
@ -310,6 +372,7 @@ pub(crate) fn declare(f: &mut Module) {
|
|||||||
f.insert_builtin("acos", acos);
|
f.insert_builtin("acos", acos);
|
||||||
f.insert_builtin("asin", asin);
|
f.insert_builtin("asin", asin);
|
||||||
f.insert_builtin("atan", atan);
|
f.insert_builtin("atan", atan);
|
||||||
|
f.insert_builtin("log", log);
|
||||||
#[cfg(feature = "random")]
|
#[cfg(feature = "random")]
|
||||||
f.insert_builtin("random", random);
|
f.insert_builtin("random", random);
|
||||||
|
|
||||||
|
@ -122,6 +122,12 @@ impl Number {
|
|||||||
self.as_float()?.sqrt(),
|
self.as_float()?.sqrt(),
|
||||||
)?)))
|
)?)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ln(self) -> Option<Self> {
|
||||||
|
Some(Number::Big(Box::new(BigRational::from_float(
|
||||||
|
self.as_float()?.ln(),
|
||||||
|
)?)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! trig_fn(
|
macro_rules! trig_fn(
|
||||||
|
@ -318,3 +318,75 @@ test!(
|
|||||||
"@use 'sass:math';\na {\n color: math.atan((0 / 0));\n}\n",
|
"@use 'sass:math';\na {\n color: math.atan((0 / 0));\n}\n",
|
||||||
"a {\n color: NaNdeg;\n}\n"
|
"a {\n color: NaNdeg;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
log_above_one,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(2);\n}\n",
|
||||||
|
"a {\n color: 0.6931471806;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_below_negative_one,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(-2);\n}\n",
|
||||||
|
"a {\n color: NaN;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_one,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(1);\n}\n",
|
||||||
|
"a {\n color: 0;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_negative_one,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(-1);\n}\n",
|
||||||
|
"a {\n color: NaN;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
#[ignore = "we do not support Infinity"]
|
||||||
|
log_zero,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(0);\n}\n",
|
||||||
|
"a {\n color: -Infinity;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_point_five,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(.5);\n}\n",
|
||||||
|
"a {\n color: -0.6931471806;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_nan,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log((0 / 0));\n}\n",
|
||||||
|
"a {\n color: NaN;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_base_nan,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(1, (0 / 0));\n}\n",
|
||||||
|
"a {\n color: NaN;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_base_above_one,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(2, 2);\n}\n",
|
||||||
|
"a {\n color: 1;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_base_below_negative_one,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(2, -2);\n}\n",
|
||||||
|
"a {\n color: NaN;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
#[ignore = "we do not support Infinity"]
|
||||||
|
log_base_one,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(2, 1);\n}\n",
|
||||||
|
"a {\n color: Infinity;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_base_negative_one,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(2, -1);\n}\n",
|
||||||
|
"a {\n color: NaN;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_base_zero,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(2, 0);\n}\n",
|
||||||
|
"a {\n color: 0;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
log_base_point_five,
|
||||||
|
"@use 'sass:math';\na {\n color: math.log(2, .5);\n}\n",
|
||||||
|
"a {\n color: -1;\n}\n"
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user