def parse_moves
      s0 = @current_pos
      s1 = parse_firstboard
      if s1 != :failed
        s2 = []
        s3 = parse_move
        while s3 != :failed
          s2 << s3
          s3 = parse_move
        end
        s3 = parse_result
        s3 = nil if s3 == :failed
        @reported_pos = s0
        s0 = -> (hd, tl, res) do
          tl.unshift(hd)
          tl << { "special" => res } if res && !tl[tl.length - 1]["special"]
          tl
        end.call(s1, s2, s3)
      else
        @current_pos = s0
        s0 = :failed
      end
      s0
    end
def parse_moves
      s0 = @current_pos
      s1 = parse_firstboard
      if s1 != :failed
        s2 = []
        s3 = parse_move
        while s3 != :failed
          s2 << s3
          s3 = parse_move
        end
        s3 = parse_result
        s3 = nil if s3 == :failed
        @reported_pos = s0
        s0 = -> (hd, tl, res) do
          tl.unshift(hd)
          tl << { "special" => res } if res && !tl[tl.length - 1]["special"]
          tl
        end.call(s1, s2, s3)
      else
        @current_pos = s0
        s0 = :failed
      end
      s0
    end
moves : firstboard : move* result?