Class: RADRewriter

Inherits:
Rewriter
  • Object
show all
Defined in:
lib/rad/rad_rewriter.rb

Instance Method Summary collapse

Constructor Details

#initializeRADRewriter

:nodoc:



4
5
6
7
# File 'lib/rad/rad_rewriter.rb', line 4

def initialize # :nodoc:
  super
  self.auto_shift_type = true
end

Instance Method Details

#process_iter(exp) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/rad/rad_rewriter.rb', line 9

def process_iter(exp)
  call = process exp.shift
  var  = process exp.shift
  body = process exp.shift

  var = s(:dasgn_curr, Unique.next) if var.nil?

  assert_type call, :call

  if call[2] != :each then # TODO: fix call[n] (api)
    call.shift # :call
    lhs = call.shift
    method_name = call.shift

    case method_name
    when :downto then
      var.shift # 
      start_value = lhs
      finish_value = call.pop.pop # not sure about this
      var_name = var.shift
      body.find_and_replace_all(:dvar, :lvar)
      result = s(:dummy,
                 s(:lasgn, var_name, start_value),
                 s(:while,
                   s(:call, s(:lvar, var_name), :>=,
                     s(:arglist, finish_value)),
                   s(:block,
                     body,
                     s(:lasgn, var_name,
                       s(:call, s(:lvar, var_name), :-,
                         s(:arglist, s(:lit, 1))))), true))
    when :upto then
      # REFACTOR: completely duped from above and direction changed
      var.shift # 
      start_value = lhs
      finish_value = call.pop.pop # not sure about this
      var_name = var.shift
      body.find_and_replace_all(:dvar, :lvar)
      result = s(:dummy,
                 s(:lasgn, var_name, start_value),
                 s(:while,
                   s(:call, s(:lvar, var_name), :<=,
                     s(:arglist, finish_value)),
                   s(:block,
                     body,
                     s(:lasgn, var_name,
                       s(:call, s(:lvar, var_name), :+,
                         s(:arglist, s(:lit, 1))))), true))

     when :times then
       # REFACTOR: mostly duped from above and gave default start value of 0
       # and a finish value that was the start value above
       var.shift 
       start_value = s(:lit, 0)
       finish_value = lhs
       var_name = var.shift
       body.find_and_replace_all(:dvar, :lvar)
       result = s(:dummy,
                  s(:lasgn, var_name, start_value),
                  s(:while,
                    s(:call, s(:lvar, var_name), :<,
                      s(:arglist, finish_value)),
                    s(:block,
                      body,
                      s(:lasgn, var_name,
                        s(:call, s(:lvar, var_name), :+,
                          s(:arglist, s(:lit, 1))))), true))
    when :define_method then
      # BEFORE: [:iter, [:call, nil, :define_method, [:array, [:lit, :bmethod_added]]], [:dasgn_curr, :x], [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]
      # we want to get it rewritten for the scope/block context, so:
      #   - throw call away
      #   - rewrite to args
      #   - plop body into a scope
      # AFTER:  [:block, [:args, :x], [:call, [:lvar, :x], :+, [:arglist, [:lit, 1]]]]
      var.find_and_replace_all(:dasgn_curr, :args)
      body.find_and_replace_all(:dvar, :lvar)
      result = s(:block, var, body)
    else
      # HACK we butchered call up top
      result = s(:iter, s(:call, lhs, method_name, call.shift), var, body)
    end
  else
    if var.nil? then
      var = s(:lvar, Unique.next)
    end

    s(:iter, call, var, body)
  end
end