(parse input)
(parse input opts)
Returns a hierarcichal (I can never spell that goddamn word) vector of tuples
representing each distinct Clojure token from the input string. Takes an options
map that allows you to apply parinferish via the :mode option (:indent, :paren, :smart).
Note that if you use parinfer, the return value will include both the inserted and removed
tokens. The tokens parinfer wants to remove will be removed by the `flatten` function.
Source
(defn
parse
"Returns a hierarcichal (I can never spell that goddamn word) vector of tuples\n representing each distinct Clojure token from the input string. Takes an options\n map that allows you to apply parinferish via the :mode option (:indent, :paren, :smart).\n Note that if you use parinfer, the return value will include both the inserted and removed\n tokens. The tokens parinfer wants to remove will be removed by the `flatten` function."
([input] (parse input {}))
([input opts]
(when
(and
(= :smart (:mode opts))
(or (nil? (:cursor-line opts)) (nil? (:cursor-column opts))))
(throw
(ex-info
"Smart mode requires :cursor-line and :cursor-column"
{})))
(let
[*error
(volatile! nil)
*line
(volatile! 0)
*column
(volatile! 0)
*indent
(volatile! 0)
tokens
(loop
[input-str input tokens (transient []) last-token nil]
(if-let
[[group-name token]
(some
(fn
[[group-name regex]]
(when-let
[match (re-find regex input-str)]
[group-name match]))
regexes)]
(let
[token
(if
(= group-name :string)
(parse-string token input-str)
token)
token-data
(read-token
group-name
token
*error
*line
*column
*indent
last-token)]
(recur
(subs input-str (count token))
(conj! tokens token-data)
token-data))
(persistent! tokens)))
opts
(assoc opts :*error *error :*index (volatile! -1))
opts
(cond-> opts @*error (dissoc :mode))]
(loop
[structured-tokens []]
(if-let
[token-data (read-useful-token tokens opts)]
(recur (conj structured-tokens token-data))
(let
[{:keys [mode]} opts]
(vary-meta
structured-tokens
assoc
:mode
mode
:error?
(some? @*error))))))))