Closed notwa closed 2 years ago
Supporting the keyword arguments initializer is a straightforward change, as keyword arguments are already passed to C function implementations as a dictionary:
diff --git a/src/obj_dict.c b/src/obj_dict.c
index 2f6b9dd..1338a57 100644
--- a/src/obj_dict.c
+++ b/src/obj_dict.c
@@ -39,9 +39,13 @@ static void _dict_gcsweep(KrkInstance * self) {
#define CURRENT_NAME self
KRK_METHOD(dict,__init__,{
- METHOD_TAKES_NONE();
- krk_initTable(&self->entries);
- return argv[0];
+ if (hasKw) {
+ return argv[argc];
+ } else {
+ METHOD_TAKES_NONE();
+ krk_initTable(&self->entries);
+ return argv[0];
+ }
})
KRK_METHOD(dict,__getitem__,{
The iterable
and mapping
initializers are a bit less straightforward. iterable
inputs should be doable, though mapping
s I think I'm missing plumbing for.
>>> dict(((1,2),))
=> {1: 2}
>>> dict(((1,2),),a=42)
=> {1: 2, 'a': 42}
>>> dict(((1,2),(3,4),(5,6)),a=42)
=> {1: 2, 'a': 42, 3: 4, 5: 6}
>>> let keys = ("key", "this")
=> ('key', 'this')
>>> let values = ("value", "that")
=> ('value', 'that')
>>> print(dict(zip(keys, values)))
{'this': 'that', 'key': 'value'}
diff --git a/src/obj_dict.c b/src/obj_dict.c
index 8fb4182..a1156f0 100644
--- a/src/obj_dict.c
+++ b/src/obj_dict.c
@@ -38,14 +38,45 @@ static void _dict_gcsweep(KrkInstance * self) {
#define CURRENT_CTYPE KrkDict *
#define CURRENT_NAME self
+#define unpackArray(counter, indexer) do { \
+ for (size_t i = 0; i < counter; ++i) { \
+ if (keyOrValue == 0) { keyOrValue = 1; key = indexer; } \
+ else if (keyOrValue == 1) { keyOrValue = 0; krk_tableSet(&self->entries, key, indexer); } \
+ if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return 1; \
+ } \
+ } while (0)
+static int unpackKeyValuePair(KrkDict * self, KrkValue pair) {
+ KrkValue key;
+ int keyOrValue = 0;
+ unpackIterableFast(pair);
+ return 0;
+}
+#undef unpackArray
+
+#define unpackArray(counter, indexer) do { \
+ for (size_t i = 0; i < counter; ++i) { \
+ if (unpackKeyValuePair(self, indexer) || (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION)) \
+ return 1; \
+ } \
+ } while (0)
+static int unpackKeyValueSequence(KrkDict * self, KrkValue array) {
+ unpackIterableFast(array);
+ return 0;
+}
+#undef unpackArray
+
KRK_METHOD(dict,__init__,{
+ METHOD_TAKES_AT_MOST(1);
+ krk_initTable(&self->entries);
+
+ if (argc > 1) {
+ if (unpackKeyValueSequence(self, argv[1])) return NONE_VAL();
+ }
+
if (hasKw) {
- return argv[argc];
- } else {
- METHOD_TAKES_NONE();
- krk_initTable(&self->entries);
- return argv[0];
+ krk_tableAddAll(AS_DICT(argv[argc]), &self->entries);
}
+ return argv[0];
})
KRK_METHOD(dict,__getitem__,{
compared to Python 3,
the
dict
built-in does not take arguments (and raises an error; fair enough).thefixed!dict
built-in silently ignores keyword arguments. this is my motivation for writing this issue.