From 8c20b7229a5857c68a9be775fdbb75e22d1ef4e6 Mon Sep 17 00:00:00 2001 From: bakpakin Date: Wed, 12 Jul 2017 14:47:09 -0400 Subject: [PATCH] Refactor module and env code into separate files. --- Makefile | 2 +- client/main.c | 2 +- core/env.c | 134 +++++++++++++++++++++++++++++++++ core/module.c | 101 +++++++++++++++++++++++++ core/util.c | 198 ------------------------------------------------- libs/hello.gst | 4 +- 6 files changed, 239 insertions(+), 202 deletions(-) create mode 100644 core/env.c create mode 100644 core/module.c diff --git a/Makefile b/Makefile index 96e11e83..ab04bad9 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ all: $(GST_TARGET) ##### The core vm and runtime ##### ################################### GST_CORE_SOURCES=$(addprefix core/,\ - compile.c parse.c stl.c ids.c util.c\ + compile.c parse.c stl.c ids.c util.c env.c module.c\ value.c vm.c ds.c gc.c thread.c serialize.c\ string.c) GST_CORE_OBJECTS=$(patsubst %.c,%.o,$(GST_CORE_SOURCES)) diff --git a/client/main.c b/client/main.c index 7a13ab8f..2a5bf883 100644 --- a/client/main.c +++ b/client/main.c @@ -113,7 +113,7 @@ static int debug_run(Gst *vm, FILE *in, int64_t flags) { printf_flags(flags, "31", "parse error: unexpected end of source%s\n", ""); return 1; } - /* Otherwise we finished the file with no problems*/ + /* Otherwise we finished the file with no problems */ return 0; } reader = buffer; diff --git a/core/env.c b/core/env.c new file mode 100644 index 00000000..c637b525 --- /dev/null +++ b/core/env.c @@ -0,0 +1,134 @@ +/* +* Copyright (c) 2017 Calvin Rose +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include + +static GstTable *gst_env_keytab(Gst *vm, GstTable *env, const char *keyword) { + GstTable *tab; + GstValue key = gst_string_cv(vm, keyword); + GstValue maybeTab = gst_table_get(env, key); + if (maybeTab.type != GST_TABLE) { + tab = gst_table(vm, 10); + gst_table_put(vm, env, key, gst_wrap_table(tab)); + } else { + tab = maybeTab.data.table; + } + return tab; +} + +GstTable *gst_env_nils(Gst *vm, GstTable *env) { + return gst_env_keytab(vm, env, "nils"); +} + +GstTable *gst_env_meta(Gst *vm, GstTable *env) { + return gst_env_keytab(vm, env, "meta"); +} + +/* Add many global variables and bind to nil */ +static void mergenils(Gst *vm, GstTable *destEnv, GstTable *nils) { + const GstValue *data = nils->data; + uint32_t len = nils->capacity; + uint32_t i; + GstTable *destNils = gst_env_nils(vm, destEnv); + for (i = 0; i < len; i += 2) { + if (data[i].type == GST_SYMBOL) { + gst_table_put(vm, destEnv, data[i], gst_wrap_nil()); + gst_table_put(vm, destNils, data[i], gst_wrap_boolean(1)); + } + } +} + +/* Add many global variable metadata */ +static void mergemeta(Gst *vm, GstTable *destEnv, GstTable *meta) { + const GstValue *data = meta->data; + uint32_t len = meta->capacity; + uint32_t i; + GstTable *destMeta = gst_env_meta(vm, destEnv); + for (i = 0; i < len; i += 2) { + if (data[i].type == GST_SYMBOL) { + gst_table_put(vm, destMeta, data[i], data[i + 1]); + } + } +} + +/* Simple strequal between gst string ans c string, no 0s in b allowed */ +static int streq(const char *str, const uint8_t *b) { + uint32_t len = gst_string_length(b); + uint32_t i; + const uint8_t *ustr = (const uint8_t *)str; + for (i = 0; i < len; ++i) { + if (ustr[i] != b[i]) + return 0; + } + return 1; +} + +/* Add many global variables */ +void gst_env_merge(Gst *vm, GstTable *destEnv, GstTable *srcEnv) { + const GstValue *data = srcEnv->data; + uint32_t len = srcEnv->capacity; + uint32_t i; + for (i = 0; i < len; i += 2) { + if (data[i].type == GST_SYMBOL) { + gst_table_put(vm, destEnv, data[i], data[i + 1]); + } else if (data[i].type == GST_STRING) { + const uint8_t *k = data[i].data.string; + if (streq("nils", k)) { + if (data[i + 1].type == GST_TABLE) + mergenils(vm, destEnv, data[i + 1].data.table); + } else if (streq("meta", k)) { + if (data[i + 1].type == GST_TABLE) + mergemeta(vm, destEnv, data[i + 1].data.table); + } + } + } +} + +void gst_env_put(Gst *vm, GstTable *env, GstValue key, GstValue value) { + GstTable *meta = gst_env_meta(vm, env); + gst_table_put(vm, meta, key, gst_wrap_nil()); + gst_table_put(vm, env, key, value); + if (value.type == GST_NIL) { + gst_table_put(vm, gst_env_nils(vm, env), key, gst_wrap_boolean(1)); + } +} + +void gst_env_putc(Gst *vm, GstTable *env, const char *key, GstValue value) { + GstValue keyv = gst_string_cvs(vm, key); + gst_env_put(vm, env, keyv, value); +} + +void gst_env_putvar(Gst *vm, GstTable *env, GstValue key, GstValue value) { + GstTable *meta = gst_env_meta(vm, env); + GstTable *newmeta = gst_table(vm, 4); + GstArray *ref = gst_array(vm, 1); + ref->count = 1; + ref->data[0] = value; + gst_table_put(vm, env, key, gst_wrap_array(ref)); + gst_table_put(vm, newmeta, gst_string_cv(vm, "mutable"), gst_wrap_boolean(1)); + gst_table_put(vm, meta, key, gst_wrap_table(newmeta)); +} + +void gst_env_putvarc(Gst *vm, GstTable *env, const char *key, GstValue value) { + GstValue keyv = gst_string_cvs(vm, key); + gst_env_putvar(vm, env, keyv, value); +} \ No newline at end of file diff --git a/core/module.c b/core/module.c new file mode 100644 index 00000000..2bcec6e2 --- /dev/null +++ b/core/module.c @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2017 Calvin Rose +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include + +static void gst_cmodule_register(Gst *vm, const char *name, const GstModuleItem *mod) { + uint32_t startLength; + GstBuffer *buffer = gst_buffer(vm, 10); + gst_buffer_append_cstring(vm, buffer, name); + gst_buffer_push(vm, buffer, '.'); + startLength = buffer->count; + while (mod->name != NULL) { + GstValue key; + buffer->count = startLength; + gst_buffer_append_cstring(vm, buffer, mod->name); + key = gst_wrap_symbol(gst_buffer_to_string(vm, buffer)); + gst_table_put(vm, vm->registry, key, gst_wrap_cfunction(mod->data)); + gst_table_put(vm, vm->registry, gst_wrap_cfunction(mod->data), key); + mod++; + } +} + +static GstValue gst_cmodule_table(Gst *vm, const GstModuleItem *mod) { + GstTable *module = gst_table(vm, 10); + while (mod->name != NULL) { + GstValue key = gst_string_cvs(vm, mod->name); + gst_table_put(vm, module, key, gst_wrap_cfunction(mod->data)); + mod++; + } + return gst_wrap_table(module); +} + +static GstValue gst_cmodule_struct(Gst *vm, const GstModuleItem *mod) { + uint32_t count = 0; + const GstModuleItem *m = mod; + GstValue *st; + while (m->name != NULL) { + ++count; + ++m; + } + st = gst_struct_begin(vm, count); + m = mod; + while (m->name != NULL) { + gst_struct_put(st, + gst_string_cvs(vm, m->name), + gst_wrap_cfunction(m->data)); + ++m; + } + return gst_wrap_struct(gst_struct_end(vm, st)); +} + +void gst_module(Gst *vm, const char *packagename, const GstModuleItem *mod) { + gst_table_put(vm, vm->modules, gst_string_cvs(vm, packagename), gst_cmodule_struct(vm, mod)); + gst_cmodule_register(vm, packagename, mod); +} + +void gst_module_mutable(Gst *vm, const char *packagename, const GstModuleItem *mod) { + gst_table_put(vm, vm->modules, gst_string_cvs(vm, packagename), gst_cmodule_table(vm, mod)); + gst_cmodule_register(vm, packagename, mod); +} + +void gst_module_put(Gst *vm, const char *packagename, const char *name, GstValue v) { + GstValue modtable = gst_table_get(vm->modules, gst_string_cvs(vm, packagename)); + if (modtable.type == GST_TABLE) { + GstTable *table = modtable.data.table; + if (v.type == GST_CFUNCTION) { + GstValue key; + GstBuffer *buffer = gst_buffer(vm, 10); + gst_buffer_append_cstring(vm, buffer, packagename); + gst_buffer_push(vm, buffer, '.'); + gst_buffer_append_cstring(vm, buffer, name); + key = gst_wrap_string(gst_buffer_to_string(vm, buffer)); + gst_table_put(vm, vm->registry, key, v); + gst_table_put(vm, vm->registry, v, key); + } + gst_table_put(vm, table, gst_string_cvs(vm, name), v); + } +} + +GstValue gst_module_get(Gst *vm, const char *packagename) { + return gst_table_get(vm->modules, gst_string_cvs(vm, packagename)); +} \ No newline at end of file diff --git a/core/util.c b/core/util.c index d075302a..d2724785 100644 --- a/core/util.c +++ b/core/util.c @@ -89,7 +89,6 @@ void *gst_check_userdata(Gst *vm, uint32_t i, const GstUserType *type) { /* Parsing utils */ /****/ - /* Get an integer power of 10 */ static double exp10(int power) { if (power == 0) return 1; @@ -170,92 +169,6 @@ int gst_read_real(const uint8_t *string, const uint8_t *end, double *ret, int fo return 1; } -/****/ -/* Module utils */ -/****/ - -static void gst_cmodule_register(Gst *vm, const char *name, const GstModuleItem *mod) { - uint32_t startLength; - GstBuffer *buffer = gst_buffer(vm, 10); - gst_buffer_append_cstring(vm, buffer, name); - gst_buffer_push(vm, buffer, '.'); - startLength = buffer->count; - while (mod->name != NULL) { - GstValue key; - buffer->count = startLength; - gst_buffer_append_cstring(vm, buffer, mod->name); - key = gst_wrap_symbol(gst_buffer_to_string(vm, buffer)); - gst_table_put(vm, vm->registry, key, gst_wrap_cfunction(mod->data)); - gst_table_put(vm, vm->registry, gst_wrap_cfunction(mod->data), key); - mod++; - } -} - -static GstValue gst_cmodule_table(Gst *vm, const GstModuleItem *mod) { - GstTable *module = gst_table(vm, 10); - while (mod->name != NULL) { - GstValue key = gst_string_cvs(vm, mod->name); - gst_table_put(vm, module, key, gst_wrap_cfunction(mod->data)); - mod++; - } - return gst_wrap_table(module); -} - -static GstValue gst_cmodule_struct(Gst *vm, const GstModuleItem *mod) { - uint32_t count = 0; - const GstModuleItem *m = mod; - GstValue *st; - while (m->name != NULL) { - ++count; - ++m; - } - st = gst_struct_begin(vm, count); - m = mod; - while (m->name != NULL) { - gst_struct_put(st, - gst_string_cvs(vm, m->name), - gst_wrap_cfunction(m->data)); - ++m; - } - return gst_wrap_struct(gst_struct_end(vm, st)); -} - -void gst_module(Gst *vm, const char *packagename, const GstModuleItem *mod) { - gst_table_put(vm, vm->modules, gst_string_cvs(vm, packagename), gst_cmodule_struct(vm, mod)); - gst_cmodule_register(vm, packagename, mod); -} - -void gst_module_mutable(Gst *vm, const char *packagename, const GstModuleItem *mod) { - gst_table_put(vm, vm->modules, gst_string_cvs(vm, packagename), gst_cmodule_table(vm, mod)); - gst_cmodule_register(vm, packagename, mod); -} - -void gst_module_put(Gst *vm, const char *packagename, const char *name, GstValue v) { - GstValue modtable = gst_table_get(vm->modules, gst_string_cvs(vm, packagename)); - if (modtable.type == GST_TABLE) { - GstTable *table = modtable.data.table; - if (v.type == GST_CFUNCTION) { - GstValue key; - GstBuffer *buffer = gst_buffer(vm, 10); - gst_buffer_append_cstring(vm, buffer, packagename); - gst_buffer_push(vm, buffer, '.'); - gst_buffer_append_cstring(vm, buffer, name); - key = gst_wrap_string(gst_buffer_to_string(vm, buffer)); - gst_table_put(vm, vm->registry, key, v); - gst_table_put(vm, vm->registry, v, key); - } - gst_table_put(vm, table, gst_string_cvs(vm, name), v); - } -} - -GstValue gst_module_get(Gst *vm, const char *packagename) { - return gst_table_get(vm->modules, gst_string_cvs(vm, packagename)); -} - -/****/ -/* Misc */ -/****/ - /* Utilities for manipulating different types with the same semantics */ /* Read both tuples and arrays as c pointers + uint32_t length. Return 1 if the @@ -341,115 +254,4 @@ int gst_callc(Gst *vm, GstCFunction fn, int numargs, ...) { result = fn(vm); gst_thread_popframe(vm, vm->thread); return result; -} - -static GstTable *gst_env_keytab(Gst *vm, GstTable *env, const char *keyword) { - GstTable *tab; - GstValue key = gst_string_cv(vm, keyword); - GstValue maybeTab = gst_table_get(env, key); - if (maybeTab.type != GST_TABLE) { - tab = gst_table(vm, 10); - gst_table_put(vm, env, key, gst_wrap_table(tab)); - } else { - tab = maybeTab.data.table; - } - return tab; -} - -GstTable *gst_env_nils(Gst *vm, GstTable *env) { - return gst_env_keytab(vm, env, "nils"); -} - -GstTable *gst_env_meta(Gst *vm, GstTable *env) { - return gst_env_keytab(vm, env, "meta"); -} - -/* Add many global variables and bind to nil */ -static void mergenils(Gst *vm, GstTable *destEnv, GstTable *nils) { - const GstValue *data = nils->data; - uint32_t len = nils->capacity; - uint32_t i; - GstTable *destNils = gst_env_nils(vm, destEnv); - for (i = 0; i < len; i += 2) { - if (data[i].type == GST_SYMBOL) { - gst_table_put(vm, destEnv, data[i], gst_wrap_nil()); - gst_table_put(vm, destNils, data[i], gst_wrap_boolean(1)); - } - } -} - -/* Add many global variable metadata */ -static void mergemeta(Gst *vm, GstTable *destEnv, GstTable *meta) { - const GstValue *data = meta->data; - uint32_t len = meta->capacity; - uint32_t i; - GstTable *destMeta = gst_env_meta(vm, destEnv); - for (i = 0; i < len; i += 2) { - if (data[i].type == GST_SYMBOL) { - gst_table_put(vm, destMeta, data[i], data[i + 1]); - } - } -} - -/* Simple strequal between gst string ans c string, no 0s in b allowed */ -static int streq(const char *str, const uint8_t *b) { - uint32_t len = gst_string_length(b); - uint32_t i; - const uint8_t *ustr = (const uint8_t *)str; - for (i = 0; i < len; ++i) { - if (ustr[i] != b[i]) - return 0; - } - return 1; -} - -/* Add many global variables */ -void gst_env_merge(Gst *vm, GstTable *destEnv, GstTable *srcEnv) { - const GstValue *data = srcEnv->data; - uint32_t len = srcEnv->capacity; - uint32_t i; - for (i = 0; i < len; i += 2) { - if (data[i].type == GST_SYMBOL) { - gst_table_put(vm, destEnv, data[i], data[i + 1]); - } else if (data[i].type == GST_STRING) { - const uint8_t *k = data[i].data.string; - if (streq("nils", k)) { - if (data[i + 1].type == GST_TABLE) - mergenils(vm, destEnv, data[i + 1].data.table); - } else if (streq("meta", k)) { - if (data[i + 1].type == GST_TABLE) - mergemeta(vm, destEnv, data[i + 1].data.table); - } - } - } -} - -void gst_env_put(Gst *vm, GstTable *env, GstValue key, GstValue value) { - GstTable *meta = gst_env_meta(vm, env); - gst_table_put(vm, meta, key, gst_wrap_nil()); - gst_table_put(vm, env, key, value); - if (value.type == GST_NIL) { - gst_table_put(vm, gst_env_nils(vm, env), key, gst_wrap_boolean(1)); - } -} - -void gst_env_putc(Gst *vm, GstTable *env, const char *key, GstValue value) { - GstValue keyv = gst_string_cvs(vm, key); - gst_env_put(vm, env, keyv, value); -} - -void gst_env_putvar(Gst *vm, GstTable *env, GstValue key, GstValue value) { - GstTable *meta = gst_env_meta(vm, env); - GstTable *newmeta = gst_table(vm, 4); - GstArray *ref = gst_array(vm, 1); - ref->count = 1; - ref->data[0] = value; - gst_table_put(vm, env, key, gst_wrap_array(ref)); - gst_table_put(vm, newmeta, gst_string_cv(vm, "mutable"), gst_wrap_boolean(1)); - gst_table_put(vm, meta, key, gst_wrap_table(newmeta)); -} - -void gst_env_putvarc(Gst *vm, GstTable *env, const char *key, GstValue value) { - GstValue keyv = gst_string_cvs(vm, key); - gst_env_putvar(vm, env, keyv, value); } \ No newline at end of file diff --git a/libs/hello.gst b/libs/hello.gst index b587de48..0ad16e2f 100644 --- a/libs/hello.gst +++ b/libs/hello.gst @@ -2,9 +2,9 @@ (do (+ 1 2 3)) -(print _ ) +(print (+ 1 2 3)) -"Comment" +# Comment (var i 0) (while (< i 1000) (print i)