diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-09-09 21:53:51 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-09-09 21:53:51 +0100 |
commit | 3546644ebcd8112b089555e69dcd7a5dad5b434b (patch) | |
tree | 0525c7ac4274c3ef1a91907b75f3f1f30897d25e /src | |
parent | bb88a32d105da31e5cdd2ad713016c88b96ac0ce (diff) | |
download | gleam_stdlib-3546644ebcd8112b089555e69dcd7a5dad5b434b.tar.gz gleam_stdlib-3546644ebcd8112b089555e69dcd7a5dad5b434b.zip |
Negative indexes in Erlang
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam_stdlib.erl | 53 | ||||
-rw-r--r-- | src/gleam_stdlib.js | 2 |
2 files changed, 37 insertions, 18 deletions
diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl index 92cae8e..2f234e7 100644 --- a/src/gleam_stdlib.erl +++ b/src/gleam_stdlib.erl @@ -59,24 +59,31 @@ classify(X) when is_integer(X) -> <<"Int">>; classify(X) when is_float(X) -> <<"Float">>; classify(X) when is_list(X) -> <<"List">>; classify(X) when is_boolean(X) -> <<"Bool">>; -classify(X) when is_function(X, 0) -> <<"zero arity function">>; -classify(X) when is_tuple(X) -> iolist_to_binary([integer_to_list(tuple_size(X)), " element tuple"]); -classify(_) -> "some other type". +classify(X) when is_map(X) -> <<"Map">>; +classify(X) when is_tuple(X) -> + iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); +classify(X) when + is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse + is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse + is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse + is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse + is_function(X, 12) -> <<"Function">>; +classify(_) -> "Some other type". decode_tuple2({_, _} = T) -> {ok, T}; -decode_tuple2(Data) -> decode_error_msg(<<"2 element tuple">>, Data). +decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). decode_tuple3({_, _, _} = T) -> {ok, T}; -decode_tuple3(Data) -> decode_error_msg(<<"3 element tuple">>, Data). +decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). decode_tuple4({_, _, _, _} = T) -> {ok, T}; -decode_tuple4(Data) -> decode_error_msg(<<"4 element tuple">>, Data). +decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). decode_tuple5({_, _, _, _, _} = T) -> {ok, T}; -decode_tuple5(Data) -> decode_error_msg(<<"5 element tuple">>, Data). +decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). decode_tuple6({_, _, _, _, _, _} = T) -> {ok, T}; -decode_tuple6(Data) -> decode_error_msg(<<"6 element tuple">>, Data). +decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). decode_map(Data) when is_map(Data) -> {ok, Data}; decode_map(Data) -> decode_error_msg(<<"Map">>, Data). @@ -108,16 +115,28 @@ decode_field(Data, Key) -> decode_error_msg(io_lib:format("a map with key `~p`", [Key]), Data) end. -decode_element(Data, Position) when is_tuple(Data) -> - case catch element(Position + 1, Data) of - {'EXIT', _Reason} -> - Msg = ["Tuple of at least ", integer_to_list(Position + 1), " elements"], - decode_error_msg(list_to_binary(Msg), Data); - - Value -> - {ok, Value} +decode_element(Data, Index) when is_tuple(Data) -> + Error = fun(Size) -> + S = case Size of + 1 -> "s"; + _ -> "" + end, + Msg = list_to_binary(["Tuple of at least ", integer_to_list(Size), S, " elements"]), + decode_error_msg(Msg, Data) + end, + Size = tuple_size(Data), + case Index >= 0 of + true -> case Index < Size of + true -> {ok, element(Index + 1, Data)}; + false -> Error(Index + 1) + end; + false -> case abs(Index) < Size of + true -> {ok, element(Size + Index + 1, Data)}; + false -> Error(abs(Index)) + end end; -decode_element(Data, _Position) -> decode_error_msg(<<"Tuple">>, Data). +decode_element(Data, _Position) -> + decode_error_msg(<<"Tuple of at least 1 element">>, Data). decode_optional(Term, F) -> Decode = fun(Inner) -> diff --git a/src/gleam_stdlib.js b/src/gleam_stdlib.js index 9a80a6d..7ecbe11 100644 --- a/src/gleam_stdlib.js +++ b/src/gleam_stdlib.js @@ -521,7 +521,7 @@ export function decode_bit_string(data) { export function decode_element(data, index) { let error = (size) => decoder_error( - `Tuple of at least ${size} element${size > 1 ? "s" : ""}`, + `Tuple of at least ${size} element${size == 1 ? "" : "s"}`, data ); if (!Array.isArray(data)) return error(index < 0 ? 1 : index + 1); |