File: concrete-syntax/module/expression/struct.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: ConcreteSyntax#8
  module: Module#10
  module: Expression#12
has properties
function: make_struct / 2 #92
  class: Struct#14
inherits from
  Abstract ( Umu::ConcreteSyntax::Module::Expression )
has properties
attribute: body_decls [R] #15
method: initialize / 2 #18
method: to_s #27
method: pretty_print / 1 #38
method: __desugar__ / 2 #47

Code

   1  # coding: utf-8
   2  # frozen_string_literal: true
   3 
   4 
   5 
   6  module Umu
   7 
   8  module ConcreteSyntax
   9 
  10  module Module
  11 
  12  module Expression
  13 
  14  class Struct < Expression::Abstract
  15      attr_reader :body_decls
  16 
  17 
  18      def initialize(loc, body_decls)
  19          ASSERT.kind_of body_decls,  ::Array
  20 
  21          super(loc)
  22 
  23          @body_decls = body_decls
  24      end
  25 
  26 
  27      def to_s
  28          format("%%STRUCT {%s}",
  29              if self.body_decls.empty?
  30                  ' '
  31              else
  32                  self.body_decls.map(&:to_s).join(' ')
  33              end
  34          )
  35      end
  36 
  37 
  38      def pretty_print(q)
  39          PRT.group_for_enum(
  40              q, self.body_decls, bb:'%STRUCT {', eb:'}', sep:'  '
  41          ) do |decl| q.pp decl end
  42      end
  43 
  44 
  45  private
  46 
  47      def __desugar__(env, event)
  48          expr_by_label = (
  49              self.body_decls.inject([]) {
  50                  |array, decl|
  51                  ASSERT.kind_of array,   ::Array
  52                  ASSERT.kind_of decl,    Declaration::Abstract
  53 
  54                  array + decl.exported_vars
  55              }.inject({}) { |hash, vpat|
  56                  ASSERT.kind_of hash,    ::Hash
  57                  ASSERT.kind_of vpat,    CSCP::ElementOfContainer::Variable
  58 
  59                  label = vpat.var_sym
  60                  expr  = ASCE.make_identifier(vpat.loc, vpat.var_sym)
  61 
  62                  hash.merge(label => expr) { |_lab, _old_expr, new_expr|
  63                      new_expr
  64                  }
  65              }
  66          )
  67 
  68          expr = ASCE.make_struct self.loc, expr_by_label
  69 
  70          if self.body_decls.empty?
  71              expr
  72          else
  73              new_env = env.enter event
  74 
  75              ASCE.make_let(
  76                  self.loc,
  77 
  78                  ASCD.make_seq_of_declaration(
  79                      self.loc,
  80                      self.body_decls.map { |decl| decl.desugar new_env }
  81                  ),
  82 
  83                  expr
  84              )
  85          end
  86      end
  87  end
  88 
  89 
  90  module_function
  91 
  92      def make_struct(loc, body_decls)
  93          ASSERT.kind_of loc,         LOC::Entry
  94          ASSERT.kind_of body_decls,  ::Array
  95 
  96          Struct.new(loc, body_decls.freeze).freeze
  97      end
  98 
  99  end # Umu::ConcreteSyntax::Module::Expression
 100 
 101  end # Umu::ConcreteSyntax::Module
 102 
 103  end # Umu::ConcreteSyntax
 104 
 105  end # Umu