class Minjs::ECMA262::ECMA262Numeric

Class of ECMA262 Numeric element

ECMA262 say:

The Number type has exactly 18437736874454810627 (that is, 264−253+3) values, representing the double-precision 64-bit format IEEE 754 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic

To simplify the implementation, Minjs assumes that ruby has IEEE754 dobule precision.

@see www.ecma-international.org/ecma-262 ECMA262 7.8.3

Attributes

decimal[R]
exp[R]
integer[R]
number[R]

Public Class Methods

new(integer, decimal = nil, exp = nil) click to toggle source
# File lib/minjs/ecma262/literal.rb, line 650
def initialize(integer, decimal = nil, exp = nil)
  if integer == :nan or integer == "NaN"
    @number = Float::NAN
    @integer = "NaN"
    @decimal = nil
    @exp = nil
  elsif integer == :infinity or integer == Float::INFINITY or integer == "Infinity"
    @number = Float::INFINITY
    @integer = "Infinity"
    @decimal = nil
    @exp = nil
  elsif integer == -Float::INFINITY or integer == "-Infinity"
    @number = -Float::INFINITY
    @integer = "-Infinity"
    @decimal = nil
    @exp = nil
  elsif integer.kind_of? String
    @integer = integer.to_s #String
    @decimal = decimal.to_s #String
    @exp = exp ? exp.to_i : nil
    if @decimal == ""
      d = ""
    else
      d = ".#{@decimal}"
    end
    if @exp
      @number = "#{integer}#{d}e#{exp}".to_f
    else
      @number = "#{integer}#{d}".to_f
    end
    if @number.kind_of? Float and @number.nan?
      @integer = "NaN"
      @decimal = nil
      @exp = nil
    elsif @number == Float::INFINITY
      @integer = "Infinity"
      @decimal = nil
      @exp = nil
    elsif @number == -Float::INFINITY
      @integer = "-Infinity"
      @decimal = nil
      @exp = nil
    end
  elsif integer.kind_of? Numeric
    if integer.kind_of? Float and integer.nan?
      @number = Float::NAN
      @decimal = nil
      @exp = nil
    elsif integer == Float::INFINITY
      @number = Float::INFINITY
      @decimal = nil
      @exp = nil
    elsif integer == -Float::INFINITY
      @number = -Float::INFINITY
      @decimal = nil
      @exp = nil
    else
      @number = integer
      @integer = @number.to_i.to_s
      @decimal = (@number - @integer.to_i).to_s.sub(/0\.?/, '')
      @exp = nil
    end
  else
    raise 'internal error'
  end
end

Public Instance Methods

==(obj) click to toggle source

compare object

# File lib/minjs/ecma262/literal.rb, line 731
def ==(obj)
  self.class == obj.class and self.to_ecma262_string == obj.to_ecma262_string
end
deep_dup() click to toggle source

duplicate object @see Base#deep_dup

# File lib/minjs/ecma262/literal.rb, line 719
def deep_dup
  self.class.new(@number)
end
ecma262_typeof() click to toggle source

return results of ‘typeof’ operator.

@return [Symbol] :number

# File lib/minjs/ecma262/literal.rb, line 896
def ecma262_typeof
  :number
end
infinity?() click to toggle source

True if number is Infinity

# File lib/minjs/ecma262/literal.rb, line 796
def infinity?
  @number == Float::INFINITY || @number == -Float::INFINITY
end
left_hand_side_exp?() click to toggle source

@return [Boolean] true if expression is kind of LeftHandSideExpression.

# File lib/minjs/ecma262/literal.rb, line 776
def left_hand_side_exp?
  true
end
nan?() click to toggle source

True if number is NaN

# File lib/minjs/ecma262/literal.rb, line 791
def nan?
  @number.kind_of? Float and @number.nan?
end
number?() click to toggle source

True if number not Infinity nor NaN

# File lib/minjs/ecma262/literal.rb, line 801
def number?
  !nan? and !infinity?
end
side_effect?() click to toggle source

Returns this node has side effect or not. @return [Boolean]

# File lib/minjs/ecma262/literal.rb, line 869
def side_effect?
  return false
end
to_ecma262_boolean() click to toggle source

Returns results of ToBoolean()

Returns true or false if value is trivial, otherwise nil.

@return [Boolean]

@see www.ecma-international.org/ecma-262 ECMA262 9.2

# File lib/minjs/ecma262/literal.rb, line 859
def to_ecma262_boolean
  if @val == :nan or to_ecma262_string == "0"
    false
  else
    true
  end
end
to_ecma262_number() click to toggle source

Returns results of ToNumber()

Returns number if value is trivial, otherwise nil.

@return [Numeric]

@see www.ecma-international.org/ecma-262 ECMA262 9.3

# File lib/minjs/ecma262/literal.rb, line 881
def to_ecma262_number
  if nan?
    nil
  elsif @number == Float::INFINITY
    nil
  elsif @number == -Float::INFINITY
    nil
  else
    @number
  end
end
to_ecma262_string() click to toggle source

Returns results of ToString()

Returns string if value is trivial, otherwise nil.

@return [Numeric]

@see www.ecma-international.org/ecma-262 ECMA262 9.8

# File lib/minjs/ecma262/literal.rb, line 813
def to_ecma262_string
  if nan?
    "NaN"
  elsif @number == Float::INFINITY
    "Infinity"
  elsif @number == -Float::INFINITY
    "-Infinity"
  elsif @integer == '0' and @decimal.nil? and @exp.nil?
    "0"
  else
    f = @number.to_f.to_s
    _n, _e = f.split('e')
    _i, _d = _n.split('.')

    e = _e.to_i
    if(e == 0)
      if _d.to_i != 0
        return _n
      else
        return _i
      end
    elsif(e > 0 && e < 21)
      _n = _i + _d
      _n += '0' * (21 - _n.length)
      return _n
    elsif(e < 0 && e >= -6)
      _n = "0." + ('0' * (-e-1)) + _i + _d
      return _n
    else
      if e<0
        return "#{_i}.#{_d}e#{e}"
      else
        return "#{_i}.#{_d}e+#{e}"
      end
    end
  end
end
to_f() click to toggle source

to float

# File lib/minjs/ecma262/literal.rb, line 786
def to_f
  to_ecma262_string.to_f
end
to_i() click to toggle source

to integer

# File lib/minjs/ecma262/literal.rb, line 781
def to_i
  to_ecma262_string.to_i
end
to_js(options = {}) click to toggle source

Returns a ECMAScript string containg the representation of element. @see Base#to_js

# File lib/minjs/ecma262/literal.rb, line 737
def to_js(options = {})
  if nan?
    return "NaN"
  elsif @number == Float::INFINITY
    return "Infinity"
  elsif @number == -Float::INFINITY
    return "-Infinity"
  end
  t0 = to_ecma262_string
  t0.sub!(/^0\./, '.')

  t = @integer.nil? ? "" : @integer.dup.to_s

  d = @decimal.to_s
  if d == '0'
    d = ''
  end
  if d.length > 0
    if @integer == '0'
      t = ".#{d}"
    else
      t << ".#{d}"
    end
  end
  if @exp
    t << "e#{@exp}"
  end

  if !t.match(/e/) and !t.match(/\./) and t.match(/0{3,}$/)
    len = $&.length
    t.sub!(/0+$/, "e#{len}")
  end
  t.sub!(/e\+/, 'e')
  t0.sub!(/e\+/, 'e')

  t.length <= t0.length ? t : t0
end
traverse(parent) { |parent, self| ... } click to toggle source

Traverses this children and itself with given block.

@see Base#traverse

# File lib/minjs/ecma262/literal.rb, line 726
def traverse(parent, &block)
  yield parent, self
end