Change import semantics. Fix gc bug with fibers.

This commit is contained in:
Calvin Rose 2018-05-18 20:53:19 -04:00
parent 36ecbeffa6
commit 68895e27d4
7 changed files with 49 additions and 14 deletions

View File

@ -1,5 +1,4 @@
(import "examples/iterators.dst")
(import examples.iterators :as "")
(defn sum3
"Solve the 3SUM problem in O(n^2) time."

View File

@ -66,6 +66,9 @@
(def t (type x))
(if (= t :integer) true (= t :real)))
(defn fiber? [x] (= (type x) :fiber))
(defn string? [x] (= (type x) :string))
(defn symbol? [x] (= (type x) :symbol))
(defn buffer? [x] (= (type x) :buffer))
(defn function? [x] (= (type x) :function))
(defn cfunction? [x] (= (type x) :cfunction))
(defn abstract? [x] (= (type x) :abstract))
@ -970,7 +973,29 @@ environment is needed, use run-context."
(run-context *env* chunks (fn [x] (:= returnval x)) default-error-handler)
returnval)
(def require (do
(def module.paths @[
"./?.dst"
"./?/init.dst"
"./dst_modules/?.dst"
"./dst_modules/?/init.dst"
])
(defn module.find
"Open a file given a module name."
[name]
(def normname (string.replace-all "." "/" name))
(defn checkmodule
[f testpath]
(if f f (do
(def p (string.replace-all "?" normname testpath))
(file.open p))))
(reduce checkmodule nil module.paths))
(def require
"Require a module with the given name. Will search all of the paths in
module.paths, then the path as a raw file path. Returns the new environment
returned from compiling and running the file."
(do
(def cache @{})
(def loading @{})
(fn [path]
@ -986,7 +1011,9 @@ environment is needed, use run-context."
(def newenv (make-env))
(put cache path newenv)
(put loading path true)
(def f (file.open path))
(def f (or (module.find path) (file.open path)))
(if (not f)
(error (string "could not open file for module " path)))
(defn chunks [buf] (file.read f 1024 buf))
(run-context newenv chunks identity default-error-handler)
(file.close f)
@ -996,10 +1023,12 @@ environment is needed, use run-context."
(defn import* [env path & args]
(def newenv (require path))
(def {
:as as
:prefix prefix
} (apply1 table args))
(var k (next newenv nil))
(def prefix (if prefix prefix ""))
(def {:meta meta} newenv)
(def prefix (or (and as (string as ".")) prefix (string path ".")))
(while k
(def v (get newenv k))
(when (not (get v :private))
@ -1007,7 +1036,17 @@ environment is needed, use run-context."
(:= k (next newenv k))))
(defmacro import [path & args]
(apply tuple import* '_env path args))
"Import a module. First requires the module, and then merges its
symbols into the current environment, prepending a given prefix as needed.
(use the :as or :prefix option to set a prefix). If no prefix is provided,
use the name of the module as a prefix."
(def upath (string (ast.unwrap path)))
(def argm (map (fn [x]
(if (and (symbol? x) (= (get x 0) 58))
x
(string x)))
(ast.unwrap args)))
(apply tuple import* '_env upath argm))
(defn repl [getchunk onvalue onerr]
"Run a repl. The first parameter is an optional function to call to

View File

@ -188,9 +188,7 @@ recur:
return;
dst_gc_mark(fiber);
/* Check if new fiber - all status bits sets indicate :new status */
if ((fiber->flags & DST_FIBER_STATUS_MASK) == DST_FIBER_STATUS_MASK)
dst_mark_function(fiber->root);
dst_mark_function(fiber->root);
i = fiber->frame;
j = fiber->stackstart - DST_FRAME_SIZE;

View File

@ -193,8 +193,7 @@ static int dst_io_fopen(DstArgs args) {
DST_THROW(args, "invalid file mode");
}
f = fopen((const char *)fname, (const char *)fmode);
if (!f) DST_THROW(args, "could not open file");
DST_RETURN(args, makef(f, flags));
DST_RETURN(args, f ? makef(f, flags) : dst_wrap_nil());
}
/* Read a certain number of bytes into memory */

View File

@ -40,7 +40,7 @@
(+= i (dohandler (string.slice arg 1 2) i))
(do
(:= *no-file* false)
(import arg)
(import* _env arg)
(++ i))))
(when (or *should-repl* *no-file*)

View File

@ -18,7 +18,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
(import "test/helper.dst")
(import test.helper :prefix "")
(start-suite 0)
(assert (= 10 (+ 1 2 3 4)) "addition")

View File

@ -18,7 +18,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
(import "test/helper.dst")
(import test.helper :prefix "")
(start-suite 1)
(assert (= 400.0 (sqrt 160000)) "sqrt(160000)=400")