@@ -177,6 +177,7 @@ static term nif_erlang_setnode_2(Context *ctx, int argc, term argv[]);
177
177
static term nif_erlang_memory (Context * ctx , int argc , term argv []);
178
178
static term nif_erlang_monitor (Context * ctx , int argc , term argv []);
179
179
static term nif_erlang_demonitor (Context * ctx , int argc , term argv []);
180
+ static term nif_erlang_list_to_bitstring_1 (Context * ctx , int argc , term argv []);
180
181
static term nif_erlang_unlink (Context * ctx , int argc , term argv []);
181
182
static term nif_atomvm_add_avm_pack_binary (Context * ctx , int argc , term argv []);
182
183
static term nif_atomvm_add_avm_pack_file (Context * ctx , int argc , term argv []);
@@ -197,6 +198,9 @@ static term nif_code_ensure_loaded(Context *ctx, int argc, term argv[]);
197
198
static term nif_erlang_module_loaded (Context * ctx , int argc , term argv []);
198
199
static term nif_erlang_nif_error (Context * ctx , int argc , term argv []);
199
200
static term nif_lists_reverse (Context * ctx , int argc , term argv []);
201
+ static term nif_lists_keyfind (Context * ctx , int argc , term argv []);
202
+ static term nif_lists_keymember (Context * ctx , int argc , term argv []);
203
+ static term nif_lists_member (Context * ctx , int argc , term argv []);
200
204
static term nif_maps_from_keys (Context * ctx , int argc , term argv []);
201
205
static term nif_maps_next (Context * ctx , int argc , term argv []);
202
206
static term nif_unicode_characters_to_list (Context * ctx , int argc , term argv []);
@@ -764,6 +768,22 @@ static const struct Nif erlang_lists_subtract_nif = {
764
768
.base .type = NIFFunctionType ,
765
769
.nif_ptr = nif_erlang_lists_subtract
766
770
};
771
+ static const struct Nif lists_member_nif = {
772
+ .base .type = NIFFunctionType ,
773
+ .nif_ptr = nif_lists_member
774
+ };
775
+ static const struct Nif lists_keymember_nif = {
776
+ .base .type = NIFFunctionType ,
777
+ .nif_ptr = nif_lists_keymember
778
+ };
779
+ static const struct Nif lists_keyfind_nif = {
780
+ .base .type = NIFFunctionType ,
781
+ .nif_ptr = nif_lists_keyfind
782
+ };
783
+ static const struct Nif list_to_bitstring_nif = {
784
+ .base .type = NIFFunctionType ,
785
+ .nif_ptr = nif_erlang_list_to_bitstring_1
786
+ };
767
787
static const struct Nif zlib_compress_nif = {
768
788
.base .type = NIFFunctionType ,
769
789
.nif_ptr = nif_zlib_compress_1
@@ -5824,6 +5844,97 @@ static term nif_erlang_lists_subtract(Context *ctx, int argc, term argv[])
5824
5844
return result ;
5825
5845
}
5826
5846
5847
+ static term nif_lists_member (Context * ctx , int argc , term argv [])
5848
+ {
5849
+ UNUSED (argc )
5850
+ term elem = argv [0 ];
5851
+ term list = argv [1 ];
5852
+
5853
+ while (term_is_nonempty_list (list )) {
5854
+ term head = term_get_list_head (list );
5855
+
5856
+ TermCompareResult cmp_result = term_compare (head , elem , TermCompareExact , ctx -> global );
5857
+
5858
+ if (cmp_result == TermEquals ) {
5859
+ return TRUE_ATOM ;
5860
+ }
5861
+
5862
+ if (UNLIKELY (cmp_result == TermCompareMemoryAllocFail )) {
5863
+ RAISE_ERROR (OUT_OF_MEMORY_ATOM );
5864
+ }
5865
+
5866
+ list = term_get_list_tail (list );
5867
+ }
5868
+
5869
+ VALIDATE_VALUE (list , term_is_nil );
5870
+
5871
+ return FALSE_ATOM ;
5872
+ }
5873
+
5874
+ static term nif_lists_keymember (Context * ctx , int argc , term argv [])
5875
+ {
5876
+ term result = nif_lists_keyfind (ctx , argc , argv );
5877
+ if (UNLIKELY (term_is_invalid_term (result ))) {
5878
+ return result ;
5879
+ }
5880
+ return result == FALSE_ATOM ? FALSE_ATOM : TRUE_ATOM ;
5881
+ }
5882
+
5883
+ static term nif_lists_keyfind (Context * ctx , int argc , term argv [])
5884
+ {
5885
+ UNUSED (argc )
5886
+ term key = argv [0 ];
5887
+ term n = argv [1 ];
5888
+ term tuple_list = argv [2 ];
5889
+
5890
+ VALIDATE_VALUE (n , term_is_integer );
5891
+
5892
+ avm_int_t n_pos = term_to_int (n );
5893
+
5894
+ if (n_pos <= 0 ) {
5895
+ RAISE_ERROR (BADARG_ATOM );
5896
+ }
5897
+
5898
+ while (term_is_nonempty_list (tuple_list )) {
5899
+ term tuple = term_get_list_head (tuple_list );
5900
+
5901
+ if (!term_is_tuple (tuple )) {
5902
+ tuple_list = term_get_list_tail (tuple_list );
5903
+ continue ;
5904
+ }
5905
+
5906
+ int tuple_size = term_get_tuple_arity (tuple );
5907
+
5908
+ if (n_pos > tuple_size ) {
5909
+ tuple_list = term_get_list_tail (tuple_list );
5910
+ continue ;
5911
+ }
5912
+
5913
+ term nth_element = term_get_tuple_element (tuple , n_pos - 1 );
5914
+
5915
+ TermCompareResult cmp_result = term_compare (nth_element , key , TermCompareExact , ctx -> global );
5916
+
5917
+ if (cmp_result == TermEquals ) {
5918
+ return tuple ;
5919
+ }
5920
+ if (UNLIKELY (cmp_result == TermCompareMemoryAllocFail )) {
5921
+ RAISE_ERROR (OUT_OF_MEMORY_ATOM );
5922
+ }
5923
+
5924
+ tuple_list = term_get_list_tail (tuple_list );
5925
+ }
5926
+
5927
+ VALIDATE_VALUE (tuple_list , term_is_nil );
5928
+
5929
+ return FALSE_ATOM ;
5930
+ }
5931
+
5932
+ static term nif_erlang_list_to_bitstring_1 (Context * ctx , int argc , term argv [])
5933
+ {
5934
+ // TODO: implement proper list_to_bitstring function when the bitstrings are supported
5935
+ return nif_erlang_list_to_binary_1 (ctx , argc , argv );
5936
+ }
5937
+
5827
5938
#ifdef WITH_ZLIB
5828
5939
static term nif_zlib_compress_1 (Context * ctx , int argc , term argv [])
5829
5940
{
0 commit comments