File: concrete-syntax/core/declaration/recursive.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: ConcreteSyntax#8
  module: Core#10
  module: Declaration#12
has properties
function: make_recursive / 2 #109
  class: Recursive#14
inherits from
  Abstract ( Umu::ConcreteSyntax::Core::Declaration )
has properties
attribute: functions [R] #15
method: initialize / 2 #18
method: to_s #27
method: pretty_print / 1 #34
method: exported_vars #54
method: __desugar__ / 2 #66

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 Declaration
  13 
  14  class Recursive < Declaration::Abstract
  15      attr_reader :functions
  16 
  17 
  18      def initialize(loc, functions)
  19          ASSERT.kind_of functions, ::Array
  20 
  21          super(loc)
  22 
  23          @functions = functions
  24      end
  25 
  26 
  27      def to_s
  28          format("%%FUN %%REC %s",
  29              self.functions.map(&:to_s).join(' %%AND ')
  30          )
  31      end
  32 
  33 
  34      def pretty_print(q)
  35          q.text '%FUN %REC '
  36 
  37          fst_func, *not_fst_funcs = self.functions
  38          q.pp fst_func
  39 
  40          not_fst_funcs.each do |func|
  41              q.breakable
  42 
  43              q.text '%AND'
  44 
  45              q.breakable
  46 
  47              PRT.group q do
  48                  q.pp func
  49              end
  50          end
  51      end
  52 
  53 
  54      def exported_vars
  55          self.functions.inject([]) { |array, function|
  56              ASSERT.kind_of array,       ::Array
  57              ASSERT.kind_of function,    Function::Abstract
  58 
  59              array + function.exported_vars
  60          }.freeze
  61      end
  62 
  63 
  64  private
  65 
  66      def __desugar__(env, event)
  67          new_env = env.enter event
  68 
  69          case self.functions.size
  70          when 0
  71              ASSERT.abort self.inspect
  72          when 1
  73              function = self.functions[0]
  74              ASSERT.kind_of function, Function::Abstract
  75 
  76              ASCD.make_recursive(
  77                  function.loc,
  78                  function.lam_expr.sym,
  79                  function.lam_expr.desugar(new_env)
  80              )
  81          else
  82              functions = self.functions.inject({}) {
  83                  |hash, function|
  84                  ASSERT.kind_of hash,        ::Hash
  85                  ASSERT.kind_of function,    Function::Abstract
  86 
  87                  hash.merge(
  88                      function.lam_expr.sym => ECV.make_recursive_target(
  89                          function.lam_expr.desugar(new_env)
  90                      )
  91                  ) {
  92                      raise X::SyntaxError.new(
  93                          function.loc,
  94                          "In mutual recursion, duplicated variable: '%s'",
  95                                                  function.lam_expr.sym.to_s
  96                      )
  97                  }
  98              }
  99 
 100              ASCD.make_mutual_recursive self.loc, functions
 101          end
 102      end
 103  end
 104 
 105 
 106 
 107  module_function
 108 
 109      def make_recursive(loc, functions)
 110          ASSERT.kind_of loc,         LOC::Entry
 111          ASSERT.kind_of functions,   ::Array
 112 
 113          Recursive.new(loc, functions.freeze).freeze
 114      end
 115 
 116  end # Umu::ConcreteSyntax::Core::Declaration
 117 
 118  end # Umu::ConcreteSyntax::Core
 119 
 120  end # Umu::ConcreteSyntax
 121 
 122  end # Umu