Skip to content

Commit

Permalink
Merge branch 'main' into better_trig_func_impl
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaida-Amethyst authored Jan 25, 2025
2 parents d53c46f + 9e073ba commit 0d1f40c
Show file tree
Hide file tree
Showing 18 changed files with 366 additions and 60 deletions.
30 changes: 30 additions & 0 deletions buffer/buffer.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,36 @@ pub fn write_bytes(self : T, value : Bytes) -> Unit {
self.len += val_len
}

///|
/// Writes a sequence of bytes from a BytesView into the buffer.
///
/// Parameters:
///
/// * `buffer` : The buffer to write to.
/// * `value` : The BytesView containing the bytes to write.
///
/// Example:
///
/// ```moonbit
/// test "write_bytesview" {
/// let buf = @buffer.new()
/// let view = b"Test"[1:3]
/// buf.write_bytesview(view)
/// inspect!(
/// buf.contents(),
/// content=
/// #|b"\x65\x73"
/// ,
/// )
/// }
/// ```
pub fn write_bytesview(self : T, value : BytesView) -> Unit {
let val_len = value.length()
self.grow_if_necessary(self.len + val_len)
self.data.blit_from_bytesview(self.len, value)
self.len += val_len
}

///|
/// Writes a portion of a string into the buffer in UTF-16LE encoding.
///
Expand Down
1 change: 1 addition & 0 deletions buffer/buffer.mbti
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ impl T {
to_unchecked_string(Self) -> String //deprecated
write_byte(Self, Byte) -> Unit
write_bytes(Self, Bytes) -> Unit
write_bytesview(Self, BytesView) -> Unit
write_char(Self, Char) -> Unit
write_double_be(Self, Double) -> Unit
write_double_le(Self, Double) -> Unit
Expand Down
11 changes: 11 additions & 0 deletions buffer/buffer_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,14 @@ test "write_iter" {
,
)
}

test "write_bytesview" {
let buf = @buffer.new(size_hint=4)
buf.write_bytesview(b"Test"[1:3])
inspect!(
buf.contents(),
content=
#|b"\x65\x73"
,
)
}
3 changes: 2 additions & 1 deletion builtin/builtin.mbti
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,7 @@ impl Result {

impl FixedArray {
blit_from_bytes(Self[Byte], Int, Bytes, Int, Int) -> Unit
blit_from_bytesview(Self[Byte], Int, BytesView) -> Unit
blit_from_string(Self[Byte], Int, String, Int, Int) -> Unit
blit_to[A](Self[A], Self[A], len~ : Int, src_offset~ : Int = .., dst_offset~ : Int = ..) -> Unit
compare[T : Compare](Self[T], Self[T]) -> Int
Expand All @@ -718,7 +719,7 @@ impl FixedArray {
}

impl Bytes {
blit(Bytes, Int, Bytes, Int, Int) -> Unit
blit(Bytes, Int, Bytes, Int, Int) -> Unit //deprecated
copy(Bytes) -> Bytes
length(Bytes) -> Int
make(Int, Byte) -> Bytes
Expand Down
35 changes: 34 additions & 1 deletion builtin/bytes.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,39 @@ pub fn FixedArray::blit_from_bytes(
}
}

///|
/// Copy bytes from a BytesView into a fixed array of bytes.
///
/// Parameters:
///
/// * `self` : The destination fixed array of bytes.
/// * `bytes_offset` : The starting position in the destination array where bytes will be copied.
/// * `src` : The source BytesView to copy from.
///
/// Throws a panic if:
/// * `bytes_offset` is negative
/// * The destination array is too small to hold all bytes from the source BytesView
///
/// Example:
///
/// ```moonbit
/// let arr = FixedArray::make(4, b'\x00')
/// let view = b"\x01\x02\x03"[1:]
/// arr.blit_from_bytesview(1, view)
/// inspect!(arr, content="[b'\\x00', b'\\x02', b'\\x03', b'\\x00']")
/// ```
pub fn FixedArray::blit_from_bytesview(
self : FixedArray[Byte],
bytes_offset : Int,
src : BytesView
) -> Unit {
let src_len = src.length()
guard bytes_offset >= 0 && bytes_offset + src_len - 1 < self.length()
for i = 0, j = bytes_offset; i < src_len; i = i + 1, j = j + 1 {
self[j] = src[i]
}
}

///|
/// Creates a new byte sequence by copying all bytes from the input sequence.
///
Expand All @@ -240,7 +273,7 @@ pub fn FixedArray::blit_from_bytes(
/// }
/// ```
pub fn Bytes::copy(self : Bytes) -> Bytes {
Bytes::new(self.length())..blit(0, self, 0, self.length())
Bytes::makei(self.length(), fn(i) { self[i] })
}

///|
Expand Down
38 changes: 1 addition & 37 deletions builtin/bytes_block.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,7 @@ fn Bytes::unsafe_blit(
///|
/// Copies a sequence of bytes from a source byte sequence to a destination byte
/// sequence.
///
/// Parameters:
///
/// * `self` : The destination byte sequence where bytes will be copied to.
/// * `dst_offset` : The starting position in the destination sequence where
/// bytes will be written.
/// * `src` : The source byte sequence from which bytes will be copied.
/// * `src_offset` : The starting position in the source sequence from which
/// bytes will be read.
/// * `length` : The number of bytes to copy.
///
/// Throws a runtime error if:
///
/// * `length` is negative
/// * `dst_offset` is negative
/// * `src_offset` is negative
/// * The range `[dst_offset, dst_offset + length)` exceeds the length of the
/// destination sequence
/// * The range `[src_offset, src_offset + length)` exceeds the length of the
/// source sequence
///
/// Example:
///
/// ```moonbit
/// test "Bytes::blit" {
/// let dst = Bytes::of_string("Hello, world!")
/// let src = Bytes::of_string("MOONBIT")
/// dst.blit(14, src, 0, 8)
/// @json.inspect!(dst.to_unchecked_string(), content="Hello, MOONd!")
/// }
///
/// test "panic Bytes::blit/out_of_bounds" {
/// let dst = Bytes::of_string("Hello")
/// let src = Bytes::of_string("World")
/// ignore(dst.blit(6, src, 0, 20)) // Range exceeds destination length
/// }
/// ```
/// @alert deprecated "Bytes is about to be changed to immutable, use `FixedArray[Byte]` instead"
pub fn Bytes::blit(
self : Bytes,
dst_offset : Int,
Expand Down
15 changes: 15 additions & 0 deletions builtin/fixedarray_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,18 @@ test "is_empty" {
let arr : FixedArray[Int] = []
assert_true!(arr.is_empty())
}

test "fixed array iter with early termination" {
let arr : FixedArray[Int] = [1, 2, 3]
let mut count = 0
let iter = arr.iter()
let _ = iter.run(fn(x) {
count = count + 1
if x == 2 {
IterEnd
} else {
IterContinue
}
})
inspect!(count, content="2")
}
6 changes: 6 additions & 0 deletions builtin/intrinsics_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -433,3 +433,9 @@ test "UInt::reinterpret_as_float roundtrip" {
assert_eq!(roundtrip_value, value)
}
}

test "convert byte to int64" {
let b = b'\xFF'
let result = b.to_int64()
inspect!(result, content="255")
}
48 changes: 48 additions & 0 deletions builtin/linked_hash_set_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,51 @@ test "from_iter empty iter" {
let map : Set[Int] = Set::from_iter(Iter::empty())
inspect!(map, content="{}")
}

test "remove item causes break when psl < i" {
let set = Set::new()
..add(1)
..add(11) // This goes to a different bucket due to hash collision
..remove(21) // Key doesn't exist, will cause psl < i and break
assert_eq!(set.size(), 2)
}

test "to_array_empty" {
inspect!((Set::new() : Set[Int]).to_array(), content="[]")
}

test "to_array_non_empty" {
let set = Set::new()..add(1)..add(2)..add(3)
inspect!(set.to_array(), content="[1, 2, 3]")
}

test "op_equal: different size" {
let set1 = Set::new()..add(1)
let set2 = Set::new()
inspect!(set1 == set2, content="false")
}

test "op_equal: different keys" {
let set1 = Set::new()..add(1)
let set2 = Set::new()..add(2)
inspect!(set1 == set2, content="false")
}

test "op_equal: same sets" {
let set1 = Set::new()..add(1)
let set2 = Set::new()..add(1)
inspect!(set1 == set2, content="true")
}

test "remove_and_check when key not found in empty slot" {
// Try to remove from empty set
inspect!(Set::new().remove_and_check(1), content="false")
}

test "trigger grow" {
let set = Set::new(capacity=2)
for i in 0..<10 {
assert_true!(set.add_and_check(i))
}
inspect!(set, content="{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}")
}
21 changes: 0 additions & 21 deletions builtin/panic_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -197,27 +197,6 @@ test "panic from_octets coverage for empty octets" {
BigInt::from_octets(b"") |> ignore
}

test "panic blit_negative_length" {
let b1 = Bytes::of_string("abcdef")
let b2 = Bytes::of_string("ABCDEF")
// Attempt to blit with a negative length
b1.blit(2, b2, 3, -1)
}

test "panic blit_out_of_bounds_src" {
let b1 = Bytes::of_string("abcdef")
let b2 = Bytes::of_string("ABCDEF")
// Attempt to blit with src_offset + length exceeding src length
b1.blit(4, b2, 10, 4)
}

test "panic blit_out_of_bounds_dst" {
let b1 = Bytes::of_string("abcdef")
let b2 = Bytes::of_string("ABCDEF")
// Attempt to blit with dst_offset + length exceeding dst length
b1.blit(8, b2, 6, 6)
}

test "panic sub_string with invalid byte_length" {
let bytes = Bytes::of_string("Hello, World!")
bytes.to_unchecked_string(offset=0, length=-1) |> ignore
Expand Down
10 changes: 10 additions & 0 deletions builtin/show_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,13 @@ test "Show for Char" {
inspect!('\''.to_string(), content="'")
inspect!('\\'.to_string(), content="\\")
}

test "char show hex digits" {
inspect!('\x01', content="'\\x01'")
inspect!('\x0b', content="'\\x0b'")
}

test "char_special" {
inspect!('\r', content="'\\r'")
inspect!('\b', content="'\\b'")
}
19 changes: 19 additions & 0 deletions bytes/bytes_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,22 @@ test "Bytes::from_iter with multiple elements" {
let bytes = Bytes::from_iter(iter)
inspect!(bytes, content="b\"\\x61\\x62\\x63\"")
}

test "Fixed::blit_from_bytesview" {
let arr = FixedArray::make(4, b'\x00')
let view = b"\x01\x02\x03"[1:]
arr.blit_from_bytesview(1, view)
inspect!(arr, content="[b'\\x00', b'\\x02', b'\\x03', b'\\x00']")
}

test "panic Fixed::blit_from_bytesview 1" {
let arr = FixedArray::make(2, b'\x00')
let view = b"\x01\x02\x03"[1:]
ignore(arr.blit_from_bytesview(1, view))
}

test "panic Fixed::blit_from_bytesview 2" {
let arr = FixedArray::make(2, b'\x00')
let view = b"\x01\x02\x03"[1:]
ignore(arr.blit_from_bytesview(-1, view))
}
30 changes: 30 additions & 0 deletions float/float_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,33 @@ test "@float.Float::is_nan" {
inspect!(@float.min_value.is_nan(), content="false")
inspect!(@float.min_positive.is_nan(), content="false")
}

test "Float::default()" {
inspect!(Float::default(), content="0")
}

test "Float::to_be_bytes with various values" {
let f1 : Float = 0.0
inspect!(f1.to_be_bytes(), content="b\"\\x00\\x00\\x00\\x00\"")
let f2 : Float = -1.0
inspect!(f2.to_be_bytes(), content="b\"\\xbf\\x80\\x00\\x00\"")
let f3 : Float = @float.infinity
inspect!(f3.to_be_bytes(), content="b\"\\x7f\\x80\\x00\\x00\"")
let f4 : Float = @float.not_a_number
inspect!(f4.to_be_bytes(), content="b\"\\x7f\\xc0\\x00\\x00\"")
}

test "to_le_bytes for zero" {
inspect!(
(0.0 : Float).to_le_bytes(),
content=
#|b"\x00\x00\x00\x00"
,
)
inspect!(
(-0.0 : Float).to_le_bytes(),
content=
#|b"\x00\x00\x00\x80"
,
)
}
20 changes: 20 additions & 0 deletions immut/hashmap/HAMT_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,23 @@ test "hash" {
let map4 = @hashmap.of([("one", 1), ("two", 2), ("three", 3)])
inspect!(map1.hash() == map4.hash(), content="false")
}

test "each on empty map" {
let empty = @hashmap.new()
let mut sum = 0
empty.each(fn(k : Int, v : Int) { sum = sum + k + v })
inspect!(sum, content="0")
}

test "remove non-existent key with hash collision" {
let map = @hashmap.of([("a", 1)])
let new_map = map.remove("b")
inspect!(new_map.size(), content="1")
}

test "remove all keys from collision bucket" {
let map = @hashmap.from_array([("a", 1), ("b", 2)])
let map1 = map.remove("a")
let map2 = map1.remove("b")
inspect!(map2.size(), content="0")
}
Loading

0 comments on commit 0d1f40c

Please sign in to comment.