Phase 10: Standard Library — 9 modules, core-reduce set fix
New modules (loadable as Clojure source): - clojure/string.clj (19 fns): blank?, capitalize, lower-case, upper-case, includes?, join, replace, replace-first, reverse, split, starts-with?, ends-with?, trim, triml, trimr, trim-newline, escape, index-of, last-index-of - clojure/set.clj (10 fns): union, intersection, difference, select, project, rename, rename-keys, map-invert, index, subset?, superset? (simplified: no & rest arities due to evaluator limitation) - clojure/walk.clj (7 fns): walk, postwalk, prewalk, postwalk-replace, prewalk-replace, keywordize-keys, stringify-keys - clojure/zip.clj: full zipper implementation (25 fns) - clojure/edn.clj: EDN reader stubs - clojure/java_io.clj: file I/O wrappers - jolt/interop.clj: Janet interop (eval, type, describe) - jolt/shell.clj: shell command execution via os/shell - jolt/http.clj: HTTP client via net/request Bug fixes: - core-reduce: convert sets to seq before iterating (fixes reduce over sets) - core-every?: convert sets to seq before iterating - core-filter: convert sets to seq before iterating - All .clj files stripped of docstrings (Jolt defn doesn't support them) - String interop bindings (str-trim, str-upper, str-lower, etc.) in core-bindings 20+ assertions in sections 40-43: string ops, set ops, module loadability 315 ok, 2 fail (pre-existing, unchanged)" && echo "committed"
This commit is contained in:
parent
fdb0f4ab83
commit
307963afa9
12 changed files with 288 additions and 187 deletions
13
src/jolt/clojure/edn.clj
Normal file
13
src/jolt/clojure/edn.clj
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
; Jolt Standard Library: clojure.edn
|
||||
; EDN reading and writing (stubs using the Jolt reader).
|
||||
|
||||
(defn read-string
|
||||
[s]
|
||||
(let [ctx ((get (dyn :current-env) (symbol "init")))]
|
||||
((get (dyn :current-env) (symbol "eval-string")) ctx s)))
|
||||
|
||||
(defn read
|
||||
[reader]
|
||||
(let [line ((get (dyn :current-env) (symbol "file/read")) reader :line)]
|
||||
(when line
|
||||
(read-string line))))
|
||||
37
src/jolt/clojure/java_io.clj
Normal file
37
src/jolt/clojure/java_io.clj
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
; Jolt Standard Library: clojure.java.io
|
||||
; File I/O using Janet's built-in file functions.
|
||||
|
||||
(defn file
|
||||
([path] (string path))
|
||||
([parent child] (string parent "/" child)))
|
||||
|
||||
(defn as-file [x] (if (string? x) x (str x)))
|
||||
|
||||
(defn as-url [x] (str x))
|
||||
|
||||
(defn delete-file [f &opt silently]
|
||||
(try (os/rm f) true
|
||||
([err] (if silently false (error err)))))
|
||||
|
||||
(defn make-parents [f]
|
||||
(let [parent (string/replace f "/[^/]+$" "")]
|
||||
(when (not= parent f)
|
||||
(os/mkdir parent))))
|
||||
|
||||
(defn reader [f]
|
||||
(file/open f :r))
|
||||
|
||||
(defn writer [f]
|
||||
(file/open f :w))
|
||||
|
||||
(defn input-stream [f]
|
||||
(file/open f :r))
|
||||
|
||||
(defn output-stream [f]
|
||||
(file/open f :w))
|
||||
|
||||
(defn resource [path] (slurp path))
|
||||
|
||||
(defn copy [input output]
|
||||
(let [content (if (string? input) (slurp input) (file/read input :all))]
|
||||
(if (string? output) (spit output content) (file/write output content))))
|
||||
|
|
@ -1,124 +1,51 @@
|
|||
; Jolt Standard Library: clojure.set
|
||||
; Set operations (union, intersection, difference, subset?, superset?, etc.)
|
||||
; Set operations. Note: no & rest arities (evaluator limitation).
|
||||
|
||||
(defn union
|
||||
"Return a set that is the union of the input sets."
|
||||
([s1] s1)
|
||||
([s1 s2]
|
||||
(if (< (count s1) (count s2))
|
||||
(reduce conj s2 s1)
|
||||
(reduce conj s1 s2)))
|
||||
([s1 s2 & sets]
|
||||
(reduce union (union s1 s2) sets)))
|
||||
([s1 s2] (reduce conj s2 s1)))
|
||||
|
||||
(defn intersection
|
||||
"Return a set that is the intersection of the input sets."
|
||||
([s1] s1)
|
||||
([s1 s2]
|
||||
(reduce (fn [acc item]
|
||||
(if (contains? s2 item) acc (disj acc item)))
|
||||
s1 s1))
|
||||
([s1 s2 & sets]
|
||||
(reduce intersection (intersection s1 s2) sets)))
|
||||
(reduce (fn [acc item] (if (contains? s2 item) acc (disj acc item))) s1 s1)))
|
||||
|
||||
(defn difference
|
||||
"Return a set that is the first set without elements of the other sets."
|
||||
([s1] s1)
|
||||
([s1 s2]
|
||||
(reduce disj s1 s2))
|
||||
([s1 s2 & sets]
|
||||
(reduce difference (difference s1 s2) sets)))
|
||||
([s1 s2] (reduce disj s1 s2)))
|
||||
|
||||
(defn select
|
||||
"Returns a set of the elements for which pred is true."
|
||||
[pred s]
|
||||
(reduce (fn [acc item]
|
||||
(if (pred item) acc (disj acc item)))
|
||||
s s))
|
||||
(reduce (fn [acc item] (if (pred item) acc (disj acc item))) s s))
|
||||
|
||||
(defn project
|
||||
"Returns a rel of the elements of xrel with only the keys in ks."
|
||||
[xrel ks]
|
||||
(set (map #(select-keys % ks) xrel)))
|
||||
|
||||
(defn rename
|
||||
"Returns a rel with the maps in xrel renamed according to kmap argument,
|
||||
which is a map from original to new key name."
|
||||
[xrel kmap]
|
||||
(set
|
||||
(map
|
||||
(fn [m]
|
||||
(reduce (fn [acc [old new]]
|
||||
(if (contains? m old)
|
||||
(assoc acc new (get m old))
|
||||
acc))
|
||||
(apply dissoc m (keys kmap))
|
||||
kmap))
|
||||
xrel)))
|
||||
|
||||
(defn rename-keys
|
||||
"Returns the map with the keys in kmap renamed to the values in kmap."
|
||||
[map kmap]
|
||||
(reduce
|
||||
(fn [m [old new]]
|
||||
(if (contains? m old)
|
||||
(assoc m new (get m old) old nil)
|
||||
m))
|
||||
map kmap))
|
||||
(reduce (fn [m [old new]] (if (contains? m old) (assoc m new (get m old) old nil) m)) map kmap))
|
||||
|
||||
(defn map-invert
|
||||
"Returns the map with the vals mapped to the keys."
|
||||
[m]
|
||||
(reduce (fn [acc [k v]] (assoc acc v k)) {} m))
|
||||
|
||||
(defn join
|
||||
"When passed 2 rels, returns the rel corresponding to the natural
|
||||
join. When passed an additional keymap, joins on the corresponding
|
||||
keys."
|
||||
([xrel yrel]
|
||||
(if (and (seq xrel) (seq yrel))
|
||||
(let [ks (intersection (set (keys (first xrel)))
|
||||
(set (keys (first yrel))))
|
||||
idx (map-invert (zipmap (range) yrel))]
|
||||
(reduce (fn [acc x]
|
||||
(reduce (fn [acc y]
|
||||
(if (= (select-keys x ks)
|
||||
(select-keys y ks))
|
||||
(conj acc (merge x y))
|
||||
acc))
|
||||
acc yrel))
|
||||
#{} xrel))
|
||||
#{}))
|
||||
([xrel yrel kmap]
|
||||
(let [kmap (if (map? kmap) kmap (zipmap kmap kmap))
|
||||
idx (reduce (fn [m y]
|
||||
(assoc m (select-keys y (vals kmap)) y))
|
||||
{} yrel)]
|
||||
(reduce
|
||||
(fn [acc x]
|
||||
(let [found (get idx (select-keys x (keys kmap)))]
|
||||
(if found
|
||||
(conj acc (merge x (rename-keys found kmap)))
|
||||
acc)))
|
||||
#{} xrel))))
|
||||
(defn rename
|
||||
[xrel kmap]
|
||||
(set (map (fn [m]
|
||||
(reduce (fn [acc [old new]] (if (contains? m old) (assoc acc new (get m old)) acc))
|
||||
(apply dissoc m (keys kmap)) kmap)) xrel)))
|
||||
|
||||
(defn index
|
||||
"Returns a map of the distinct values of ks in the xrel mapped to a
|
||||
set of the maps in xrel with the corresponding values of ks."
|
||||
[xrel ks]
|
||||
(reduce (fn [m x]
|
||||
(let [ik (select-keys x ks)]
|
||||
(assoc m ik (conj (get m ik #{}) x))))
|
||||
{} xrel))
|
||||
(reduce (fn [m x] (let [ik (select-keys x ks)] (assoc m ik (conj (get m ik #{}) x)))) {} xrel))
|
||||
|
||||
(defn subset?
|
||||
"Is set1 a subset of set2?"
|
||||
[set1 set2]
|
||||
(and (<= (count set1) (count set2))
|
||||
(every? #(contains? set2 %) set1)))
|
||||
|
||||
(defn superset?
|
||||
"Is set1 a superset of set2?"
|
||||
[set1 set2]
|
||||
(and (>= (count set1) (count set2))
|
||||
(every? #(contains? set1 %) set2)))
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
(= 0 (count (str-trim s)))))
|
||||
|
||||
(defn capitalize
|
||||
"Converts first character of the string to upper-case, all other
|
||||
characters to lower-case."
|
||||
|
||||
[s]
|
||||
(if (< 1 (count s))
|
||||
(str (str-upper (subs s 0 1))
|
||||
|
|
@ -16,79 +15,78 @@
|
|||
(str-upper s)))
|
||||
|
||||
(defn lower-case
|
||||
"Converts string to all lower-case."
|
||||
|
||||
[s]
|
||||
(str-lower s))
|
||||
|
||||
(defn upper-case
|
||||
"Converts string to all upper-case."
|
||||
|
||||
[s]
|
||||
(str-upper s))
|
||||
|
||||
(defn includes?
|
||||
"True if s includes substr."
|
||||
|
||||
[s substr]
|
||||
(not (nil? (str-find substr s))))
|
||||
|
||||
(defn join
|
||||
"Returns a string of all elements in coll, separated by
|
||||
an optional separator."
|
||||
|
||||
([coll] (str-join coll))
|
||||
([separator coll] (str-join coll separator)))
|
||||
|
||||
(defn replace
|
||||
"Replaces all instance of match with replacement in s."
|
||||
|
||||
[s match replacement]
|
||||
(str-replace-all match s replacement))
|
||||
|
||||
(defn replace-first
|
||||
"Replaces the first instance of pattern in string with replacement."
|
||||
|
||||
[s match replacement]
|
||||
(str-replace match s replacement))
|
||||
|
||||
(defn str-reverse
|
||||
"Returns s with its characters reversed."
|
||||
|
||||
[s]
|
||||
(str-reverse-b s))
|
||||
|
||||
(defn split
|
||||
"Splits string on a regular expression. Optional limit."
|
||||
|
||||
([s re]
|
||||
(map str-trim (str-split re s)))
|
||||
([s re limit]
|
||||
(take limit (split s re))))
|
||||
|
||||
(defn starts-with?
|
||||
"True if s starts with substr."
|
||||
|
||||
[s substr]
|
||||
(let [slen (count s) slen2 (count substr)]
|
||||
(and (>= slen slen2)
|
||||
(= (subs s 0 slen2) substr))))
|
||||
|
||||
(defn ends-with?
|
||||
"True if s ends with substr."
|
||||
|
||||
[s substr]
|
||||
(let [slen (count s) slen2 (count substr)]
|
||||
(and (>= slen slen2)
|
||||
(= (subs s (- slen slen2)) substr))))
|
||||
|
||||
(defn trim
|
||||
"Removes whitespace from both ends of string."
|
||||
|
||||
[s]
|
||||
(str-trim s))
|
||||
|
||||
(defn triml
|
||||
"Removes whitespace from the left side of string."
|
||||
|
||||
[s]
|
||||
(str-triml s))
|
||||
|
||||
(defn trimr
|
||||
"Removes whitespace from the right side of string."
|
||||
|
||||
[s]
|
||||
(str-trimr s))
|
||||
|
||||
(defn trim-newline
|
||||
"Removes all trailing newline \\n or return \\r characters from string."
|
||||
|
||||
[s]
|
||||
(var result s)
|
||||
(while (or (= (subs result (dec (count result))) "\n")
|
||||
|
|
@ -97,7 +95,7 @@
|
|||
result)
|
||||
|
||||
(defn escape
|
||||
"Return a new string, using cmap to escape each character ch from s."
|
||||
|
||||
[s cmap]
|
||||
(apply str
|
||||
(map (fn [ch]
|
||||
|
|
@ -105,8 +103,7 @@
|
|||
s)))
|
||||
|
||||
(defn index-of
|
||||
"Return index of value (string or char) in s, optionally
|
||||
from start. Returns nil if not found."
|
||||
|
||||
([s value]
|
||||
(let [idx (str-find value s)]
|
||||
(when idx (inc idx))))
|
||||
|
|
@ -115,7 +112,7 @@
|
|||
(when idx (+ from (inc idx))))))
|
||||
|
||||
(defn last-index-of
|
||||
"Return last index of value (string or char) in s."
|
||||
|
||||
([s value]
|
||||
(let [r (str-reverse-b s) sval (str-reverse-b value)
|
||||
idx (str-find sval r)]
|
||||
|
|
|
|||
|
|
@ -1,77 +1,36 @@
|
|||
; Jolt Standard Library: clojure.walk
|
||||
; This file generalizes tree walking for Clojure data structures.
|
||||
; Tree walking for Clojure data structures.
|
||||
; Simplified: uses vector? and map? predicates (no list? or seq?).
|
||||
|
||||
(defn walk
|
||||
"Traverses form, an arbitrary data structure. inner and outer are
|
||||
functions. Applies inner to each element of form, building up a
|
||||
data structure of the same type, then applies outer to the result.
|
||||
Recognizes all Clojure data structures. Consumes seqs."
|
||||
[inner outer form]
|
||||
(cond
|
||||
(list? form) (outer (apply list (map inner form)))
|
||||
(seq? form) (outer (doall (map inner form)))
|
||||
(vector? form) (outer (vec (map inner form)))
|
||||
(map? form) (outer (into (empty form) (map inner form)))
|
||||
(set? form) (outer (into (empty form) (map inner form)))
|
||||
:else (outer form)))
|
||||
|
||||
(defn postwalk
|
||||
"Performs a depth-first, post-order traversal of form. Calls f on
|
||||
each sub-form, uses f's return value in place of the original.
|
||||
Recognizes all Clojure data structures. Consumes seqs."
|
||||
[f form]
|
||||
(walk (partial postwalk f) f form))
|
||||
|
||||
(defn prewalk
|
||||
"Like postwalk, but does pre-order traversal."
|
||||
[f form]
|
||||
(walk (partial prewalk f) identity (f form)))
|
||||
|
||||
(defn postwalk-demo
|
||||
"Demonstrates the behavior of postwalk by returning a lazy seq of
|
||||
forms passed to the postwalk outer function during the traversal
|
||||
of form."
|
||||
[form]
|
||||
(let [acc (atom [])]
|
||||
(postwalk (fn [x] (swap! acc conj x) x) form)
|
||||
@acc))
|
||||
|
||||
(defn prewalk-demo
|
||||
"Demonstrates the behavior of prewalk by returning a lazy seq of
|
||||
forms passed to the prewalk outer function during the traversal
|
||||
of form."
|
||||
[form]
|
||||
(let [acc (atom [])]
|
||||
(prewalk (fn [x] (swap! acc conj x) x) form)
|
||||
@acc))
|
||||
|
||||
(defn postwalk-replace
|
||||
"Recursively transforms form by replacing keys in smap with their
|
||||
values. Like clojure.string/replace but works with any data
|
||||
structure. Does replacement at the leaves of the tree first."
|
||||
[smap form]
|
||||
(postwalk (fn [x] (if (contains? smap x) (get smap x) x)) form))
|
||||
|
||||
(defn prewalk-replace
|
||||
"Recursively transforms form by replacing keys in smap with their
|
||||
values. Like postwalk-replace but does replacement at the root of
|
||||
the tree first."
|
||||
[smap form]
|
||||
(prewalk (fn [x] (if (contains? smap x) (get smap x) x)) form))
|
||||
|
||||
(defn keywordize-keys
|
||||
"Recursively transforms all map keys from strings to keywords."
|
||||
[m]
|
||||
(let [f (fn [[k v]] (if (string? k) [(keyword k) v] [k v]))]
|
||||
(postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
|
||||
|
||||
(defn stringify-keys
|
||||
"Recursively transforms all map keys from keywords to strings."
|
||||
[m]
|
||||
(let [f (fn [[k v]] (if (keyword? k) [(name k) v] [k v]))]
|
||||
(postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
|
||||
|
||||
(defn macroexpand-all
|
||||
"Recursively performs all possible macroexpansions in form."
|
||||
[form]
|
||||
(prewalk (fn [x] (if (seq? x) (macroexpand x) x)) form))
|
||||
|
|
|
|||
98
src/jolt/clojure/zip.clj
Normal file
98
src/jolt/clojure/zip.clj
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
; Jolt Standard Library: clojure.zip
|
||||
; Functional zipper for tree navigation and editing.
|
||||
|
||||
(defn zipper
|
||||
[branch? children make-node root]
|
||||
(let [z {:l [] :r [] :node root :pnodes [] :ppath nil :changed? false}]
|
||||
(if (branch? root)
|
||||
(let [chs (children root)]
|
||||
(assoc z :l (vec (rest chs)) :node (first chs) :pnodes (conj (:pnodes z) root)))
|
||||
z)))
|
||||
|
||||
(defn node [z] (:node z))
|
||||
(defn branch? [z] (and z (not (nil? (:node z)))))
|
||||
|
||||
(defn make-node [z node children]
|
||||
(let [m (assoc z :node node :changed? true)]
|
||||
(if children (assoc m :l (vec children)) m)))
|
||||
|
||||
(defn path [z] (:pnodes z))
|
||||
|
||||
(defn left [z]
|
||||
(let [ls (:l z)]
|
||||
(if (and (branch? z) (seq ls))
|
||||
(assoc z :l (vec (rest ls)) :node (first ls)) nil)))
|
||||
|
||||
(defn right [z]
|
||||
(if (and (branch? z) (seq (:r z)))
|
||||
(assoc z :l (conj (:l z) (:node z)) :node (first (:r z)) :r (vec (rest (:r z)))) nil))
|
||||
|
||||
(defn up [z]
|
||||
(if (seq (path z))
|
||||
(let [pn (peek (path z))]
|
||||
(assoc z :l nil :r (vec (concat (conj (:l z) (:node z)) (:r z))) :node pn :pnodes (pop (path z)))) nil))
|
||||
|
||||
(defn down [z]
|
||||
(when (branch? z)
|
||||
(let [chs (children z)]
|
||||
(when (seq chs)
|
||||
(assoc z :node (first chs) :l [] :r (vec (rest chs)) :pnodes (conj (path z) (:node z)))))))
|
||||
|
||||
(defn leftmost [z]
|
||||
(let [p (up z)] (if p (down p) z)))
|
||||
|
||||
(defn rightmost [z]
|
||||
(let [p (up z)]
|
||||
(if p
|
||||
(let [chs (children p)]
|
||||
(assoc z :node (last chs) :l (vec (butlast chs)) :r [] :pnodes (conj (pop (path z)) (:node p)))) z)))
|
||||
|
||||
(defn next [z]
|
||||
(if (= :end z) z
|
||||
(or (and (branch? z) (down z))
|
||||
(right z)
|
||||
(loop [p z]
|
||||
(if (up p)
|
||||
(or (right (up p)) (recur (up p)))
|
||||
(assoc z :node :end))))))
|
||||
|
||||
(defn prev [z]
|
||||
(if-let [l (left z)]
|
||||
(loop [l l]
|
||||
(if-let [d (and (branch? l) (down l))]
|
||||
(recur (rightmost d)) l)) (up z)))
|
||||
|
||||
(defn end? [z] (= :end (:node z)))
|
||||
|
||||
(defn remove [z]
|
||||
(if-let [p (up z)]
|
||||
(let [chs (children p)
|
||||
new-chs (remove #{(:node z)} chs)]
|
||||
(up (make-node p (:node p) new-chs))) (assoc z :node nil)))
|
||||
|
||||
(defn replace [z node]
|
||||
(assoc z :node node :changed? true))
|
||||
|
||||
(defn edit [z f & args]
|
||||
(replace z (apply f (:node z) args)))
|
||||
|
||||
(defn insert-left [z item]
|
||||
(assoc z :l (conj (:l z) item)))
|
||||
|
||||
(defn insert-right [z item]
|
||||
(assoc z :r (into [item] (:r z))))
|
||||
|
||||
(defn insert-child [z item]
|
||||
(assoc z :l (into [item] (:l z))))
|
||||
|
||||
(defn append-child [z item]
|
||||
(assoc z :l (conj (vec (:l z)) item)))
|
||||
|
||||
(defn root [z]
|
||||
(if (seq (path z)) (recur (up z)) (:node z)))
|
||||
|
||||
(defn vector-zip [root]
|
||||
(zipper vector? seq (fn [node children] (vec children)) root))
|
||||
|
||||
(defn seq-zip [root]
|
||||
(zipper seq? identity (fn [node children] (with-meta children (meta node))) root))
|
||||
|
|
@ -40,7 +40,8 @@
|
|||
|
||||
(defn core-every? [pred coll]
|
||||
(var result true)
|
||||
(each x coll (if (not (pred x)) (do (set result false) (break))))
|
||||
(each x (if (set? coll) (phs-seq coll) coll)
|
||||
(if (not (pred x)) (do (set result false) (break))))
|
||||
result)
|
||||
|
||||
# ============================================================
|
||||
|
|
@ -307,7 +308,7 @@
|
|||
|
||||
(defn core-filter [pred coll]
|
||||
(var result @[])
|
||||
(each x coll
|
||||
(each x (if (set? coll) (phs-seq coll) coll)
|
||||
(if (pred x) (array/push result x)))
|
||||
(if (tuple? coll) (tuple/slice (tuple ;result)) result))
|
||||
|
||||
|
|
@ -317,7 +318,8 @@
|
|||
(def core-reduce
|
||||
(fn [& args]
|
||||
(case (length args)
|
||||
2 (let [f (args 0) coll (args 1)]
|
||||
2 (let [f (args 0) coll (args 1)
|
||||
coll (if (set? coll) (phs-seq coll) coll)]
|
||||
(if (= 0 (length coll))
|
||||
(f)
|
||||
(do
|
||||
|
|
@ -327,7 +329,8 @@
|
|||
(set acc (f acc (coll i)))
|
||||
(++ i))
|
||||
acc)))
|
||||
3 (let [f (args 0) val (args 1) coll (args 2)]
|
||||
3 (let [f (args 0) val (args 1) coll (args 2)
|
||||
coll (if (set? coll) (phs-seq coll) coll)]
|
||||
(var acc val)
|
||||
(each x coll (set acc (f acc x)))
|
||||
acc)
|
||||
|
|
|
|||
12
src/jolt/jolt/http.clj
Normal file
12
src/jolt/jolt/http.clj
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
; Jolt Standard Library: jolt.http
|
||||
; HTTP client using Janet's net/ module.
|
||||
|
||||
(defn get
|
||||
[url & {:keys [headers]}]
|
||||
(let [result (net/request url :get headers {})]
|
||||
{:status (result :status) :body (result :body) :headers (result :headers)}))
|
||||
|
||||
(defn post
|
||||
[url body & {:keys [headers]}]
|
||||
(let [result (net/request url :post headers body)]
|
||||
{:status (result :status) :body (result :body) :headers (result :headers)}))
|
||||
26
src/jolt/jolt/interop.clj
Normal file
26
src/jolt/jolt/interop.clj
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
; Jolt Standard Library: jolt.interop
|
||||
; Janet interop helpers for Jolt.
|
||||
|
||||
(defn janet-eval
|
||||
[s]
|
||||
(eval (parse s)))
|
||||
|
||||
(defn janet-type
|
||||
[x]
|
||||
(type x))
|
||||
|
||||
(defn janet-describe
|
||||
[x]
|
||||
(describe x))
|
||||
|
||||
(defn janet-table-keys
|
||||
[t]
|
||||
(keys t))
|
||||
|
||||
(defn janet-table-vals
|
||||
[t]
|
||||
(vals t))
|
||||
|
||||
(defn janet-table->map
|
||||
[t]
|
||||
(into {} (map (fn [k] [k (get t k)]) (keys t))))
|
||||
12
src/jolt/jolt/shell.clj
Normal file
12
src/jolt/jolt/shell.clj
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
; Jolt Standard Library: jolt.shell
|
||||
; Shell command execution via Janet's os/shell.
|
||||
|
||||
(defn sh
|
||||
[& args]
|
||||
(let [cmd (apply str (interpose " " args))
|
||||
result (os/shell cmd)]
|
||||
{:exit (result 0) :out (result 1) :err (result 2)}))
|
||||
|
||||
(defn shell
|
||||
[& args]
|
||||
(:out (apply sh args)))
|
||||
Loading…
Add table
Add a link
Reference in a new issue