Class: Wardite::F64

Inherits:
Object
  • Object
show all
Includes:
ValueHelper
Defined in:
lib/wardite/value.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ValueHelper

#F32, #F64, #I32, #I64

Instance Attribute Details

#valueObject

: Float



621
622
623
# File 'lib/wardite/value.rb', line 621

def value
  @value
end

Class Method Details

.from_bytes(str) ⇒ Object



625
626
627
628
629
630
631
# File 'lib/wardite/value.rb', line 625

def self.from_bytes(str)
  v = str.unpack("E")[0]
  if !v.is_a?(Float)
    raise "broken string or unsupported size: #{str.inspect} -> 8"
  end
  Wardite::F64(v)
end

Instance Method Details

#==(other) ⇒ Object



816
817
818
# File 'lib/wardite/value.rb', line 816

def ==(other)
  return self.class == other.class && self.value == other.value
end

#convert_s(to:) ⇒ Object

Raises:



760
761
762
# File 'lib/wardite/value.rb', line 760

def convert_s(to:)
  raise EvalError, "unsupported operation"
end

#convert_u(to:) ⇒ Object

Raises:



766
767
768
# File 'lib/wardite/value.rb', line 766

def convert_u(to:)
  raise EvalError, "unsupported operation"
end

#demote(to:) ⇒ Object

TODO:

no loss of digits…

Raises:



773
774
775
776
# File 'lib/wardite/value.rb', line 773

def demote(to:)
  raise EvalError, "unsupported operation" if to != :f32
  F32(value)
end

#extend_s(to:) ⇒ Object

Raises:



661
662
663
# File 'lib/wardite/value.rb', line 661

def extend_s(to:)
  raise EvalError, "unsupported operation"
end

#extend_u(to:) ⇒ Object

Raises:



667
668
669
# File 'lib/wardite/value.rb', line 667

def extend_u(to:)
  raise EvalError, "unsupported operation"
end

#extendN_s(from:, to:) ⇒ Object

Raises:



796
797
798
# File 'lib/wardite/value.rb', line 796

def extendN_s(from:, to:)
  raise EvalError, "unsupported operation"
end

#inspectObject



812
813
814
# File 'lib/wardite/value.rb', line 812

def inspect
  "F64(#{@value})"
end

#memsizeObject



634
635
636
# File 'lib/wardite/value.rb', line 634

def memsize
  64
end

#packed(size: nil) ⇒ Object



649
650
651
# File 'lib/wardite/value.rb', line 649

def packed(size: nil)
  [self.value].pack("E")
end

#promote(to:) ⇒ Object

Raises:



780
781
782
# File 'lib/wardite/value.rb', line 780

def promote(to:)
  raise EvalError, "unsupported operation"
end

#reinterpret(to:) ⇒ Object

Raises:



786
787
788
789
790
791
# File 'lib/wardite/value.rb', line 786

def reinterpret(to:)
  raise EvalError, "unsupported operation" if to != :i64
  v = [value].pack("d").unpack("L!")[0]
  raise EvalError, "[BUG] String#unpack is broke, really?" if !v.is_a?(Integer)
  I64(v)
end

#signObject



639
640
641
642
643
644
645
# File 'lib/wardite/value.rb', line 639

def sign
  upper = [0.0].pack("G")[0]&.ord&.<<(7)
  if !upper
    raise "[BUG] Array#pack looks broken?"
  end
  upper.zero? ? :positive : :negative
end

#trunc_s(to:, saturating: false) ⇒ Object

See Also:

  • same as F32


675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
# File 'lib/wardite/value.rb', line 675

def trunc_s(to:, saturating: false)
  v = value.to_i
  case to
  when :i32
    if v >= 0
      i32_signed_max = I32::I32_MAX >> 1
      if saturating
        v = i32_signed_max if v > i32_signed_max
      else
        v = v & i32_signed_max
      end
      I32(v & i32_signed_max)
    else
      i32_signed_min = -(I32::I32_MAX >> 1) - 1
      if saturating
        v = i32_signed_min if v < i32_signed_min
      else
        v = v & I32::I32_MAX
        if (v >> 31).zero?
          raise EvalError, "[undefined behavior] detected overflow: #{value}"
        end
      end
      I32(v)
    end
  when :i64
    if v >= 0
      i64_signed_max = I64::I64_MAX >> 1
      if saturating
        v = i64_signed_max if v > i64_signed_max
      else
        v = v & i64_signed_max
      end
      I64(v & i64_signed_max)
    else
      i64_signed_min = -(I64::I64_MAX >> 1) - 1
      if saturating
        v = i64_signed_min if v < i64_signed_min
      else
        v = v & I64::I64_MAX
        if (v >> 63).zero?
          raise EvalError, "[undefined behavior] detected overflow: #{value}"
        end
      end
      I64(v)
    end
  else
    raise EvalError, "unsupported operation to: #{to}"
  end
end

#trunc_sat_s(to:) ⇒ Object



808
809
810
# File 'lib/wardite/value.rb', line 808

def trunc_sat_s(to:)
  trunc_s(to: to, saturating: true)
end

#trunc_sat_u(to:) ⇒ Object



802
803
804
# File 'lib/wardite/value.rb', line 802

def trunc_sat_u(to:)
  trunc_u(to: to, saturating: true)
end

#trunc_u(to:, saturating: false) ⇒ Object

See Also:

  • same as F32


729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
# File 'lib/wardite/value.rb', line 729

def trunc_u(to:, saturating: false)
  v = value.to_i
  if v < 0
    if saturating
      v = 0
    else
      raise EvalError, "[undefined behavior] unexpected negative value"
    end
  end
  case to
  when :i32
    if saturating
      v = I32::I32_MAX if v > I32::I32_MAX
    else
      v = v & I32::I32_MAX
    end
    I32(v)
  when :i64
    if saturating
      v = I64::I64_MAX if v > I64::I64_MAX
    else
      v = v & I64::I64_MAX
    end
    I64(v)
  else
    raise EvalError, "unsupported operation to: #{to}"
  end
end

#wrap(to:) ⇒ Object

Raises:



655
656
657
# File 'lib/wardite/value.rb', line 655

def wrap(to:)
  raise EvalError, "unsupported operation"
end