summaryrefslogtreecommitdiff
path: root/src/library/utility/math.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-03 11:44:53 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-03 13:35:39 +0100
commit37a7afddfaffd44cb9bc013c9506599267e08983 (patch)
tree20e7d62d3c5418baff01a21d0406b91bf3096214 /src/library/utility/math.rs
parent56342bd972a13ffe21beaf2b87ab7eb1597704b4 (diff)
Split crates
Diffstat (limited to 'src/library/utility/math.rs')
-rw-r--r--src/library/utility/math.rs144
1 files changed, 0 insertions, 144 deletions
diff --git a/src/library/utility/math.rs b/src/library/utility/math.rs
deleted file mode 100644
index 7c3af490..00000000
--- a/src/library/utility/math.rs
+++ /dev/null
@@ -1,144 +0,0 @@
-use std::cmp::Ordering;
-
-use crate::library::prelude::*;
-
-/// Convert a value to an integer.
-pub fn int(_: &mut Vm, args: &mut Args) -> SourceResult<Value> {
- let Spanned { v, span } = args.expect("value")?;
- Ok(Value::Int(match v {
- Value::Bool(v) => v as i64,
- Value::Int(v) => v,
- Value::Float(v) => v as i64,
- Value::Str(v) => match v.parse() {
- Ok(v) => v,
- Err(_) => bail!(span, "invalid integer"),
- },
- v => bail!(span, "cannot convert {} to integer", v.type_name()),
- }))
-}
-
-/// Convert a value to a float.
-pub fn float(_: &mut Vm, args: &mut Args) -> SourceResult<Value> {
- let Spanned { v, span } = args.expect("value")?;
- Ok(Value::Float(match v {
- Value::Int(v) => v as f64,
- Value::Float(v) => v,
- Value::Str(v) => match v.parse() {
- Ok(v) => v,
- Err(_) => bail!(span, "invalid float"),
- },
- v => bail!(span, "cannot convert {} to float", v.type_name()),
- }))
-}
-
-/// The absolute value of a numeric value.
-pub fn abs(_: &mut Vm, args: &mut Args) -> SourceResult<Value> {
- let Spanned { v, span } = args.expect("numeric value")?;
- Ok(match v {
- Value::Int(v) => Value::Int(v.abs()),
- Value::Float(v) => Value::Float(v.abs()),
- Value::Angle(v) => Value::Angle(v.abs()),
- Value::Ratio(v) => Value::Ratio(v.abs()),
- Value::Fraction(v) => Value::Fraction(v.abs()),
- Value::Length(_) | Value::Relative(_) => {
- bail!(span, "cannot take absolute value of a length")
- }
- v => bail!(span, "expected numeric value, found {}", v.type_name()),
- })
-}
-
-/// The minimum of a sequence of values.
-pub fn min(_: &mut Vm, args: &mut Args) -> SourceResult<Value> {
- minmax(args, Ordering::Less)
-}
-
-/// The maximum of a sequence of values.
-pub fn max(_: &mut Vm, args: &mut Args) -> SourceResult<Value> {
- minmax(args, Ordering::Greater)
-}
-
-/// Find the minimum or maximum of a sequence of values.
-fn minmax(args: &mut Args, goal: Ordering) -> SourceResult<Value> {
- let mut extremum = args.expect::<Value>("value")?;
- for Spanned { v, span } in args.all::<Spanned<Value>>()? {
- match v.partial_cmp(&extremum) {
- Some(ordering) => {
- if ordering == goal {
- extremum = v;
- }
- }
- None => bail!(
- span,
- "cannot compare {} and {}",
- extremum.type_name(),
- v.type_name(),
- ),
- }
- }
- Ok(extremum)
-}
-
-/// Whether an integer is even.
-pub fn even(_: &mut Vm, args: &mut Args) -> SourceResult<Value> {
- Ok(Value::Bool(args.expect::<i64>("integer")? % 2 == 0))
-}
-
-/// Whether an integer is odd.
-pub fn odd(_: &mut Vm, args: &mut Args) -> SourceResult<Value> {
- Ok(Value::Bool(args.expect::<i64>("integer")? % 2 != 0))
-}
-
-/// The modulo of two numbers.
-pub fn mod_(_: &mut Vm, args: &mut Args) -> SourceResult<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(Value::Int(res)),
- 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(Value::Float(a % b))
-}
-
-/// Create a sequence of numbers.
-pub fn range(_: &mut Vm, args: &mut Args) -> SourceResult<Value> {
- let first = args.expect::<i64>("end")?;
- let (start, end) = match args.eat::<i64>()? {
- Some(second) => (first, second),
- None => (0, first),
- };
-
- let step: i64 = match args.named("step")? {
- Some(Spanned { v: 0, span }) => bail!(span, "step must not be zero"),
- Some(Spanned { v, .. }) => v,
- None => 1,
- };
-
- let mut x = start;
- let mut seq = vec![];
-
- while x.cmp(&end) == 0.cmp(&step) {
- seq.push(Value::Int(x));
- x += step;
- }
-
- Ok(Value::Array(Array::from_vec(seq)))
-}