lib/processor.rb in rubyless-0.2.0 vs lib/processor.rb in rubyless-0.3.0

- old
+ new

@@ -1,33 +1,42 @@ require 'rubygems' -require 'parse_tree' +require 'ruby_parser' +require 'sexp_processor' require 'basic_types' require 'typed_string' require 'safe_class' +require 'ruby-debug' +Debugger.start -module RubyLess +module RubyLess class RubyLessProcessor < SexpProcessor attr_reader :ruby INFIX_OPERATOR = [:"<=>", :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%] PREFIX_OPERATOR = [:"-@"] def self.translate(string, helper) - sexp = ParseTree.translate(string) + sexp = RubyParser.new.parse(string) self.new(helper).process(sexp) end def initialize(helper) super() - @helper = helper - @indent = " " + @helper = helper + @indent = " " self.auto_shift_type = true self.strict = true self.expected = TypedString end + #def process(exp) + # return nil if exp.nil? + # method = exp.shift + # send("process_#{method}", exp) + #end + def process_and(exp) t "(#{process(exp.shift)} and #{process(exp.shift)})", Boolean end def process_or(exp) @@ -35,16 +44,16 @@ end def process_not(exp) t "not #{process(exp.shift)}", Boolean end - + def process_if(exp) cond = process(exp.shift) true_res = process(exp.shift) false_res = process(exp.shift) - + if true_res && false_res && true_res.klass != false_res.klass raise "Error in conditional expression: '#{true_res}' and '#{false_res}' do not return results of same type (#{true_res.klass} != #{false_res.klass})." end raise "Error in conditional expression." unless true_res || false_res opts = {} @@ -88,11 +97,12 @@ method = opts[:method] || var_name.to_s t method, opts end def process_lit(exp) - t exp.shift.to_s, Number + lit = exp.shift + t lit.inspect, lit.class == Symbol ? Symbol : Number end def process_str(exp) t exp.shift.inspect, String end @@ -112,19 +122,19 @@ elsif !opts.kind_of?(Hash) opts = {:class => opts} end TypedString.new(content, opts) end - + def t_if(cond, true_res, opts) if cond != [] if cond.size > 1 condition = "(#{cond.join(' && ')})" else condition = cond.join('') end - + # we can append to 'raw' if opts[:nil] # applied method could produce a nil value (so we cannot concat method on top of 'raw' and only check previous condition) t "(#{condition} ? #{true_res} : nil)", opts else @@ -136,41 +146,48 @@ end end def method_call(receiver, exp) method = exp.shift - if args = exp.shift rescue nil - args = process args || [] - signature = [method] + [args.klass].flatten ## FIXME: error prone ! + arg_sexp = args = exp.shift # rescue nil + if arg_sexp + args = process(arg_sexp) + if args == '' + signature = [method] + else + signature = [method] + [args.klass].flatten + end # execution conditional cond = args.cond || [] else args = [] signature = [method] cond = [] end - + if receiver if receiver.could_be_nil? cond += receiver.cond end - raise "'#{receiver}' does not respond to '#{method}(#{args.raw})'." unless opts = get_method(signature, receiver.klass) + raise "'#{receiver}' does not respond to '#{method}(#{signature[1..-1].join(', ')})'." unless opts = get_method(signature, receiver.klass) method = opts[:method] if opts[:method] if method == :/ t_if cond, "(#{receiver.raw}#{method}#{args.raw} rescue nil)", opts.merge(:nil => true) elsif INFIX_OPERATOR.include?(method) t_if cond, "(#{receiver.raw}#{method}#{args.raw})", opts elsif PREFIX_OPERATOR.include?(method) t_if cond, "#{method.to_s[0..0]}#{receiver.raw}", opts + elsif method == :[] + t_if cond, "#{receiver.raw}[#{args.raw}]", opts else - args = "(#{args.raw})" if args != [] + args = "(#{args.raw})" if args != '' t_if cond, "#{receiver.raw}.#{method}#{args}", opts end else raise "Unknown method '#{method}(#{args.raw})'." unless opts = get_method(signature, @helper, false) method = opts[:method] if opts[:method] - args = "(#{args.raw})" if args != [] + args = "(#{args.raw})" if args != '' t_if cond, "#{method}#{args}", opts end end def parse_dstr(exp, in_regex = false) @@ -190,10 +207,10 @@ def escape_str(str, in_regex = false) res = str.gsub(/"/, '\"').gsub(/\n/, '\n') res.gsub!(/\//, '\/') if in_regex res end - + def get_method(signature, receiver, is_method = true) res = receiver.respond_to?(:safe_method_type) ? receiver.safe_method_type(signature) : SafeClass.safe_method_type_for(receiver, signature) res = res.call(@helper) if res.kind_of?(Proc) res end