File: concrete-syntax/core/expression/nary/branch/case/rule/datum.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_case_rule_datum / 3 #188
  module: Nary#14
  module: Branch#16
  module: Rule#18
  module: Case#20
  class: Datum#22
inherits from
  Abstract ( Umu::ConcreteSyntax::Core::Expression::Nary::Branch::Rule::Case )
has properties
alias: tag_sym obj #23
attribute: opt_contents_pat [R] #24
method: initialize / 3 #26
method: type_sym #36
method: to_s #41
method: pretty_print / 1 #54
method: desugar_for_rule / 2 #64

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 Nary
  15 
  16  module Branch
  17 
  18  module Rule
  19 
  20  module Case
  21 
  22  class Datum < Abstract
  23      alias       tag_sym obj
  24      attr_reader :opt_contents_pat
  25 
  26      def initialize(loc, tag_sym, opt_contents_pat)
  27          ASSERT.kind_of      tag_sym,            ::Symbol
  28          ASSERT.opt_kind_of  opt_contents_pat,   CSCP::Abstract
  29 
  30          super(loc, tag_sym)
  31 
  32          @opt_contents_pat = opt_contents_pat
  33      end
  34 
  35 
  36      def type_sym
  37          :Datum
  38      end
  39 
  40 
  41      def to_s
  42          format("%s%s",
  43                  self.tag_sym.to_s,
  44 
  45                  if self.opt_contents_pat
  46                      ' ' + self.opt_contents_pat.to_s
  47                  else
  48                      ''
  49                  end
  50          )
  51      end
  52 
  53 
  54      def pretty_print(q)
  55          q.text self.tag_sym.to_s
  56 
  57          if self.opt_contents_pat
  58              q.text ' '
  59              q.pp self.opt_contents_pat
  60          end
  61      end
  62 
  63 
  64      def desugar_for_rule(env, case_expr)
  65          ASSERT.kind_of case_expr, Branch::Case
  66 
  67          source_expr = case_expr.expr.desugar env
  68 
  69          leafs = case_expr.rules.inject({}) { |leafs, rule|
  70              ASSERT.kind_of leafs,   ::Hash
  71              ASSERT.kind_of rule,    Rule::Abstraction::Abstract
  72 
  73              head = rule.head
  74              ASSERT.kind_of head, Rule::Case::Abstract
  75              unless head.kind_of? Rule::Case::Datum
  76                  raise X::SyntaxError.new(
  77                      rule.loc,
  78                      format("Inconsistent rule categories " +
  79                                  "in case-expression, " +
  80                              "1st is %s : %s(#%d), " +
  81                              "but another is %s : %s(#%d)",
  82                          self.to_s,
  83                          self.type_sym.to_s,
  84                          self.loc.line_num + 1,
  85                          __escape_string_format__(head.to_s),
  86                          head.type_sym.to_s,
  87                          head.loc.line_num + 1
  88                      )
  89                  )
  90              end
  91 
  92              body_expr = if head.opt_contents_pat
  93                      contents_decl = head.opt_contents_pat.desugar_value(
  94                          ASCE.make_send(
  95                              case_expr.expr.loc,
  96 
  97                              if source_expr.simple?
  98                                  source_expr
  99                              else
 100                                  ASCE.make_identifier(
 101                                      source_expr.loc, :'%x'
 102                                  )
 103                              end,
 104 
 105                              ASCE.make_message(
 106                                  case_expr.expr.loc, :contents
 107                              )
 108                          ),
 109 
 110                          env
 111                      )
 112                      ASSERT.kind_of contents_decl, ASCD::Abstract
 113 
 114                      ASCE.make_let(
 115                          rule.loc,
 116 
 117                          ASCD.make_seq_of_declaration(
 118                              rule.loc,
 119                              [contents_decl]
 120                          ),
 121 
 122                          rule.body_expr.desugar(env)
 123                      )
 124                  else
 125                      case_expr.desugar_body_expr env, rule
 126                  end
 127 
 128              leafs.merge(head.tag_sym => body_expr) {
 129                  raise X::SyntaxError.new(
 130                      rule.loc,
 131                      format("Duplicated rules in case-expression: %s",
 132                          head.to_s
 133                      )
 134                  )
 135              }
 136          }
 137 
 138          if source_expr.simple?
 139              ASCE.make_switch(
 140                  case_expr.loc,
 141                  ASCE.make_send(
 142                      source_expr.loc,
 143                      source_expr,
 144                      ASCE.make_message(source_expr.loc, :tag),
 145                      [],
 146                      :Datum
 147                  ),
 148                  :Symbol,
 149                  leafs,
 150                  case_expr.desugar_else_expr(env)
 151              )
 152          else
 153              ASCE.make_let(
 154                  case_expr.loc,
 155 
 156                  ASCD.make_seq_of_declaration(
 157                      source_expr.loc,
 158                      [ASCD.make_value(source_expr.loc, :'%x', source_expr)]
 159                  ),
 160 
 161                  ASCE.make_switch(
 162                      case_expr.loc,
 163                      ASCE.make_send(
 164                          source_expr.loc,
 165                          ASCE.make_identifier(source_expr.loc, :'%x'),
 166                          ASCE.make_message(source_expr.loc, :tag)
 167                      ),
 168                      :Symbol,
 169                      leafs,
 170                      case_expr.desugar_else_expr(env)
 171                  )
 172              )
 173          end
 174      end
 175  end
 176 
 177  end # Umu::ConcreteSyntax::Core::Expression::Nary::Branch::Rule::Case
 178 
 179  end # Umu::ConcreteSyntax::Core::Expression::Nary::Branch::Rule
 180 
 181  end # Umu::ConcreteSyntax::Core::Expression::Nary::Branch
 182 
 183  end # Umu::ConcreteSyntax::Core::Expression::Nary
 184 
 185 
 186  module_function
 187 
 188      def make_case_rule_datum(loc, tag_sym, opt_contents_pat)
 189          ASSERT.kind_of      loc,                LOC::Entry
 190          ASSERT.kind_of      tag_sym,            ::Symbol
 191          ASSERT.opt_kind_of  opt_contents_pat,   CSCP::Abstract
 192 
 193          Nary::Branch::Rule::Case::Datum.new(
 194              loc, tag_sym, opt_contents_pat
 195          ).freeze
 196      end
 197 
 198  end # Umu::ConcreteSyntax::Core::Expression
 199 
 200  end # Umu::ConcreteSyntax::Core
 201 
 202  end # Umu::ConcreteSyntax
 203 
 204  end # Umu