Skip to content

Commit

Permalink
=</2 infix operator
Browse files Browse the repository at this point in the history
Implemented as `erlang::is_equal_or_less_than_2`.
  • Loading branch information
KronicDeth committed Apr 17, 2019
1 parent a0c4ca0 commit 1511d7c
Show file tree
Hide file tree
Showing 17 changed files with 2,022 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lumen_runtime/src/binary/sub.rs
Expand Up @@ -421,7 +421,13 @@ impl PartialOrd<heap::Binary> for Binary {

break;
}
(None, None) => break,
(None, None) => {
if 0 < self.bit_count {
partial_ordering = Some(Greater);
}

break;
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions lumen_runtime/src/otp/erlang.rs
Expand Up @@ -680,6 +680,14 @@ pub fn is_boolean_1(term: Term) -> Term {
.into()
}

/// `=</2` infix operator. Floats and integers are converted.
///
/// **NOTE: `=</2` is not a typo. Unlike `>=/2`, which has the `=` second, Erlang put the `=` first
/// for `=</2`, instead of the more common `<=`.
pub fn is_equal_or_less_than_2(left: Term, right: Term) -> Term {
left.le(&right).into()
}

pub fn is_float_1(term: Term) -> Term {
match term.tag() {
Boxed => {
Expand Down
1 change: 1 addition & 0 deletions lumen_runtime/src/otp/erlang/tests.rs
Expand Up @@ -54,6 +54,7 @@ mod is_atom_1;
mod is_binary_1;
mod is_bitstring_1;
mod is_boolean_1;
mod is_equal_or_less_than_2;
mod is_float_1;
mod is_greater_than_2;
mod is_greater_than_or_equal_2;
Expand Down
31 changes: 31 additions & 0 deletions lumen_runtime/src/otp/erlang/tests/is_equal_or_less_than_2.rs
@@ -0,0 +1,31 @@
use super::*;

mod with_atom_left;
mod with_big_integer_left;
mod with_empty_list_left;
mod with_external_pid_left;
mod with_float_left;
mod with_heap_binary_left;
mod with_list_left;
mod with_local_pid_left;
mod with_local_reference_left;
mod with_map_left;
mod with_small_integer_left;
mod with_subbinary_left;
mod with_tuple_left;

fn is_equal_or_less_than<L, R>(left: L, right: R, expected: bool)
where
L: FnOnce(&mut Process) -> Term,
R: FnOnce(Term, &mut Process) -> Term,
{
with_process(|mut process| {
let left = left(&mut process);
let right = right(left, &mut process);

assert_eq!(
erlang::is_equal_or_less_than_2(left, right),
expected.into()
);
});
}
@@ -0,0 +1,113 @@
use super::*;

#[test]
fn with_small_integer_right_returns_false() {
is_equal_or_less_than(|_, mut process| 0.into_process(&mut process), false)
}

#[test]
fn with_big_integer_right_returns_false() {
is_equal_or_less_than(
|_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process),
false,
)
}

#[test]
fn with_float_right_returns_false() {
is_equal_or_less_than(|_, mut process| 0.0.into_process(&mut process), false)
}

#[test]
fn with_lesser_atom_returns_false() {
is_equal_or_less_than(|_, _| Term::str_to_atom("keft", DoNotCare).unwrap(), false);
}

#[test]
fn with_same_atom_returns_true() {
is_equal_or_less_than(|left, _| left, true);
}

#[test]
fn with_same_atom_value_returns_true() {
is_equal_or_less_than(|_, _| Term::str_to_atom("left", DoNotCare).unwrap(), true);
}

#[test]
fn with_greater_atom_returns_true() {
is_equal_or_less_than(|_, _| Term::str_to_atom("meft", DoNotCare).unwrap(), true);
}

#[test]
fn with_local_reference_right_returns_true() {
is_equal_or_less_than(|_, mut process| Term::local_reference(&mut process), true);
}

#[test]
fn with_local_pid_right_returns_true() {
is_equal_or_less_than(|_, _| Term::local_pid(0, 1).unwrap(), true);
}

#[test]
fn with_external_pid_right_returns_true() {
is_equal_or_less_than(
|_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(),
true,
);
}

#[test]
fn with_tuple_right_returns_true() {
is_equal_or_less_than(
|_, mut process| Term::slice_to_tuple(&[], &mut process),
true,
);
}

#[test]
fn with_map_right_returns_true() {
is_equal_or_less_than(|_, mut process| Term::slice_to_map(&[], &mut process), true);
}

#[test]
fn with_empty_list_right_returns_true() {
is_equal_or_less_than(|_, _| Term::EMPTY_LIST, true);
}

#[test]
fn with_list_right_returns_true() {
is_equal_or_less_than(
|_, mut process| {
Term::cons(
0.into_process(&mut process),
1.into_process(&mut process),
&mut process,
)
},
true,
);
}

#[test]
fn with_heap_binary_right_returns_true() {
is_equal_or_less_than(
|_, mut process| Term::slice_to_binary(&[], &mut process),
true,
);
}

#[test]
fn with_subbinary_right_returns_true() {
is_equal_or_less_than(|_, mut process| bitstring!(1 :: 1, &mut process), true);
}

fn is_equal_or_less_than<R>(right: R, expected: bool)
where
R: FnOnce(Term, &mut Process) -> Term,
{
super::is_equal_or_less_than(
|_| Term::str_to_atom("left", DoNotCare).unwrap(),
right,
expected,
);
}
@@ -0,0 +1,137 @@
use super::*;

#[test]
fn with_lesser_small_integer_right_returns_false() {
is_equal_or_less_than(|_, mut process| 0.into_process(&mut process), false)
}

#[test]
fn with_greater_small_integer_right_returns_true() {
super::is_equal_or_less_than(
|mut process| (crate::integer::small::MIN - 1).into_process(&mut process),
|_, mut process| crate::integer::small::MIN.into_process(&mut process),
true,
);
}

#[test]
fn with_lesser_big_integer_right_returns_false() {
is_equal_or_less_than(
|_, mut process| (crate::integer::small::MIN - 1).into_process(&mut process),
false,
)
}

#[test]
fn with_same_big_integer_right_returns_true() {
is_equal_or_less_than(|left, _| left, true)
}

#[test]
fn with_same_value_big_integer_right_returns_true() {
is_equal_or_less_than(
|_, mut process| (crate::integer::small::MAX + 1).into_process(&mut process),
true,
)
}

#[test]
fn with_greater_big_integer_right_returns_true() {
is_equal_or_less_than(
|_, mut process| (crate::integer::small::MAX + 2).into_process(&mut process),
true,
)
}

#[test]
fn with_lesser_float_right_returns_false() {
is_equal_or_less_than(|_, mut process| 0.0.into_process(&mut process), false)
}

#[test]
fn with_greater_float_right_returns_true() {
super::is_equal_or_less_than(
|mut process| (crate::integer::small::MIN - 1).into_process(&mut process),
|_, mut process| 0.0.into_process(&mut process),
true,
);
}

#[test]
fn with_atom_right_returns_true() {
is_equal_or_less_than(|_, _| Term::str_to_atom("right", DoNotCare).unwrap(), true);
}

#[test]
fn with_local_reference_right_returns_true() {
is_equal_or_less_than(|_, mut process| Term::local_reference(&mut process), true);
}

#[test]
fn with_local_pid_right_returns_true() {
is_equal_or_less_than(|_, _| Term::local_pid(0, 1).unwrap(), true);
}

#[test]
fn with_external_pid_right_returns_true() {
is_equal_or_less_than(
|_, mut process| Term::external_pid(1, 2, 3, &mut process).unwrap(),
true,
);
}

#[test]
fn with_tuple_right_returns_true() {
is_equal_or_less_than(
|_, mut process| Term::slice_to_tuple(&[], &mut process),
true,
);
}

#[test]
fn with_map_right_returns_true() {
is_equal_or_less_than(|_, mut process| Term::slice_to_map(&[], &mut process), true);
}

#[test]
fn with_empty_list_right_returns_true() {
is_equal_or_less_than(|_, _| Term::EMPTY_LIST, true);
}

#[test]
fn with_list_right_returns_true() {
is_equal_or_less_than(
|_, mut process| {
Term::cons(
0.into_process(&mut process),
1.into_process(&mut process),
&mut process,
)
},
true,
);
}

#[test]
fn with_heap_binary_right_returns_true() {
is_equal_or_less_than(
|_, mut process| Term::slice_to_binary(&[], &mut process),
true,
);
}

#[test]
fn with_subbinary_right_returns_true() {
is_equal_or_less_than(|_, mut process| bitstring!(1 :: 1, &mut process), true);
}

fn is_equal_or_less_than<R>(right: R, expected: bool)
where
R: FnOnce(Term, &mut Process) -> Term,
{
super::is_equal_or_less_than(
|mut process| (crate::integer::small::MAX + 1).into_process(&mut process),
right,
expected,
);
}

0 comments on commit 1511d7c

Please sign in to comment.