1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-28 11:09:54 +00:00

Add flycheck function to core.

Also make flychecking work with stdin out of the box.
This commit is contained in:
Calvin Rose 2021-01-06 17:27:17 -06:00
parent f5877ac6d1
commit 545df28d71
2 changed files with 69 additions and 49 deletions

View File

@ -2,6 +2,8 @@
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 - ??? ## Unreleased - ???
- Make janet's `-k` flag work on stdin if no files are given.
- Add `flycheck` function to core.
- Make `backmatch` and `backref` more expressive in pegs. - Make `backmatch` and `backref` more expressive in pegs.
- Fix buggy `string/split`. - Fix buggy `string/split`.
- Add `fiber/last-value` to get the value that was last yielded, errored, or signaled - Add `fiber/last-value` to get the value that was last yielded, errored, or signaled

View File

@ -3158,7 +3158,7 @@
### ###
### ###
### CLI Tool Main ### Flychecking
### ###
### ###
@ -3187,6 +3187,43 @@
(defn- use-2 [evaluator args] (defn- use-2 [evaluator args]
(each a args (import* (string a) :prefix "" :evaluator evaluator))) (each a args (import* (string a) :prefix "" :evaluator evaluator)))
(defn- evaluator
[thunk source env where]
(when (tuple? source)
(def head (source 0))
(def safe-check (safe-forms head))
(cond
# Sometimes safe form
(function? safe-check)
(if (safe-check source) (thunk))
# Always safe form
safe-check
(thunk)
# Use
(= 'use head)
(use-2 evaluator (tuple/slice source 1))
# Import-like form
(importers head)
(do
(let [[l c] (tuple/sourcemap source)
newtup (tuple/setmap (tuple ;source :evaluator evaluator) l c)]
((compile newtup env where)))))))
(defn flycheck
``Check a file for errors without running the file. Found errors will be printed to stderr
in the usual format. Macros will still be executed, however, so
arbitrary execution is possible. Other arguments are the same as dofile. `path` can also be
a file value such as stdin.``
[path &keys kwargs]
(dofile path :evaluator evaluator ;(kvs kwargs)))
###
###
### CLI Tool Main
###
###
# conditional compilation for reduced os # conditional compilation for reduced os
(def- getenv-alias (if-let [entry (in root-env 'os/getenv)] (entry :value) (fn [&]))) (def- getenv-alias (if-let [entry (in root-env 'os/getenv)] (entry :value) (fn [&])))
@ -3262,30 +3299,6 @@
(def h (in handlers n)) (def h (in handlers n))
(if h (h i) (do (print "unknown flag -" n) ((in handlers "h"))))) (if h (h i) (do (print "unknown flag -" n) ((in handlers "h")))))
(defn- evaluator
[thunk source env where]
(if *compile-only*
(when (tuple? source)
(def head (source 0))
(def safe-check (safe-forms head))
(cond
# Sometimes safe form
(function? safe-check)
(if (safe-check source) (thunk))
# Always safe form
safe-check
(thunk)
# Use
(= 'use head)
(use-2 evaluator (tuple/slice source 1))
# Import-like form
(importers head)
(do
(let [[l c] (tuple/sourcemap source)
newtup (tuple/setmap (tuple ;source :evaluator evaluator) l c)]
((compile newtup env where))))))
(thunk)))
# Process arguments # Process arguments
(var i 0) (var i 0)
(def lenargs (length args)) (def lenargs (length args))
@ -3298,32 +3311,37 @@
(def env (make-env)) (def env (make-env))
(def subargs (array/slice args i)) (def subargs (array/slice args i))
(put env :args subargs) (put env :args subargs)
(dofile arg :prefix "" :exit *exit-on-error* :evaluator evaluator :env env) (if *compile-only*
(unless *compile-only* (flycheck arg :exit *exit-on-error* :env env)
(if-let [main (get (in env 'main) :value)] (do
(let [thunk (compile [main ;(tuple/slice args i)] env arg)] (dofile arg :exit *exit-on-error* :env env)
(if (function? thunk) (thunk) (error (thunk :error)))))) (if-let [main (get (in env 'main) :value)]
(let [thunk (compile [main ;(tuple/slice args i)] env arg)]
(if (function? thunk) (thunk) (error (thunk :error)))))))
(set i lenargs)))) (set i lenargs))))
(when (and (not *compile-only*) (or *should-repl* *no-file*)) (if (or *should-repl* *no-file*)
(if-not *quiet* (if
(print "Janet " janet/version "-" janet/build " " (os/which) "/" (os/arch) " - '(doc)' for help")) *compile-only* (flycheck stdin :source "stdin" :exit *exit-on-error*)
(flush) (do
(defn getprompt [p] (if-not *quiet*
(def [line] (parser/where p)) (print "Janet " janet/version "-" janet/build " " (os/which) "/" (os/arch) " - '(doc)' for help"))
(string "repl:" line ":" (parser/state p :delimiters) "> ")) (flush)
(defn getstdin [prompt buf _] (defn getprompt [p]
(file/write stdout prompt) (def [line] (parser/where p))
(file/flush stdout) (string "repl:" line ":" (parser/state p :delimiters) "> "))
(file/read stdin :line buf)) (defn getstdin [prompt buf _]
(def env (make-env)) (file/write stdout prompt)
(if *debug* (put env :debug true)) (file/flush stdout)
(def getter (if *raw-stdin* getstdin getline)) (file/read stdin :line buf))
(defn getchunk [buf p] (def env (make-env))
(getter (getprompt p) buf env)) (if *debug* (put env :debug true))
(setdyn :pretty-format (if *colorize* "%.20Q" "%.20q")) (def getter (if *raw-stdin* getstdin getline))
(setdyn :err-color (if *colorize* true)) (defn getchunk [buf p]
(repl getchunk nil env))) (getter (getprompt p) buf env))
(setdyn :pretty-format (if *colorize* "%.20Q" "%.20q"))
(setdyn :err-color (if *colorize* true))
(repl getchunk nil env)))))
(undef no-side-effects is-safe-def safe-forms importers use-2 getenv-alias) (undef no-side-effects is-safe-def safe-forms importers use-2 getenv-alias)