 ;; start and end position (each a vector [line column] counting from 1).
 
 ;; File information, if any, to include together with token position
-(def ^:dynamic *file* false)
+(def ^:dynamic *file* nil)
 
 (defn init-state [input]
-  [(delta/positioned-stream input {:line-offset 1 :column-offset 0}) '(0) ()])
+  [(delta/positioned-stream input {:line-offset 1 :column-offset 0}) () '(0) ()])
 
 (defn σ-in [σ] (σ 0))
-(defn σ-indent-stack [σ] (σ 1))
-(defn σ-out [σ] (σ 2))
+(defn σ-out [σ] (σ 1))
+(defn σ-indent-stack [σ] (σ 2))
+(defn σ-delim-stack [σ] (σ 3))
 
 (defn in-char [in] (let [[[x]] in] x))
 (defn in-position [in] (let [[[_ l c]] in] [l c]))

(defn &position [σ] [(in-column (σ-in σ)) σ])
(defn &column [σ] [(in-column (σ-in σ)) σ])
(defn &indent-stack [σ] [(σ-indent-stack σ) σ])
(defn &read-char [[in is out]] [(in-char in) [(rest in) is out]])
(defn &emit [& α] (fn [[in is out]] [nil [in is (apply conj out α)]]))
(defn &done? [σ] [(done? σ) σ])
(defn &flush [[in is out]] [(reverse out) [in is ()]])
(defn &neof [σ] ((if (done? σ) (&error {:r "unexpected EOF"}) &nil) σ))
(defn &eof [σ] ((if (done? σ) &nil (&error {:r "expected EOF"})) σ))


    (+ col0 col1)))

(defn &indent [column]
  (fn [[in out [top :as is] ds :as σ]]
    (let [pos (in-position in)
          info [*file* pos pos]
          tok+ #(conj % [%2 nil info])]
      (if (> column top)
        [nil [in (tok+ out :indent) (conj is column) ds]]
        (loop [[top & ris :as is] is
               out out]
          (cond
           (= column top) [nil [in out is ds]]
           (or (empty? ris) (> column top)) ((&error {:r "invalid dedentation"}) σ)
           :else (recur ris (tok+ out :dedent))))))))

(defn char-range [first last]
  (map char (range (int first) (inc (int last)))))
