class SyntaxTree::YARV::Defined


~~~
defined?(x)
~~~ruby
### Usage
pushes its value onto the stack. Otherwise it pushes ‘nil`.
`defined` checks if the top value of the stack is defined. If it is, it
### Summary

def ==(other)

def ==(other)
  other.is_a?(Defined) && other.type == type && other.name == name &&
    other.message == message
end

def call(vm)

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

def deconstruct_keys(_keys)

def deconstruct_keys(_keys)
  { type: type, name: name, message: message }
end

def disasm(fmt)

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

def initialize(type, name, message)

def initialize(type, name, message)
  @type = type
  @name = name
  @message = message
end

def length

def length
  4
end

def pops

def pops
  1
end

def pushes

def pushes
  1
end

def to_a(_iseq)

def to_a(_iseq)
  [:defined, type, name, message]
end