Class: CodeTools::AST::ConcatArgs

Inherits:
Node
  • Object
show all
Defined in:
lib/rubinius/code/ast/values.rb

Instance Attribute Summary collapse

Attributes inherited from Node

#line

Instance Method Summary collapse

Methods inherited from Node

#ascii_graph, #attributes, #children, #defined, match_arguments?, match_send?, #new_block_generator, #new_generator, #node_name, #or_bytecode, #pos, #set_child, #transform, transform, transform_comment, transform_kind, transform_kind=, transform_name, #value_defined, #visit, #walk

Constructor Details

#initialize(line, array, rest) ⇒ ConcatArgs

Returns a new instance of ConcatArgs.



104
105
106
107
108
# File 'lib/rubinius/code/ast/values.rb', line 104

def initialize(line, array, rest)
  @line = line
  @array = array
  @rest = rest
end

Instance Attribute Details

#arrayObject

Returns the value of attribute array.



102
103
104
# File 'lib/rubinius/code/ast/values.rb', line 102

def array
  @array
end

#restObject

Returns the value of attribute rest.



102
103
104
# File 'lib/rubinius/code/ast/values.rb', line 102

def rest
  @rest
end

Instance Method Details

#bytecode(g) ⇒ Object



110
111
112
113
114
115
116
117
# File 'lib/rubinius/code/ast/values.rb', line 110

def bytecode(g)
  @array.bytecode(g) if @array

  @rest.bytecode(g)
  convert_to_a(g)

  g.send :+, 1, true if @array
end

#convert_to_a(g) ⇒ Object

TODO: de-dup



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/rubinius/code/ast/values.rb', line 120

def convert_to_a(g)
  done = g.new_label
  coerce = g.new_label
  make_array = g.new_label

  kind_of_array(g, done)

  g.dup
  g.push_literal :to_a
  g.push_true
  g.send :respond_to?, 2, true
  g.goto_if_true coerce

  make_array.set!
  g.make_array 1
  g.goto done

  coerce.set!
  g.dup
  g.send :to_a, 0, true

  discard = g.new_label
  check_array = g.new_label

  g.dup
  g.goto_if_not_nil check_array

  g.pop
  g.goto make_array

  check_array.set!
  kind_of_array(g, discard)

  g.push_type
  g.move_down 2
  g.push_literal :to_a
  g.push_cpath_top
  g.find_const :Array
  g.send :coerce_to_type_error, 4, true
  g.goto done

  discard.set!
  g.swap
  g.pop

  done.set!
end

#kind_of_array(g, label) ⇒ Object



168
169
170
171
172
173
174
175
# File 'lib/rubinius/code/ast/values.rb', line 168

def kind_of_array(g, label)
  g.dup
  g.push_cpath_top
  g.find_const :Array
  g.swap
  g.kind_of
  g.goto_if_true label
end

#peel_lhsObject

Dive down and try to find an array of regular values that could construct the left side of a concatination. This is used to minimize the splat doing a send.



180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/rubinius/code/ast/values.rb', line 180

def peel_lhs
  case @array
  when ConcatArgs
    @array.peel_lhs
  when ArrayLiteral
    ary = @array.body
    @array = nil
    ary
  else
    nil
  end
end

#splat?Boolean

Returns:

  • (Boolean)


197
198
199
# File 'lib/rubinius/code/ast/values.rb', line 197

def splat?
  true
end

#to_sexpObject



193
194
195
# File 'lib/rubinius/code/ast/values.rb', line 193

def to_sexp
  [:argscat, @array.to_sexp, @rest.to_sexp]
end