Skip to content

Commit

Permalink
Add a math module to the standard lib
Browse files Browse the repository at this point in the history
I need some rudimentary stdlib stuff for the tutorial.

Closes #1042
  • Loading branch information
marijnh committed Oct 18, 2011
1 parent d9d0782 commit 71a4a66
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 21 deletions.
6 changes: 3 additions & 3 deletions src/comp/middle/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1305,17 +1305,17 @@ fn valid_range_bounds(l1: @ast::lit, l2: @ast::lit) -> bool {
let s2 = lit_as_float(l2);
let f1 = std::float::from_str(s1);
let f2 = std::float::from_str(s2);
ret *util::common::min(f1, f2) == f1
ret std::math::min(f1, f2) == f1
}
ast::lit_uint(_) | ast::lit_char(_) {
let u1 = lit_as_uint(l1);
let u2 = lit_as_uint(l2);
ret *util::common::min(u1, u2) == u1
ret std::math::min(u1, u2) == u1
}
_ {
let i1 = lit_as_int(l1);
let i2 = lit_as_int(l2);
ret *util::common::min(i1, i2) == i1
ret std::math::min(i1, i2) == i1
}
}
}
Expand Down
29 changes: 11 additions & 18 deletions src/comp/util/common.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import std::{str, map, uint, int, option};
import std::math::{max, min};
import std::map::hashmap;
import std::option::{none, some};
import syntax::ast;
Expand Down Expand Up @@ -131,53 +132,45 @@ fn lit_in_range(l: @ast::lit, m1: @ast::lit, m2: @ast::lit) -> bool {
irange(i1, i2) {
alt l.node {
ast::lit_int(i3) | ast::lit_mach_int(_, i3) {
i3 >= *min(i1, i2) && i3 <= *max(i1, i2)
i3 >= min(i1, i2) && i3 <= max(i1, i2)
}
_ { fail }
}
}
urange(u1, u2) {
alt l.node {
ast::lit_uint(u3) {
u3 >= *min(u1, u2) && u3 <= *max(u1, u2)
u3 >= min(u1, u2) && u3 <= max(u1, u2)
}
_ { fail }
}
}
crange(c1, c2) {
alt l.node {
ast::lit_char(c3) {
(c3 as uint) >= *min(c1 as uint, c2 as uint) &&
(c3 as uint) <= *max(c1 as uint, c2 as uint)
(c3 as uint) >= min(c1 as uint, c2 as uint) &&
(c3 as uint) <= max(c1 as uint, c2 as uint)
}
_ { fail }
}
}
frange(f1, f2) {
alt l.node {
ast::lit_float(f3) | ast::lit_mach_float(_, f3) {
std::float::from_str(f3) >= *min(f1, f2) &&
std::float::from_str(f3) <= *max(f1, f2)
std::float::from_str(f3) >= min(f1, f2) &&
std::float::from_str(f3) <= max(f1, f2)
}
_ { fail }
}
}
}
}

fn min<@T>(x: T, y: T) -> @T {
ret @(if x > y { y } else { x });
}

fn max<@T>(x: T, y: T) -> @T {
ret @(if x > y { x } else { y });
}

fn ranges_overlap<@T>(a1: T, a2: T, b1: T, b2: T) -> bool {
let min1 = *min(a1, a2);
let max1 = *max(a1, a2);
let min2 = *min(b1, b2);
let max2 = *max(b1, b2);
let min1 = min(a1, a2);
let max1 = max(a1, a2);
let min2 = min(b1, b2);
let max2 = max(b1, b2);
ret (min1 >= min2 && max1 <= max2) || (min1 <= min2 && max1 >= min2) ||
(min1 >= min2 && min1 <= max2) || (max1 >= min2 && max1 <= max2);
}
Expand Down
22 changes: 22 additions & 0 deletions src/lib/math.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
native "llvm" mod llvm {
fn sqrt(n: float) -> float = "sqrt.f64";
fn sin(n: float) -> float = "sin.f64";
fn asin(n: float) -> float = "asin.f64";
fn cos(n: float) -> float = "cos.f64";
fn acos(n: float) -> float = "acos.f64";
fn tan(n: float) -> float = "tan.f64";
fn atan(n: float) -> float = "atan.f64";
}

fn sqrt(x: float) -> float { llvm::sqrt(x) }
fn sin(x: float) -> float { llvm::sin(x) }
fn cos(x: float) -> float { llvm::cos(x) }
fn tan(x: float) -> float { llvm::tan(x) }
fn asin(x: float) -> float { llvm::asin(x) }
fn acos(x: float) -> float { llvm::acos(x) }
fn atan(x: float) -> float { llvm::atan(x) }

const pi: float = 3.141592653589793;

fn min<@T>(x: T, y: T) -> T { x < y ? x : y }
fn max<@T>(x: T, y: T) -> T { x < y ? y : x }
1 change: 1 addition & 0 deletions src/lib/std.rc
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ mod ptr;
mod test;
mod unsafe;
mod term;
mod math;

#[cfg(unicode)]
mod unicode;
Expand Down
34 changes: 34 additions & 0 deletions src/test/stdtest/math.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use std;
import std::math::*;

#[test]
fn test_sqrt() {
assert sqrt(9.0) == 3.0;
assert sqrt(4.0) == 2.0;
assert sqrt(1.0) == 1.0;
assert sqrt(0.0) == 0.0;
}

#[test]
fn test_max_min() {
assert max(0, 1) == 1;
assert min(0, 1) == 0;
assert max(0, -1) == 0;
assert min(0, -1) == -1;
assert max(0.0, 1.0) == 1.0;
assert min(0.0, 1.0) == 0.0;
}

#[test]
fn test_angle() {
fn angle(vec: (float, float)) -> float {
alt vec {
(0f, y) when y < 0f { 1.5 * std::math::pi }
(0f, y) { 0.5 * std::math::pi }
(x, y) { std::math::atan(y / x) }
}
}
assert angle((1f, 0f)) == 0f;
assert angle((1f, 1f)) == 0.25 * pi;
assert angle((0f, 1f)) == 0.5 * pi;
}
1 change: 1 addition & 0 deletions src/test/stdtest/stdtest.rc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mod task;
mod test;
mod uint;
mod float;
mod math;

// Local Variables:
// mode: rust
Expand Down

0 comments on commit 71a4a66

Please sign in to comment.