class Sexp

def + o # :nodoc:

:nodoc:
def + o # :nodoc:
  self.dup.concat o
end

def [] a # :nodoc:

:nodoc:
def [] a # :nodoc:
  # TODO: figure out a way to make this STRICT_SEXP happy
  s = super
  if Sexp === s then
    s.file = self.file
    s.line = self.line
    s.modified = self.modified
  end
  s
end

def all_structural_subhashes

def all_structural_subhashes
  hashes = []
  self.deep_each do |node|
    hashes << node.structural_hash
  end
  hashes
end

def code_index

def code_index
  {
   :block  => 0,    # s(:block,                   *code)
   :class  => 2,    # s(:class,      name, super, *code)
   :module => 1,    # s(:module,     name,        *code)
   :defn   => 2,    # s(:defn,       name, args,  *code)
   :defs   => 3,    # s(:defs, recv, name, args,  *code)
   :iter   => 2,    # s(:iter, recv,       args,  *code)
  }[self.sexp_type]
end

def initialize_copy o # :nodoc:

:nodoc:
def initialize_copy o # :nodoc:
  s = super
  s.file = o.file
  s.line = o.line
  s.modified = o.modified
  s
end

def pure_ruby_hash # :nodoc: see above

:nodoc: see above
def pure_ruby_hash # :nodoc: see above
  hash = 0
  n = NODE_NAMES[sexp_type]
  raise "Bad lookup: #{first} in #{sexp.inspect}" unless n
  hash += n          & MAX_INT32
  hash += hash << 10 & MAX_INT32
  hash ^= hash >>  6 & MAX_INT32
  each do |o|
    next unless Sexp === o
    hash = hash + o.pure_ruby_hash  & MAX_INT32
    hash = (hash + (hash << 10)) & MAX_INT32
    hash = (hash ^ (hash >>  6)) & MAX_INT32
  end
  hash = (hash + (hash <<  3)) & MAX_INT32
  hash = (hash ^ (hash >> 11)) & MAX_INT32
  hash = (hash + (hash << 15)) & MAX_INT32
  hash
end

def split_at n

def split_at n
  return self[0..n], self[n+1..-1]
end

def split_code

def split_code
  index = self.code_index
  self.split_at index if index
end

def structural_hash

def structural_hash
  @structural_hash ||= pure_ruby_hash
end