From de9180fecadaa0e5f06749d8949f7e905fae6ee3 Mon Sep 17 00:00:00 2001
From: Jan Max Meyer <jmm@phorward.de>
Date: Tue, 17 Dec 2024 10:31:12 +0100
Subject: [PATCH] fix+doc: docs for `dict()`, removed `dict_push()`

---
 src/_builtins.rs  |  6 +--
 src/value/dict.rs | 99 ++++++++++++++++++++++++++++++++---------------
 tests/dict.tok    | 27 ++++++-------
 3 files changed, 80 insertions(+), 52 deletions(-)

diff --git a/src/_builtins.rs b/src/_builtins.rs
index d34eb07..12f5ca6 100644
--- a/src/_builtins.rs
+++ b/src/_builtins.rs
@@ -6,7 +6,7 @@
 use crate::builtin::Builtin;
 
 /*GENERATE cargo run -- _builtins.tok -- `find . -name "*.rs"` */
-pub static BUILTINS: [Builtin; 69] = [
+pub static BUILTINS: [Builtin; 68] = [
     Builtin {
         name: "Float",
         func: crate::value::token::tokay_token_float,
@@ -83,10 +83,6 @@ pub static BUILTINS: [Builtin; 69] = [
         name: "dict_pop",
         func: crate::value::dict::Dict::tokay_method_dict_pop,
     },
-    Builtin {
-        name: "dict_push",
-        func: crate::value::dict::Dict::tokay_method_dict_push,
-    },
     Builtin {
         name: "dict_set_item",
         func: crate::value::dict::Dict::tokay_method_dict_set_item,
diff --git a/src/value/dict.rs b/src/value/dict.rs
index ab846e9..422b84e 100644
--- a/src/value/dict.rs
+++ b/src/value/dict.rs
@@ -81,6 +81,7 @@ impl Object for Dict {
     }
 }
 
+#[allow(unused_doc_comments)]
 impl Dict {
     pub fn new() -> Self {
         Self {
@@ -100,8 +101,25 @@ impl Dict {
         self.shift_remove(&RefValue::from(key)) // fixme: improve lookup!
     }
 
-    tokay_method!("dict : @", Ok(RefValue::from(Dict::new())));
+    /** Creates a new `dict`.
 
+    Any provided `nargs` become key-value-pairs in the newly created dict.
+
+    This can also be shortcut by the `()` syntax.
+    */
+    tokay_method!(
+        "dict : @**nargs",
+        Ok(RefValue::from(if let Some(nargs) = nargs {
+            nargs.clone()
+        } else {
+            Dict::new()
+        }))
+    );
+
+    /** Creates an iterator over a `dict`.
+
+    The iterator is a method-iterator calling `iter_values()`.
+    */
     tokay_method!("dict_iter : @dict", {
         // If index is void, create an iterator on keys.
         if dict.is("dict") {
@@ -121,6 +139,7 @@ impl Dict {
         }
     });
 
+    /// Returns the number of items in the `dict`.
     tokay_method!("dict_len : @dict", {
         let dict = dict.borrow();
 
@@ -136,6 +155,7 @@ impl Dict {
         }
     });
 
+    /// Clone `dict` into a standalone copy.
     tokay_method!("dict_clone : @dict", {
         let dict = dict.borrow();
 
@@ -151,7 +171,12 @@ impl Dict {
         }
     });
 
-    // Method to retrieve or iterate the keys of a dict.
+    /** Retrieve or iterate the keys of a `dict`.
+
+    When no `index` is given, the method returns an iterator over the keys.
+    Otherwise, the key at the provided `index` is returned, or `default` in
+    case the `index` is out of bounds.
+    */
     tokay_method!("dict_keys : @dict, index=void, default=void", {
         // If index is void, create an iterator on keys.
         if index.is_void() {
@@ -181,7 +206,12 @@ impl Dict {
         }
     });
 
-    // Method to retrieve or iterate the values of a dict.
+    /** Retrieve or iterate the values of a `dict`.
+
+    When no `index` is given, the method returns an iterator over the values.
+    Otherwise, the value at the provided `index` is returned, or `default` in
+    case the `index` is out of bounds.
+    */
     tokay_method!("dict_values : @dict, index=void, default=void", {
         // If index is void, create an iterator on keys.
         if index.is_void() {
@@ -211,7 +241,14 @@ impl Dict {
         }
     });
 
-    // Method to retrieve or iterate a list of [key, value] from a dict by index
+    /** Retrieve or iterate both keys and values of a `dict`.
+
+    The function returns a list of key-value for each result.
+
+    When no `index` is given, the method returns an iterator over the key-value-pairs.
+    Otherwise, the key-value-pair at the provided `index` is returned, or `default` in
+    case the `index` is out of bounds.
+    */
     tokay_method!("dict_items : @dict, index=void, default=void", {
         // If index is void, create an iterator on items.
         if index.is_void() {
@@ -241,12 +278,16 @@ impl Dict {
         }
     });
 
-    tokay_method!("dict_get_item : @dict, item, default=void", {
-        if !item.is_hashable() {
+    /** Retrieve item with `key` from `dict`. Returns `default` when key is not found.
+
+    This method is also invoked when using the `dict` item syntax.
+    */
+    tokay_method!("dict_get_item : @dict, key, default=void", {
+        if !key.is_hashable() {
             return Err(Error::from(format!(
                 "{} unhashable type '{}'",
                 __function,
-                item.name()
+                key.name()
             )));
         }
 
@@ -254,8 +295,8 @@ impl Dict {
         let dict = dict.borrow();
 
         if let Some(dict) = dict.object::<Dict>() {
-            if let Some(item) = dict.get(&item) {
-                Ok(item.clone())
+            if let Some(key) = dict.get(&key) {
+                Ok(key.clone())
             } else {
                 Ok(default)
             }
@@ -269,12 +310,21 @@ impl Dict {
         }
     });
 
-    tokay_method!("dict_set_item : @dict, item, value=void", {
-        if !item.is_hashable() {
+    /** Insert or replace `value` under the given `key` in `dict`.
+
+    When `value` is provided as void, the key is removed.
+
+    Returns the previous item's value if the key already existed in `dict`,
+    otherwise void.
+
+    This method is also invoked when assigning to a `dict` item.
+    */
+    tokay_method!("dict_set_item : @dict, key, value=void", {
+        if !key.is_hashable() {
             return Err(Error::from(format!(
                 "{} unhashable type '{}'",
                 __function,
-                item.name()
+                key.name()
             )));
         }
 
@@ -282,10 +332,10 @@ impl Dict {
 
         if let Some(dict) = dict.object_mut::<Dict>() {
             if value.is_void() {
-                dict.shift_remove(&item);
+                dict.shift_remove(&key);
                 Ok(value![void])
             } else {
-                dict.insert(item, value.clone());
+                dict.insert(key, value.clone());
                 Ok(value)
             }
         } else {
@@ -298,6 +348,7 @@ impl Dict {
         }
     });
 
+    /** Merges dict `other` into `dict`. */
     tokay_method!("dict_merge : @dict, other", {
         {
             let dict = &mut *dict.borrow_mut();
@@ -330,25 +381,9 @@ impl Dict {
         Ok(dict)
     });
 
-    tokay_method!("dict_push : @dict, key, value", {
-        let dict = &mut *dict.borrow_mut();
-
-        if let Some(dict) = dict.object_mut::<Dict>() {
-            Ok(if let Some(old) = dict.insert(key, value) {
-                old
-            } else {
-                value!(void)
-            })
-        } else {
-            Err(Error::from(format!(
-                "{} only accepts '{}' as parameter, not '{}'",
-                __function,
-                "dict",
-                dict.name()
-            )))
-        }
-    });
+    /** Returns and removes `key` from `dict`.
 
+    When the given `key` does not exist, `default` will be returned, */
     tokay_method!("dict_pop : @dict, key=void, default=void", {
         let dict = &mut *dict.borrow_mut();
 
diff --git a/tests/dict.tok b/tests/dict.tok
index 164b9cd..667926d 100644
--- a/tests/dict.tok
+++ b/tests/dict.tok
@@ -19,6 +19,9 @@ x : 10
 d = (b => 3 c => 1 a => 2)
 d
 
+dict()
+dict(a=1, b=2, c=3)
+
 ## Comparison
 
 a = (a => 1 b => 2)
@@ -83,6 +86,8 @@ d = (a => 1  b => 2)
 d.len()
 dict_len("Donkey")  # invalid
 
+# iter / values
+
 list(iter(d))
 list(d.values)
 d.values(0)
@@ -90,12 +95,16 @@ d.values(1)
 type(d.values(2))
 d.values(2, default="Esel")
 
+# keys
+
 list(d.keys)
 d.keys(0)
 d.keys(1)
 type(d.keys(2))
 d.keys(2, default="Esel")
 
+# items
+
 list(d.items)
 d.items(0)
 d.items(1)
@@ -119,18 +128,6 @@ d
 d.merge(d)
 (a => 23 b => 42) $1.merge($1)
 
-## push
-
-d = dict()
-d.push(1, 2)
-d.push(2, 3)
-d
-
-d = dict()
-d.push(1, 2)
-d.push(2, 3)
-d.push(1, 4)
-
 ## pop
 
 d = ("esel" => 1 "bert" => 2 "edgar" => 42 "klaus" => 23)
@@ -157,6 +154,9 @@ d
 
 #(b => 3 c => 1 a => 2)
 
+#()
+#(a => 1 b => 2 c => 3)
+
 #(true, true, true, false, true, true, true, true, true, true)
 
 #"John"
@@ -203,9 +203,6 @@ d
 #(a => 1 b => 2 c => 3)
 #((a => 23 b => 42), (a => 23 b => 42))
 
-#(1 => 2 2 => 3)
-#2
-
 #(esel => 1 bert => 2 edgar => 42 klaus => 23)
 #"eugen"
 #2