From 41c99b373dd049be8f644524d2f5c187919e6c91 Mon Sep 17 00:00:00 2001 From: Jason_000 Date: Mon, 5 Jul 2021 18:49:14 +0100 Subject: [PATCH 1/7] Fix printing bound methods --- src/vm/object.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vm/object.c b/src/vm/object.c index 033f10fc..9ccc4ca0 100644 --- a/src/vm/object.c +++ b/src/vm/object.c @@ -537,32 +537,32 @@ char *objectToString(Value value) { char *methodString; if (method->method->function->name != NULL) { - methodString = malloc(sizeof(char) * (method->method->function->name->length + 17)); - switch (method->method->function->type) { case TYPE_STATIC: { - snprintf(methodString, method->method->function->name->length + 17, "", method->method->function->name->chars); + methodString = malloc(sizeof(char) * (method->method->function->name->length + 17)); + snprintf(methodString, method->method->function->name->length + 17, "", method->method->function->name->chars); break; } default: { - snprintf(methodString, method->method->function->name->length + 17, "", method->method->function->name->chars); + methodString = malloc(sizeof(char) * (method->method->function->name->length + 16)); + snprintf(methodString, method->method->function->name->length + 16, "", method->method->function->name->chars); break; } } } else { - methodString = malloc(sizeof(char) * 16); - switch (method->method->function->type) { case TYPE_STATIC: { + methodString = malloc(sizeof(char) * 16); memcpy(methodString, "", 15); methodString[15] = '\0'; break; } default: { - memcpy(methodString, "", 15); - methodString[15] = '\0'; + methodString = malloc(sizeof(char) * 15); + memcpy(methodString, "", 14); + methodString[14] = '\0'; break; } } From ad89531d8ec31bae1be56927de17ba0f50db4ed5 Mon Sep 17 00:00:00 2001 From: Jason_000 Date: Tue, 6 Jul 2021 23:29:03 +0100 Subject: [PATCH 2/7] Add dict.forEach --- src/vm/datatypes/dicts/dict-source.h | 14 ++++++++++++++ src/vm/datatypes/dicts/dict.du | 13 +++++++++++++ src/vm/datatypes/{ => dicts}/dicts.c | 20 ++++++++++++++++++++ src/vm/datatypes/{ => dicts}/dicts.h | 4 ++-- src/vm/datatypes/generate.du | 1 + src/vm/vm.c | 14 ++++++++++++-- 6 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 src/vm/datatypes/dicts/dict-source.h create mode 100644 src/vm/datatypes/dicts/dict.du rename src/vm/datatypes/{ => dicts}/dicts.c (87%) rename src/vm/datatypes/{ => dicts}/dicts.h (79%) diff --git a/src/vm/datatypes/dicts/dict-source.h b/src/vm/datatypes/dicts/dict-source.h new file mode 100644 index 00000000..6c0d320c --- /dev/null +++ b/src/vm/datatypes/dicts/dict-source.h @@ -0,0 +1,14 @@ +#define DICTU_DICT_SOURCE "/**\n" \ +" * This file contains all the methods for Lists written in Dictu that\n" \ +" * are unable to be written in C due to re-enterability issues.\n" \ +" *\n" \ +" * We should always strive to write methods in C where possible.\n" \ +" */\n" \ +"def forEach(dict, func) {\n" \ +" const dictKeys = dict.keys();\n" \ +"\n" \ +" for (var i = 0; i < dictKeys.len(); i += 1) {\n" \ +" func(dictKeys[i], dict[dictKeys[i]]);\n" \ +" }\n" \ +"}\n" \ + diff --git a/src/vm/datatypes/dicts/dict.du b/src/vm/datatypes/dicts/dict.du new file mode 100644 index 00000000..7259499a --- /dev/null +++ b/src/vm/datatypes/dicts/dict.du @@ -0,0 +1,13 @@ +/** + * This file contains all the methods for Lists written in Dictu that + * are unable to be written in C due to re-enterability issues. + * + * We should always strive to write methods in C where possible. + */ +def forEach(dict, func) { + const dictKeys = dict.keys(); + + for (var i = 0; i < dictKeys.len(); i += 1) { + func(dictKeys[i], dict[dictKeys[i]]); + } +} \ No newline at end of file diff --git a/src/vm/datatypes/dicts.c b/src/vm/datatypes/dicts/dicts.c similarity index 87% rename from src/vm/datatypes/dicts.c rename to src/vm/datatypes/dicts/dicts.c index 62a6956f..9fdc93df 100644 --- a/src/vm/datatypes/dicts.c +++ b/src/vm/datatypes/dicts/dicts.c @@ -1,5 +1,15 @@ #include "dicts.h" +/* + * Note: We should try to implement everything we can in C + * rather than in the host language as C will always + * be faster than Dictu, and there will be extra work + * at startup running the Dictu code, however compromises + * must be made due to the fact the VM is not re-enterable + */ + +#include "dict-source.h" + static Value toStringDict(DictuVM *vm, int argCount, Value *args) { if (argCount != 0) { runtimeError(vm, "toString() takes no arguments (%d given)", argCount); @@ -156,4 +166,14 @@ void declareDictMethods(DictuVM *vm) { defineNative(vm, &vm->dictMethods, "copy", copyDictShallow); defineNative(vm, &vm->dictMethods, "deepCopy", copyDictDeep); defineNative(vm, &vm->dictMethods, "toBool", boolNative); // Defined in util + + dictuInterpret(vm, "Dict", DICTU_DICT_SOURCE); + + Value Dict; + tableGet(&vm->modules, copyString(vm, "Dict", 4), &Dict); + + ObjModule *DictModule = AS_MODULE(Dict); + push(vm, Dict); + tableAddAll(vm, &DictModule->values, &vm->dictMethods); + pop(vm); } diff --git a/src/vm/datatypes/dicts.h b/src/vm/datatypes/dicts/dicts.h similarity index 79% rename from src/vm/datatypes/dicts.h rename to src/vm/datatypes/dicts/dicts.h index 38431720..0238f139 100644 --- a/src/vm/datatypes/dicts.h +++ b/src/vm/datatypes/dicts/dicts.h @@ -5,8 +5,8 @@ #include #include -#include "copy.h" -#include "../util.h" +#include "../copy.h" +#include "../../util.h" void declareDictMethods(DictuVM *vm); diff --git a/src/vm/datatypes/generate.du b/src/vm/datatypes/generate.du index f29a0ee1..775efe8c 100644 --- a/src/vm/datatypes/generate.du +++ b/src/vm/datatypes/generate.du @@ -27,6 +27,7 @@ def generate(filename) { var files = [ 'lists/list', + 'dicts/dict', 'result/result' ]; diff --git a/src/vm/vm.c b/src/vm/vm.c index 0beb497d..d942782d 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -17,7 +17,7 @@ #include "datatypes/nil.h" #include "datatypes/strings.h" #include "datatypes/lists/lists.h" -#include "datatypes/dicts.h" +#include "datatypes/dicts/dicts.h" #include "datatypes/sets.h" #include "datatypes/files.h" #include "datatypes/class.h" @@ -501,7 +501,17 @@ static bool invoke(DictuVM *vm, ObjString *name, int argCount) { case OBJ_DICT: { Value value; if (tableGet(&vm->dictMethods, name, &value)) { - return callNativeMethod(vm, value, argCount); + if (IS_NATIVE(value)) { + return callNativeMethod(vm, value, argCount); + } + + push(vm, peek(vm, 0)); + + for (int i = 2; i <= argCount + 1; i++) { + vm->stackTop[-i] = peek(vm, i); + } + + return call(vm, AS_CLOSURE(value), argCount + 1); } runtimeError(vm, "Dict has no method %s().", name->chars); From 6e0830057d12b7567a7eade9921eaacd4d0fea34 Mon Sep 17 00:00:00 2001 From: Jason_000 Date: Wed, 7 Jul 2021 00:00:10 +0100 Subject: [PATCH 3/7] Add documentation and tests for dict.forEach --- docs/docs/collections/dictionaries.md | 13 +++++++++++++ tests/dicts/forEach.du | 27 +++++++++++++++++++++++++++ tests/dicts/import.du | 1 + 3 files changed, 41 insertions(+) create mode 100644 tests/dicts/forEach.du diff --git a/docs/docs/collections/dictionaries.md b/docs/docs/collections/dictionaries.md index 9f7359ca..63c850e6 100644 --- a/docs/docs/collections/dictionaries.md +++ b/docs/docs/collections/dictionaries.md @@ -130,4 +130,17 @@ This is the exact same scenario as lists, so refer to [copying Lists](#copying-l var myDict = {"key": {"test": 10}}; var myDict1 = myDict.copy(); // Shallow copy var myDict2 = myDict.deepCopy(); // Deep copy +``` + +### dict.forEach(func) + +To run a function on every element in a dictionary we use `.forEach`. The callback function +passed to `.forEach` expects two parameters which will be the key-value pair of the dictionary. + +```cs +const myDict = {"key": 1, "key1": 2}; + +myDict.forEach(def (key, value) => { + print("Key: {} Value: {}".format(key, value)); +}); ``` \ No newline at end of file diff --git a/tests/dicts/forEach.du b/tests/dicts/forEach.du new file mode 100644 index 00000000..4ea748be --- /dev/null +++ b/tests/dicts/forEach.du @@ -0,0 +1,27 @@ +/** + * forEach.du + * + * Testing the dict.forEach() method + * + * .forEach() loops over a dictionary + */ + +const myDict = {"key": 1, "key1": 2, "key2": 3}; +var count = 0; + +myDict.forEach(def (key, value) => { + count += 1; + assert(type(key) == "string"); + assert(type(value) == "number"); +}); + +assert(count == 3); + +const myNewDict = {1: 1, 2: 2, 3: 3}; +var sum = 0; + +myNewDict.forEach(def (key, value) => { + sum += key + value; +}); + +assert(sum == 12); diff --git a/tests/dicts/import.du b/tests/dicts/import.du index 71ef6496..6a0d39d2 100644 --- a/tests/dicts/import.du +++ b/tests/dicts/import.du @@ -13,3 +13,4 @@ import "copy.du"; import "len.du"; import "toString.du"; import "toBool.du"; +import "forEach.du"; From dd66c735cf22827eb237b420f9766f86fb8aec57 Mon Sep 17 00:00:00 2001 From: Jason_000 Date: Fri, 9 Jul 2021 16:06:13 +0100 Subject: [PATCH 4/7] Update dict.du --- src/vm/datatypes/dicts/dict.du | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vm/datatypes/dicts/dict.du b/src/vm/datatypes/dicts/dict.du index 7259499a..5730a8af 100644 --- a/src/vm/datatypes/dicts/dict.du +++ b/src/vm/datatypes/dicts/dict.du @@ -1,5 +1,5 @@ /** - * This file contains all the methods for Lists written in Dictu that + * This file contains all the methods for Dicts written in Dictu that * are unable to be written in C due to re-enterability issues. * * We should always strive to write methods in C where possible. @@ -10,4 +10,4 @@ def forEach(dict, func) { for (var i = 0; i < dictKeys.len(); i += 1) { func(dictKeys[i], dict[dictKeys[i]]); } -} \ No newline at end of file +} From c087164c522ba3d5526e844126905412831d6aa4 Mon Sep 17 00:00:00 2001 From: Jason_000 Date: Fri, 9 Jul 2021 16:06:30 +0100 Subject: [PATCH 5/7] Update dict-source.h --- src/vm/datatypes/dicts/dict-source.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm/datatypes/dicts/dict-source.h b/src/vm/datatypes/dicts/dict-source.h index 6c0d320c..022e782a 100644 --- a/src/vm/datatypes/dicts/dict-source.h +++ b/src/vm/datatypes/dicts/dict-source.h @@ -1,5 +1,5 @@ #define DICTU_DICT_SOURCE "/**\n" \ -" * This file contains all the methods for Lists written in Dictu that\n" \ +" * This file contains all the methods for Dicts written in Dictu that\n" \ " * are unable to be written in C due to re-enterability issues.\n" \ " *\n" \ " * We should always strive to write methods in C where possible.\n" \ From b1b9b34fd766ebda68d4486c8477e643e9d5e68c Mon Sep 17 00:00:00 2001 From: Jason_000 Date: Sun, 8 Aug 2021 16:20:52 +0100 Subject: [PATCH 6/7] Add DO sponsorship tags --- README.md | 7 +++++++ docs/docs/thank-you.md | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 docs/docs/thank-you.md diff --git a/README.md b/README.md index 8c5cbc45..0d6a935c 100644 --- a/README.md +++ b/README.md @@ -97,3 +97,10 @@ in the [DictuVSC repo](https://github.com/dictu-lang/DictuVSC). ## Credits This language was initially based on the very good [craftinginterpreters book](http://www.craftinginterpreters.com/contents.html), along with inspiration from [Wren](https://github.com/wren-lang/wren). + +

This project is supported by:

+

+ + + +

diff --git a/docs/docs/thank-you.md b/docs/docs/thank-you.md new file mode 100644 index 00000000..9c36143a --- /dev/null +++ b/docs/docs/thank-you.md @@ -0,0 +1,17 @@ +--- +layout: default +title: Thank you! +nav_order: 16 +--- + +# Thank You! +{: .no_toc } + +## DigitalOcean + +Dictu has been proudly sponsored by [DigitalOcean](https://m.do.co/c/02bd923f5cda). They are providing the project with a generous amount + of credits so that testing of the Dictu VM can be carried out across a number of different platform versions along with providing the use of + tooling that comes with these specific platforms. + +I've personally been using their services for many years prior to this sponsorship so can attest to their excellent service, so if you too wish + to sign up, you can do so via [this](https://m.do.co/c/02bd923f5cda) referral link! \ No newline at end of file From 4977ba5faee4f4771d5e41721ecfbc4b7dab5511 Mon Sep 17 00:00:00 2001 From: Jason_000 Date: Sun, 8 Aug 2021 16:25:32 +0100 Subject: [PATCH 7/7] Bump version to 0.20 --- docs/_config.yml | 2 +- src/include/dictu_include.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 835044e9..6871e498 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -5,7 +5,7 @@ description: >- color_scheme: "dictu" # Custom theme logo: "/assets/images/dictu-logo/dictu-wordmark.svg" -version: "0.19.0" +version: "0.20.0" github_username: dictu-lang search_enabled: true diff --git a/src/include/dictu_include.h b/src/include/dictu_include.h index 8181ef1f..67980dfc 100644 --- a/src/include/dictu_include.h +++ b/src/include/dictu_include.h @@ -4,7 +4,7 @@ #include #define DICTU_MAJOR_VERSION "0" -#define DICTU_MINOR_VERSION "19" +#define DICTU_MINOR_VERSION "20" #define DICTU_PATCH_VERSION "0" #define DICTU_STRING_VERSION "Dictu Version: " DICTU_MAJOR_VERSION "." DICTU_MINOR_VERSION "." DICTU_PATCH_VERSION "\n"