File: concrete-syntax/core/expression/unary/container/named-tuple.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_named_tuple_label / 2 #159
function: make_named_tuple / 2 #167
  module: Unary#14
  module: Container#16
  module: Named#18
  class: Label#20
inherits from
  Abstract ( Umu::ConcreteSyntax::Core::Expression::Unary )
has properties
alias: sym obj #21
method: initialize / 2 #24
method: hash #31
method: eql? / 1 #36
method: to_s #41
method: __desugar__ / 2 #48
  class: Entry#55
inherits from
  Abstract ( Umu::ConcreteSyntax::Core::Expression::Unary::Container )
has properties
attribute: index_by_label [R] #56
method: initialize / 2 #59
method: to_s #94
method: pretty_print / 1 #108
method: __desugar__ / 2 #125

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 Named
  19 
  20  class Label < Unary::Abstract
  21      alias sym obj
  22 
  23 
  24      def initialize(loc, sym)
  25          ASSERT.kind_of sym, ::Symbol
  26 
  27          super
  28      end
  29 
  30 
  31      def hash
  32          self.sym.hash
  33      end
  34 
  35 
  36      def eql?(other)
  37          self.sym.eql? other.sym
  38      end
  39 
  40 
  41      def to_s
  42          self.sym.to_s + ':'
  43      end
  44 
  45 
  46  private
  47 
  48      def __desugar__(_env, _event)
  49          ASCE.make_named_tuple_label self.loc, self.sym
  50      end
  51  end
  52 
  53 
  54 
  55  class Entry < Abstract
  56      attr_reader :index_by_label
  57 
  58 
  59      def initialize(loc, fields)
  60          ASSERT.kind_of  fields, ::Array
  61          ASSERT.assert   fields.size >= 2
  62 
  63          index_by_label, exprs = fields.each_with_index.inject([{}, []]) {
  64              |(hash, array), (pair, index)|
  65              ASSERT.kind_of  hash,   ::Hash
  66              ASSERT.kind_of  array,  ::Array
  67              ASSERT.kind_of  pair,   ::Array
  68              ASSERT.kind_of  index,  ::Integer
  69 
  70              label, opt_expr = pair
  71              ASSERT.kind_of     label,    Label
  72              ASSERT.opt_kind_of opt_expr, CSCE::Abstract
  73 
  74              [
  75                  hash.merge(label => index) {
  76                      raise X::SyntaxError.new(
  77                          label.loc,
  78                          format("Duplicated label in named tuple: '%s'",
  79                                  label.sym
  80                          )
  81                      )
  82                  },
  83 
  84                  array + [opt_expr]
  85              ]
  86          }
  87 
  88          @index_by_label = index_by_label.freeze
  89 
  90          super(loc, exprs.freeze)
  91      end
  92 
  93 
  94      def to_s
  95          format("(%s)",
  96              self.index_by_label.map { |label, index|
  97                  opt_expr = self.exprs[index]
  98 
  99                  format("%s%s",
 100                          label.to_s,
 101                          opt_expr ? opt_expr.to_s : ''
 102                  )
 103              }.join(' ')
 104          )
 105      end
 106 
 107 
 108      def pretty_print(q)
 109          PRT.group_for_enum(
 110              q, self.index_by_label, bb:'(', eb:')', join:' '
 111          ) do |label, index|
 112 
 113              opt_expr = self.exprs[index]
 114 
 115              q.text label.to_s
 116              if opt_expr
 117                  q.pp opt_expr
 118              end
 119          end
 120      end
 121 
 122 
 123  private
 124 
 125      def __desugar__(env, event)
 126          new_env = env.enter event
 127 
 128          exprs = self.index_by_label.inject([]) { |array, (label, index)|
 129              opt_expr = self.exprs[index]
 130 
 131              array + [
 132                  if opt_expr
 133                      opt_expr.desugar(new_env)
 134                  else
 135                      ASCE.make_identifier label.loc, label.sym
 136                  end
 137              ]
 138          }
 139 
 140          index_by_label = self.index_by_label.inject({}) {
 141              |hash, (label, index)|
 142 
 143              hash.merge(label.desugar(new_env) => index)
 144          }
 145 
 146          ASCE.make_named_tuple self.loc, exprs, index_by_label
 147      end
 148  end
 149 
 150  end # Umu::ConcreteSyntax::Core::Expression::Unary::Container::Named
 151 
 152  end # Umu::ConcreteSyntax::Core::Expression::Unary::Container
 153 
 154  end # Umu::ConcreteSyntax::Core::Expression::Unary
 155 
 156 
 157  module_function
 158 
 159      def make_named_tuple_label(loc, sym)
 160          ASSERT.kind_of loc,     LOC::Entry
 161          ASSERT.kind_of sym,     ::Symbol
 162 
 163          Unary::Container::Named::Label.new(loc, sym).freeze
 164      end
 165 
 166 
 167      def make_named_tuple(loc, fields)
 168          ASSERT.kind_of loc,     LOC::Entry
 169          ASSERT.kind_of fields,  ::Array
 170 
 171          Unary::Container::Named::Entry.new(loc, fields.freeze).freeze
 172      end
 173 
 174  end # Umu::ConcreteSyntax::Core::Expression
 175 
 176  end # Umu::ConcreteSyntax::Core
 177 
 178  end # Umu::ConcreteSyntax
 179 
 180  end # Umu