class Sexp

ZenTest FULL

def self.for(klass, method = nil, walk_ancestors = false)

def self.for(klass, method = nil, walk_ancestors = false)
  require 'parse_tree'
  sexp = if walk_ancestors and method then
           klass.ancestors.each do |klass|
             sexp = ParseTree.translate klass, method
             break sexp unless sexp == [nil]
           end
         else
           ParseTree.translate klass, method
         end
  Sexp.from_array sexp
end

def self.from_array(a)

def self.from_array(a)
  ary = Array === a ? a : [a]
  result = self.new
  ary.each do |x|
    case x
    when Sexp
      result << x
    when Array
      result << self.from_array(x)
    else
      result << x
    end
  end
  result
end

def ==(obj) # :nodoc:

:nodoc:
def ==(obj) # :nodoc:
  if obj.class == self.class then
    super
  else
    false
  end
end

def ===(sexp)

def ===(sexp)
  return nil unless Sexp === sexp
  pattern = self # this is just for my brain
  return true if pattern == sexp
  sexp.each do |subset|
    return true if pattern === subset
  end
  return nil
end

def =~(pattern)

def =~(pattern)
  return pattern === self
end

def array_type?

def array_type?
  type = self.first
  @@array_types.include? type
end

def each_of_type(t, &b)

def each_of_type(t, &b)
  each do | elem |
    if Sexp === elem then
      elem.each_of_type(t, &b)
      b.call(elem) if elem.first == t
    end
  end
end

def find_and_replace_all(from, to)

def find_and_replace_all(from, to)
  each_with_index do | elem, index |
    if Sexp === elem then
      elem.find_and_replace_all(from, to)
    else
      self[index] = to if elem == from
    end
  end
end

def gsub(pattern, repl)

def gsub(pattern, repl)
  return repl if pattern == self
  new = self.map do |subset|
    case subset
    when Sexp then
      subset.gsub(pattern, repl)
    else
      subset
    end
  end
  return Sexp.from_array(new)
end

def initialize(*args)

def initialize(*args)
  super(args)
end

def inspect # :nodoc:

:nodoc:
def inspect # :nodoc:
  sexp_str = self.map {|x|x.inspect}.join(', ')
  return "s(#{sexp_str})"
end

def method_missing(meth, delete=false)

def method_missing(meth, delete=false)
  matches = find_all { | sexp | Sexp === sexp and sexp.first == meth }
  case matches.size
  when 0 then
    nil
  when 1 then
    match = matches.first
    delete match if delete
    match
  else
    raise NoMethodError, "multiple nodes for #{meth} were found in #{inspect}"
  end
end

def pretty_print(q) # :nodoc:

:nodoc:
def pretty_print(q) # :nodoc:
  q.group(1, 's(', ')') do
    q.seplist(self) {|v| q.pp v }
  end
end

def sexp_body

def sexp_body
  self[1..-1]
end

def shift

def shift
  raise "I'm empty" if self.empty?
  super
end if $DEBUG or $TESTING

def structure

def structure
  result = self.class.new
  if Array === self.first then
    result = self.first.structure
  else
    result << self.first
    self.grep(Array).each do |subexp|
      result << subexp.structure
    end
  end
  result
end

def sub(pattern, repl)

def sub(pattern, repl)
  return repl.dup if pattern == self
  done = false
  new = self.map do |subset|
    if done then
      subset
    else
      case subset
      when Sexp then
        if pattern == subset then
          done = true
          repl.dup
        elsif pattern === subset then
          done = true
          subset.sub pattern, repl
        else
          subset
        end
      else
        subset
      end
    end
  end
  return Sexp.from_array(new)
end

def to_a # :nodoc:

:nodoc:
def to_a # :nodoc:
  self.map { |o| Sexp === o ? o.to_a : o }
end

def to_s # :nodoc:

:nodoc:
def to_s # :nodoc:
  inspect
end