Skip to content

Instantly share code, notes, and snippets.

@micha
Last active February 6, 2016 17:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micha/9da4d8f28714c89f664b to your computer and use it in GitHub Desktop.
Save micha/9da4d8f28714c89f664b to your computer and use it in GitHub Desktop.
(ns jt.core)
(defn jt*
([in-stack op-stack args] (jt* in-stack op-stack [[]] args))
([[i & is :as in-stack] [op & ops :as op-stack] table [x & xs :as args]]
(cond (nil? x) table
(vector? i) (let [is (next in-stack)
jt #(jt* (conj is %) op-stack args)]
(for [r1 table r2 (mapcat jt i)] (into r1 r2)))
:else (case x
"[" (let [os (if-not (seq op)
op-stack
(conj ops (conj op nil)))]
(jt* in-stack (conj os []) table xs))
"]" (let [ps (when (peek op) ["-p"])
us (repeat (count (keep identity op)) "-u")]
(jt* in-stack ops table (concat ps us xs)))
"-u" (jt* (next in-stack) op-stack table xs)
"-p" (jt* in-stack op-stack (mapv #(conj % i) table) xs)
"-d" (jt* (conj in-stack (get i (first xs))) op-stack table (rest xs))
(jt* in-stack (conj ops (conj op x)) table (conj args "-d"))))))
(defn jt
[in args]
(loop [[a & as :as args] args conf {:fs "\t" :rs "\n"}]
(case a
"-F" (recur (next as) (assoc conf :fs (first as)))
"-R" (recur (next as) (assoc conf :rs (first as)))
(doseq [row (jt* (list in) () args)]
(print (apply str (concat (interpose (:fs conf) row) [(:rs conf)])))))))
(comment
(require '[clojure.string :refer [split]])
(def in
{"Type" "frob"
"Poobs" [{"Foop" 100}
{"Foop" 200}
{"Foop" 300}]
"Things" [{"ThingName" "t1"
"Items" [{"ItemName" "i1"}
{"ItemName" "i2"}]}
{"ThingName" "t2"
"Items" [{"ItemName" "i3"}
{"ItemName" "i4"}]}]})
(defn jtsh
[in argstr]
(jt in (split argstr #" ")))
;; normal unix options
(jtsh in "-d Type -p -u -d Poobs -d Foop -p -u -u -d Things -d ThingName -p -u -d Items -d ItemName -p -u -u")
;; produces this result on stdout:
frob 100 t1 i1
frob 100 t1 i2
frob 100 t2 i3
frob 100 t2 i4
frob 200 t1 i1
frob 200 t1 i2
frob 200 t2 i3
frob 200 t2 i4
frob 300 t1 i1
frob 300 t1 i2
frob 300 t2 i3
frob 300 t2 i4
;; equivalent (better?) option format
(jtsh in "-F : [ Type ] [ Poobs Foop ] [ Things [ ThingName ] [ Items ItemName ] ]")
;; produces this result on stdout:
frob:100:t1:i1
frob:100:t1:i2
frob:100:t2:i3
frob:100:t2:i4
frob:200:t1:i1
frob:200:t1:i2
frob:200:t2:i3
frob:200:t2:i4
frob:300:t1:i1
frob:300:t1:i2
frob:300:t2:i3
frob:300:t2:i4
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment