Class: SyntaxTree::YARV::Defined

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

Overview

### 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) ~~~

Constant Summary collapse

TYPE_NIL =
1
TYPE_IVAR =
2
TYPE_LVAR =
3
TYPE_GVAR =
4
TYPE_CVAR =
5
TYPE_CONST =
6
TYPE_METHOD =
7
TYPE_YIELD =
8
TYPE_ZSUPER =
9
TYPE_SELF =
10
TYPE_TRUE =
11
TYPE_FALSE =
12
TYPE_ASGN =
13
TYPE_EXPR =
14
TYPE_REF =
15
TYPE_FUNC =
16
TYPE_CONST_FROM =
17

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Instruction

#branch_targets, #canonical, #falls_through?, #leaves?, #side_effects?

Constructor Details

#initialize(type, name, message) ⇒ Defined

Returns a new instance of Defined.



880
881
882
883
884
# File 'lib/syntax_tree/yarv/instructions.rb', line 880

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

Instance Attribute Details

#messageObject (readonly)

Returns the value of attribute message.



878
879
880
# File 'lib/syntax_tree/yarv/instructions.rb', line 878

def message
  @message
end

#nameObject (readonly)

Returns the value of attribute name.



878
879
880
# File 'lib/syntax_tree/yarv/instructions.rb', line 878

def name
  @name
end

#typeObject (readonly)

Returns the value of attribute type.



878
879
880
# File 'lib/syntax_tree/yarv/instructions.rb', line 878

def type
  @type
end

Instance Method Details

#==(other) ⇒ Object



939
940
941
942
# 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) ⇒ Object



956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
# 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) ⇒ Object



935
936
937
# File 'lib/syntax_tree/yarv/instructions.rb', line 935

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

#disasm(fmt) ⇒ Object



886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
# 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

#lengthObject



944
945
946
# File 'lib/syntax_tree/yarv/instructions.rb', line 944

def length
  4
end

#popsObject



948
949
950
# File 'lib/syntax_tree/yarv/instructions.rb', line 948

def pops
  1
end

#pushesObject



952
953
954
# File 'lib/syntax_tree/yarv/instructions.rb', line 952

def pushes
  1
end

#to_a(_iseq) ⇒ Object



931
932
933
# File 'lib/syntax_tree/yarv/instructions.rb', line 931

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