File: concrete-syntax/core/pattern/container/product.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: ConcreteSyntax#8
  module: Core#10
  module: Pattern#12
has properties
function: make_tuple / 2 #274
function: make_named_tuple / 2 #282
function: make_named_tuple_label / 2 #289
  module: Container#14
  module: Product#16
  class: Abstract#18
inherits from
  Abstract ( Umu::ConcreteSyntax::Core::Pattern::Container )
has properties
alias: pats array #19
method: exported_vars #22
method: __desugar_value__ / 3 #34
method: __desugar_lambda__ / 3 #48
method: __desugar_pattern__ / 1 #61
method: __type_sym__ #88
method: __make_selector__ / 3 #93
  class: Tuple#100
inherits from
  Abstract ( Umu::ConcreteSyntax::Core::Pattern::Container::Product )
has properties
method: initialize / 2 #101
method: each #121
method: to_s #130
method: pretty_print / 1 #135
method: __type_sym__ #142
method: __make_selector__ / 3 #147
  module: Named#154
  class: Label#156
inherits from
  Model ( Umu::Abstraction )
has properties
attribute: sym [R] #157
method: initialize / 2 #160
method: hash #169
method: eql? / 1 #174
method: to_s #179
  class: Entry#186
inherits from
  Abstract ( Umu::ConcreteSyntax::Core::Pattern::Container::Product )
has properties
attribute: index_by_label [R] #187
method: initialize / 2 #190
method: each #227
method: to_s #241
method: pretty_print / 1 #246
method: __type_sym__ #253
method: __make_selector__ / 3 #258

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 Pattern
  13 
  14  module Container
  15 
  16  module Product
  17 
  18  class Abstract < Container::Abstract
  19      alias pats array
  20 
  21 
  22      def exported_vars
  23          self.reject(&:wildcard?).inject([]) { |array, epat|
  24              ASSERT.kind_of array,  ::Array
  25              ASSERT.kind_of epat,   Pattern::Abstract
  26 
  27              array + epat.exported_vars
  28          }.freeze
  29      end
  30 
  31 
  32  private
  33 
  34      def __desugar_value__(expr, env, _event)
  35          ASSERT.kind_of expr, ASCE::Abstract
  36 
  37          ASCD.make_seq_of_declaration(
  38              self.loc,
  39              [
  40                  ASCD.make_value(self.loc, :'%t', expr, __type_sym__)
  41              ] + (
  42                  __desugar_pattern__(:'%t')
  43              )
  44          )
  45      end
  46 
  47 
  48      def __desugar_lambda__(seq_num, env, _event)
  49          ASSERT.kind_of seq_num, ::Integer
  50 
  51          var_sym = __gen_sym__ seq_num
  52 
  53          CSCP.make_result(
  54              ASCE.make_identifier(self.loc, var_sym),
  55              __desugar_pattern__(var_sym),
  56              __type_sym__
  57          )
  58      end
  59 
  60 
  61      def __desugar_pattern__(var_sym)
  62          ASSERT.kind_of var_sym, ::Symbol
  63 
  64          self.each_with_index.reject { |epat, _index|
  65              ASSERT.kind_of epat, ElementOfContainer::Abstract
  66 
  67              epat.wildcard? && epat.opt_type_sym.nil?
  68          }.map { |epat, index|
  69              ASSERT.kind_of epat,   ElementOfContainer::Abstract
  70              ASSERT.kind_of index,  ::Integer
  71 
  72              expr = ASCE.make_product(
  73                          epat.loc,
  74                          ASCE.make_identifier(epat.loc, var_sym),
  75                          __make_selector__(epat.loc, index, epat)
  76                      )
  77 
  78              ASCD.make_value(
  79                  epat.loc,
  80                  epat.var_pat.var_sym,
  81                  expr,
  82                  epat.var_pat.opt_type_sym
  83              )
  84          }
  85      end
  86 
  87 
  88      def __type_sym__
  89          raise X::InternalSubclassResponsibility
  90      end
  91 
  92 
  93      def __make_selector__(_loc, _index, _epat)
  94          raise X::InternalSubclassResponsibility
  95      end
  96  end
  97 
  98 
  99 
 100  class Tuple < Abstract
 101      def initialize(loc, vpats)
 102          ASSERT.kind_of  vpats, ::Array
 103          ASSERT.assert   vpats.size >= 2
 104 
 105          vpats.reject(&:wildcard?).inject({}) do |hash, vpat|
 106              ASSERT.kind_of hash,    ::Hash
 107              ASSERT.kind_of vpat,    ElementOfContainer::Variable
 108 
 109              hash.merge(vpat.var_sym => true) {
 110                  raise X::SyntaxError.new(
 111                      vpat.loc,
 112                      "Duplicated pattern variable: '%s'", vpat.to_s
 113                  )
 114              }
 115          end
 116 
 117          super
 118      end
 119 
 120 
 121      def each
 122          self.pats.each do |vpat|
 123              ASSERT.kind_of vpat, ElementOfContainer::Variable
 124 
 125              yield vpat
 126          end
 127      end
 128 
 129 
 130      def to_s
 131          format "(%s)", self.map(&:to_s).join(', ')
 132      end
 133 
 134 
 135      def pretty_print(q)
 136          PRT.group_for_enum q, self, bb:'(', eb:')', join:', '
 137      end
 138 
 139 
 140  private
 141 
 142      def __type_sym__
 143          :Product
 144      end
 145 
 146 
 147      def __make_selector__(loc, index, _pat)
 148          ASCE.make_number_selector loc, index + 1
 149      end
 150  end
 151 
 152 
 153 
 154  module Named
 155 
 156  class Label < Abstraction::Model
 157      attr_reader :sym
 158 
 159 
 160      def initialize(loc, sym)
 161          ASSERT.kind_of sym, ::Symbol
 162 
 163          super(loc)
 164 
 165          @sym = sym
 166      end
 167 
 168 
 169      def hash
 170          self.sym.hash
 171      end
 172 
 173 
 174      def eql?(other)
 175          self.sym.eql? other.sym
 176      end
 177 
 178 
 179      def to_s
 180          self.sym.to_s + ':'
 181      end
 182  end
 183 
 184 
 185 
 186  class Entry < Abstract
 187      attr_reader :index_by_label
 188 
 189 
 190      def initialize(loc, fields)
 191          ASSERT.kind_of  fields, ::Array
 192          ASSERT.assert   fields.size >= 1
 193 
 194          @index_by_label, vpat_hash, _index =
 195           fields
 196          .inject(
 197               [{},     {},     0    ]
 198          ) { |(l_hash, v_hash, index), (label, vpat)|
 199              ASSERT.kind_of l_hash, ::Hash
 200              ASSERT.kind_of v_hash, ::Hash
 201              ASSERT.kind_of label,  Label
 202              ASSERT.kind_of vpat,   ElementOfContainer::Variable
 203 
 204              [
 205                  l_hash.merge(label => index) {
 206                      raise X::SyntaxError.new(
 207                          label.loc,
 208                          "Duplicated pattern label: '%s'", label.to_s
 209                      )
 210                  },
 211 
 212                  v_hash.merge(vpat => true) {
 213                      raise X::SyntaxError.new(
 214                          vpat.loc,
 215                          "Duplicated pattern variable: '%s'", vpat.to_s
 216                      )
 217                  },
 218 
 219                  index + 1
 220              ]
 221          }
 222 
 223          super(loc, vpat_hash.keys)
 224      end
 225 
 226 
 227      def each
 228          self.index_by_label.each do |label, index|
 229              ASSERT.kind_of label, Label
 230              ASSERT.kind_of index, ::Integer
 231 
 232              yield CSCP.make_named_tuple_field(
 233                             self.loc,
 234                             label,
 235                             self.pats[index]
 236                         )
 237          end
 238      end
 239 
 240 
 241      def to_s
 242          format "(%s)", self.map(&:to_s).join(' ')
 243      end
 244 
 245 
 246      def pretty_print(q)
 247          PRT.group_for_enum q, self, bb:'(', eb:')', join:' '
 248      end
 249 
 250 
 251  private
 252 
 253      def __type_sym__
 254          :Named
 255      end
 256 
 257 
 258      def __make_selector__(loc, _index, fpat)
 259          ASSERT.kind_of fpat, ElementOfContainer::Field
 260 
 261          ASCE.make_label_selector loc, fpat.label.sym
 262      end
 263  end
 264 
 265  end # Umu::ConcreteSyntax::Core::Pattern::Container::Product::Named
 266 
 267  end # Umu::ConcreteSyntax::Core::Pattern::Container::Product
 268 
 269  end # Umu::ConcreteSyntax::Core::Pattern::Container
 270 
 271 
 272  module_function
 273 
 274      def make_tuple(loc, vpats)
 275          ASSERT.kind_of loc,     LOC::Entry
 276          ASSERT.kind_of vpats,   ::Array
 277 
 278          Container::Product::Tuple.new(loc, vpats.freeze).freeze
 279      end
 280 
 281 
 282      def make_named_tuple(loc, fields)
 283          ASSERT.kind_of loc,     LOC::Entry
 284          ASSERT.kind_of fields,  ::Array
 285 
 286          Container::Product::Named::Entry.new(loc, fields.freeze).freeze
 287      end
 288 
 289      def make_named_tuple_label(loc, sym)
 290          ASSERT.kind_of loc,     LOC::Entry
 291          ASSERT.kind_of sym,     ::Symbol
 292 
 293          Container::Product::Named::Label.new(loc, sym).freeze
 294      end
 295 
 296 
 297  end # Umu::ConcreteSyntax::Core::Pattern
 298 
 299  end # Umu::ConcreteSyntax::Core
 300 
 301  end # Umu::ConcreteSyntax
 302 
 303  end # Umu