<commit_before>require 'corelib/numeric'

class Number < Numeric
  Opal.bridge(self, `Number`)

  `Number.prototype.$$is_number = true`

  def send_coerced(method, other)
    begin
      a, b = other.coerce(self)
    rescue
      case method
      when :+, :-, :*, :/, :%, :&, :|, :^, :**
        raise TypeError, "#{other.class} can't be coerce into Numeric"

      when :>, :>=, :<, :<=, :<=>
        raise ArgumentError, "comparison of #{self.class} with #{other.class} failed"
      end
    end

    a.__send__ method, b
  end

  def __id__
    `(self * 2) + 1`
  end

  alias object_id __id__

  def +(other)
    %x{
      if (other.$$is_number) {
        return self + other;
      }
      else {
        return #{send_coerced :+, other};
      }
    }
  end

  def -(other)
    %x{
      if (other.$$is_number) {
        return self - other;
      }
      else {
        return #{send_coerced :-, other};
      }
    }
  end

  def *(other)
    %x{
      if (other.$$is_number) {
        return self * other;
      }
      else {
        return #{send_coerced :*, other};
      }
    }
  end

  def /(other)
    %x{
      if (other.$$is_number) {
        return self / other;
      }
      else {
        return #{send_coerced :/, other};
      }
    }
  end

  alias fdiv /

  def %(other)
    %x{
      if (other.$$is_number) {
        if (other < 0 || self < 0) {
          return (self % other + other) % other;
        }
        else {
          return self % other;
        }
      }
      else {
        return #{send_coerced :%, other};
      }
    }
  end

  def &(other)
    %x{
      if (other.$$is_number) {
        return self & other;
      }
      else {
        return #{send_coerced :&, other};
      }
    }
  end

  def |(other)
    %x{
      if (other.$$is_number) {
        return self | other;
      }
      else {
        return #{send_coerced :|, other};
      }
    }
  end

  def ^(other)
    %x{
      if (other.$$is_number) {
        return self ^ other;
      }
      else {
        return #{send_coerced :^, other};
      }
    }
  end

  def <(other)
    %x{
      if (other.$$is_number) {
        return self < other;
      }
      else {
        return #{send_coerced :<, other};
      }
    }
  end

  def <=(other)
    %x{
      if (other.$$is_number) {
        return self <= other;
      }
      else {
        return #{send_coerced :<=, other};
      }
    }
  end

  def >(other)
    %x{
      if (other.$$is_number) {
        return self > other;
      }
      else {
        return #{send_coerced :>, other};
      }
    }
  end

  def >=(other)
    %x{
      if (other.$$is_number) {
        return self >= other;
      }
      else {
        return #{send_coerced :>=, other};
      }
    }
  end

  def <=>(other)
    %x{
      if (other.$$is_number) {
        return self > other ? 1 : (self < other ? -1 : 0);
      }
      else {
        return #{send_coerced :<=>, other};
      }
    }
  rescue ArgumentError
    nil
  end

  def <<(count)
    count = Opal.coerce_to! count, Integer, :to_int

    `#{count} > 0 ? self << #{count} : self >> -#{count}`
  end

  def >>(count)
    count = Opal.coerce_to! count, Integer, :to_int

    `#{count} > 0 ? self >> #{count} : self << -#{count}`
  end

  def [](bit)
    bit = Opal.coerce_to! bit, Integer, :to_int
    min = -(2**30)
    max =  (2**30) - 1

    `(#{bit} < #{min} || #{bit} > #{max}) ? 0 : (self >> #{bit}) % 2`
  end

  def +@
    `+self`
  end

  def -@
    `-self`
  end

  def ~
    `~self`
  end

  def **(other)
    %x{
      if (other.$$is_number) {
        return Math.pow(self, other);
      }
      else {
        return #{send_coerced :**, other};
      }
    }
  end

  def ==(other)
    %x{
      if (other.$$is_number) {
        return self == Number(other);
      }
      else if (#{other.respond_to? :==}) {
        return #{other == self};
      }
      else {<commit_msg>Number#** can actually return Complex and Rational<commit_after>require 'corelib/numeric'

class Number < Numeric
  Opal.bridge(self, `Number`)

  `Number.prototype.$$is_number = true`

  def send_coerced(method, other)
    begin
      a, b = other.coerce(self)
    rescue
      case method
      when :+, :-, :*, :/, :%, :&, :|, :^, :**
        raise TypeError, "#{other.class} can't be coerce into Numeric"

      when :>, :>=, :<, :<=, :<=>
        raise ArgumentError, "comparison of #{self.class} with #{other.class} failed"
      end
    end

    a.__send__ method, b
  end

  def __id__
    `(self * 2) + 1`
  end

  alias object_id __id__

  def +(other)
    %x{
      if (other.$$is_number) {
        return self + other;
      }
      else {
        return #{send_coerced :+, other};
      }
    }
  end

  def -(other)
    %x{
      if (other.$$is_number) {
        return self - other;
      }
      else {
        return #{send_coerced :-, other};
      }
    }
  end

  def *(other)
    %x{
      if (other.$$is_number) {
        return self * other;
      }
      else {
        return #{send_coerced :*, other};
      }
    }
  end

  def /(other)
    %x{
      if (other.$$is_number) {
        return self / other;
      }
      else {
        return #{send_coerced :/, other};
      }
    }
  end

  alias fdiv /

  def %(other)
    %x{
      if (other.$$is_number) {
        if (other < 0 || self < 0) {
          return (self % other + other) % other;
        }
        else {
          return self % other;
        }
      }
      else {
        return #{send_coerced :%, other};
      }
    }
  end

  def &(other)
    %x{
      if (other.$$is_number) {
        return self & other;
      }
      else {
        return #{send_coerced :&, other};
      }
    }
  end

  def |(other)
    %x{
      if (other.$$is_number) {
        return self | other;
      }
      else {
        return #{send_coerced :|, other};
      }
    }
  end

  def ^(other)
    %x{
      if (other.$$is_number) {
        return self ^ other;
      }
      else {
        return #{send_coerced :^, other};
      }
    }
  end

  def <(other)
    %x{
      if (other.$$is_number) {
        return self < other;
      }
      else {
        return #{send_coerced :<, other};
      }
    }
  end

  def <=(other)
    %x{
      if (other.$$is_number) {
        return self <= other;
      }
      else {
        return #{send_coerced :<=, other};
      }
    }
  end

  def >(other)
    %x{
      if (other.$$is_number) {
        return self > other;
      }
      else {
        return #{send_coerced :>, other};
      }
    }
  end

  def >=(other)
    %x{
      if (other.$$is_number) {
        return self >= other;
      }
      else {
        return #{send_coerced :>=, other};
      }
    }
  end

  def <=>(other)
    %x{
      if (other.$$is_number) {
        return self > other ? 1 : (self < other ? -1 : 0);
      }
      else {
        return #{send_coerced :<=>, other};
      }
    }
  rescue ArgumentError
    nil
  end

  def <<(count)
    count = Opal.coerce_to! count, Integer, :to_int

    `#{count} > 0 ? self << #{count} : self >> -#{count}`
  end

  def >>(count)
    count = Opal.coerce_to! count, Integer, :to_int

    `#{count} > 0 ? self >> #{count} : self << -#{count}`
  end

  def [](bit)
    bit = Opal.coerce_to! bit, Integer, :to_int
    min = -(2**30)
    max =  (2**30) - 1

    `(#{bit} < #{min} || #{bit} > #{max}) ? 0 : (self >> #{bit}) % 2`
  end

  def +@
    `+self`
  end

  def -@
    `-self`
  end

  def ~
    `~self`
  end

  def **(other)
    if Float === other && self < 0
      Complex.new(self, 0) ** other
    elsif Integer === other && other < 0
      Rational.new(self, 1) ** other
    elsif `other.$$is_number`
      `Math.pow(self, other)`
    else
      send_coerced :**, other
    end
  end

  def ==(other)
    %x{
      if (other.$$is_number) {
        return self == Number(other);
      }
      else if (#{other.respond_to? :==}) {
        return #{other == self};
      }
      else {
{'fraction_non_alphanumeric': 0.16263542454018645, 'fraction_numerical': 0.005039052658100277, 'mean_word_length': 1.541293213828425, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7423884', 'n_tokens_mistral': 2990, 'n_tokens_neox': 2855, 'n_words': 676}