(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.

Example

(parse "(+ 1 2)")

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))))))))