class SyntaxTree::YARV::Defined

### Summary

‘defined` checks if the top value of the stack is defined. If it is, it pushes its value onto the stack. Otherwise it pushes `nil`.

### Usage

~~~ruby defined?(x) ~~~

Constants

TYPE_ASGN
TYPE_CONST
TYPE_CONST_FROM
TYPE_CVAR
TYPE_EXPR
TYPE_FALSE
TYPE_FUNC
TYPE_GVAR
TYPE_IVAR
TYPE_LVAR
TYPE_METHOD
TYPE_NIL
TYPE_REF
TYPE_SELF
TYPE_TRUE
TYPE_YIELD
TYPE_ZSUPER

Attributes

message[R]
name[R]
type[R]

Public Class Methods

new(type, name, message) click to toggle source
# File lib/syntax_tree/yarv/instructions.rb, line 880
def initialize(type, name, message)
  @type = type
  @name = name
  @message = message
end

Public Instance Methods

==(other) click to toggle source
# File lib/syntax_tree/yarv/instructions.rb, line 939
def ==(other)
  other.is_a?(Defined) && other.type == type && other.name == name &&
    other.message == message
end
call(vm) click to toggle source
# File lib/syntax_tree/yarv/instructions.rb, line 956
def call(vm)
  object = vm.pop

  result =
    case type
    when TYPE_NIL, TYPE_SELF, TYPE_TRUE, TYPE_FALSE, TYPE_ASGN, TYPE_EXPR
      message
    when TYPE_IVAR
      message if vm.frame._self.instance_variable_defined?(name)
    when TYPE_LVAR
      raise NotImplementedError, "defined TYPE_LVAR"
    when TYPE_GVAR
      message if global_variables.include?(name)
    when TYPE_CVAR
      clazz = vm.frame._self
      clazz = clazz.singleton_class unless clazz.is_a?(Module)
      message if clazz.class_variable_defined?(name)
    when TYPE_CONST
      clazz = vm.frame._self
      clazz = clazz.singleton_class unless clazz.is_a?(Module)
      message if clazz.const_defined?(name)
    when TYPE_METHOD
      raise NotImplementedError, "defined TYPE_METHOD"
    when TYPE_YIELD
      raise NotImplementedError, "defined TYPE_YIELD"
    when TYPE_ZSUPER
      raise NotImplementedError, "defined TYPE_ZSUPER"
    when TYPE_REF
      raise NotImplementedError, "defined TYPE_REF"
    when TYPE_FUNC
      message if object.respond_to?(name, true)
    when TYPE_CONST_FROM
      defined =
        vm.frame.nesting.any? { |scope| scope.const_defined?(name, true) }
      message if defined
    end

  vm.push(result)
end
deconstruct_keys(_keys) click to toggle source
# File lib/syntax_tree/yarv/instructions.rb, line 935
def deconstruct_keys(_keys)
  { type: type, name: name, message: message }
end
disasm(fmt) click to toggle source
# File lib/syntax_tree/yarv/instructions.rb, line 886
def disasm(fmt)
  type_name =
    case type
    when TYPE_NIL
      "nil"
    when TYPE_IVAR
      "ivar"
    when TYPE_LVAR
      "lvar"
    when TYPE_GVAR
      "gvar"
    when TYPE_CVAR
      "cvar"
    when TYPE_CONST
      "const"
    when TYPE_METHOD
      "method"
    when TYPE_YIELD
      "yield"
    when TYPE_ZSUPER
      "zsuper"
    when TYPE_SELF
      "self"
    when TYPE_TRUE
      "true"
    when TYPE_FALSE
      "false"
    when TYPE_ASGN
      "asgn"
    when TYPE_EXPR
      "expr"
    when TYPE_REF
      "ref"
    when TYPE_FUNC
      "func"
    when TYPE_CONST_FROM
      "constant-from"
    end

  fmt.instruction(
    "defined",
    [type_name, fmt.object(name), fmt.object(message)]
  )
end
length() click to toggle source
# File lib/syntax_tree/yarv/instructions.rb, line 944
def length
  4
end
pops() click to toggle source
# File lib/syntax_tree/yarv/instructions.rb, line 948
def pops
  1
end
pushes() click to toggle source
# File lib/syntax_tree/yarv/instructions.rb, line 952
def pushes
  1
end
to_a(_iseq) click to toggle source
# File lib/syntax_tree/yarv/instructions.rb, line 931
def to_a(_iseq)
  [:defined, type, name, message]
end