File: value/core/atom/number/abstract.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: Value#8
  module: Core#10
has properties
function: make_number / 2 #260
  module: Atom#12
  module: Number#14
  class: Abstract#16
inherits from
  Abstract ( Umu::Value::Core::Atom )
has properties
method: initialize / 1 #17
method: to_s #24
method: meth_is_zero / 3 #40
method: meth_is_positive / 3 #50
method: meth_is_negative / 3 #60
method: meth_to_int / 3 #70
method: meth_to_float / 3 #90
method: meth_negate / 3 #100
method: meth_absolute / 3 #110
method: + / 1 #115
method: meth_add / 4 #127
method: meth_sub / 4 #139
method: meth_multiply / 4 #151
method: meth_divide / 4 #163
method: meth_modulo / 4 #183
method: meth_power / 4 #203
method: meth_random / 3 #223

Code

   1  # coding: utf-8
   2  # frozen_string_literal: true
   3 
   4 
   5 
   6  module Umu
   7 
   8  module Value
   9 
  10  module Core
  11 
  12  module Atom
  13 
  14  module Number
  15 
  16  class Abstract < Atom::Abstract
  17      def initialize(val)
  18          ASSERT.kind_of val, ::Numeric
  19 
  20          super
  21      end
  22 
  23 
  24      def to_s
  25          val = self.val
  26 
  27          if val < 0
  28              format "-%s", val.abs.inspect
  29          else
  30              val.inspect
  31          end
  32      end
  33 
  34 
  35      define_instance_method(
  36          :meth_is_zero,
  37          :zero?, [],
  38          [], VCA::Bool
  39      )
  40      def meth_is_zero(_loc, _env, _event)
  41          VC.make_bool self.val.zero?
  42      end
  43 
  44 
  45      define_instance_method(
  46          :meth_is_positive,
  47          :positive?, [],
  48          [], VCA::Bool
  49      )
  50      def meth_is_positive(_loc, _env, _event)
  51          VC.make_bool(self.val > 0)
  52      end
  53 
  54 
  55      define_instance_method(
  56          :meth_is_negative,
  57          :negative?, [],
  58          [], VCA::Bool
  59      )
  60      def meth_is_negative(_loc, _env, _event)
  61          VC.make_bool(self.val < 0)
  62      end
  63 
  64 
  65      define_instance_method(
  66          :meth_to_int,
  67          :'to-i', [],
  68          [], VCAN::Int
  69      )
  70      def meth_to_int(loc, env, _event)
  71          begin
  72              VC.make_integer self.val.to_i
  73          rescue ::FloatDomainError
  74              raise X::ArgumentError.new(
  75                  loc,
  76                  env,
  77                  "Domain error on float number %s : %s",
  78                          self.to_s,
  79                          self.type_sym.to_s
  80              )
  81          end
  82      end
  83 
  84 
  85      define_instance_method(
  86          :meth_to_float,
  87          :'to-f', [],
  88          [], VCAN::Float
  89      )
  90      def meth_to_float(_loc, _env, _event)
  91          VC.make_float self.val.to_f
  92      end
  93 
  94 
  95      define_instance_method(
  96          :meth_negate,
  97          :negate, [],
  98          [], self
  99      )
 100      def meth_negate(_loc, _env, _event)
 101          VC.make_number self.class, - self.val
 102      end
 103 
 104 
 105      define_instance_method(
 106          :meth_absolute,
 107          :abs, [],
 108          [], self
 109      )
 110      def meth_absolute(_loc, _env, _event)
 111          VC.make_number self.class, self.val.abs
 112      end
 113 
 114 
 115      def +(other)
 116          ASSERT.kind_of other, Number::Abstract
 117 
 118          VC.make_number self.class, self.val + other.val
 119      end
 120 
 121 
 122      define_instance_method(
 123          :meth_add,
 124          :'+', [],
 125          [self], self
 126      )
 127      def meth_add(_loc, _env, _event, other)
 128          ASSERT.kind_of other, Number::Abstract
 129 
 130          self.+ other
 131      end
 132 
 133 
 134      define_instance_method(
 135          :meth_sub,
 136          :'-', [],
 137          [self], self
 138      )
 139      def meth_sub(_loc, _env, _event, other)
 140          ASSERT.kind_of other, Number::Abstract
 141 
 142          VC.make_number self.class, self.val - other.val
 143      end
 144 
 145 
 146      define_instance_method(
 147          :meth_multiply,
 148          :'*', [],
 149          [self], self
 150      )
 151      def meth_multiply(_loc, _env, _event, other)
 152          ASSERT.kind_of other, Number::Abstract
 153 
 154          VC.make_number self.class, self.val * other.val
 155      end
 156 
 157 
 158      define_instance_method(
 159          :meth_divide,
 160          :'/', [],
 161          [self], self
 162      )
 163      def meth_divide(loc, env, _event, other)
 164          ASSERT.kind_of other, Number::Abstract
 165 
 166          begin
 167              VC.make_number self.class, self.val / other.val
 168          rescue ::ZeroDivisionError
 169              raise X::ZeroDivisionError.new(
 170                  loc,
 171                  env,
 172                  "Zero devision error"
 173              )
 174          end
 175      end
 176 
 177 
 178      define_instance_method(
 179          :meth_modulo,
 180          :mod, [],
 181          [self], self
 182      )
 183      def meth_modulo(loc, env, _event, other)
 184          ASSERT.kind_of other, Number::Abstract
 185 
 186          begin
 187              VC.make_number self.class, self.val % other.val
 188          rescue ::ZeroDivisionError
 189              raise X::ZeroDivisionError.new(
 190                  loc,
 191                  env,
 192                  "Zero devision error"
 193              )
 194          end
 195      end
 196 
 197 
 198      define_instance_method(
 199          :meth_power,
 200          :pow, [],
 201          [self], self
 202      )
 203      def meth_power(loc, env, _event, other)
 204          ASSERT.kind_of other, Number::Abstract
 205 
 206          begin
 207              VC.make_number self.class, self.val ** other.val
 208          rescue ::ZeroDivisionError
 209              raise X::ZeroDivisionError.new(
 210                  loc,
 211                  env,
 212                  "Zero devision error"
 213              )
 214          end
 215      end
 216 
 217 
 218      define_instance_method(
 219          :meth_random,
 220          :random, [],
 221          [], self
 222      )
 223      def meth_random(loc, env, _event)
 224          value = if self.val > 0
 225                  begin
 226                      VC.make_number self.class, ::Random.rand(self.val)
 227                  rescue Errno::EDOM
 228                      raise X::ArgumentError.new(
 229                          loc,
 230                          env,
 231                          "Domain error on float number %s : %s",
 232                                  self.to_s,
 233                                  self.type_sym.to_s
 234                      )
 235                  end
 236              elsif self.val < 0
 237                  raise X::ArgumentError.new(
 238                      loc,
 239                      env,
 240                      "Invalid argument %s : %s",
 241                              self.to_s,
 242                              self.type_sym.to_s
 243                  )
 244              else
 245                  self
 246              end
 247 
 248          ASSERT.kind_of value, Number::Abstract
 249      end
 250  end
 251  Abstract.freeze
 252 
 253  end # Umu::Value::Core::Atom::Number
 254 
 255  end # Umu::Value::Core::Atom
 256 
 257 
 258  module_function
 259 
 260      def make_number(klass, val)
 261          ASSERT.subclass_of  klass,  VCAN::Abstract
 262          ASSERT.kind_of      val,    ::Numeric
 263 
 264          klass.new(val).freeze
 265      end
 266 
 267  end # Umu::Value::Core
 268 
 269  end # Umu::Value
 270 
 271  end # Umu