         tag = 'BOOL'
     @token tag, id
     @token ':', ':' if colon
-    true
+    input.length
 
   # Matches numbers, including decimals, hex, and exponential notation.
   # Be careful not to interfere with ranges-in-progress.
   numberToken: ->
-    return false unless match = NUMBER.exec @chunk
+    return 0 unless match = NUMBER.exec @chunk
     number = match[0]
-    return false if @tag() is '.' and number.charAt(0) is '.'
-    @i += number.length
+    return 0 if @tag() is '.' and number.charAt(0) is '.'
     @token 'NUMBER', number
-    true
+    number.length
 
   # Matches strings, including multi-line strings. Ensures that quotation marks
   # are balanced within the string's contents, and within nested interpolations.
   stringToken: ->
     switch @chunk.charAt 0
       when "'"
-        return false unless match = SIMPLESTR.exec @chunk
+        return 0 unless match = SIMPLESTR.exec @chunk
         @token 'STRING', (string = match[0]).replace MULTILINER, '\\\n'
       when '"'
-        return false unless string = @balancedString @chunk, [['"', '"'], ['#{', '}']]
+        return 0 unless string = @balancedString @chunk, [['"', '"'], ['#{', '}']]
         if 0 < string.indexOf '#{', 1
           @interpolateString string.slice 1, -1
         else
           @token 'STRING', @escapeLines string
       else
-        return false
+        return 0
     @line += count string, '\n'
-    @i += string.length
-    true
+    string.length
 
   # Matches heredocs, adjusting indentation to the correct level, as heredocs
   # preserve whitespace, but ignore indentation to the left.
   heredocToken: ->
-    return false unless match = HEREDOC.exec @chunk
+    return 0 unless match = HEREDOC.exec @chunk
     heredoc = match[0]
     quote = heredoc.charAt 0
     doc = @sanitizeHeredoc match[2], {quote, indent: null}

      @indebt = 0
      @outdentToken @indent - size, noNewlines
    @indent = size
    true

  # Record an outdent token or multiple tokens, if we happen to be moving back
  # inwards past several recorded indents.

  # referenced as property names here, so you can still do `jQuery.is()` even
  # though `is` means `===` otherwise.
  identifierToken: ->
    return 0 unless match = IDENTIFIER.exec @chunk
    [input, id, colon] = match
    if id is 'all' and @tag() is 'FOR'
      @token 'ALL', id
      return 3
    if id is 'from' and @tag(1) is 'FOR'
      @seenFor  = no
      @seenFrom = yes
      @token 'FROM', id
      return 4
    if id is 'to' and @seenFrom
      @seenFrom = no
      @token 'TO', id
      return 2
    forcedIdentifier = colon or @tagAccessor()
    tag = 'IDENTIFIER'
    if id in JS_KEYWORDS or
