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