   ([]
      (&error {}))
   ([details]
-     (fn [[in _ _]]
+     (fn [[in]]
        (let [[l c] (in-position in)]
          (fail (conj details [:file *file*] [:line l] [:column c]))))))
 (def &fail (&error))

          \v (&return \u000b) ;; ASCII Vertical Tab (VT)
          \N (if (= ub \u) &named-char &fail)
          \x &latin1-char ;; \xhh Character with hex value hh
          \u &unicode-char-16 ;; \uxxxx	Character with 16-bit hex value xxxx (Unicode only)
          \U &unicode-char-32 ;; \Uxxxxxxxx Character with 32-bit hex value xxxxxxxx (Unicode only)
          (if (oct-digit c) &octal-char &fail)))]
   x))

    _ (&string-end-quote long? q)]
   [:string [s long? q ub r]]))

(def &numeric-literal
  (&error {:r "&numeric-literal is not implemented yet"}))

(def delimiters
  '("@" "," ":" "." "`" "=" ";"
    "+=" "-=" "*=" "/=" "//" "%="
    "&=" "|=" "^=" ">>=" "<<=" "**="))

(def operators
  '("+" "-" "*" "**" "/" "//" "%"
    "<<" ">>" "&" "|" "^" "~"
    "<=" ">=" "==" "!=" "<>" "<" ">"))

(def delimiters-and-operators
  ;; Order matters: prefixes must come afterwards, or we must use a better decision algorithm.
  (sort-by count > (concat delimiters operators)))

(def &delimiter-or-operator
  (&let [s (&or* (map #(&string= %) delimiters-and-operators))]
    [(keyword s) nil]))

(def paren-closer {\( \) \[ \] \{ \}})

(def &paren
  (&or
   (&bind (&char-if #{\( \[ \{})
          #(fn [[in out is ds]]
             [[% nil] [in out is (conj ds (paren-closer %))]]))
   (&bind (&char-if #{\) \] \}})
          #(fn [[in out is ds :as σ]]
             [[% nil]
              [in out is (if (= % (first ds)) (rest ds) ((&error {:r "Unmatched delimiter"}) σ))]]))))

(def &token
  (&let
   [start &position
    [type data] (&or &string-literal &numeric-literal
                     &paren &ident-or-keyword &delimiter-or-operator)
    end &position
      (&emit [type data [*file* start end]])]
   nil))
