Class: SyntaxTree::YARV::ExpandArray

Inherits:
Object
  • Object
show all
Defined in:
lib/syntax_tree/yarv/instructions.rb

Overview

### Summary

expandarray looks at the top of the stack, and if the value is an array it replaces it on the stack with number elements of the array, or nil if the elements are missing.

### Usage

~~~ruby x, = [true, false, nil] ~~~

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(number, flags) ⇒ ExpandArray



1447
1448
1449
1450
# File 'lib/syntax_tree/yarv/instructions.rb', line 1447

def initialize(number, flags)
  @number = number
  @flags = flags
end

Instance Attribute Details

#flagsObject (readonly)

Returns the value of attribute flags.



1445
1446
1447
# File 'lib/syntax_tree/yarv/instructions.rb', line 1445

def flags
  @flags
end

#numberObject (readonly)

Returns the value of attribute number.



1445
1446
1447
# File 'lib/syntax_tree/yarv/instructions.rb', line 1445

def number
  @number
end

Instance Method Details

#==(other) ⇒ Object



1464
1465
1466
1467
# File 'lib/syntax_tree/yarv/instructions.rb', line 1464

def ==(other)
  other.is_a?(ExpandArray) && other.number == number &&
    other.flags == flags
end

#call(vm) ⇒ Object



1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
# File 'lib/syntax_tree/yarv/instructions.rb', line 1485

def call(vm)
  object = vm.pop
  object =
    if Array === object
      object.dup
    elsif object.respond_to?(:to_ary, true)
      object.to_ary
    else
      [object]
    end

  splat_flag = flags & 0x01 > 0
  postarg_flag = flags & 0x02 > 0

  if number == 0 && splat_flag == 0
    # no space left on stack
  elsif postarg_flag
    values = []

    if number > object.size
      (number - object.size).times { values.push(nil) }
    end
    [number, object.size].min.times { values.push(object.pop) }
    values.push(object.to_a) if splat_flag

    values.each { |item| vm.push(item) }
  else
    values = []

    [number, object.size].min.times { values.push(object.shift) }
    if number > values.size
      (number - values.size).times { values.push(nil) }
    end
    values.push(object.to_a) if splat_flag

    values.reverse_each { |item| vm.push(item) }
  end
end

#canonicalObject



1481
1482
1483
# File 'lib/syntax_tree/yarv/instructions.rb', line 1481

def canonical
  self
end

#deconstruct_keys(_keys) ⇒ Object



1460
1461
1462
# File 'lib/syntax_tree/yarv/instructions.rb', line 1460

def deconstruct_keys(_keys)
  { number: number, flags: flags }
end

#disasm(fmt) ⇒ Object



1452
1453
1454
# File 'lib/syntax_tree/yarv/instructions.rb', line 1452

def disasm(fmt)
  fmt.instruction("expandarray", [fmt.object(number), fmt.object(flags)])
end

#lengthObject



1469
1470
1471
# File 'lib/syntax_tree/yarv/instructions.rb', line 1469

def length
  3
end

#popsObject



1473
1474
1475
# File 'lib/syntax_tree/yarv/instructions.rb', line 1473

def pops
  1
end

#pushesObject



1477
1478
1479
# File 'lib/syntax_tree/yarv/instructions.rb', line 1477

def pushes
  number
end

#to_a(_iseq) ⇒ Object



1456
1457
1458
# File 'lib/syntax_tree/yarv/instructions.rb', line 1456

def to_a(_iseq)
  [:expandarray, number, flags]
end