File: value/core/product/tuple.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_tuple / 3 #133
  module: Product#12
  class: Tuple#14
inherits from
  Abstract ( Umu::Value::Core::Product )
has properties
alias: values objs #15
method: to_s #18
method: pretty_print / 1 #23
method: meth_to_string / 3 #33
method: meth_is_equal / 4 #49
method: meth_is_less_than / 4 #72

Class Hierarchy

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 Product
  13 
  14  class Tuple < Abstract
  15      alias values objs
  16 
  17 
  18      def to_s
  19          format "(%s)", self.map(&:to_s).join(', ')
  20      end
  21 
  22 
  23      def pretty_print(q)
  24          PRT.group_for_enum q, self, bb:'(', eb:')', join:', '
  25      end
  26 
  27 
  28      define_instance_method(
  29          :meth_to_string,
  30          :'to-s', [],
  31          [], VCA::String
  32      )
  33      def meth_to_string(loc, env, event)
  34          VC.make_string(
  35              format("(%s)",
  36                  self.map { |elem|
  37                      elem.meth_to_string(loc, env, event).val
  38                  }.join(', ')
  39              )
  40          )
  41      end
  42 
  43 
  44      define_instance_method(
  45          :meth_is_equal,
  46          :'==', [],
  47          [VC::Top], VCA::Bool
  48      )
  49      def meth_is_equal(loc, env, event, other)
  50          ASSERT.kind_of other, VC::Top
  51 
  52          unless other.kind_of?(self.class) && self.arity == other.arity
  53              return VC.make_false
  54          end
  55 
  56          VC.make_bool(
  57              self.values.zip(other.values).all? {
  58                  |self_value, other_value|
  59 
  60                  other_value.kind_of?(self_value.class) &&
  61                  self_value.meth_is_equal(loc, env, event, other_value).true?
  62              }
  63          )
  64      end
  65 
  66 
  67      define_instance_method(
  68          :meth_is_less_than,
  69          :'<', [],
  70          [self], VCA::Bool
  71      )
  72      def meth_is_less_than(loc, env, event, other)
  73          ASSERT.kind_of other, VCP::Tuple
  74 
  75          unless other.kind_of?(self.class) && self.arity == other.arity
  76              raise X::TypeError.new(
  77                  loc,
  78                  env,
  79                  "Expected a tuple of %d element, but %d: %s",
  80                      self.arity, other.arity, other.to_s
  81              )
  82          end
  83 
  84          result, _index = self.values
  85              .zip(other.values)
  86              .inject([VC.make_false, 0]) {
  87              |(res, index), (self_value, other_value)|
  88              ASSERT.kind_of res,         VCA::Bool
  89              ASSERT.kind_of index,       ::Integer
  90              ASSERT.kind_of self_value,  VC::Top
  91              ASSERT.kind_of other_value, VC::Top
  92 
  93              unless other_value.kind_of?(self_value.class)
  94                  raise X::TypeError.new(
  95                      loc,
  96                      env,
  97                      "In %d's element of tuple, " +
  98                              "expected a %s, but %s : %s",
  99                          index + 1,
 100                          self_value.type_sym,
 101                          other_value.to_s,
 102                          other_value.type_sym
 103                  )
 104              end
 105 
 106              if self_value.meth_is_less_than(        # self < other
 107                  loc, env, event, other_value
 108              ).true?
 109                  break VC.make_true
 110              elsif self_value.meth_is_equal(         # self = other
 111                  loc, env, event, other_value
 112              ).true?
 113                  [res, index + 1]
 114              elsif other_value.meth_is_less_than(    # self > other
 115                  loc, env, event, self_value
 116              ).true?
 117                  break VC.make_false
 118              else
 119                  ASSERT.abort 'No case'
 120              end
 121          }
 122 
 123          ASSERT.kind_of result, VCA::Bool
 124      end
 125  end
 126  Tuple.freeze
 127 
 128  end # Umu::Value::Core::Product
 129 
 130 
 131  module_function
 132 
 133      def make_tuple(fst_value, snd_value, *tail_values)
 134          ASSERT.kind_of fst_value,   ::Object
 135          ASSERT.kind_of snd_value,   ::Object
 136          ASSERT.kind_of tail_values, ::Array
 137 
 138          Product::Tuple.new(
 139              fst_value, snd_value, tail_values.freeze
 140          ).freeze
 141      end
 142 
 143  end # Umu::Value::Core
 144 
 145  end # Umu::Value
 146 
 147  end # Umu