Class: Rubinius::ToolSet.current::TS::AST::OpAssign2

Inherits:
Node
  • Object
show all
Defined in:
lib/rubinius/ast/operators.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, receiver, name, op, value) ⇒ OpAssign2

Returns a new instance of OpAssign2.



232
233
234
235
236
237
238
239
# File 'lib/rubinius/ast/operators.rb', line 232

def initialize(line, receiver, name, op, value)
  @line = line
  @receiver = receiver
  @name = name
  @op = op
  @value = value
  @assign = name.to_s[-1] == ?= ? name : :"#{name}="
end

Instance Attribute Details

#assignObject

Returns the value of attribute assign.



230
231
232
# File 'lib/rubinius/ast/operators.rb', line 230

def assign
  @assign
end

#nameObject

Returns the value of attribute name.



230
231
232
# File 'lib/rubinius/ast/operators.rb', line 230

def name
  @name
end

#opObject

Returns the value of attribute op.



230
231
232
# File 'lib/rubinius/ast/operators.rb', line 230

def op
  @op
end

#receiverObject

Returns the value of attribute receiver.



230
231
232
# File 'lib/rubinius/ast/operators.rb', line 230

def receiver
  @receiver
end

#valueObject

Returns the value of attribute value.



230
231
232
# File 'lib/rubinius/ast/operators.rb', line 230

def value
  @value
end

Instance Method Details

#bytecode(g) ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/rubinius/ast/operators.rb', line 241

def bytecode(g)
  pos(g)

  # X: h[:a] += 3, given h.a == 2
  @receiver.bytecode(g)
  # X: TOS = h
  g.dup
  g.send @name, 0
  # X: TOS = 2

  if @op == :or or @op == :and
    fnd = g.new_label
    fin = g.new_label

    g.dup
    if @op == :or
      g.git fnd
    else
      g.gif fnd
    end

    # Remove the copy of 2 and push @value on the stack
    g.pop
    @value.bytecode(g)

    # Retain the this value to use as the expression value
    g.dup
    g.move_down 2

    # Call the assignement method, passing @value as the argument
    g.send @assign, 1
    g.pop

    g.goto fin

    fnd.set!

    # Clean up the stack
    g.swap
    g.pop

    fin.set!
  else
    @value.bytecode(g)
    # X: TOS = 3
    # X: 2 + 3
    g.send @op, 1

    # Retain the this value to use as the expression value
    g.dup
    g.move_down 2
    # X: TOS = 5
    g.send @assign, 1
    # X: TOS = 5 (or whatever a=() returns)

    # Discard the methods return value
    g.pop
  end
end

#to_sexpObject



301
302
303
304
# File 'lib/rubinius/ast/operators.rb', line 301

def to_sexp
  op = @op == :or ? :"||" : :"&&"
  [:op_asgn2, @receiver.to_sexp, :"#{@name}=", op, @value.to_sexp]
end