1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
extern crate mech_core;
extern crate mech_utilities;
extern crate libm;
use mech_core::{Interner, Transaction};
use mech_core::{Value, Table};
use mech_utilities::Watcher;
use mech_core::{Quantity, ToQuantity, QuantityMath, make_quantity};
use libm::{sin, cos, fmod, round, floor};

static PI: f64 = 3.141592653589793238462643383279502884197169399375105820974944592307816406286;


#[no_mangle]
pub extern "C" fn math_sin(input: Vec<(String, Table)>) -> Table {
  let (argument, table_ref) = &input[0];
  let mut out = Table::new(0,table_ref.rows,table_ref.columns);
  if argument == "radians" {

  } else if argument == "degrees" {
    for i in 0..table_ref.columns as usize {
      for j in 0..table_ref.rows as usize {
        let x = &table_ref.data[i][j];
        let result = match fmod(x.as_float().unwrap(), 360.0) {
          0.0 => 0.0,
          90.0 => 1.0,
          180.0 => 0.0,
          270.0 => -1.0,
          _ => sin(x.as_float().unwrap() * PI / 180.0),
        };
        out.data[i][j] = Value::from_quantity(result.to_quantity());
      }
    }
  }
  out 
}

#[no_mangle]
pub extern "C" fn math_cos(input: Vec<(String, Table)>) -> Table {
  let (argument, table_ref) = &input[0];
  let mut out = Table::new(0,table_ref.rows,table_ref.columns);
  if argument == "radians" {

  } else if argument == "degrees" {
    for i in 0..table_ref.columns as usize {
      for j in 0..table_ref.rows as usize {
        let x = &table_ref.data[i][j];
        let result = match fmod(x.as_float().unwrap(), 360.0) {
          0.0 => 1.0,
          90.0 => 0.0,
          180.0 => -1.0,
          270.0 => 0.0,
          _ => cos(x.as_float().unwrap() * PI / 180.0),
        };
        out.data[i][j] = Value::from_quantity(result.to_quantity());
      }
    }
  }
  out 
}


#[no_mangle]
pub extern "C" fn math_round(input: Vec<(String, Table)>) -> Table {
  let (argument, table_ref) = &input[0];
  let mut out = Table::new(0,table_ref.rows,table_ref.columns);
  for i in 0..table_ref.columns as usize {
    for j in 0..table_ref.rows as usize {
      let x = &table_ref.data[i][j];
      let result = match x {
        Value::Number(n) => Value::from_quantity(round(n.to_float()).to_quantity()),
        _ => Value::Empty
      };
      out.data[i][j] = result;
    }
  }
  out
}

#[no_mangle]
pub extern "C" fn math_floor(input: Vec<(String, Table)>) -> Table {
  let (argument, table_ref) = &input[0];
  let mut out = Table::new(0,table_ref.rows,table_ref.columns);
  for i in 0..table_ref.columns as usize {
    for j in 0..table_ref.rows as usize {
      let x = &table_ref.data[i][j];
      let result = match x {
        Value::Number(n) => Value::from_quantity(floor(n.to_float()).to_quantity()),
        _ => Value::Empty
      };
      out.data[i][j] = result;
    }
  }
  out
}