I only spent about 30 minutes on this and it does a minimal job of  
passing the current tests (plus the ones added by Sander). It'll  
break when other ruby expression types (if/case/blocks) are thrown at  
it, but those are really easy to cover if need be. That said, I  
thought this was a good example of the power of ParseTree.

This requires the latest release of ParseTree. The rest came from  
ZenHacks/ruby2ruby but I extracted the crucial bits and put them in  
here directly.

#!/usr/local/bin/ruby -w

# Your mission: Create a function named sxp() that can take a block
# (not a string), and create an s-expression representing the code in
# the block.

require 'rubygems'
require 'parse_tree'
require 'sexp_processor'

############################################################
# From unreleased ruby2ruby:

class ProcStoreTmp
   @@n = 0
   def self.name
     @@n += 1
     return :"myproc#{@@n}"
   end
end

class Method
   def with_class_and_method_name
     if self.inspect =~ /<Method: (.*)\#(.*)>/ then
       klass = eval $1 # cheap
       method  = $2.intern
       raise "Couldn't determine class from #{self.inspect}" if  
klass.nil?
       return yield(klass, method)
     else
       raise "Can't parse signature: #{self.inspect}"
     end
   end

   def to_sexp
     with_class_and_method_name do |klass, method|
       ParseTree.new(false).parse_tree_for_method(klass, method)
     end
   end
end

class Proc
   def to_method
     name = ProcStoreTmp.name
     ProcStoreTmp.send(:define_method, name, self)
     ProcStoreTmp.new.method(name)
   end

   def to_sexp
     body = self.to_method.to_sexp[2][1..-1]
     [:proc, *body]
   end
end

# END unreleased ruby2ruby:
############################################################


class Quiz < SexpProcessor
   def initialize
     super
     self.auto_shift_type = true
     self.strict = false
     self.expected = Object
   end

   def process_proc(exp)
     return * _list(exp)
   end

   def process_fcall(exp)
     [exp.shift, process(exp.shift)]
   end

   def process_call(exp)
     lhs = process(exp.shift)
     name = exp.shift
     rhs = process(exp.shift)
     [name, lhs, rhs].compact
   end

   def process_array(exp)
     return * _list(exp)
   end

   def process_lit(exp)
     exp.shift
   end

   def process_str(exp)
     exp.shift
   end

   def _list(exp)
     result = []
     until exp.empty? do
       result << process(exp.shift)
     end
     result
   end
end

def sxp(&block)
   Quiz.new.process(block.to_sexp)
end

if $0 == __FILE__ then
   require 'test/unit'

   class TestQuiz < Test::Unit::TestCase
     def test_sxp_nested_calls
       assert_equal [:max, [:count, :name]], sxp{max(count(:name))}
     end

     def test_sxp_call_plus_eval
       assert_equal [:count, [:+, 3, 7]], sxp{count(3+7)}
     end

     def test_sxp_binarymsg_mixed_1
       assert_equal [:+, 3, :symbol], sxp{3+:symbol}
     end

     def test_sxp_binarymsg_mixed_call
       assert_equal [:+, 3, [:count, :field]], sxp{3+count(:field)}
     end

     def test_sxp_binarymsg_mixed_2
       assert_equal [:/, 7, :field], sxp{7/:field}
     end

     def test_sxp_binarymsg_mixed_3
       assert_equal [:>, :field, 5], sxp{:field > 5}
     end

     def test_sxp_lits
       assert_equal 8, sxp{8}
     end

     def test_sxp_binarymsg_syms
       assert_equal [:==, :field1, :field2], sxp{:field1 == :field2 }
     end

     def test_sxp_from_sander_dot_land_at_gmail_com
       assert_equal [:==,[:^, 2, 3], [:^, 1, 1]], sxp{ 2^3 == 1^1}
       assert_equal [:==, [:+, 3.0, 0.1415], 3], sxp{3.0 + 0.1415 == 3}

       assert_equal([:|,
                     [:==, [:+, :hello, :world], :helloworld],
                     [:==, [:+, [:+, "hello", " "], "world"], "hello  
world"]] ,
                    sxp {
                      (:hello + :world == :helloworld) |
                      ('hello' + ' ' + 'world' == 'hello world')
                    })

       assert_equal  [:==, [:+, [:abs, [:factorial, 3]], [:*,  
[:factorial, 4], 42]],
                      [:+, [:+, 4000000, [:**, 2, 32]], [:%, 2.7,  
1.1]]],
       sxp{ 3.factorial.abs + 4.factorial * 42 ==  4_000_000 + 2**32  
+ 2.7 % 1.1 }
     end

     def test_ihavenocluewhy
       assert_equal 11, 5 + 6
       assert_raise(TypeError) { 7 / :field }
       assert_raise(NoMethodError) { 7+count(:field) }
       assert_raise(NoMethodError) { :field > 5 }
     end
   end
end