File: concrete-syntax/core/expression/unary/container/comprehension.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: ConcreteSyntax#8
  module: Core#10
  module: Expression#12
has properties
function: make_generator / 3 #287
function: make_guard / 2 #298
function: make_list_comprehension / 3 #308
function: make_stream_comprehension / 3 #319
  module: Unary#14
  module: Container#16
  module: Comprehension#18
  module: Qualifier#20
  class: Abstract#22
inherits from
  Model ( Umu::Abstraction )
has properties
attribute: expr [R] #23
method: initialize / 2 #26
method: pretty_print / 1 #35
  class: Generator#42
inherits from
  Abstract ( Umu::ConcreteSyntax::Core::Expression::Unary::Container::Comprehension::Qualifier )
has properties
attribute: pat [R] #43
method: initialize / 3 #46
method: to_s #56
method: pretty_print / 1 #61
method: desugar_qualifier / 6 #69
  class: Guard#110
  module: Entry#157
  class: Abstract#159
inherits from
  Abstract ( Umu::ConcreteSyntax::Core::Expression::Unary::Container )
has properties
alias: qualifiers exprs #160
attribute: expr [R] #161
method: initialize / 3 #164
method: to_s #174
method: pretty_print / 1 #189
method: __desugar__ / 2 #200
  class: List#226
  class: Stream#252

Code

   1  # coding: utf-8
   2  # frozen_string_literal: true
   3 
   4 
   5 
   6  module Umu
   7 
   8  module ConcreteSyntax
   9 
  10  module Core
  11 
  12  module Expression
  13 
  14  module Unary
  15 
  16  module Container
  17 
  18  module Comprehension
  19 
  20  module Qualifier
  21 
  22  class Abstract < Umu::Abstraction::Model
  23      attr_reader :expr
  24 
  25 
  26      def initialize(loc, expr)
  27          ASSERT.kind_of expr, CSCE::Abstract
  28 
  29          super(loc)
  30 
  31          @expr = expr
  32      end
  33 
  34 
  35      def pretty_print(_q)
  36          raise X::InternalSubclassResponsibility
  37      end
  38  end
  39 
  40 
  41 
  42  class Generator < Abstract
  43      attr_reader :pat
  44 
  45 
  46      def initialize(loc, pat, expr)
  47          ASSERT.kind_of pat,     CSCP::Abstract
  48          ASSERT.kind_of expr,    CSCE::Abstract
  49 
  50          super(loc, expr)
  51 
  52          @pat = pat
  53      end
  54 
  55 
  56      def to_s
  57          format "%%VAL %s <- %s", self.pat.to_s, self.expr.to_s
  58      end
  59 
  60 
  61      def pretty_print(q)
  62          q.text '%VAL '
  63          q.pp self.pat
  64          q.text ' <- '
  65          q.pp self.expr
  66      end
  67 
  68 
  69      def desugar_qualifier(
  70          env, elem_expr, tail_qualifiers, type_coercion_sym,
  71          make_comprehension, _make_morph
  72      )
  73          ASSERT.kind_of env,                 E::Entry
  74          ASSERT.kind_of elem_expr,           CSCE::Abstract
  75          ASSERT.kind_of tail_qualifiers,     ::Array
  76          ASSERT.kind_of type_coercion_sym,   ::Symbol
  77          ASSERT.kind_of make_comprehension,  ::Proc
  78          ASSERT.kind_of _make_morph,         ::Proc
  79 
  80          body_expr = make_comprehension.call(
  81                           self.loc, elem_expr, tail_qualifiers
  82                      )
  83 
  84          ASCE.make_send(
  85              self.loc,
  86 
  87              self.expr.desugar(env),
  88 
  89              ASCE.make_message(self.loc, type_coercion_sym),
  90 
  91              [
  92                  ASCE.make_message(
  93                      self.loc,
  94 
  95                      :'concat-map',
  96 
  97                      [
  98                          CSCE.make_lambda(
  99                              self.loc, [self.pat], body_expr
 100                          ).desugar(env)
 101                      ]
 102                  )
 103              ]
 104          )
 105      end
 106  end
 107 
 108 
 109 
 110  class Guard < Abstract
 111      def to_s
 112          format "%%IF %s", self.expr.to_s
 113      end
 114 
 115 
 116      def pretty_print(q)
 117          q.text '%IF '
 118          q.pp self.expr
 119      end
 120 
 121 
 122      def desugar_qualifier(
 123          env, elem_expr, tail_qualifiers, _type_coercion_sym,
 124          make_comprehension, make_morph
 125      )
 126          ASSERT.kind_of env,                 E::Entry
 127          ASSERT.kind_of elem_expr,           CSCE::Abstract
 128          ASSERT.kind_of tail_qualifiers,     ::Array
 129          ASSERT.kind_of _type_coercion_sym,  ::Symbol
 130          ASSERT.kind_of make_comprehension,  ::Proc
 131          ASSERT.kind_of make_morph,         ::Proc
 132 
 133          then_expr = make_comprehension.call(
 134                           self.loc, elem_expr, tail_qualifiers
 135                      )
 136 
 137          ASCE.make_if(
 138              self.loc,
 139 
 140              [
 141                  ASCE.make_rule(
 142                      elem_expr.loc,
 143                      self.expr.desugar(env),
 144                      then_expr.desugar(env)
 145                  )
 146              ],
 147 
 148              make_morph.call(self.loc, [])
 149          )
 150      end
 151  end
 152 
 153  end # Umu::ConcreteSyntax::Core::Expression::Unary::Container::Comprehension::Qualifier
 154 
 155 
 156 
 157  module Entry
 158 
 159  class Abstract < Container::Abstract
 160      alias       qualifiers exprs
 161      attr_reader :expr
 162 
 163 
 164      def initialize(loc, expr, qualifiers)
 165          ASSERT.kind_of expr,        CSCE::Abstract
 166          ASSERT.kind_of qualifiers,  ::Array
 167 
 168          super(loc, qualifiers)
 169 
 170          @expr = expr
 171      end
 172 
 173 
 174      def to_s
 175          format("%s%s|%s]",
 176              __bb__,
 177 
 178              self.expr.to_s,
 179 
 180              if self.qualifiers.empty?
 181                  ''
 182              else
 183                  ' ' + self.qualifiers.map(&:to_s).join(' ')
 184              end
 185          )
 186      end
 187 
 188 
 189      def pretty_print(q)
 190          PRT.group q, bb:__bb__, eb:'|' do
 191              q.pp self.expr
 192          end
 193 
 194          PRT.group_for_enum q, self.qualifiers, eb:']', sep:' ', join:' '
 195      end
 196 
 197 
 198  private
 199 
 200      def __desugar__(env, event)
 201          new_env = env.enter event
 202 
 203          if self.qualifiers.empty?
 204              __make_morph__ self.loc, [self.expr.desugar(new_env)]
 205          else
 206              hd_qualifier, *tl_qualifiers = qualifiers
 207              ASSERT.kind_of hd_qualifier, Qualifier::Abstract
 208 
 209              hd_qualifier.desugar_qualifier(
 210                  new_env, self.expr, tl_qualifiers, __type_coercion_sym__,
 211 
 212                  lambda { |loc, expr, qualifiers|
 213                      __make_comprehension__ loc, expr, qualifiers
 214                  },
 215 
 216                  lambda { |loc, exprs|
 217                      __make_morph__ loc, exprs
 218                  }
 219              )
 220          end
 221      end
 222  end
 223 
 224 
 225 
 226  class List < Abstract
 227 
 228  private
 229 
 230      def __bb__
 231          '[|'
 232      end
 233 
 234 
 235      def __type_coercion_sym__
 236          :'to-list'
 237      end
 238 
 239 
 240      def __make_comprehension__(loc, expr, qualifiers)
 241          CSCE.make_list_comprehension loc, expr, qualifiers
 242      end
 243 
 244 
 245      def __make_morph__(loc, exprs)
 246          ASCE.make_list loc, exprs
 247      end
 248  end
 249 
 250 
 251 
 252  class Stream < Abstract
 253 
 254  private
 255 
 256      def __bb__
 257          '&[|'
 258      end
 259 
 260 
 261      def __type_coercion_sym__
 262          :'susp'
 263      end
 264 
 265 
 266      def __make_comprehension__(loc, expr, qualifiers)
 267          CSCE.make_stream_comprehension loc, expr, qualifiers
 268      end
 269 
 270 
 271      def __make_morph__(loc, exprs)
 272          ASCE.make_stream loc, exprs
 273      end
 274  end
 275 
 276  end # Umu::ConcreteSyntax::Core::Expression::Unary::Container::Comprehension::Entry
 277 
 278  end # Umu::ConcreteSyntax::Core::Expression::Unary::Container::Comprehension
 279 
 280  end # Umu::ConcreteSyntax::Core::Expression::Unary::Container
 281 
 282  end # Umu::ConcreteSyntax::Core::Expression::Unary
 283 
 284 
 285  module_function
 286 
 287      def make_generator(loc, pat, expr)
 288          ASSERT.kind_of loc,     LOC::Entry
 289          ASSERT.kind_of pat,     CSCP::Abstract
 290          ASSERT.kind_of expr,    CSCE::Abstract
 291 
 292          Unary::Container::Comprehension::Qualifier::Generator.new(
 293              loc, pat, expr
 294          ).freeze
 295      end
 296 
 297 
 298      def make_guard(loc, expr)
 299          ASSERT.kind_of loc,     LOC::Entry
 300          ASSERT.kind_of expr,    CSCE::Abstract
 301 
 302          Unary::Container::Comprehension::Qualifier::Guard.new(
 303              loc, expr
 304          ).freeze
 305      end
 306 
 307 
 308      def make_list_comprehension(loc, expr, qualifiers)
 309          ASSERT.kind_of loc,         LOC::Entry
 310          ASSERT.kind_of expr,        CSCE::Abstract
 311          ASSERT.kind_of qualifiers,  ::Array
 312 
 313          Unary::Container::Comprehension::Entry::List.new(
 314              loc, expr, qualifiers.freeze
 315          ).freeze
 316      end
 317 
 318 
 319      def make_stream_comprehension(loc, expr, qualifiers)
 320          ASSERT.kind_of loc,         LOC::Entry
 321          ASSERT.kind_of expr,        CSCE::Abstract
 322          ASSERT.kind_of qualifiers,  ::Array
 323 
 324          Unary::Container::Comprehension::Entry::Stream.new(
 325              loc, expr, qualifiers.freeze
 326          ).freeze
 327      end
 328 
 329  end # Umu::ConcreteSyntax::Core::Expression
 330 
 331  end # Umu::ConcreteSyntax::Core
 332 
 333  end # Umu::ConcreteSyntax
 334 
 335  end # Umu