bbc-basic: Add 'dissoc' and 'vals' core functions.
authorBen Harris <bjh21@bjh21.me.uk>
Sun, 12 May 2019 20:52:15 +0000 (21:52 +0100)
committerBen Harris <bjh21@bjh21.me.uk>
Sat, 18 May 2019 04:48:32 +0000 (05:48 +0100)
bbc-basic/core
bbc-basic/types

index cef923d..554afb1 100644 (file)
@@ -208,6 +208,14 @@ DEF FNcore_call(fn%, args%)
     WHEN 45
       PROCcore_prepare_args("h*", "assoc")
       =FNcore_assoc(args%(0), args%)
+    DATA dissoc, 46
+    WHEN 46
+      PROCcore_prepare_args("h*", "dissoc")
+      WHILE NOT FNis_empty(args%)
+        args%(0) = FNhashmap_remove(args%(0), FNunbox_string(FNfirst(args%)))
+        args% = FNrest(args%)
+      ENDWHILE
+      =args%(0)
     DATA get, 47
     WHEN 47
       IF FNis_nil(FNfirst(args%)) THEN =FNnil
@@ -221,6 +229,10 @@ DEF FNcore_call(fn%, args%)
     WHEN 49
       PROCcore_prepare_args("h", "keys")
       =FNhashmap_keys(args%(0))
+    DATA vals, 50
+    WHEN 50
+      PROCcore_prepare_args("h", "vals")
+      =FNhashmap_vals(args%(0))
     DATA "", -1
   ENDCASE
 ERROR &40E809F1, "Call to non-existent core function"
index 54ca929..e77516e 100644 (file)
@@ -484,6 +484,23 @@ DEF FNhashmap_set(map%, key$, val%)
     =FNhashmap_alloc_node(Z%(map%,0)>>16, FNhashmap_set(Z%(map%,1), key$, val%), Z%(map%,2))
   ENDIF
 
+DEF FNhashmap_remove(map%, key$)
+  LOCAL child%
+  IF FNis_empty_hashmap(map%) THEN =map%
+  IF FNtype_of(map%) = &0A THEN
+    IF S$(Z%(map%,1)) = key$ THEN =FNempty_hashmap
+  ENDIF
+  IF FNkey_bit(key$, Z%(map%,0) >> 16) THEN
+    child% = FNhashmap_remove(Z%(map%,2), key$)
+    IF FNis_empty_hashmap(child%) THEN =Z%(map%,1)
+    =FNhashmap_alloc_node(Z%(map%,0)>>16, Z%(map%,1), child%)
+  ELSE
+    child% = FNhashmap_remove(Z%(map%,1), key$)
+    IF FNis_empty_hashmap(child%) THEN =Z%(map%,2)
+    =FNhashmap_alloc_node(Z%(map%,0)>>16, child%, Z%(map%,2))
+  ENDIF
+
+
 DEF FNhashmap_get(map%, key$)
   IF NOT FNis_hashmap(map%) THEN ERROR &40E80918, "Can't get item from a non-hashmap"
   IF FNis_empty_hashmap(map%) THEN =FNnil
@@ -513,6 +530,17 @@ DEF FNhashmap_keys1(map%, acc%)
   ENDIF
 =FNhashmap_keys1(Z%(map%,2), FNhashmap_keys1(Z%(map%,1), acc%))
 
+DEF FNhashmap_vals(map%)
+=FNhashmap_vals1(map%, FNempty)
+
+DEF FNhashmap_vals1(map%, acc%)
+  REM PROChashmap_dump(map%)
+  IF FNis_empty_hashmap(map%) THEN =acc%
+  IF FNtype_of(map%) = &0A THEN
+    =FNalloc_pair(Z%(map%,2), acc%)
+  ENDIF
+=FNhashmap_vals1(Z%(map%,2), FNhashmap_vals1(Z%(map%,1), acc%))
+
 DEF PROChashmap_dump(map%)
   IF FNis_empty_hashmap(map%) THEN
     PRINT "[empty]"