Skip to content

Commit

Permalink
feat(vm): Add the std.byte module
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Mar 30, 2018
1 parent 0be8ab7 commit ecbbc13
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static STD_LIBS: &[(&str, &str)] = &std_libs!(
"bool",
"float",
"int",
"byte",
"char",
"io",
"list",
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ impl VmBuilder {
.unwrap_or_else(|err| panic!("{}", err));

add_extern_module(&vm, "std.prim", ::vm::primitives::load);
add_extern_module(&vm, "std.byte.prim", ::vm::primitives::load_byte);
add_extern_module(&vm, "std.int.prim", ::vm::primitives::load_int);
add_extern_module(&vm, "std.float.prim", ::vm::primitives::load_float);
add_extern_module(&vm, "std.string.prim", ::vm::primitives::load_string);
Expand Down
63 changes: 63 additions & 0 deletions std/byte.glu
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
let { Semigroup, Monoid, Group, Eq, Ord, Ordering, Num, Show } = import! std.prelude

let additive =
let semigroup : Semigroup Byte = {
append = \x y -> x #Byte+ y
}

let monoid : Monoid Byte = {
semigroup = semigroup,
empty = 0b,
}

let group : Group Byte = {
monoid = monoid,
inverse = \x -> 0b #Byte- x,
}

{ semigroup, monoid, group }

let multiplicative =
let semigroup : Semigroup Byte = {
append = \x y -> x #Byte* y
}

let monoid : Monoid Byte = {
semigroup = semigroup,
empty = 1b,
}

{ semigroup, monoid }

let eq : Eq Byte = {
(==) = \l r -> l #Byte== r
}

let ord : Ord Byte = {
eq = eq,
compare = \l r -> if l #Byte< r then LT else if l #Byte== r then EQ else GT,
}

let num : Num Byte = {
ord = ord,
(+) = additive.semigroup.append,
(-) = \l r -> l #Byte- r,
(*) = multiplicative.semigroup.append,
(/) = \l r -> l #Byte/ r,
negate = additive.group.inverse,
}

let show : Show Byte = {
show = (import! std.prim).show_byte
}

{
additive,
multiplicative,
eq,
ord,
num,
show,
..
import! std.byte.prim
}
8 changes: 2 additions & 6 deletions tests/pass/arithmetic.glu
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,16 @@ let float = import! std.float
let byte @ { ? } = import! std.byte

let byte_tests =
let { (+), (-), (*) } = int.num
group "byte" [
test "arithmetic" <| \_ ->
assert_eq 2b 2b
*> assert_eq 12b (10b + 2b)
*> assert_eq 123b (50b * 2b + 9b * 3b - 4b),
test "from_int" <| \_ -> assert_eq (byte.from_float 2.0) 2,
test "from_int_saturate" <| \_ -> assert_eq (byte.from_int 200) 256,
test "from_int" <| \_ -> assert_eq (byte.from_int 2) 2b,
test "from_int_truncate" <| \_ -> assert_eq (byte.from_int 2000) 208b,
]

let int_tests =
let { (+), (-), (*) } = int.num
group "int" [
test "arithmetic" <| \_ ->
assert_eq 2 2
Expand All @@ -30,11 +28,9 @@ let int_tests =
]

let float_tests =
let { (+), (-), (*) } = float.num
group "float" [
test "float" <| \_ -> assert_eq 91.0 (50.0 * 2.0 - 3.0 * 3.0),
test "from_int" <| \_ -> assert_eq (float.from_int 2) 2.0,
test "from_byte" <| \_ -> assert_eq (float.from_byte 2b) 2.0,
]

group "arithmetic" [byte_tests, int_tests, float_tests]
22 changes: 14 additions & 8 deletions vm/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ fn show_char(c: char) -> String {
format!("{}", c)
}

fn show_byte(c: u8) -> String {
format!("{}", c)
}

extern "C" fn error(_: &Thread) -> Status {
// We expect a string as an argument to this function but we only return Status::Error
// and let the caller take care of printing the message
Expand Down Expand Up @@ -360,9 +364,9 @@ pub fn load_byte(vm: &Thread) -> Result<ExternModule> {
min_value => std::byte::prim::min_value(),
max_value => std::byte::prim::max_value(),
count_ones => primitive!(1 std::byte::prim::count_ones),
count_zeroes => primitive!(1 std::byte::prim::count_zeroes),
leading_zeroes => primitive!(1 std::byte::prim::leading_zeroes),
trailing_zeroes => primitive!(1 std::byte::prim::trailing_zeroes),
count_zeros => primitive!(1 std::byte::prim::count_zeros),
leading_zeros => primitive!(1 std::byte::prim::leading_zeros),
trailing_zeros => primitive!(1 std::byte::prim::trailing_zeros),
rotate_left => primitive!(2 std::byte::prim::rotate_left),
rotate_right => primitive!(2 std::byte::prim::rotate_right),
swap_bytes => primitive!(1 std::byte::prim::swap_bytes),
Expand All @@ -371,8 +375,8 @@ pub fn load_byte(vm: &Thread) -> Result<ExternModule> {
to_be => primitive!(1 std::byte::prim::to_be),
to_le => primitive!(1 std::byte::prim::to_le),
pow => primitive!(2 std::byte::prim::pow),
from_float => named_primitive!(1, "std.byte.prim.from_int", |i: VmInt| i as u8),
parse => named_primitive!(1, "std.byte.prim.parse", parse::<VmInt>)
from_int => named_primitive!(1, "std.byte.prim.from_int", |i: VmInt| i as u8),
parse => named_primitive!(1, "std.byte.prim.parse", parse::<u8>)
},
)
}
Expand All @@ -386,9 +390,9 @@ pub fn load_int(vm: &Thread) -> Result<ExternModule> {
min_value => std::int::prim::min_value(),
max_value => std::int::prim::max_value(),
count_ones => primitive!(1 std::int::prim::count_ones),
count_zeroes => primitive!(1 std::int::prim::count_zeroes),
leading_zeroes => primitive!(1 std::int::prim::leading_zeroes),
trailing_zeroes => primitive!(1 std::int::prim::trailing_zeroes),
count_zeros => primitive!(1 std::int::prim::count_zeros),
leading_zeros => primitive!(1 std::int::prim::leading_zeros),
trailing_zeros => primitive!(1 std::int::prim::trailing_zeros),
rotate_left => primitive!(2 std::int::prim::rotate_left),
rotate_right => primitive!(2 std::int::prim::rotate_right),
swap_bytes => primitive!(1 std::int::prim::swap_bytes),
Expand All @@ -401,6 +405,7 @@ pub fn load_int(vm: &Thread) -> Result<ExternModule> {
signum => primitive!(1 std::int::prim::signum),
is_positive => primitive!(1 std::int::prim::is_positive),
is_negative => primitive!(1 std::int::prim::is_negative),
from_byte => named_primitive!(1, "std.int.prim.from_byte", |b: u8| b as VmInt),
from_float => named_primitive!(1, "std.int.prim.from_float", |f: f64| f as VmInt),
parse => named_primitive!(1, "std.int.prim.parse", parse::<VmInt>)
},
Expand Down Expand Up @@ -494,6 +499,7 @@ pub fn load(vm: &Thread) -> Result<ExternModule> {
record! {
show_int => primitive!(1 std::prim::show_int),
show_float => primitive!(1 std::prim::show_float),
show_byte => primitive!(1 std::prim::show_byte),
show_char => primitive!(1 std::prim::show_char),
string_compare => named_primitive!(2, "std.prim.string_compare", str::cmp),
string_eq => named_primitive!(2, "std.prim.string_eq", <str as PartialEq>::eq),
Expand Down

0 comments on commit ecbbc13

Please sign in to comment.