|
4 | 4 | (:require [fs :refer [createReadStream]] |
5 | 5 | [path :refer [basename dirname join resolve]] |
6 | 6 | [module :refer [Module]] |
| 7 | + [commander] |
| 8 | + [wisp.package :refer [version]] |
7 | 9 |
|
8 | 10 | [wisp.string :refer [split join upper-case replace]] |
9 | 11 | [wisp.sequence :refer [first second last count reduce rest |
|
15 | 17 | [wisp.ast :refer [pr-str name]] |
16 | 18 | [wisp.compiler :refer [compile]])) |
17 | 19 |
|
18 | | - |
19 | | -(defn flag? |
20 | | - [param] |
21 | | - ;; HACK: Workaround for segfault #6691 |
22 | | - (identical? (subs param 0 2) (name :--))) |
23 | | - |
24 | | -(defn flag->key |
25 | | - [flag] |
26 | | - (subs flag 2)) |
27 | | - |
28 | | -;; Just mungle all the `--param value` pairs into global *env* hash. |
29 | | -(defn parse-params |
30 | | - [params] |
31 | | - (loop [input params |
32 | | - output {}] |
33 | | - (if (empty? input) |
34 | | - output |
35 | | - (let [name (first input) |
36 | | - value (second input)] |
37 | | - (if (flag? name) |
38 | | - (if (or (nil? value) (flag? value)) |
39 | | - (recur (rest input) |
40 | | - (assoc output (flag->key name) true)) |
41 | | - (recur (drop 2 input) |
42 | | - (assoc output (flag->key name) value))) |
43 | | - (recur (rest input) |
44 | | - output)))))) |
45 | | - |
46 | | - |
47 | | - |
48 | 20 | (defn compile-stdin |
49 | 21 | [options] |
50 | 22 | (with-stream-content process.stdin |
51 | 23 | compile-string |
52 | | - options)) |
| 24 | + (conj {} options))) |
| 25 | +;; (conj {:source-uri options}) causes segfault for some reason |
53 | 26 |
|
54 | 27 | (defn compile-file |
55 | 28 | [path options] |
|
61 | 34 | [source options] |
62 | 35 | (let [channel (or (:print options) :code) |
63 | 36 | output (compile source options) |
64 | | - content (if (= channel :code) |
65 | | - (:code output) |
66 | | - (JSON.stringify (get output channel) 2 2))] |
67 | | - (.write process.stdout (or content "nil")) |
68 | | - (if (:error output) (throw (:error output))))) |
| 37 | + content (cond |
| 38 | + (= channel :code) (:code output) |
| 39 | + (= channel :expansion) (:expansion output) |
| 40 | + :else (JSON.stringify (get output channel) 2 2))] |
| 41 | + (.write process.stdout (or content "nil")) |
| 42 | + (if (:error output) (throw (.-error output))))) |
69 | 43 |
|
70 | 44 | (defn with-stream-content |
71 | 45 | [input resume options] |
|
82 | 56 | ;; https://github.com/joyent/node/blob/master/lib/module.js#L489-493 |
83 | 57 | (Module._load (resolve path) null true)) |
84 | 58 |
|
| 59 | +(defmacro -> |
| 60 | + [& operations] |
| 61 | + (reduce |
| 62 | + (fn [form operation] |
| 63 | + (cons (first operation) |
| 64 | + (cons form (rest operation)))) |
| 65 | + (first operations) |
| 66 | + (rest operations))) |
| 67 | + |
| 68 | +(defn parse-params |
| 69 | + [params] |
| 70 | + (let [options (-> commander |
| 71 | + (.version version) |
| 72 | + (.usage "[options] <file ...>") |
| 73 | + (.option "-r, --run" |
| 74 | + "compile and execute the file (same as wisp path/to/file.wisp)") |
| 75 | + (.option "-c, --compile" |
| 76 | + "compile given file and prints to stdout") |
| 77 | + (.option "-i, --interactive" |
| 78 | + "run an interactive wisp REPL (same as wisp with no params)") |
| 79 | + (.option "--print <format>" |
| 80 | + "use custom print output `expansion`,`forms`, `ast`, `js-ast` or (default) `code`" |
| 81 | + str |
| 82 | + "code") |
| 83 | + (.option "--no-map" |
| 84 | + "disable source map generation") |
| 85 | + (.parse params))] |
| 86 | + (conj {:no-map (not (:map options))} |
| 87 | + options))) |
85 | 88 |
|
86 | 89 | (defn main |
87 | 90 | [] |
88 | | - (let [options (parse-params (drop 2 process.argv))] |
89 | | - (cond (not process.stdin.isTTY) (compile-stdin options) |
90 | | - (< (count process.argv) 3) (start-repl) |
91 | | - (and (= (count process.argv) 3) |
92 | | - (not (flag? (last process.argv)))) (run (last process.argv)) |
93 | | - (:compile options) (compile-file (:compile options) options)))) |
| 91 | + (let [options (parse-params process.argv) |
| 92 | + path (aget options.args 0)] |
| 93 | + (cond options.run (run path) |
| 94 | + (not process.stdin.isTTY) (compile-stdin options) |
| 95 | + options.interactive (start-repl) |
| 96 | + options.compile (compile-file path options) |
| 97 | + path (run path) |
| 98 | + :else (start-repl)))) |
0 commit comments