Module: EndlessRuby
Overview
EndlessRubyはRubyをendを取り除いて書けます。
erファイルをrequire
require 'homuhomu.er' | require 'homuhomu'
erファイルを実行
$ path/to/endlessruby.rb homuhomu.er
erファイルをコンパイル
$ path/to/endlessruby.rb -c src/homuhomu.er -o lib
# => src/homuhomu.er をコンパイルして lib/homuhomu.rb を書き出します。
# -o が省略された場合はカレントディレクトリに書き出します。
Example:
class EndlessRubyWorld
def self.hello!
puts "hello!"
[-2, -1, 0, 1, 2].reject do |x|
x < 0
end.each do |n|
puts n
Defined Under Namespace
Modules: Main
Constant Summary collapse
- VERSION =
EndlessRuby のバージョンです
"0.0.1"
Instance Method Summary collapse
-
#endless_ruby_to_pure_ruby(src) ⇒ Object
(also: #to_pure_ruby, #ER2PR, #ER2RB)
EndlessRubyの構文をピュアなRubyの構文に変換します。.
-
#ereval(src, binding = TOPLEVEL_BINDING, filename = __FILE__, lineno = 1) ⇒ Object
文字列をEndlessRubyの構文として実行します。引数の意味はKernel#evalと同じです.
-
#pure_ruby_to_endless_ruby(src) ⇒ Object
(also: #RB2ER, #PR2ER)
Rubyの構文をEndlessRubyの構文に変換します。.
Instance Method Details
#endless_ruby_to_pure_ruby(src) ⇒ Object Also known as: to_pure_ruby, ER2PR, ER2RB
EndlessRubyの構文をピュアなRubyの構文に変換します。
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/endlessruby.rb', line 107 def endless_ruby_to_pure_ruby src endless = src.split "\n" pure = [] i = 0 while i < endless.length pure << (currently_line = endless[i]) if currently_line =~ /(.*)(?:^|(?:(?!\\).))\#(?!\{).*$/ currently_line = $1 end if blank_line? currently_line i += 1 next end # ブロックを作らない構文なら単に無視する next i += 1 unless BLOCK_KEYWORDS.any? { |k| k[0] =~ unindent(currently_line) } # ブロックに入る keyword = BLOCK_KEYWORDS.each { |k| break k if k[0] =~ unindent(currently_line) } currently_indent_depth = indent_count currently_line base_indent_depth = currently_indent_depth inner_statements = [] # def method1 # statemetns # # document of method2 # def method2 # statements # のような場合にコメントの部分はmethod1内に含まないようにする。 # def method1 # statemetns # # comment # return # のような場合と区別するため。 comment_count = 0 in_here_document = nil while i < endless.length inner_currently_line = endless[i + 1] if inner_currently_line =~ /(.*)(?:^|(?:(?!\\).))\#(?!\{).*$/ if blank_line?($1) && currently_indent_depth >= indent_count(inner_currently_line) comment_count += 1 end inner_currently_line = $1 elsif blank_line? inner_currently_line comment_count += 1 end if blank_line? inner_currently_line inner_statements << endless[i + 1] i += 1 next end just_after_indent_depth = indent_count inner_currently_line # 次の行がendならば意図のあるものなのでendを持ちあ揚げない if inner_currently_line =~ /^\s*end(?!\w).*$/ comment_count = 0 end if base_indent_depth < just_after_indent_depth comment_count = 0 end if in_here_document if (in_here_document[0] == '' && inner_currently_line =~ /^#{in_here_document[1]}\s*$/) || # <<DEFINE case (in_here_document[0] == '-' && inner_currently_line =~ /^\s*#{in_here_document[1]}\s*$/) # <<-DEFINE case in_here_document = nil inner_statements << endless[i + 1] i += 1 next else inner_statements << endless[i + 1] i += 1 next end end if inner_currently_line =~ /^.*?\<\<(\-?)(\w+)(?!\w).*$/ in_here_document = [$1, $2] end if base_indent_depth > indent_count(inner_currently_line) break end if base_indent_depth == indent_count(inner_currently_line) unless keyword[1..-1].any? { |k| k =~ unindent(inner_currently_line) } break end end inner_statements << endless[i + 1] i += 1 end # endをコメントより上の行へ持ち上げる if 0 < comment_count comment_count.times do inner_statements.pop end i -= comment_count end pure += ER2PR(inner_statements.join("\n")).split "\n" # 次の行がendならばendを補完しない(ワンライナーのため) unless @decompile unless endless[i + 1] && endless[i + 1] =~ /^\s*end(?!\w).*$/ pure << "#{' '*currently_indent_depth}end" end else # メソッドチェインは削除しない if endless[i + 1] && endless[i + 1] =~ /^\s*end(?:\s|$)\s*$/ i += 1 end end i += 1 end pure.join "\n" end |
#ereval(src, binding = TOPLEVEL_BINDING, filename = __FILE__, lineno = 1) ⇒ Object
文字列をEndlessRubyの構文として実行します。引数の意味はKernel#evalと同じです
86 87 88 89 90 91 92 |
# File 'lib/endlessruby.rb', line 86 def ereval(src, binding=TOPLEVEL_BINDING, filename=__FILE__, lineno=1) at = caller eval(ER2PR(src), binding, filename, lineno) rescue Exception => e $@ = at raise e end |
#pure_ruby_to_endless_ruby(src) ⇒ Object Also known as: RB2ER, PR2ER
Rubyの構文をEndlessRubyの構文に変換します。
95 96 97 98 99 100 |
# File 'lib/endlessruby.rb', line 95 def pure_ruby_to_endless_ruby src @decompile = true s = ER2RB(src) @decompile = nil s end |