mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Add modulo
This commit is contained in:
parent
e6a0447f9d
commit
3f76aadb1a
@ -139,6 +139,7 @@ pub fn new() -> Scope {
|
|||||||
std.def_func("max", max);
|
std.def_func("max", max);
|
||||||
std.def_func("even", even);
|
std.def_func("even", even);
|
||||||
std.def_func("odd", odd);
|
std.def_func("odd", odd);
|
||||||
|
std.def_func("mod", modulo);
|
||||||
std.def_func("range", range);
|
std.def_func("range", range);
|
||||||
std.def_func("rgb", rgb);
|
std.def_func("rgb", rgb);
|
||||||
std.def_func("lower", lower);
|
std.def_func("lower", lower);
|
||||||
|
@ -170,6 +170,36 @@ pub fn odd(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
|
|||||||
Ok(Value::Bool(args.expect::<i64>("integer")? % 2 != 0))
|
Ok(Value::Bool(args.expect::<i64>("integer")? % 2 != 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The modulo of two numbers.
|
||||||
|
pub fn modulo(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
|
||||||
|
let Spanned { v: v1, span: span1 } = args.expect("integer or float")?;
|
||||||
|
let Spanned { v: v2, span: span2 } = args.expect("integer or float")?;
|
||||||
|
|
||||||
|
let (a, b) = match (v1, v2) {
|
||||||
|
(Value::Int(a), Value::Int(b)) => match a.checked_rem(b) {
|
||||||
|
Some(res) => return Ok(res.into()),
|
||||||
|
None => bail!(span2, "divisor must not be zero"),
|
||||||
|
},
|
||||||
|
(Value::Int(a), Value::Float(b)) => (a as f64, b),
|
||||||
|
(Value::Float(a), Value::Int(b)) => (a, b as f64),
|
||||||
|
(Value::Float(a), Value::Float(b)) => (a, b),
|
||||||
|
(Value::Int(_), b) | (Value::Float(_), b) => bail!(
|
||||||
|
span2,
|
||||||
|
format!("expected integer or float, found {}", b.type_name())
|
||||||
|
),
|
||||||
|
(a, _) => bail!(
|
||||||
|
span1,
|
||||||
|
format!("expected integer or float, found {}", a.type_name())
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
if b == 0.0 {
|
||||||
|
bail!(span2, "divisor must not be zero");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((a % b).into())
|
||||||
|
}
|
||||||
|
|
||||||
/// Find the minimum or maximum of a sequence of values.
|
/// Find the minimum or maximum of a sequence of values.
|
||||||
fn minmax(args: &mut Args, goal: Ordering) -> TypResult<Value> {
|
fn minmax(args: &mut Args, goal: Ordering) -> TypResult<Value> {
|
||||||
let mut extremum = args.expect::<Value>("value")?;
|
let mut extremum = args.expect::<Value>("value")?;
|
||||||
|
@ -18,6 +18,22 @@
|
|||||||
#test(odd(-1), true)
|
#test(odd(-1), true)
|
||||||
#test(even(-11), false)
|
#test(even(-11), false)
|
||||||
|
|
||||||
|
---
|
||||||
|
// Test the `mod` function.
|
||||||
|
#test(mod(1, 1), 0)
|
||||||
|
#test(mod(5, 3), 2)
|
||||||
|
#test(mod(5, -3), 2)
|
||||||
|
#test(mod(22.5, 10), 2.5)
|
||||||
|
#test(mod(9, 4.5), 0)
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 9-10 divisor must not be zero
|
||||||
|
#mod(5, 0)
|
||||||
|
|
||||||
|
---
|
||||||
|
// Error: 11-14 divisor must not be zero
|
||||||
|
#mod(3.0, 0.0)
|
||||||
|
|
||||||
---
|
---
|
||||||
// Error: 6-16 cannot take absolute value of a linear
|
// Error: 6-16 cannot take absolute value of a linear
|
||||||
#abs(10pt + 50%)
|
#abs(10pt + 50%)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user