1 #!/usr/bin/ruby 2 # encoding: utf-8 3 4 module ANTLR3 5 module Util 6 7 module_function 8 9 def snake_case( str ) 10 str = str.to_s.gsub( /([A-Z]+)([A-Z][a-z])/,'\1_\2' ) 11 str.gsub!( /([a-z\d])([A-Z])/,'\1_\2' ) 12 str.tr!( "-", "_" ) 13 str.downcase! 14 str 15 end 16 17 def parse_version( version_string ) 18 version_string.split( '.' ).map! do | segment | 19 segment.to_i 20 end.freeze 21 end 22 23 def tidy( here_doc, flow = false ) 24 here_doc.gsub!( /^ *\| ?/, '' ) 25 if flow 26 here_doc.strip! 27 here_doc.gsub!( /\s+/, ' ' ) 28 end 29 return here_doc 30 end 31 32 def silence_warnings 33 verbosity, $VERBOSE = $VERBOSE, nil 34 return yield 35 ensure 36 $VERBOSE = verbosity 37 end 38 39 end 40 41 module ClassMacros 42 43 private 44 45 def shared_attribute( name, *additional_members ) 46 attr_reader name 47 48 additional_writers = additional_members.inject( '' ) do |src, attr| 49 src << "@#{ attr } = value if @#{ attr }\n" 50 end 51 52 file, line, = caller[ 1 ].split( ':', 3 ) 53 class_eval( <<-END, file, line.to_i ) 54 def #{ name }= value 55 @#{ name } = value 56 57 each_delegate do |del| 58 del.#{ name } = value 59 end 60 61 #{ additional_writers } 62 end 63 END 64 end 65 66 def abstract( name, message = nil ) 67 message ||= "abstract method -- #{ self.class }::#{ name } has not been implemented" 68 file, line, = caller[ 1 ].split( ':', 3 ) 69 class_eval( <<-END, file, line.to_i ) 70 def #{ name }( * ) 71 raise TypeError, #{ message.to_s.inspect } 72 end 73 END 74 end 75 76 def deprecate( name, extra_message = nil ) 77 hidden_name = "deprecated_#{ name }" 78 method_defined?( hidden_name ) and return 79 80 alias_method( hidden_name, name ) 81 private( hidden_name ) 82 83 message = "warning: method #{ self }##{ name } is deprecated" 84 extra_message and message << '; ' << extra_message.to_s 85 86 class_eval( <<-END ) 87 def #{ name }( *args, &block ) 88 warn( #{ message.inspect } ) 89 #{ hidden_name }( *args, &block ) 90 end 91 END 92 end 93 94 def alias_accessor( alias_name, attr_name ) 95 alias_method( alias_name, attr_name ) 96 alias_method( :"#{ alias_name }=", :"#{ attr_name }=" ) 97 end 98 99 end 100 101 end 102 103 class Integer 104 105 # Returns the lower of self or x. 106 # 107 # 4.at_least(5) #=> 5 108 # 6.at_least(5) #=> 6 109 # 110 # CREDIT Florian Gross 111 112 def at_least( x ) 113 ( self >= x ) ? self : x 114 end 115 116 # Returns the greater of self or x. 117 # 118 # 4.at_most(5) #=> 4 119 # 6.at_most(5) #=> 5 120 # 121 # CREDIT Florian Gross 122 123 def at_most( x ) 124 ( self <= x ) ? self : x 125 end 126 127 # Returns self if above the given lower bound, or 128 # within the given lower and upper bounds, 129 # otherwise returns the the bound of which the 130 # value falls outside. 131 # 132 # 4.bound(3) #=> 4 133 # 4.bound(5) #=> 5 134 # 4.bound(2,7) #=> 4 135 # 9.bound(2,7) #=> 7 136 # 1.bound(2,7) #=> 2 137 # 138 # CREDIT Trans 139 140 def bound( lower, upper=nil ) 141 return lower if self < lower 142 return self unless upper 143 return upper if self > upper 144 return self 145 end 146 147 end 148 149 150 class Range 151 def covers?( range ) 152 range.first >= first or return false 153 if exclude_end? 154 range.exclude_end? ? last >= range.last : last > range.last 155 else 156 range.exclude_end? ? last.succ >= range.last : last >= range.last 157 end 158 end 159 160 def covered_by?( range ) 161 range.covers?( self ) 162 end 163 164 def overlaps?( range ) 165 range.include?( first ) or include?( range.first ) 166 end 167 168 def disjoint?( range ) 169 not overlaps?( range ) 170 end 171 172 end 173