File: abstract-syntax/core/expression/nary/interval.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: AbstractSyntax#8
  module: Core#10
  module: Expression#12
has properties
function: make_interval / 4 #258
function: make_interval_stream / 4 #270
  module: Nary#14
  module: Interval#16
  class: Abstract#18
inherits from
  Abstract ( Umu::AbstractSyntax::Core::Expression )
has properties
attribute: fst_expr [R] #19
attribute: opt_snd_expr [R] #19
attribute: opt_lst_expr [R] #19
method: initialize / 4 #22
method: to_s #35
method: __bb__ #58
method: __evaluate__ / 2 #63
method: __make__ / 4 #202
method: __validate_second_value__ / 4 #207
  class: Basic#213
inherits from
  Abstract ( Umu::AbstractSyntax::Core::Expression::Nary::Interval )
has properties
method: initialize / 4 #214
method: __bb__ #225
method: __make__ / 4 #230
  class: Stream#237
inherits from
  Abstract ( Umu::AbstractSyntax::Core::Expression::Nary::Interval )
has properties
method: __bb__ #241
method: __make__ / 4 #246

Code

   1  # coding: utf-8
   2  # frozen_string_literal: true
   3 
   4 
   5 
   6  module Umu
   7 
   8  module AbstractSyntax
   9 
  10  module Core
  11 
  12  module Expression
  13 
  14  module Nary
  15 
  16  module Interval
  17 
  18  class Abstract < Expression::Abstract
  19      attr_reader :fst_expr, :opt_snd_expr, :opt_lst_expr
  20 
  21 
  22      def initialize(loc, fst_expr, opt_snd_expr, opt_lst_expr)
  23          ASSERT.kind_of     fst_expr,        ASCE::Abstract
  24          ASSERT.opt_kind_of opt_snd_expr,    ASCE::Abstract
  25          ASSERT.opt_kind_of opt_lst_expr,    ASCE::Abstract
  26 
  27          super(loc)
  28 
  29          @fst_expr     = fst_expr
  30          @opt_snd_expr = opt_snd_expr
  31          @opt_lst_expr = opt_lst_expr
  32      end
  33 
  34 
  35      def to_s
  36          format("%s%s%s ..%s]",
  37              __bb__,
  38 
  39              self.fst_expr.to_s,
  40 
  41              if self.opt_snd_expr
  42                  format ", %s", self.opt_snd_expr.to_s
  43              else
  44                  ''
  45              end,
  46 
  47              if self.opt_lst_expr
  48                  format " %s", self.opt_lst_expr.to_s
  49              else
  50                  ''
  51              end
  52          )
  53      end
  54 
  55 
  56  private
  57 
  58      def __bb__
  59          raise X::InternalSubclassResponsibility
  60      end
  61 
  62 
  63      def __evaluate__(env, event)
  64          ASSERT.kind_of env,     E::Entry
  65          ASSERT.kind_of event,   E::Tracer::Event
  66 
  67          new_env = env.enter event
  68 
  69          fst_result = self.fst_expr.evaluate new_env
  70          ASSERT.kind_of fst_result, ASR::Value
  71          fst_value = fst_result.value
  72          ASSERT.kind_of fst_value, VC::Top
  73          unless fst_value.kind_of? VCAN::Int
  74              raise X::TypeError.new(
  75                  self.loc,
  76                  env,
  77                  "Type error in interval-expression, " +
  78                          "expected a Int as first value, but %s : %s",
  79                      fst_value.to_s,
  80                      fst_value.type_sym.to_s
  81              )
  82          end
  83 
  84          opt_snd_value = (
  85              if self.opt_snd_expr
  86                  snd_result = self.opt_snd_expr.evaluate new_env
  87                  ASSERT.kind_of snd_result, ASR::Value
  88                  snd_value = snd_result.value
  89                  ASSERT.kind_of snd_value, VC::Top
  90                  unless snd_value.kind_of? VCAN::Int
  91                      raise X::TypeError.new(
  92                          self.loc,
  93                          env,
  94                          "Type error in interval-expression, " +
  95                              "expected a Int as second value, but %s : %s",
  96                              snd_value.to_s,
  97                              snd_value.type_sym.to_s
  98                      )
  99                  end
 100 
 101                  snd_value
 102              else
 103                  nil
 104              end
 105          )
 106 
 107          opt_lst_value = (
 108              if self.opt_lst_expr
 109                  lst_result = self.opt_lst_expr.evaluate new_env
 110                  ASSERT.kind_of lst_result, ASR::Value
 111 
 112                  lst_val = lst_result.value
 113                  ASSERT.kind_of lst_val, VC::Top
 114                  unless lst_val.kind_of? VCAN::Int
 115                      raise X::TypeError.new(
 116                          self.loc,
 117                          env,
 118                          "Type error in interval-expression, " +
 119                                  "expected a Int as last value, but %s : %s",
 120                              lst_val.to_s,
 121                              lst_val.type_sym.to_s
 122                      )
 123                  end
 124 
 125                  lst_val
 126              else
 127                  nil
 128              end
 129          )
 130 
 131          step_value = VC.make_integer(
 132              if opt_lst_value
 133                  lst_value = opt_lst_value
 134 
 135                  if fst_value.val <= lst_value.val
 136                      if opt_snd_value
 137                          snd_value = opt_snd_value
 138                          unless (fst_value.val < snd_value.val &&
 139                                  snd_value.val < lst_value.val)
 140                              raise X::ValueError.new(
 141                                  self.loc,
 142                                  env,
 143                                  "The second value must be between " +
 144                                      "the first and last value, but %s : %s",
 145                                      snd_value.to_s,
 146                                      snd_value.type_sym.to_s
 147                              )
 148                          end
 149 
 150                          snd_value.val - fst_value.val
 151                      else
 152                          1
 153                      end
 154                  else
 155                      if opt_snd_value
 156                          snd_value = opt_snd_value
 157                          unless (fst_value.val > snd_value.val &&
 158                                  snd_value.val > lst_value.val)
 159                              raise X::ValueError.new(
 160                                  self.loc,
 161                                  env,
 162                                  "The second value must be between " +
 163                                      "the first and last value, but %s : %s",
 164                                      snd_value.to_s,
 165                                      snd_value.type_sym.to_s
 166                              )
 167                          end
 168 
 169                          snd_value.val - fst_value.val
 170                      else
 171                          -1
 172                      end
 173                  end
 174              else
 175                  if opt_snd_value
 176                      snd_value = opt_snd_value
 177 
 178                      if fst_value.val == snd_value.val
 179                          raise X::ValueError.new(
 180                              self.loc,
 181                              env,
 182                              "The first value and second value " +
 183                                  "must be not equal, but %s : %s",
 184                                  snd_value.to_s,
 185                                  snd_value.type_sym.to_s
 186                          )
 187                      else
 188                          snd_value.val - fst_value.val
 189                      end
 190                  else
 191                      1
 192                  end
 193              end
 194          )
 195 
 196          __make__ fst_value, lst_value, step_value, env.va_context
 197      end
 198 
 199 
 200  private
 201 
 202      def __make__(_fst_value, _lst_value, _step_value, _va_context)
 203          raise X::InternalSubclassResponsibility
 204      end
 205 
 206 
 207      def __validate_second_value__(loc, env, fst_value, snd_value)
 208      end
 209  end
 210 
 211 
 212 
 213  class Basic < Abstract
 214      def initialize(loc, fst_expr, opt_snd_expr, lst_expr)
 215          ASSERT.kind_of     fst_expr,        ASCE::Abstract
 216          ASSERT.opt_kind_of opt_snd_expr,    ASCE::Abstract
 217          ASSERT.kind_of     lst_expr,        ASCE::Abstract
 218 
 219          super
 220      end
 221 
 222 
 223  private
 224 
 225      def __bb__
 226          '['
 227      end
 228 
 229 
 230      def __make__(fst_value, lst_value, step_value, _va_context)
 231          VC.make_interval fst_value, lst_value, step_value
 232      end
 233  end
 234 
 235 
 236 
 237  class Stream < Abstract
 238 
 239  private
 240 
 241      def __bb__
 242          '&['
 243      end
 244 
 245 
 246      def __make__(fst_value, lst_value, step_value, va_context)
 247          VC.make_interval_stream fst_value, lst_value, step_value, va_context
 248      end
 249  end
 250 
 251  end # Umu::AbstractSyntax::Core::Expression::Nary::Interval
 252 
 253  end # Umu::AbstractSyntax::Core::Expression::Nary
 254 
 255 
 256  module_function
 257 
 258      def make_interval(loc, fst_expr, opt_snd_expr, lst_expr)
 259          ASSERT.kind_of     loc,             LOC::Entry
 260          ASSERT.kind_of     fst_expr,        ASCE::Abstract
 261          ASSERT.opt_kind_of opt_snd_expr,    ASCE::Abstract
 262          ASSERT.kind_of     lst_expr,        ASCE::Abstract
 263 
 264          Nary::Interval::Basic.new(
 265              loc, fst_expr, opt_snd_expr, lst_expr
 266          ).freeze
 267      end
 268 
 269 
 270      def make_interval_stream(loc, fst_expr, opt_snd_expr, opt_lst_expr)
 271          ASSERT.kind_of     loc,             LOC::Entry
 272          ASSERT.kind_of     fst_expr,        ASCE::Abstract
 273          ASSERT.opt_kind_of opt_snd_expr,    ASCE::Abstract
 274          ASSERT.opt_kind_of opt_lst_expr,    ASCE::Abstract
 275 
 276          Nary::Interval::Stream.new(
 277              loc, fst_expr, opt_snd_expr, opt_lst_expr
 278          ).freeze
 279      end
 280 
 281  end # Umu::AbstractSyntax::Core::Expression
 282 
 283  end # Umu::AbstractSyntax::Core
 284 
 285  end # Umu::AbstractSyntax
 286 
 287  end # Umu