Merge branch 'roc-lang:main' into list-update

This commit is contained in:
KilianVounckx 2023-05-30 08:54:26 +02:00 committed by GitHub
commit c22a9ef8b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 307 additions and 305 deletions

View file

@ -44,6 +44,8 @@ pub const RocDec = extern struct {
return ret;
}
// TODO: If Str.toDec eventually supports more error types, return errors here.
// For now, just return null which will give the default error.
pub fn fromStr(roc_str: RocStr) ?RocDec {
if (roc_str.isEmpty()) {
return null;
@ -79,7 +81,8 @@ pub const RocDec = extern struct {
var after_str_len = (length - 1) - pi;
if (after_str_len > decimal_places) {
@panic("TODO runtime exception for too many decimal places!");
// TODO: runtime exception for too many decimal places!
return null;
}
var diff_decimal_places = decimal_places - after_str_len;
@ -96,7 +99,8 @@ pub const RocDec = extern struct {
var result: i128 = undefined;
var overflowed = @mulWithOverflow(i128, before, one_point_zero_i128, &result);
if (overflowed) {
@panic("TODO runtime exception for overflow!");
// TODO: runtime exception for overflow!
return null;
}
before_val_i128 = result;
}
@ -107,7 +111,8 @@ pub const RocDec = extern struct {
var result: i128 = undefined;
var overflowed = @addWithOverflow(i128, before, after, &result);
if (overflowed) {
@panic("TODO runtime exception for overflow!");
// TODO: runtime exception for overflow!
return null;
}
break :blk .{ .num = result };
} else {
@ -184,7 +189,7 @@ pub const RocDec = extern struct {
position += 1;
const trailing_zeros: u6 = count_trailing_zeros_base10(num);
if (trailing_zeros == decimal_places) {
if (trailing_zeros >= decimal_places) {
// add just a single zero if all decimal digits are zero
str_bytes[position] = '0';
position += 1;
@ -851,6 +856,14 @@ test "fromStr: .123.1" {
try expectEqual(dec, null);
}
test "toStr: 100.00" {
var dec: RocDec = .{ .num = 100000000000000000000 };
var res_roc_str = dec.toStr();
const res_slice: []const u8 = "100.0"[0..];
try expectEqualSlices(u8, res_slice, res_roc_str.asSlice());
}
test "toStr: 123.45" {
var dec: RocDec = .{ .num = 123450000000000000000 };
var res_roc_str = dec.toStr();

View file

@ -95,7 +95,7 @@ Dict k v := {
# TODO: define Eq and Hash that are unordered. Only if value has hash/eq?
metadata : List I8,
dataIndices : List Nat,
data : List (T k v),
data : List (k, v),
size : Nat,
} | k has Hash & Eq
has [
@ -175,12 +175,12 @@ single = \k, v ->
## |> Dict.insert 2 "Two"
## |> Dict.insert 3 "Three"
## |> Dict.insert 4 "Four"
## |> Bool.isEq (Dict.fromList [T 1 "One", T 2 "Two", T 3 "Three", T 4 "Four"])
## |> Bool.isEq (Dict.fromList [(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")])
## ```
fromList : List (T k v) -> Dict k v | k has Hash & Eq
fromList : List (k, v) -> Dict k v | k has Hash & Eq
fromList = \data ->
# TODO: make this efficient. Should just set data and then set all indicies in the hashmap.
List.walk data (empty {}) (\dict, T k v -> insert dict k v)
List.walk data (empty {}) (\dict, (k, v) -> insert dict k v)
## Returns the number of values in the dictionary.
## ```
@ -238,7 +238,7 @@ clear = \@Dict { metadata, dataIndices, data } ->
## ```
walk : Dict k v, state, (state, k, v -> state) -> state | k has Hash & Eq
walk = \@Dict { data }, initialState, transform ->
List.walk data initialState (\state, T k v -> transform state k v)
List.walk data initialState (\state, (k, v) -> transform state k v)
## Same as [Dict.walk], except you can stop walking early.
##
@ -270,7 +270,7 @@ walk = \@Dict { data }, initialState, transform ->
## ```
walkUntil : Dict k v, state, (state, k, v -> [Continue state, Break state]) -> state | k has Hash & Eq
walkUntil = \@Dict { data }, initialState, transform ->
List.walkUntil data initialState (\state, T k v -> transform state k v)
List.walkUntil data initialState (\state, (k, v) -> transform state k v)
## Get the value for a given key. If there is a value for the specified key it
## will return [Ok value], otherwise return [Err KeyNotFound].
@ -296,7 +296,7 @@ get = \@Dict { metadata, dataIndices, data }, key ->
when findIndexHelper metadata dataIndices data h2Key key probe 0 is
Ok index ->
dataIndex = listGetUnsafe dataIndices index
(T _ v) = listGetUnsafe data dataIndex
(_, v) = listGetUnsafe data dataIndex
Ok v
@ -353,7 +353,7 @@ insert = \@Dict { metadata, dataIndices, data, size }, key, value ->
@Dict {
metadata,
dataIndices,
data: List.set data dataIndex (T key value),
data: List.set data dataIndex (key, value),
size,
}
@ -447,9 +447,9 @@ update = \dict, key, alter ->
## |> Dict.insert 3 "Three"
## |> Dict.insert 4 "Four"
## |> Dict.toList
## |> Bool.isEq [T 1 "One", T 2 "Two", T 3 "Three", T 4 "Four"]
## |> Bool.isEq [(1, "One"), (2, "Two"), (3, "Three"), (4, "Four")]
## ```
toList : Dict k v -> List (T k v) | k has Hash & Eq
toList : Dict k v -> List (k, v) | k has Hash & Eq
toList = \@Dict { data } ->
data
@ -466,7 +466,7 @@ toList = \@Dict { data } ->
## ```
keys : Dict k v -> List k | k has Hash & Eq
keys = \@Dict { data } ->
List.map data (\T k _ -> k)
List.map data (\(k, _) -> k)
## Returns the values of a dictionary as a [List].
## This requires allocating a temporary [List], prefer using [Dict.toList] or [Dict.walk] instead.
@ -481,7 +481,7 @@ keys = \@Dict { data } ->
## ```
values : Dict k v -> List v | k has Hash & Eq
values = \@Dict { data } ->
List.map data (\T _ v -> v)
List.map data (\(_, v) -> v)
## Combine two dictionaries by keeping the [union](https://en.wikipedia.org/wiki/Union_(set_theory))
## of all the key-value pairs. This means that all the key-value pairs in
@ -567,7 +567,7 @@ removeAll = \xs, ys ->
swapAndUpdateDataIndex : Dict k v, Nat, Nat -> Dict k v | k has Hash & Eq
swapAndUpdateDataIndex = \@Dict { metadata, dataIndices, data, size }, removedIndex, lastIndex ->
(T key _) = listGetUnsafe data lastIndex
(key, _) = listGetUnsafe data lastIndex
hashKey =
createLowLevelHasher PseudoRandSeed
|> Hash.hash key
@ -603,7 +603,7 @@ insertNotFoundHelper = \@Dict { metadata, dataIndices, data, size }, key, value,
probe = newProbe h1Key (div8 (List.len metadata))
index = nextEmptyOrDeletedHelper metadata probe 0
dataIndex = List.len data
nextData = List.append data (T key value)
nextData = List.append data (key, value)
@Dict {
metadata: List.set metadata index h2Key,
@ -629,7 +629,7 @@ nextEmptyOrDeletedHelper = \metadata, probe, offset ->
# TODO: investigate if this needs to be split into more specific helper functions.
# There is a chance that returning specific sub-info like the value would be faster.
findIndexHelper : List I8, List Nat, List (T k v), I8, k, Probe, Nat -> Result Nat [NotFound] | k has Hash & Eq
findIndexHelper : List I8, List Nat, List (k, v), I8, k, Probe, Nat -> Result Nat [NotFound] | k has Hash & Eq
findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset ->
# For finding a value, we must search past all deleted element tombstones.
index = Num.addWrap (mul8 probe.slotIndex) offset
@ -642,7 +642,7 @@ findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset ->
else if md == h2Key then
# Potentially matching slot, check if the key is a match.
dataIndex = listGetUnsafe dataIndices index
(T k _) = listGetUnsafe data dataIndex
(k, _) = listGetUnsafe data dataIndex
if k == key then
# We have a match, return its index.
@ -687,7 +687,7 @@ rehash = \@Dict { metadata, dataIndices, data, size } ->
rehashHelper newDict metadata dataIndices data 0
rehashHelper : Dict k v, List I8, List Nat, List (T k v), Nat -> Dict k v | k has Hash & Eq
rehashHelper : Dict k v, List I8, List Nat, List (k, v), Nat -> Dict k v | k has Hash & Eq
rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index ->
when List.get oldMetadata index is
Ok md ->
@ -695,7 +695,7 @@ rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index ->
if md >= 0 then
# We have an actual element here
dataIndex = listGetUnsafe oldDataIndices index
(T k _) = listGetUnsafe oldData dataIndex
(k, _) = listGetUnsafe oldData dataIndex
insertForRehash dict k dataIndex
else
@ -731,8 +731,6 @@ emptySlot = -128
deletedSlot : I8
deletedSlot = -2
T k v : [T k v]
# Capacity must be a power of 2.
# We still will use slots of 8 even though this version has no true slots.
# We just move an element at a time.
@ -869,7 +867,7 @@ expect
expect
dict =
fromList [T 1u8 1u8, T 2 2, T 3 3]
fromList [(1u8, 1u8), (2, 2), (3, 3)]
|> remove 1
|> remove 3
@ -877,7 +875,7 @@ expect
expect
list =
fromList [T 1u8 1u8, T 2u8 2u8, T 3 3]
fromList [(1u8, 1u8), (2u8, 2u8), (3, 3)]
|> remove 1
|> insert 0 0
|> remove 3