feat: CLI file execution — 'jolt file.clj [args]' runs a script (binds *command-line-args*/*file*), '-e EXPR' evaluates, '-h' help; fix print/println/pr/prn to space-separate, render collections, and not double-newline
This commit is contained in:
parent
37c8971d41
commit
e87f6db10e
3 changed files with 72 additions and 8 deletions
16
README.md
16
README.md
|
|
@ -35,10 +35,14 @@ This compiles `src/jolt/*.janet` into a standalone `build/jolt` executable. Requ
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
```
|
```
|
||||||
build/jolt
|
build/jolt # start a REPL
|
||||||
|
build/jolt file.clj [args] # run a Clojure file (binds *command-line-args*)
|
||||||
|
build/jolt -e EXPR [args] # evaluate EXPR and print the result
|
||||||
|
build/jolt -h # help
|
||||||
```
|
```
|
||||||
|
|
||||||
Drops into a read-eval-print loop where you can type Clojure expressions:
|
With no arguments it drops into a read-eval-print loop (multi-line forms are
|
||||||
|
accumulated until balanced):
|
||||||
|
|
||||||
```
|
```
|
||||||
user=> (+ 1 2)
|
user=> (+ 1 2)
|
||||||
|
|
@ -51,6 +55,14 @@ user=> (fib 10)
|
||||||
55
|
55
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Running a file evaluates its top-level forms:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ echo '(println "hello" (* 6 7))' > hello.clj
|
||||||
|
$ build/jolt hello.clj
|
||||||
|
hello 42
|
||||||
|
```
|
||||||
|
|
||||||
## Test
|
## Test
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1207,20 +1207,32 @@
|
||||||
# I/O — minimal wrappers
|
# I/O — minimal wrappers
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
(def core-print print)
|
# print/println use str semantics (bare strings); pr/prn use readable (quoted).
|
||||||
(def core-println (fn [& xs] (apply print xs) (print "\n") nil))
|
# All space-separate their args, like Clojure.
|
||||||
|
(defn core-print [& xs]
|
||||||
|
(var i 0)
|
||||||
|
(while (< i (length xs))
|
||||||
|
(if (> i 0) (prin " "))
|
||||||
|
(prin (str-render-one (xs i)))
|
||||||
|
(++ i))
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(defn core-println [& xs]
|
||||||
|
(apply core-print xs)
|
||||||
|
(prin "\n")
|
||||||
|
nil)
|
||||||
|
|
||||||
(defn core-pr [& xs]
|
(defn core-pr [& xs]
|
||||||
(var i 0)
|
(var i 0)
|
||||||
(while (< i (length xs))
|
(while (< i (length xs))
|
||||||
(if (> i 0) (prin " "))
|
(if (> i 0) (prin " "))
|
||||||
(prin (xs i))
|
(let [b @""] (pr-render b (xs i)) (prin (string b)))
|
||||||
(++ i))
|
(++ i))
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defn core-prn [& xs]
|
(defn core-prn [& xs]
|
||||||
(apply core-pr xs)
|
(apply core-pr xs)
|
||||||
(print "\n")
|
(prin "\n")
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defn core-pr-str [& xs]
|
(defn core-pr-str [& xs]
|
||||||
|
|
|
||||||
|
|
@ -163,10 +163,9 @@
|
||||||
(write-value v buf)
|
(write-value v buf)
|
||||||
(print (string buf)))
|
(print (string buf)))
|
||||||
|
|
||||||
(defn main [&]
|
(defn- run-repl []
|
||||||
(print "Jolt — Clojure on Janet")
|
(print "Jolt — Clojure on Janet")
|
||||||
(print "Type (exit) to quit.\n")
|
(print "Type (exit) to quit.\n")
|
||||||
|
|
||||||
(var running true)
|
(var running true)
|
||||||
(var pending "") # accumulates a form split across multiple input lines
|
(var pending "") # accumulates a form split across multiple input lines
|
||||||
(while running
|
(while running
|
||||||
|
|
@ -190,3 +189,44 @@
|
||||||
(try
|
(try
|
||||||
(print-value (eval-string ctx input))
|
(print-value (eval-string ctx input))
|
||||||
([err] (eprint "Error: " err))))))))))))
|
([err] (eprint "Error: " err))))))))))))
|
||||||
|
|
||||||
|
(defn- set-command-line-args [argv]
|
||||||
|
# bind clojure.core/*command-line-args* to a vector of the remaining args
|
||||||
|
(ns-intern (ctx-find-ns ctx "clojure.core") "*command-line-args*"
|
||||||
|
(tuple/slice (tuple ;argv))))
|
||||||
|
|
||||||
|
(defn- run-file [path argv]
|
||||||
|
(set-command-line-args argv)
|
||||||
|
(ns-intern (ctx-find-ns ctx "clojure.core") "*file*" path)
|
||||||
|
(if (not (os/stat path))
|
||||||
|
(do (eprint "Error: file not found: " path) (os/exit 1))
|
||||||
|
(let [src (slurp path)]
|
||||||
|
(try
|
||||||
|
(load-string ctx src)
|
||||||
|
([err] (eprint "Error: " err) (os/exit 1))))))
|
||||||
|
|
||||||
|
(defn- run-eval [expr argv]
|
||||||
|
(set-command-line-args argv)
|
||||||
|
(try
|
||||||
|
(let [v (load-string ctx expr)]
|
||||||
|
(when (not (nil? v)) (print-value v)))
|
||||||
|
([err] (eprint "Error: " err) (os/exit 1))))
|
||||||
|
|
||||||
|
(defn- print-help []
|
||||||
|
(print "Jolt — a Clojure interpreter on Janet\n")
|
||||||
|
(print "Usage:")
|
||||||
|
(print " jolt Start a REPL")
|
||||||
|
(print " jolt FILE.clj [args] Run a Clojure file (binds *command-line-args*)")
|
||||||
|
(print " jolt -e EXPR [args] Evaluate EXPR and print the result")
|
||||||
|
(print " jolt -h | --help Show this help"))
|
||||||
|
|
||||||
|
(defn main [&]
|
||||||
|
(def args (or (dyn :args) @[])) # @["jolt" arg1 arg2 ...]
|
||||||
|
(def argv (if (> (length args) 1) (array/slice args 1) @[]))
|
||||||
|
(ctx-set-current-ns ctx "user")
|
||||||
|
(cond
|
||||||
|
(empty? argv) (run-repl)
|
||||||
|
(or (= (argv 0) "-h") (= (argv 0) "--help")) (print-help)
|
||||||
|
(= (argv 0) "-e") (run-eval (get argv 1 "") (array/slice argv 2))
|
||||||
|
(= (argv 0) "-") (run-file "/dev/stdin" (array/slice argv 1))
|
||||||
|
(run-file (argv 0) (array/slice argv 1))))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue