def process(exp)
return nil if exp.nil?
if self.context.empty? then
p :rewriting unless debug.empty?
exp = self.rewrite(exp)
p :done_rewriting unless debug.empty?
end
unless @unsupported_checked then
m = public_methods.grep(/^process_/) { |o| o.to_s.sub(/^process_/, '').to_sym }
supported = m - (m - @unsupported)
raise UnsupportedNodeError, "#{supported.inspect} shouldn't be in @unsupported" unless supported.empty?
@unsupported_checked = true
end
result = self.expected.new
type = exp.first
raise "type should be a Symbol, not: #{exp.first.inspect}" unless
Symbol === type
in_context type do
if @debug.has_key? type then
str = exp.inspect
puts "// DEBUG:(original ): #{str}" if str =~ @debug[type]
end
exp_orig = nil
exp_orig = exp.deep_clone if $DEBUG or
@debug.has_key? type or @exceptions.has_key?(type)
raise UnsupportedNodeError, "'#{type}' is not a supported node type" if
@unsupported.include? type
meth = @processors[type] || @default_method
if meth then
if @warn_on_default and meth == @default_method then
warn "WARNING: Using default method #{meth} for #{type}"
end
exp.shift if @auto_shift_type and meth != @default_method
result = error_handler(type, exp_orig) do
self.send(meth, exp)
end
if @debug.has_key? type then
str = exp.inspect
puts "// DEBUG (processed): #{str}" if str =~ @debug[type]
end
raise SexpTypeError, "Result must be a #{@expected}, was #{result.class}:#{result.inspect}" unless @expected === result
self.assert_empty(meth, exp, exp_orig) if @require_empty
else
unless @strict then
until exp.empty? do
sub_exp = exp.shift
sub_result = nil
if Array === sub_exp then
sub_result = error_handler(type, exp_orig) do
process(sub_exp)
end
raise "Result is a bad type" unless Array === sub_exp
raise "Result does not have a type in front: #{sub_exp.inspect}" unless Symbol === sub_exp.first unless sub_exp.empty?
else
sub_result = sub_exp
end
result << sub_result
end
begin
result.sexp_type = exp.sexp_type
rescue Exception
end
else
msg = "Bug! Unknown node-type #{type.inspect} to #{self.class}"
msg += " in #{exp_orig.inspect} from #{caller.inspect}" if $DEBUG
raise UnknownNodeError, msg
end
end
end
result
end