diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d14442f..e1e0db63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - Argument to `(error)` combinator in PEGs is now optional. - Add `(line)` and `(column)` combinators to PEGs to capture source line and column. This should make error reporting a bit easier. +- Add `merge-module` to core. - During installation and release, merge janetconf.h into janet.h for easier install. - Add `upscope` special form. - `os/execute` and `os/spawn` can take streams for redirecting IO. diff --git a/src/boot/boot.janet b/src/boot/boot.janet index e297df81..82c538a7 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -2153,7 +2153,7 @@ :parser parser :read read :expander expand} opts) - (default env (fiber/getenv (fiber/current))) + (default env (or (fiber/getenv (fiber/current)) @{})) (default chunks (fn [buf p] (getline "" buf env))) (default onstatus debug/stacktrace) (default on-compile-error bad-compile) @@ -2530,11 +2530,22 @@ [path & args] (require-1 path args (struct ;args))) +(defn merge-module + "Merge a module source into the target environment with a prefix, as with the import macro. + This lets users emulate the behavior of import with a custom module table. + If export is truthy, then merged functions are not marked as private. Returns + the modified target environment." + [target source &opt prefix export] + (loop [[k v] :pairs source :when (symbol? k) :when (not (v :private))] + (def newv (table/setproto @{:private (not export)} v)) + (put target (symbol prefix k) newv)) + target) + (defn import* `Function form of import. Same parameters, but the path and other symbol parameters should be strings instead.` [path & args] - (def env (fiber/getenv (fiber/current))) + (def env (curenv)) (def kargs (table ;args)) (def {:as as :prefix prefix @@ -2544,9 +2555,7 @@ (and as (string as "/")) prefix (string (last (string/split "/" path)) "/"))) - (loop [[k v] :pairs newenv :when (symbol? k) :when (not (v :private))] - (def newv (table/setproto @{:private (not ep)} v)) - (put env (symbol prefix k) newv))) + (merge-module env newenv prefix ep)) (undef require-1) diff --git a/src/core/ev.c b/src/core/ev.c index 1d97ae23..70a5f254 100644 --- a/src/core/ev.c +++ b/src/core/ev.c @@ -1684,6 +1684,8 @@ static Janet cfun_ev_call(int32_t argc, Janet *argv) { janet_arity(argc, 1, -1); JanetFunction *fn = janet_getfunction(argv, 0); JanetFiber *fiber = janet_fiber(fn, 64, argc - 1, argv + 1); + fiber->env = janet_table(0); + fiber->env->proto = janet_current_fiber()->env; if (NULL == fiber) janet_panicf("invalid arity to function %v", argv[0]); janet_schedule(fiber, janet_wrap_nil()); return janet_wrap_fiber(fiber);