File: environment/tracer/tracer.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: Umu#6
  module: Environment#8
  module: Tracer#10
has properties
function: make_event / 4 #47
function: trace / 6 #57
function: trace_single / 6 #87
function: class_to_string / 1 #115
constant: ABBREVIATABLE_MODULE_NAMES #135
function: abbreviate / 1 #180
  class: Event#12
inherits from
  Object ( Builtin-Module )
has properties
attribute: label [R] #13
attribute: klass [R] #14
attribute: loc [R] #15
attribute: msg [R] #16
method: initialize / 4 #19
method: to_s #32

Class Hierarchy

Code

   1  # coding: utf-8
   2  # frozen_string_literal: true
   3 
   4 
   5 
   6  module Umu
   7 
   8  module Environment
   9 
  10  module Tracer
  11 
  12  class Event
  13      attr_reader :label
  14      attr_reader :klass
  15      attr_reader :loc
  16      attr_reader :msg
  17 
  18 
  19      def initialize(label, klass, loc, msg)
  20          ASSERT.kind_of label,   ::String
  21          ASSERT.kind_of klass,   ::Class
  22          ASSERT.kind_of loc,     LOC::Entry
  23          ASSERT.kind_of msg,     ::String
  24 
  25          @label  = label
  26          @klass  = klass
  27          @loc    = loc
  28          @msg    = msg
  29      end
  30 
  31 
  32      def to_s
  33          format("%s:#%d:[%s] %s: %s",
  34                      self.loc.file_name,
  35                      self.loc.line_num + 1,
  36                      label,
  37                      Tracer.class_to_string(klass),
  38                      self.msg
  39          )
  40      end
  41  end
  42 
  43 
  44 
  45  module_function
  46 
  47      def make_event(label, klass, loc, msg)
  48          ASSERT.kind_of label,   ::String
  49          ASSERT.kind_of klass,   ::Class
  50          ASSERT.kind_of loc,     LOC::Entry
  51          ASSERT.kind_of msg,     ::String
  52 
  53          Event.new(label.freeze, klass, loc, msg.freeze).freeze
  54      end
  55 
  56 
  57      def trace(pref, eval_depth, label, klass, loc, msg)
  58          ASSERT.kind_of pref,        E::Preference
  59          ASSERT.kind_of eval_depth,  ::Integer
  60          ASSERT.kind_of label,       ::String
  61          ASSERT.kind_of klass,       ::Class
  62          ASSERT.kind_of loc,         LOC::Entry
  63          ASSERT.kind_of msg,         ::String
  64          ASSERT.assert block_given?
  65 
  66          if pref.trace_mode?
  67              STDERR.printf "%s[%s] %s: %s\n",
  68                              '| ' * eval_depth,
  69                              label,
  70                              Tracer.class_to_string(klass),
  71                              msg
  72          end
  73 
  74          object = yield Tracer.make_event(label, klass, loc, msg)
  75 
  76          if pref.trace_mode?
  77              STDERR.printf "%s--> %s: %s\n",
  78                              '| ' * eval_depth,
  79                              Tracer.class_to_string(object.class),
  80                              object.to_s
  81          end
  82 
  83          object
  84      end
  85 
  86 
  87      def trace_single(pref, eval_depth, label, klass, loc, msg)
  88          ASSERT.kind_of pref,        E::Preference
  89          ASSERT.kind_of eval_depth,  ::Integer
  90          ASSERT.kind_of label,       ::String
  91          ASSERT.kind_of klass,       ::Class
  92          ASSERT.kind_of loc,         LOC::Entry
  93          ASSERT.kind_of msg,         ::String
  94 
  95          if pref.trace_mode?
  96              STDERR.printf "%s[%s] %s: %s",
  97                              '| ' * eval_depth,
  98                              label,
  99                              Tracer.class_to_string(klass),
 100                              msg
 101          end
 102 
 103          object = yield Tracer.make_event(label, klass, loc, msg)
 104 
 105          if pref.trace_mode?
 106              STDERR.printf " --> %s: %s\n",
 107                                  Tracer.class_to_string(object.class),
 108                                  object.to_s
 109          end
 110 
 111          object
 112      end
 113 
 114 
 115      def class_to_string(klass)
 116          ASSERT.kind_of klass, ::Class
 117 
 118          class_name, *fully_qualified_module_names = klass.to_s.split(/::/)
 119 
 120          s = if fully_qualified_module_names.empty?
 121                  class_name
 122              else
 123                  *module_names, fq_class_name = fully_qualified_module_names
 124 
 125                  format("%s (%s)",
 126                          fq_class_name,
 127                          Tracer.abbreviate(module_names).join('::')
 128                  )
 129              end
 130 
 131          ASSERT.kind_of s, ::String
 132      end
 133 
 134 
 135      ABBREVIATABLE_MODULE_NAMES = [
 136          # Lexical
 137          [['Lexical'],                                           'L'],
 138          [['Lexical', 'Lexer'],                                  'LL'],
 139 
 140          # ConcreteSyntax
 141          [['ConcreteSyntax'],                                    'CS'],
 142          [['ConcreteSyntax', 'Module'],                          'CSM'],
 143          [['ConcreteSyntax', 'Module',   'Declaration'],         'CSMD'],
 144          [['ConcreteSyntax', 'Module',   'Expression'],          'CSME'],
 145          [['ConcreteSyntax', 'Module',   'Pattern'],             'CSMP'],
 146          [['ConcreteSyntax', 'Core'],                            'CSC'],
 147          [['ConcreteSyntax', 'Core', 'Declaration'],             'CSCD'],
 148          [['ConcreteSyntax', 'Core', 'Expression'],              'CSCE'],
 149          [['ConcreteSyntax', 'Core', 'Expression',   'Unary'],   'CSCEU'],
 150          [['ConcreteSyntax', 'Core', 'Expression',   'Unary', 'Atom'],
 151                                                                  'CSCEUA'],
 152          [['ConcreteSyntax', 'Core', 'Expression',   'Binary'],  'CSCEB'],
 153          [['ConcreteSyntax', 'Core', 'Expression',   'Nary'],    'CSCEN'],
 154          [['ConcreteSyntax', 'Core', 'Pattern'],                 'CSCP'],
 155 
 156          # AbstractSyntax
 157          [['AbstractSyntax'],                                    'AS'],
 158          [['AbstractSyntax', 'Core'],                            'ASC'],
 159          [['AbstractSyntax', 'Core', 'Declaration'],             'ASCD'],
 160          [['AbstractSyntax', 'Core', 'Expression'],              'ASCE'],
 161          [['AbstractSyntax', 'Core', 'Expression',   'Unary'],   'ASCEU'],
 162          [['AbstractSyntax', 'Core', 'Expression',   'Unary', 'Atom'],
 163                                                                  'ASCEUA'],
 164          [['AbstractSyntax', 'Core', 'Expression',   'Binary'],  'ASCEB'],
 165          [['AbstractSyntax', 'Core', 'Expression',   'Nary'],    'ASCEN'],
 166 
 167          # Value
 168          [['Value'],                                             'V'],
 169          [['Value',          'Core'],                            'VC'],
 170          [['Value',          'Core', 'Atom'],                    'VCA'],
 171          [['Value',          'Core', 'Atom', 'Number'],          'VCAN'],
 172          [['Value',          'Core', 'Product'],                 'VCP'],
 173          [['Value',          'Core', 'Union'],                   'VCU'],
 174          [['Value',          'Core', 'Morph'],                   'VCM'],
 175 
 176          # Environment
 177          [['Environment'],                                       'E']
 178      ].sort { |(xs, _), (ys, _)| ys.size <=> xs.size }   # For longest-match
 179 
 180      def abbreviate(names)
 181          ASSERT.kind_of names, ::Array
 182 
 183          ABBREVIATABLE_MODULE_NAMES.each { |prefix_names, abbreviated_name|
 184              prefix_length = prefix_names.length
 185 
 186              if names.take(prefix_length) == prefix_names
 187                  break [abbreviated_name] + names.drop(prefix_length)
 188              else
 189                  names
 190              end
 191          }
 192      end
 193 
 194  end # Umu::Environment::Tracer
 195 
 196  end # Umu::Environment
 197 
 198  end # Umu