Make dofile error if source file errors.

This should make dofile a bit easier to use.
It also means that import properly raises errors when
things go bad.
This commit is contained in:
Calvin Rose 2020-12-14 08:23:06 -06:00
parent 392d5d51df
commit a55354357c
3 changed files with 56 additions and 34 deletions

View File

@ -1,6 +1,9 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## Unreleased - ???
- Improve error handling of `dofile`.
## 1.13.1 - 2020-12-13 ## 1.13.1 - 2020-12-13
- Pretty printing a table with a prototype will look for `:_name` instead of `:name` - Pretty printing a table with a prototype will look for `:_name` instead of `:name`
in the prototype table to tag the output. in the prototype table to tag the output.

View File

@ -1684,7 +1684,7 @@
(visit-pattern-2 anda gun preds nil nil pattern) (visit-pattern-2 anda gun preds nil nil pattern)
# Local unification # Local unification
(def unify @[]) (def unify @[])
(each syms b2g (each syms b2g
(when (< 1 (length syms)) (when (< 1 (length syms))
(array/push unify [= ;syms]))) (array/push unify [= ;syms])))
# Global unification # Global unification
@ -1706,7 +1706,7 @@
(if (= :branch el) (if (= :branch el)
(let [condition (array/pop stack) (let [condition (array/pop stack)
truthy (array/pop stack) truthy (array/pop stack)
if-form ~(if ,condition ,truthy if-form ~(if ,condition ,truthy
,(case (length stack) ,(case (length stack)
0 nil 0 nil
1 (stack 0) 1 (stack 0)
@ -2416,9 +2416,6 @@
(default where "<anonymous>") (default where "<anonymous>")
(default guard :ydt) (default guard :ydt)
# Are we done yet?
(var going true)
# Evaluate 1 source form in a protected manner # Evaluate 1 source form in a protected manner
(defn eval1 [source] (defn eval1 [source]
(def source (if expand (expand source) source)) (def source (if expand (expand source) source))
@ -2442,7 +2439,7 @@
(fiber/setenv f env) (fiber/setenv f env)
(while (fiber/can-resume? f) (while (fiber/can-resume? f)
(def res (resume f resumeval)) (def res (resume f resumeval))
(when good (when going (set resumeval (onstatus f res)))))) (when good (set resumeval (onstatus f res)))))
# Reader version # Reader version
(when read (when read
@ -2467,11 +2464,11 @@
# Loop # Loop
(def buf @"") (def buf @"")
(while going (var parser-not-done true)
(while parser-not-done
(if (env :exit) (break)) (if (env :exit) (break))
(buffer/clear buf) (buffer/clear buf)
(if (= (chunks buf p) (if (= (chunks buf p) :cancel)
:cancel)
(do (do
# A :cancel chunk represents a cancelled form in the REPL, so reset. # A :cancel chunk represents a cancelled form in the REPL, so reset.
(:flush p) (:flush p)
@ -2482,19 +2479,23 @@
(def len (length buf)) (def len (length buf))
(when (= len 0) (when (= len 0)
(:eof p) (:eof p)
(set going false)) (set parser-not-done false))
(while (> len pindex) (while (> len pindex)
(+= pindex (p-consume p buf pindex)) (+= pindex (p-consume p buf pindex))
(while (p-has-more p) (while (p-has-more p)
(eval1 (p-produce p))) (eval1 (p-produce p))
(if (env :exit) (break)))
(when (= (p-status p) :error) (when (= (p-status p) :error)
(parse-err p where)))))) (parse-err p where)
(if (env :exit) (break)))))))
# Check final parser state # Check final parser state
(while (p-has-more p) (unless (env :exit)
(eval1 (p-produce p))) (while (p-has-more p)
(when (= (p-status p) :error) (eval1 (p-produce p))
(parse-err p where)) (if (env :exit) (break)))
(when (= (p-status p) :error)
(parse-err p where)))
(in env :exit-value env)) (in env :exit-value env))
@ -2723,15 +2724,25 @@
(def spath (string path)) (def spath (string path))
(put env :current-file (or src (if-not path-is-file spath))) (put env :current-file (or src (if-not path-is-file spath)))
(put env :source (or src (if-not path-is-file spath path))) (put env :source (or src (if-not path-is-file spath path)))
(var exit-error nil)
(var exit-fiber nil)
(defn chunks [buf _] (file/read f 2048 buf)) (defn chunks [buf _] (file/read f 2048 buf))
(defn bp [&opt x y] (defn bp [&opt x y]
(def ret (bad-parse x y)) (when exit
(if exit (os/exit 1)) (bad-parse x y)
ret) (os/exit 1))
(put env :exit true)
(def [line col] (:where x))
(def pe (string (:error x) " in " y " around line " line ", column " col))
(set exit-error pe))
(defn bc [&opt x y z] (defn bc [&opt x y z]
(def ret (bad-compile x y z)) (when exit
(if exit (os/exit 1)) (bad-compile x y z)
ret) (os/exit 1))
(put env :exit true)
(def ce (string x " while compiling " z))
(set exit-error ce)
(set exit-fiber y))
(unless f (unless f
(error (string "could not find file " path))) (error (string "could not find file " path)))
(def nenv (def nenv
@ -2741,32 +2752,40 @@
:on-compile-error bc :on-compile-error bc
:on-status (fn [f x] :on-status (fn [f x]
(when (not= (fiber/status f) :dead) (when (not= (fiber/status f) :dead)
(debug/stacktrace f x) (when exit
(if exit (os/exit 1) (eflush)))) (debug/stacktrace f x)
(eflush)
(os/exit 1))
(put env :exit true)
(set exit-error x)
(set exit-fiber f)))
:evaluator evaluator :evaluator evaluator
:expander expander :expander expander
:read read :read read
:parser parser :parser parser
:source (or src (if path-is-file "<anonymous>" spath))})) :source (or src (if path-is-file "<anonymous>" spath))}))
(if-not path-is-file (file/close f)) (if-not path-is-file (file/close f))
(when exit-error
(if exit-fiber
(propagate exit-error exit-fiber)
(error exit-error)))
nenv) nenv)
(def module/loaders (def module/loaders
`A table of loading method names to loading functions. `A table of loading method names to loading functions.
This table lets require and import load many different kinds This table lets require and import load many different kinds
of files as modules.` of files as modules.`
@{:native (fn [path &] (native path (make-env))) @{:native (fn native-loader [path &] (native path (make-env)))
:source (fn [path args] :source (fn source-loader [path args]
(put module/loading path true) (put module/loading path true)
(def newenv (dofile path ;args)) (defer (put module/loading path nil)
(put module/loading path nil) (dofile path ;args)))
newenv) :preload (fn preload-loader [path & args]
:preload (fn [path & args]
(when-let [m (in module/cache path)] (when-let [m (in module/cache path)]
(if (function? m) (if (function? m)
(set (module/cache path) (m path ;args)) (set (module/cache path) (m path ;args))
m))) m)))
:image (fn [path &] (load-image (slurp path)))}) :image (fn image-loader [path &] (load-image (slurp path)))})
(defn require-1 (defn require-1
[path args kargs] [path args kargs]

View File

@ -5,9 +5,9 @@
#define JANET_VERSION_MAJOR 1 #define JANET_VERSION_MAJOR 1
#define JANET_VERSION_MINOR 13 #define JANET_VERSION_MINOR 13
#define JANET_VERSION_PATCH 1 #define JANET_VERSION_PATCH 2
#define JANET_VERSION_EXTRA "" #define JANET_VERSION_EXTRA "-dev"
#define JANET_VERSION "1.13.1" #define JANET_VERSION "1.13.2-dev"
/* #define JANET_BUILD "local" */ /* #define JANET_BUILD "local" */