├── spec ├── spec.opts ├── test_data │ ├── exist_same_name_directory │ │ └── dummy │ ├── file.er │ ├── er_omission.er │ ├── rb_omission.rb │ ├── ruby_script.rb │ └── exist_same_name_directory.er ├── endlessruby_spec.rb ├── block_expr_spec.rb ├── blank_line_spec.rb ├── use_end_case_spec.rb ├── semicolon_spec.rb ├── concrete_examples │ ├── case_1_simply_test_case.er │ └── case_1_simply_test_case.rb ├── here_document_spec.rb ├── spec_helper.rb ├── require_spec.rb ├── comment_spec.rb ├── concrete_examples_spec.rb ├── build_self_spec.rb └── simply_spec.rb ├── pkg ├── endlessruby-0.0.1 │ ├── .gemtest │ ├── spec │ │ ├── spec.opts │ │ ├── test_data │ │ │ ├── file.er │ │ │ ├── er_omission.er │ │ │ ├── rb_omission.rb │ │ │ └── ruby_script.rb │ │ ├── endlessruby_spec.rb │ │ ├── blank_line_spec.rb │ │ ├── semicolon_spec.rb │ │ ├── concrete_examples │ │ │ ├── case_1_simply_test_case.er │ │ │ └── case_1_simply_test_case.rb │ │ ├── require_spec.rb │ │ ├── here_document_spec.rb │ │ ├── spec_helper.rb │ │ ├── comment_spec.rb │ │ ├── concrete_examples_spec.rb │ │ ├── build_self_spec.rb │ │ └── simply_spec.rb │ ├── History.txt │ ├── bin │ │ └── endlessruby │ ├── src │ │ ├── er.er │ │ ├── endlessruby │ │ │ ├── extensions.er │ │ │ └── main.er │ │ └── endlessruby.er │ ├── test │ │ ├── test_helpers.rb │ │ ├── test_require.rb │ │ ├── test_use_end_case.rb │ │ └── test_simply.rb │ ├── tasks │ │ └── rspec.rake │ ├── Rakefile │ ├── Manifest.txt │ ├── README.rdoc │ └── lib │ │ ├── endlessruby │ │ ├── extensions.rb │ │ └── main.rb │ │ └── endlessruby.rb ├── endlessruby-0.1.0 │ ├── .gemtest │ ├── spec │ │ ├── spec.opts │ │ ├── test_data │ │ │ ├── file.er │ │ │ ├── er_omission.er │ │ │ ├── rb_omission.rb │ │ │ └── ruby_script.rb │ │ ├── endlessruby_spec.rb │ │ ├── blank_line_spec.rb │ │ ├── use_end_case_spec.rb │ │ ├── semicolon_spec.rb │ │ ├── concrete_examples │ │ │ ├── case_1_simply_test_case.er │ │ │ └── case_1_simply_test_case.rb │ │ ├── here_document_spec.rb │ │ ├── spec_helper.rb │ │ ├── require_spec.rb │ │ ├── comment_spec.rb │ │ ├── concrete_examples_spec.rb │ │ ├── build_self_spec.rb │ │ └── simply_spec.rb │ ├── History.txt │ ├── src │ │ ├── er.er │ │ ├── endlessruby │ │ │ ├── custom_require.er │ │ │ └── main.er │ │ └── endlessruby.er │ ├── bin │ │ └── endlessruby │ ├── test │ │ ├── test_helpers.rb │ │ ├── test_require.rb │ │ ├── test_use_end_case.rb │ │ └── test_simply.rb │ ├── tasks │ │ └── rspec.rake │ ├── Rakefile │ ├── Manifest.txt │ ├── README.rdoc │ └── lib │ │ ├── endlessruby │ │ ├── custom_require.rb │ │ └── main.rb │ │ └── endlessruby.rb ├── endlessruby-0.0.1.gem └── endlessruby-0.1.0.gem ├── test ├── bar.er ├── foo.er ├── homu.er ├── test_helpers.rb ├── test.rb ├── test_require.rb ├── test_use_end_case.rb └── test_simply.rb ├── History.txt ├── src ├── er.er ├── endlessruby │ ├── custom_require.er │ └── main.er └── endlessruby.er ├── bin └── endlessruby ├── examples ├── method_chain.er ├── __file__.er ├── hello.er └── decompile │ ├── extensions.er │ ├── main.er │ └── endlessruby.er ├── doc ├── created.rid ├── lib │ ├── EndlessRuby │ │ ├── main_rb.html │ │ └── custom_require_rb.html │ └── endlessruby_rb.html ├── index.html └── Kernel.html ├── tasks └── rspec.rake ├── Rakefile ├── Manifest.txt ├── README.rdoc ├── lib ├── endlessruby │ ├── custom_require.rb │ └── main.rb └── endlessruby.rb └── README.md /spec/spec.opts: -------------------------------------------------------------------------------- 1 | --colour -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/.gemtest: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/.gemtest: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/spec/spec.opts: -------------------------------------------------------------------------------- 1 | --colour -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/spec/spec.opts: -------------------------------------------------------------------------------- 1 | --colour -------------------------------------------------------------------------------- /spec/test_data/exist_same_name_directory/dummy: -------------------------------------------------------------------------------- 1 | dummy 2 | -------------------------------------------------------------------------------- /test/bar.er: -------------------------------------------------------------------------------- 1 | class Bar 2 | def self.hello 3 | "hello" -------------------------------------------------------------------------------- /test/foo.er: -------------------------------------------------------------------------------- 1 | class Foo 2 | def self.hello 3 | "hello" -------------------------------------------------------------------------------- /test/homu.er: -------------------------------------------------------------------------------- 1 | class Homu 2 | def self.hello 3 | "hello" 4 | -------------------------------------------------------------------------------- /History.txt: -------------------------------------------------------------------------------- 1 | === 0.0.1 2011-11-17 2 | 3 | * Alpha: 4 | * initial release 5 | * 0.1.0 release 6 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/History.txt: -------------------------------------------------------------------------------- 1 | === 0.0.1 2011-11-17 2 | 3 | * Alpha: 4 | * initial release 5 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pasberth/EndlessRuby/HEAD/pkg/endlessruby-0.0.1.gem -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0.gem: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pasberth/EndlessRuby/HEAD/pkg/endlessruby-0.1.0.gem -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/History.txt: -------------------------------------------------------------------------------- 1 | === 0.0.1 2011-11-17 2 | 3 | * Alpha: 4 | * initial release 5 | * 0.1.0 release 6 | -------------------------------------------------------------------------------- /spec/test_data/file.er: -------------------------------------------------------------------------------- 1 | $test_data = "file" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "file" 7 | -------------------------------------------------------------------------------- /src/er.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "endlessruby" 4 | require "endlessruby/main" 5 | EndlessRuby::Main.main ARGV 6 | -------------------------------------------------------------------------------- /bin/endlessruby: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "endlessruby" 4 | require "endlessruby/main" 5 | EndlessRuby::Main.main ARGV 6 | -------------------------------------------------------------------------------- /examples/method_chain.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | [-2, -1, 0, 1, 2].reject do |x| 4 | x < 0 5 | end.each do |n| 6 | puts n 7 | -------------------------------------------------------------------------------- /examples/__file__.er: -------------------------------------------------------------------------------- 1 | puts __FILE__ 2 | puts $PROGRAM_NAME 3 | p ARGV 4 | 5 | if __FILE__ == $PROGRAM_NAME 6 | puts 'insert test case to here' 7 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/spec/test_data/file.er: -------------------------------------------------------------------------------- 1 | $test_data = "file" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "file" 7 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/spec/test_data/file.er: -------------------------------------------------------------------------------- 1 | $test_data = "file" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "file" 7 | -------------------------------------------------------------------------------- /spec/test_data/er_omission.er: -------------------------------------------------------------------------------- 1 | $test_data = "er omission" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "er omission" 7 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/bin/endlessruby: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "endlessruby" 4 | require "endlessruby/main" 5 | EndlessRuby::Main.main ARGV -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/src/er.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "endlessruby" 4 | require "endlessruby/main" 5 | EndlessRuby::Main.main ARGV 6 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/src/er.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "endlessruby" 4 | require "endlessruby/main" 5 | EndlessRuby::Main.main ARGV 6 | -------------------------------------------------------------------------------- /examples/hello.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env endlessruby.rb 2 | class EndlessRubyWorld 3 | 4 | def self.hello! 5 | puts "hello!" 6 | 7 | EndlessRubyWorld.hello! -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/bin/endlessruby: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "endlessruby" 4 | require "endlessruby/main" 5 | EndlessRuby::Main.main ARGV 6 | -------------------------------------------------------------------------------- /spec/test_data/rb_omission.rb: -------------------------------------------------------------------------------- 1 | $test_data = "rb omission" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "rb omission" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/test_data/ruby_script.rb: -------------------------------------------------------------------------------- 1 | $test_data = "ruby script" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "ruby script" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/spec/test_data/er_omission.er: -------------------------------------------------------------------------------- 1 | $test_data = "er omission" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "er omission" 7 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/spec/test_data/er_omission.er: -------------------------------------------------------------------------------- 1 | $test_data = "er omission" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "er omission" 7 | -------------------------------------------------------------------------------- /spec/test_data/exist_same_name_directory.er: -------------------------------------------------------------------------------- 1 | $test_data = "exist same name directory" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "exist same name directory" -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/spec/test_data/rb_omission.rb: -------------------------------------------------------------------------------- 1 | $test_data = "rb omission" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "rb omission" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/spec/test_data/ruby_script.rb: -------------------------------------------------------------------------------- 1 | $test_data = "ruby script" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "ruby script" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/spec/test_data/rb_omission.rb: -------------------------------------------------------------------------------- 1 | $test_data = "rb omission" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "rb omission" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/spec/test_data/ruby_script.rb: -------------------------------------------------------------------------------- 1 | $test_data = "ruby script" 2 | 3 | module TestData 4 | extend self 5 | def test_data 6 | "ruby script" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /doc/created.rid: -------------------------------------------------------------------------------- 1 | Wed, 23 Nov 2011 19:29:24 +0900 2 | lib/endlessruby/custom_require.rb Wed, 23 Nov 2011 19:29:01 +0900 3 | lib/endlessruby/main.rb Wed, 23 Nov 2011 19:29:01 +0900 4 | lib/endlessruby.rb Wed, 23 Nov 2011 19:29:01 +0900 5 | -------------------------------------------------------------------------------- /test/test_helpers.rb: -------------------------------------------------------------------------------- 1 | class TestEndlessRuby 2 | 3 | def test_blank_line 4 | assert_equal true, (blank_line? " ") 5 | end 6 | 7 | def test_not_blank_line 8 | assert_equal false, (blank_line? " pass") 9 | end 10 | 11 | 12 | end 13 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/test/test_helpers.rb: -------------------------------------------------------------------------------- 1 | class TestEndlessRuby 2 | 3 | def test_blank_line 4 | assert_equal true, (blank_line? " ") 5 | end 6 | 7 | def test_not_blank_line 8 | assert_equal false, (blank_line? " pass") 9 | end 10 | 11 | 12 | end 13 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/test/test_helpers.rb: -------------------------------------------------------------------------------- 1 | class TestEndlessRuby 2 | 3 | def test_blank_line 4 | assert_equal true, (blank_line? " ") 5 | end 6 | 7 | def test_not_blank_line 8 | assert_equal false, (blank_line? " pass") 9 | end 10 | 11 | 12 | end 13 | -------------------------------------------------------------------------------- /tasks/rspec.rake: -------------------------------------------------------------------------------- 1 | begin 2 | require 'rspec' 3 | rescue LoadError 4 | require 'rubygems' unless ENV['NO_RUBYGEMS'] 5 | require 'rspec' 6 | end 7 | 8 | RSpec::Core::RakeTask.new do |t| 9 | t.rspec_opts = ['--options', "spec/spec.opts"] 10 | t.pattern = 'spec/*_spec.rb' 11 | end 12 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/tasks/rspec.rake: -------------------------------------------------------------------------------- 1 | begin 2 | require 'rspec' 3 | rescue LoadError 4 | require 'rubygems' unless ENV['NO_RUBYGEMS'] 5 | require 'rspec' 6 | end 7 | 8 | RSpec::Core::RakeTask.new do |t| 9 | t.rspec_opts = ['--options', "spec/spec.opts"] 10 | t.pattern = 'spec/*_spec.rb' 11 | end 12 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/tasks/rspec.rake: -------------------------------------------------------------------------------- 1 | begin 2 | require 'rspec' 3 | rescue LoadError 4 | require 'rubygems' unless ENV['NO_RUBYGEMS'] 5 | require 'rspec' 6 | end 7 | 8 | RSpec::Core::RakeTask.new do |t| 9 | t.rspec_opts = ['--options', "spec/spec.opts"] 10 | t.pattern = 'spec/*_spec.rb' 11 | end 12 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | gem 'hoe', '>= 2.1.0' 3 | require 'hoe' 4 | require 'fileutils' 5 | require './lib/EndlessRuby' 6 | 7 | $hoe = Hoe.spec 'endlessruby' do 8 | self.developer 'pasberth', 'pasberth@gmail.com' 9 | self.rubyforge_name = self.name 10 | self.readme_file = 'README.rdoc' 11 | end 12 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/spec/endlessruby_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/spec_helper.rb' 2 | 3 | require "simply_spec" 4 | require "comment_spec" 5 | require "blank_line_spec" 6 | require "here_document_spec" 7 | require "require_spec" 8 | require "build_self_spec" 9 | require "concrete_examples_spec" 10 | require "semicolon_spec" 11 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | gem 'hoe', '>= 2.1.0' 3 | require 'hoe' 4 | require 'fileutils' 5 | require './lib/EndlessRuby' 6 | 7 | $hoe = Hoe.spec 'endlessruby' do 8 | self.developer 'pasberth', 'pasberth@gmail.com' 9 | self.rubyforge_name = self.name 10 | self.readme_file = 'README.rdoc' 11 | end 12 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | gem 'hoe', '>= 2.1.0' 3 | require 'hoe' 4 | require 'fileutils' 5 | require './lib/EndlessRuby' 6 | 7 | $hoe = Hoe.spec 'endlessruby' do 8 | self.developer 'pasberth', 'pasberth@gmail.com' 9 | self.rubyforge_name = self.name 10 | self.readme_file = 'README.rdoc' 11 | end 12 | -------------------------------------------------------------------------------- /spec/endlessruby_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/spec_helper.rb' 2 | 3 | require "simply_spec" 4 | require "comment_spec" 5 | require "blank_line_spec" 6 | require "here_document_spec" 7 | require "require_spec" 8 | require "build_self_spec" 9 | require "concrete_examples_spec" 10 | require "semicolon_spec" 11 | require "block_expr_spec" 12 | require "use_end_case_spec" 13 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/spec/endlessruby_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/spec_helper.rb' 2 | 3 | require "simply_spec" 4 | require "comment_spec" 5 | require "blank_line_spec" 6 | require "here_document_spec" 7 | require "require_spec" 8 | require "build_self_spec" 9 | require "concrete_examples_spec" 10 | require "semicolon_spec" 11 | require "block_expr_spec" 12 | require "use_end_case_spec" 13 | -------------------------------------------------------------------------------- /spec/block_expr_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/spec_helper.rb' 2 | 3 | describe "block exprs" do 4 | 5 | it "'case' expr" do 6 | ER2RB(< lib/example.rb 21 | src/more.er => lib/more.rb 22 | として書き出されます。 23 | 24 | 実行する場合は 25 | $ endlessruby src/example.er 26 | 27 | コンパイルされていないEndlessRubyのファイルをrequire する場合は 28 | 29 | require 'endlessruby' 30 | require 'example.er' 31 | 32 | たぶんバグだらけです 33 | 34 | == FEATURES/PROBLEMS: 35 | 36 | * def method; a; end みたいな書式に対応 37 | 38 | == SYNOPSIS: 39 | 40 | = REQUIREMENTs 41 | 42 | * ruby 1.8.7, 1.9.1, or 1.9.2 ... 43 | * rubygems 44 | 45 | == INSTALL: 46 | 47 | * sudo gem install endlessruby 48 | 49 | == LICENSE: 50 | 51 | (The MIT License) 52 | 53 | Copyright (c) 2011 pasberth 54 | -------------------------------------------------------------------------------- /spec/require_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/spec_helper.rb' 2 | 3 | describe "require" do 4 | 5 | it "require the file" do 6 | require 'test_data/file.er' 7 | $test_data.should == "file" 8 | TestData.test_data.should == "file" 9 | end 10 | 11 | it "require the 'er' omission file" do 12 | require 'test_data/er_omission' 13 | $test_data.should == "er omission" 14 | TestData.test_data.should == "er omission" 15 | end 16 | 17 | it "require the ruby script 'rb' omission" do 18 | require 'test_data/rb_omission' 19 | $test_data.should == "rb omission" 20 | TestData.test_data.should == "rb omission" 21 | end 22 | 23 | it "require the ruby script" do 24 | require 'test_data/ruby_script.rb' 25 | $test_data.should == "ruby script" 26 | TestData.test_data.should == "ruby script" 27 | end 28 | 29 | it "require ellipsis of 'er' and exist same name directory" do 30 | 31 | require 'test_data/exist_same_name_directory' 32 | 33 | $test_data.should == "exist same name directory" 34 | TestData.test_data.should == "exist same name directory" 35 | end 36 | 37 | end 38 | -------------------------------------------------------------------------------- /spec/comment_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/spec_helper.rb' 2 | 3 | describe "comment out case" do 4 | 5 | it "comment" do 6 | ER2RB(< 2 | 4 | 5 | 6 | 7 | 8 | 9 | File: main.rb [RDoc Documentation] 10 | 11 | 12 | 13 | 15 | 17 | 19 | 21 | 22 | 23 | 24 |
25 |
26 |
Last Modified
27 |
2011-11-23 19:29:01 +0900
28 | 29 | 30 |
Requires
31 |
32 |
    33 | 34 |
  • optparse
  • 35 | 36 |
37 |
38 | 39 | 40 | 41 |
42 |
43 | 44 |
45 | 46 |
47 |

Description

48 | 49 |
50 | 51 |
52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /doc/lib/EndlessRuby/custom_require_rb.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | File: custom_require.rb [RDoc Documentation] 10 | 11 | 12 | 13 | 15 | 17 | 19 | 21 | 22 | 23 | 24 |
25 |
26 |
Last Modified
27 |
2011-11-23 19:29:01 +0900
28 | 29 | 30 |
Requires
31 |
32 |
    33 | 34 |
  • rubygems
  • 35 | 36 |
37 |
38 | 39 | 40 | 41 |
42 |
43 | 44 |
45 | 46 |
47 |

Description

48 | 49 |
50 | 51 |
52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /doc/lib/endlessruby_rb.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | File: endlessruby.rb [RDoc Documentation] 10 | 11 | 12 | 13 | 15 | 17 | 19 | 21 | 22 | 23 | 24 |
25 |
26 |
Last Modified
27 |
2011-11-23 19:29:01 +0900
28 | 29 | 30 |
Requires
31 |
32 |
    33 | 34 |
  • endlessruby/custom_require
  • 35 | 36 |
  • tempfile
  • 37 | 38 |
  • irb
  • 39 | 40 |
  • endlessruby/main
  • 41 | 42 |
43 |
44 | 45 | 46 | 47 |
48 |
49 | 50 |
51 | 52 |
53 |

Description

54 | 55 |
56 | 57 |
58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = EndlessRuby 2 | 3 | * http://github.com/pasberth/EndlessRuby 4 | 5 | == UPDATE: 6 | EndlessRuby 0.0.1 からのアップデート 7 | * 正規表現ベースからirbに付属しているRubyLexベースに(かなり安定したと思います) 8 | * def method; a; end みたいな書式に対応 9 | * テストしてないけどRubyLexベースなのでたぶんけっこうな数の構文に対応している気がする 10 | 11 | == DESCRIPTION: 12 | 13 | EndlessRuby は Ruby を end なしで代わりにインデントで書けるプリプロセッサまたはコンパイラです。 14 | * EndlessRuby で書かれたソースコードを Ruby プログラムから require 15 | * EndlessRuby で書かれたソースコードを ピュア Ruby にコンパイル 16 | ができます。 17 | 18 | 基本的にRubyの構文からendを取り除いただけで書けます。endを取り除かなくても実行可能です。 19 | EndlessRubyの独自な拡張的な構文はありません。 20 | ただ行単位で処理しているので def method; a; end みたいな書式できません。 21 | # 0.1.0 からできるようになりました 22 | 23 | endを取り除かなくても実行可能なので 24 | 25 | コンパイルする場合は 26 | $ endlessruby -c src/example.er src/more.er -o lib 27 | とします。 28 | この場合、 29 | src/example.er => lib/example.rb 30 | src/more.er => lib/more.rb 31 | として書き出されます。 32 | 33 | デコンパイル 34 | $ endlessruby -d lib/example.rb lib/more.rb -o src 35 | すべてのendを取り除きます 36 | 37 | 実行する場合は 38 | $ endlessruby src/example.er 39 | 40 | コンパイルされていないEndlessRubyのファイルをrequire する場合は 41 | 42 | require 'endlessruby' 43 | require 'example.er' 44 | 45 | = BE CAREFUL 46 | 47 | インデントを合わせる箇所に注意してください。インデントは行頭ではなくてキーワードに合わせてください。 48 | 49 | たとえばcaseの場合は 50 | 51 | YES: 52 | res = case x 53 | when A then a 54 | when B then b 55 | 56 | NO: 57 | res = case x 58 | when A then a 59 | when B then b 60 | 61 | 複数行のブロックを渡す場合は {} ではなくて do end を使ってください。 {} の場合は閉じカッコを省略できません。 62 | 63 | = REQUIREMENTs 64 | 65 | * ruby 1.8.7, 1.9.1, or 1.9.2 ... 66 | * rubygems 67 | 68 | == INSTALL: 69 | 70 | * sudo gem install endlessruby 71 | 72 | == LICENSE: 73 | 74 | (The MIT License) 75 | 76 | Copyright (c) 2011 pasberth 77 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/README.rdoc: -------------------------------------------------------------------------------- 1 | = EndlessRuby 2 | 3 | * http://github.com/pasberth/EndlessRuby 4 | 5 | == UPDATE: 6 | EndlessRuby 0.0.1 からのアップデート 7 | * 正規表現ベースからirbに付属しているRubyLexベースに(かなり安定したと思います) 8 | * def method; a; end みたいな書式に対応 9 | * テストしてないけどRubyLexベースなのでたぶんけっこうな数の構文に対応している気がする 10 | 11 | == DESCRIPTION: 12 | 13 | EndlessRuby は Ruby を end なしで代わりにインデントで書けるプリプロセッサまたはコンパイラです。 14 | * EndlessRuby で書かれたソースコードを Ruby プログラムから require 15 | * EndlessRuby で書かれたソースコードを ピュア Ruby にコンパイル 16 | ができます。 17 | 18 | 基本的にRubyの構文からendを取り除いただけで書けます。endを取り除かなくても実行可能です。 19 | EndlessRubyの独自な拡張的な構文はありません。 20 | ただ行単位で処理しているので def method; a; end みたいな書式できません。 21 | # 0.1.0 からできるようになりました 22 | 23 | endを取り除かなくても実行可能なので 24 | 25 | コンパイルする場合は 26 | $ endlessruby -c src/example.er src/more.er -o lib 27 | とします。 28 | この場合、 29 | src/example.er => lib/example.rb 30 | src/more.er => lib/more.rb 31 | として書き出されます。 32 | 33 | デコンパイル 34 | $ endlessruby -d lib/example.rb lib/more.rb -o src 35 | すべてのendを取り除きます 36 | 37 | 実行する場合は 38 | $ endlessruby src/example.er 39 | 40 | コンパイルされていないEndlessRubyのファイルをrequire する場合は 41 | 42 | require 'endlessruby' 43 | require 'example.er' 44 | 45 | = BE CAREFUL 46 | 47 | インデントを合わせる箇所に注意してください。インデントは行頭ではなくてキーワードに合わせてください。 48 | 49 | たとえばcaseの場合は 50 | 51 | YES: 52 | res = case x 53 | when A then a 54 | when B then b 55 | 56 | NO: 57 | res = case x 58 | when A then a 59 | when B then b 60 | 61 | 複数行のブロックを渡す場合は {} ではなくて do end を使ってください。 {} の場合は閉じカッコを省略できません。 62 | 63 | = REQUIREMENTs 64 | 65 | * ruby 1.8.7, 1.9.1, or 1.9.2 ... 66 | * rubygems 67 | 68 | == INSTALL: 69 | 70 | * sudo gem install endlessruby 71 | 72 | == LICENSE: 73 | 74 | (The MIT License) 75 | 76 | Copyright (c) 2011 pasberth 77 | -------------------------------------------------------------------------------- /src/endlessruby/custom_require.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | require 'rubygems' 5 | 6 | module Kernel 7 | 8 | alias endlessruby_original_require require 9 | 10 | # EndlessRuby によって再定義された require です。 11 | # たいていのこのrequireはオリジナルなrequireまたはrubygemsのrequireがSyntaxErrorによって失敗した場合のみ機能します。 12 | # SytanxError によってrequireが失敗した場合、pathを探してpathまたはpath.erの名前のファイルをEndlessRubyの構文として評価します。 13 | # pathが./または/で以外で始まる場合は$LOAD_PATHと$:をそれぞれ参照してpathを探します。 14 | # もしpathがそれらで始まる場合はそれぞれ参照しません。(つまり通常のrequireの動作と同じです) 15 | def require path 16 | endlessruby_original_require path 17 | rescue SyntaxError, LoadError 18 | 19 | load = lambda do |path, abspath| 20 | 21 | if !File.exist?(abspath) || File.directory?(abspath) 22 | if File.exist? "#{abspath}.er" 23 | abspath = "#{abspath}.er" 24 | else 25 | raise LoadError, "no such file to load -- #{path}" 26 | 27 | return false if $".include? abspath 28 | 29 | if File.directory? abspath 30 | raise LoadError, "Is a directory - #{path}" 31 | 32 | open(abspath) do |file| 33 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, abspath 34 | $" << abspath 35 | return true 36 | 37 | case path 38 | when /^\~(.*?)$/ 39 | load.call path, File.join(ENV['HOME'], $1) 40 | when /^\.\/.*?$/, /^\/.*?$/ 41 | load.call path, path 42 | else 43 | is_that_dir = false 44 | $:.each do |load_path| 45 | abspath = File.join load_path, path 46 | begin 47 | return load.call path, abspath 48 | rescue SyntaxError => e 49 | $stderr.puts "*ENDLESSRUBY BUG*" 50 | raise e 51 | rescue LoadError => e 52 | raise e if load_path == $:.last 53 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/src/endlessruby/custom_require.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | require 'rubygems' 5 | 6 | module Kernel 7 | 8 | alias endlessruby_original_require require 9 | 10 | # EndlessRuby によって再定義された require です。 11 | # たいていのこのrequireはオリジナルなrequireまたはrubygemsのrequireがSyntaxErrorによって失敗した場合のみ機能します。 12 | # SytanxError によってrequireが失敗した場合、pathを探してpathまたはpath.erの名前のファイルをEndlessRubyの構文として評価します。 13 | # pathが./または/で以外で始まる場合は$LOAD_PATHと$:をそれぞれ参照してpathを探します。 14 | # もしpathがそれらで始まる場合はそれぞれ参照しません。(つまり通常のrequireの動作と同じです) 15 | def require path 16 | endlessruby_original_require path 17 | rescue SyntaxError, LoadError 18 | 19 | load = lambda do |path, abspath| 20 | 21 | if !File.exist?(abspath) || File.directory?(abspath) 22 | if File.exist? "#{abspath}.er" 23 | abspath = "#{abspath}.er" 24 | else 25 | raise LoadError, "no such file to load -- #{path}" 26 | 27 | return false if $".include? abspath 28 | 29 | if File.directory? abspath 30 | raise LoadError, "Is a directory - #{path}" 31 | 32 | open(abspath) do |file| 33 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, abspath 34 | $" << abspath 35 | return true 36 | 37 | case path 38 | when /^\~(.*?)$/ 39 | load.call path, File.join(ENV['HOME'], $1) 40 | when /^\.\/.*?$/, /^\/.*?$/ 41 | load.call path, path 42 | else 43 | is_that_dir = false 44 | $:.each do |load_path| 45 | abspath = File.join load_path, path 46 | begin 47 | return load.call path, abspath 48 | rescue SyntaxError => e 49 | $stderr.puts "*ENDLESSRUBY BUG*" 50 | raise e 51 | rescue LoadError => e 52 | raise e if load_path == $:.last 53 | -------------------------------------------------------------------------------- /lib/endlessruby/custom_require.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | require 'rubygems' 5 | 6 | module Kernel 7 | 8 | alias endlessruby_original_require require 9 | 10 | # EndlessRuby によって再定義された require です。 11 | # たいていのこのrequireはオリジナルなrequireまたはrubygemsのrequireがSyntaxErrorによって失敗した場合のみ機能します。 12 | # SytanxError によってrequireが失敗した場合、pathを探してpathまたはpath.erの名前のファイルをEndlessRubyの構文として評価します。 13 | # pathが./または/で以外で始まる場合は$LOAD_PATHと$:をそれぞれ参照してpathを探します。 14 | # もしpathがそれらで始まる場合はそれぞれ参照しません。(つまり通常のrequireの動作と同じです) 15 | def require path 16 | endlessruby_original_require path 17 | rescue SyntaxError, LoadError 18 | 19 | load = lambda do |path, abspath| 20 | 21 | if !File.exist?(abspath) || File.directory?(abspath) 22 | if File.exist? "#{abspath}.er" 23 | abspath = "#{abspath}.er" 24 | else 25 | raise LoadError, "no such file to load -- #{path}" 26 | end 27 | end 28 | 29 | return false if $".include? abspath 30 | 31 | if File.directory? abspath 32 | raise LoadError, "Is a directory - #{path}" 33 | end 34 | 35 | open(abspath) do |file| 36 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, abspath 37 | $" << abspath 38 | return true 39 | end 40 | end 41 | 42 | case path 43 | when /^\~(.*?)$/ 44 | load.call path, File.join(ENV['HOME'], $1) 45 | when /^\.\/.*?$/, /^\/.*?$/ 46 | load.call path, path 47 | else 48 | is_that_dir = false 49 | $:.each do |load_path| 50 | abspath = File.join load_path, path 51 | begin 52 | return load.call path, abspath 53 | rescue SyntaxError => e 54 | $stderr.puts "*ENDLESSRUBY BUG*" 55 | raise e 56 | rescue LoadError => e 57 | raise e if load_path == $:.last 58 | end 59 | end 60 | end 61 | end 62 | end -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/lib/endlessruby/custom_require.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | require 'rubygems' 5 | 6 | module Kernel 7 | 8 | alias endlessruby_original_require require 9 | 10 | # EndlessRuby によって再定義された require です。 11 | # たいていのこのrequireはオリジナルなrequireまたはrubygemsのrequireがSyntaxErrorによって失敗した場合のみ機能します。 12 | # SytanxError によってrequireが失敗した場合、pathを探してpathまたはpath.erの名前のファイルをEndlessRubyの構文として評価します。 13 | # pathが./または/で以外で始まる場合は$LOAD_PATHと$:をそれぞれ参照してpathを探します。 14 | # もしpathがそれらで始まる場合はそれぞれ参照しません。(つまり通常のrequireの動作と同じです) 15 | def require path 16 | endlessruby_original_require path 17 | rescue SyntaxError, LoadError 18 | 19 | load = lambda do |path, abspath| 20 | 21 | if !File.exist?(abspath) || File.directory?(abspath) 22 | if File.exist? "#{abspath}.er" 23 | abspath = "#{abspath}.er" 24 | else 25 | raise LoadError, "no such file to load -- #{path}" 26 | end 27 | end 28 | 29 | return false if $".include? abspath 30 | 31 | if File.directory? abspath 32 | raise LoadError, "Is a directory - #{path}" 33 | end 34 | 35 | open(abspath) do |file| 36 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, abspath 37 | $" << abspath 38 | return true 39 | end 40 | end 41 | 42 | case path 43 | when /^\~(.*?)$/ 44 | load.call path, File.join(ENV['HOME'], $1) 45 | when /^\.\/.*?$/, /^\/.*?$/ 46 | load.call path, path 47 | else 48 | is_that_dir = false 49 | $:.each do |load_path| 50 | abspath = File.join load_path, path 51 | begin 52 | return load.call path, abspath 53 | rescue SyntaxError => e 54 | $stderr.puts "*ENDLESSRUBY BUG*" 55 | raise e 56 | rescue LoadError => e 57 | raise e if load_path == $:.last 58 | end 59 | end 60 | end 61 | end 62 | end -------------------------------------------------------------------------------- /examples/decompile/extensions.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | require 'rubygems' 5 | 6 | module Kernel 7 | 8 | alias endlessruby_original_require require 9 | 10 | # EndlessRuby によって再定義された require です。 11 | # たいていのこのrequireはオリジナルなrequireまたはrubygemsのrequireがSyntaxErrorによって失敗した場合のみ機能します。 12 | # SytanxError によってrequireが失敗した場合、pathを探してpathまたはpath.erの名前のファイルをEndlessRubyの構文として評価します。 13 | # pathが./または/で以外で始まる場合は$LOAD_PATHと$:をそれぞれ参照してpathを探します。 14 | # もしpathがそれらで始まる場合はそれぞれ参照しません。(つまり通常のrequireの動作と同じです) 15 | def require path 16 | at = caller 17 | endlessruby_original_require path 18 | rescue SyntaxError, LoadError 19 | case path 20 | when /^\.\/.*?$/, /^\/.*?$/ 21 | unless File.exist? path 22 | if File.exist? "#{path}.er" 23 | path = "#{path}.er" 24 | else 25 | $@ = at 26 | raise LoadError, "no such file to load -- #{path}" 27 | 28 | if File.directory? path 29 | $@ = at 30 | raise LoadError, "Is a directory - #{path}" 31 | 32 | open(path) do |file| 33 | begin 34 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, path 35 | rescue Exception => e 36 | $@ = at 37 | raise e 38 | return true 39 | else 40 | is_that_dir = false 41 | ($LOAD_PATH | $:).each do |load_path| 42 | real_path = File.join load_path, path 43 | unless File.exist? real_path 44 | if File.exist? "#{real_path}.er" 45 | real_path = "#{real_path}.er" 46 | else 47 | next 48 | 49 | next is_that_dir = true if File.directory? real_path 50 | open(real_path) do |file| 51 | begin 52 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, real_path 53 | rescue Exception => e 54 | $@ = at 55 | raise e 56 | return true 57 | $@ = at 58 | if is_that_dir 59 | raise LoadError, "Is a directory - #{path}" 60 | else 61 | raise LoadError, "no such file to load -- #{path}" -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/src/endlessruby/extensions.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | require 'rubygems' 5 | 6 | module Kernel 7 | 8 | alias endlessruby_original_require require 9 | 10 | # EndlessRuby によって再定義された require です。 11 | # たいていのこのrequireはオリジナルなrequireまたはrubygemsのrequireがSyntaxErrorによって失敗した場合のみ機能します。 12 | # SytanxError によってrequireが失敗した場合、pathを探してpathまたはpath.erの名前のファイルをEndlessRubyの構文として評価します。 13 | # pathが./または/で以外で始まる場合は$LOAD_PATHと$:をそれぞれ参照してpathを探します。 14 | # もしpathがそれらで始まる場合はそれぞれ参照しません。(つまり通常のrequireの動作と同じです) 15 | def require path 16 | at = caller 17 | endlessruby_original_require path 18 | rescue SyntaxError, LoadError 19 | case path 20 | when /^\.\/.*?$/, /^\/.*?$/ 21 | unless File.exist? path 22 | if File.exist? "#{path}.er" 23 | path = "#{path}.er" 24 | else 25 | $@ = at 26 | raise LoadError, "no such file to load -- #{path}" 27 | 28 | if File.directory? path 29 | $@ = at 30 | raise LoadError, "Is a directory - #{path}" 31 | 32 | open(path) do |file| 33 | begin 34 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, path 35 | rescue Exception => e 36 | $@ = at 37 | raise e 38 | return true 39 | else 40 | is_that_dir = false 41 | ($LOAD_PATH | $:).each do |load_path| 42 | real_path = File.join load_path, path 43 | unless File.exist? real_path 44 | if File.exist? "#{real_path}.er" 45 | real_path = "#{real_path}.er" 46 | else 47 | next 48 | 49 | next is_that_dir = true if File.directory? real_path 50 | open(real_path) do |file| 51 | begin 52 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, real_path 53 | rescue Exception => e 54 | $@ = at 55 | raise e 56 | return true 57 | $@ = at 58 | if is_that_dir 59 | raise LoadError, "Is a directory - #{path}" 60 | else 61 | raise LoadError, "no such file to load -- #{path}" 62 | 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #EndlessRuby 2 | 3 | If you use EndlessRuby, you can write source code without the use of 'end'. 4 | You can just write (correctly indented) ruby minus the 'end's because EndlessRuby adds them in for you. 5 | 6 | ```ruby 7 | class EndlessRubyWorld 8 | def self.hello! 9 | puts "hello!" 10 | ``` 11 | 12 | Be careful when using blocks. Use "each do" rather than "each {}". 13 | You can not do ellipsis of '}' if you use "each {}" 14 | 15 | Syntax of EndlessRuby's "each {}" case: 16 | 17 | ```ruby 18 | each { 19 | statements 20 | } 21 | ``` 22 | 23 | syntax of EndlessRuby's "each do" case: 24 | 25 | ```ruby 26 | each do 27 | statements 28 | ``` 29 | ##execute endless ruby source code: 30 | $ lib/endlessruby.rb example.er 31 | 32 | ##require endless ruby source code: 33 | 34 | ```ruby 35 | require "path/to/endlessruby" 36 | require "example.er" 37 | ``` 38 | 39 | ##compile endless ruby source code to pure ruby. 40 | $ lib/endlessruby.rb -c example.er 41 | $ lib/endlessruby.rb -c src/example.er -o lib 42 | -c option is compile and output to current directory from each arguments. arguments is filenames. 43 | -o option appoint output directory. 44 | 45 | #EndlessRuby Japanese README 46 | 47 | EndlessRuby は Ruby のコードを end を使わずにインデントで表現できます 48 | 49 | 単に省略された end を補完することしかしないので、 end とインデント以外はピュアなRubyと同じように書けます。 50 | endを省略しないこともできます。 51 | 52 | ```ruby 53 | class EndlessRubyWorld 54 | def self.hello! 55 | puts "hello!" 56 | ``` 57 | ただ、複数行にまたがるブロックを渡す場合は 58 | 59 | ```ruby 60 | each { 61 | statements 62 | } 63 | ``` 64 | ではなく 65 | 66 | ```ruby 67 | each do 68 | statements 69 | ``` 70 | 71 | を使ってください。もし each {} で渡すのなら、閉じカッコは省略できません 72 | 73 | ##メソッドチェイン 74 | ```ruby 75 | reject do |ary| 76 | ary.empty? 77 | end.each do |ary| 78 | # statements 79 | ``` 80 | 81 | ##endlessruby で書かれたソースを実行: 82 | $ lib/endlessruby.rb example.er 83 | 84 | ##endlessruby で書かれたソースをrequire 85 | ```ruby 86 | require "path/to/endlessruby" 87 | require "example.er" 88 | ``` 89 | 90 | ##明示的にコンパイルしてピュアなRubyのソースに 91 | $ lib/endlessruby.rb -c example.er 92 | $ lib/endlessruby.rb -c src/example.er -o lib 93 | -c オプションはその後渡されたすべての引数を、endlessrubyからpure rubyにコンパイルして、同じ名前.rbファイルをカレントディレクトリ以下の-oオプションのディレクトリに書き出します。もし-oが省略されたら、カレントディレクトリに書き出します。 -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/lib/endlessruby/extensions.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | require 'rubygems' 5 | 6 | module Kernel 7 | 8 | alias endlessruby_original_require require 9 | 10 | # EndlessRuby によって再定義された require です。 11 | # たいていのこのrequireはオリジナルなrequireまたはrubygemsのrequireがSyntaxErrorによって失敗した場合のみ機能します。 12 | # SytanxError によってrequireが失敗した場合、pathを探してpathまたはpath.erの名前のファイルをEndlessRubyの構文として評価します。 13 | # pathが./または/で以外で始まる場合は$LOAD_PATHと$:をそれぞれ参照してpathを探します。 14 | # もしpathがそれらで始まる場合はそれぞれ参照しません。(つまり通常のrequireの動作と同じです) 15 | def require path 16 | at = caller 17 | endlessruby_original_require path 18 | rescue SyntaxError, LoadError 19 | case path 20 | when /^\.\/.*?$/, /^\/.*?$/ 21 | unless File.exist? path 22 | if File.exist? "#{path}.er" 23 | path = "#{path}.er" 24 | else 25 | $@ = at 26 | raise LoadError, "no such file to load -- #{path}" 27 | end 28 | end 29 | 30 | if File.directory? path 31 | $@ = at 32 | raise LoadError, "Is a directory - #{path}" 33 | end 34 | 35 | open(path) do |file| 36 | begin 37 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, path 38 | rescue Exception => e 39 | $@ = at 40 | raise e 41 | end 42 | return true 43 | end 44 | else 45 | is_that_dir = false 46 | ($LOAD_PATH | $:).each do |load_path| 47 | real_path = File.join load_path, path 48 | unless File.exist? real_path 49 | if File.exist? "#{real_path}.er" 50 | real_path = "#{real_path}.er" 51 | else 52 | next 53 | end 54 | end 55 | 56 | next is_that_dir = true if File.directory? real_path 57 | open(real_path) do |file| 58 | begin 59 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, real_path 60 | rescue Exception => e 61 | $@ = at 62 | raise e 63 | end 64 | end 65 | return true 66 | end 67 | $@ = at 68 | if is_that_dir 69 | raise LoadError, "Is a directory - #{path}" 70 | else 71 | raise LoadError, "no such file to load -- #{path}" 72 | end 73 | end 74 | end 75 | end -------------------------------------------------------------------------------- /examples/decompile/main.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | module EndlessRuby::Main 5 | 6 | extend self 7 | extend EndlessRuby 8 | include EndlessRuby 9 | 10 | # er ファイルから読み込みそれをピュアなRubyにコンパイルしてrbに書き出します 11 | def compile er, rb 12 | open(er) do |erfile| 13 | open(rb, "w") do |rbfile| 14 | rbfile.write ER2PR(erfile.read) 15 | 16 | # rbファイルを読み込みそれからすべてのendを取り除きます。 17 | def decompile rb, er 18 | open(rb) do |rbfile| 19 | open(er, "w") do |erfile| 20 | erfile.write PR2ER(rbfile.read) 21 | 22 | 23 | # EndlessRuby::Main.main と同じ動作をします。このモジュールをincludeした場合に使用します。 24 | def endlessruby argv 25 | EndlessRuby::Main.main argv 26 | 27 | # $ endlessruby.rb args とまったく同じ動作をします。argvはARGVと同じ形式でなければなりません。 28 | def self.main argv 29 | 30 | if argv.first && File.exist?(argv.first) 31 | $PROGRAM_NAME = argv.shift 32 | open $PROGRAM_NAME do |file| 33 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, $PROGRAM_NAME 34 | return true 35 | 36 | require 'optparse' 37 | 38 | options = { 39 | } 40 | 41 | parser = OptionParser.new do |opts| 42 | opts.on '-o OUT' do |out| 43 | options[:out] = out 44 | 45 | opts.on '-c', '--compile' do |c| 46 | options[:compile] = true 47 | 48 | opts.on '-d', '--decompile' do |d| 49 | options[:decompile] = true 50 | 51 | opts.on '-r' do |r| 52 | options[:recursive] = true 53 | 54 | parser.parse! argv 55 | 56 | if options[:compile] 57 | out = options[:out] || '.' 58 | 59 | argv.each do |er| 60 | unless File.exist? er 61 | puts "no such file to load -- #{er}" 62 | next 63 | 64 | if File.directory? er 65 | unless options[:recursive] 66 | puts "Is a directory - #{er}" 67 | next 68 | # Unimolementation 69 | next 70 | 71 | rb = er 72 | if er =~ /^(.*)\.er$/ 73 | rb = $1 74 | rb = File.split(rb)[1] 75 | rb = File.join(out, "#{rb}.rb") 76 | compile er, rb 77 | elsif options[:decompile] 78 | out = options[:out] || '.' 79 | 80 | argv.each do |rb| 81 | unless File.exist? rb 82 | puts "no such file to load -- #{rb}" 83 | next 84 | 85 | if File.directory? rb 86 | unless options[:recursive] 87 | puts "Is a directory - #{rb}" 88 | next 89 | # Unimolementation 90 | next 91 | 92 | er = rb 93 | if rb =~ /^(.*)\.rb$/ 94 | er = $1 95 | er = File.split(er)[1] 96 | er = File.join(out, "#{er}.er") 97 | decompile rb, er -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/src/endlessruby/main.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | module EndlessRuby::Main 5 | 6 | extend self 7 | extend EndlessRuby 8 | include EndlessRuby 9 | 10 | # er ファイルから読み込みそれをピュアなRubyにコンパイルしてrbに書き出します 11 | def compile er, rb 12 | open(er) do |erfile| 13 | open(rb, "w") do |rbfile| 14 | rbfile.write ER2PR(erfile.read) 15 | 16 | # rbファイルを読み込みそれからすべてのendを取り除きます。 17 | def decompile rb, er 18 | open(rb) do |rbfile| 19 | open(er, "w") do |erfile| 20 | erfile.write PR2ER(rbfile.read) 21 | 22 | 23 | # EndlessRuby::Main.main と同じ動作をします。このモジュールをincludeした場合に使用します。 24 | def endlessruby argv 25 | EndlessRuby::Main.main argv 26 | 27 | # $ endlessruby.rb args とまったく同じ動作をします。argvはARGVと同じ形式でなければなりません。 28 | def self.main argv 29 | 30 | if argv.first && File.exist?(argv.first) 31 | $PROGRAM_NAME = argv.shift 32 | open $PROGRAM_NAME do |file| 33 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, $PROGRAM_NAME 34 | return true 35 | 36 | require 'optparse' 37 | 38 | options = { 39 | } 40 | 41 | parser = OptionParser.new do |opts| 42 | opts.on '-o OUT' do |out| 43 | options[:out] = out 44 | 45 | opts.on '-c', '--compile' do |c| 46 | options[:compile] = true 47 | 48 | opts.on '-d', '--decompile' do |d| 49 | options[:decompile] = true 50 | 51 | opts.on '-r' do |r| 52 | options[:recursive] = true 53 | 54 | parser.parse! argv 55 | 56 | if options[:compile] 57 | out = options[:out] || '.' 58 | 59 | argv.each do |er| 60 | unless File.exist? er 61 | puts "no such file to load -- #{er}" 62 | next 63 | 64 | if File.directory? er 65 | unless options[:recursive] 66 | puts "Is a directory - #{er}" 67 | next 68 | # Unimolementation 69 | next 70 | 71 | rb = er 72 | if er =~ /^(.*)\.er$/ 73 | rb = $1 74 | rb = File.split(rb)[1] 75 | rb = File.join(out, "#{rb}.rb") 76 | compile er, rb 77 | elsif options[:decompile] 78 | out = options[:out] || '.' 79 | 80 | argv.each do |rb| 81 | unless File.exist? rb 82 | puts "no such file to load -- #{rb}" 83 | next 84 | 85 | if File.directory? rb 86 | unless options[:recursive] 87 | puts "Is a directory - #{rb}" 88 | next 89 | # Unimolementation 90 | next 91 | 92 | er = rb 93 | if rb =~ /^(.*)\.rb$/ 94 | er = $1 95 | er = File.split(er)[1] 96 | er = File.join(out, "#{er}.er") 97 | decompile rb, er 98 | -------------------------------------------------------------------------------- /src/endlessruby/main.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | module EndlessRuby::Main 5 | 6 | extend self 7 | extend EndlessRuby 8 | include EndlessRuby 9 | 10 | # er ファイルから読み込みそれをピュアなRubyにコンパイルしてrbに書き出します 11 | def compile er, rb 12 | ER2PR({ :in => { :any => er }, :out => { :any => rb } }) 13 | 14 | # rbファイルを読み込みそれからすべてのendを取り除きます。 15 | def decompile rb, er 16 | PR2ER({ :in => { :any => rb }, :out => { :any => er } }) 17 | 18 | # EndlessRuby::Main.main と同じ動作をします。このモジュールをincludeした場合に使用します。 19 | def endlessruby argv 20 | EndlessRuby::Main.main argv 21 | 22 | # $ endlessruby.rb args とまったく同じ動作をします。argvはARGVと同じ形式でなければなりません。 23 | def self.main argv 24 | 25 | if argv.first && File.exist?(argv.first) 26 | $PROGRAM_NAME = argv.shift 27 | open $PROGRAM_NAME do |file| 28 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, $PROGRAM_NAME 29 | return true 30 | 31 | require 'optparse' 32 | 33 | options = { 34 | } 35 | 36 | parser = OptionParser.new do |opts| 37 | 38 | opts.version = EndlessRuby::VERSION 39 | 40 | opts.on '-o OUT', 'appoint output directory.' do |out| 41 | options[:out] = out 42 | 43 | opts.on '-c', '--compile', 'compile endlessruby source code to pure ruby' do |c| 44 | options[:compile] = true 45 | 46 | opts.on '-d', '--decompile', 'decompile pure ruby source code to endless ruby' do |d| 47 | options[:decompile] = true 48 | 49 | opts.on '-r', 'unimplemented' do |r| 50 | options[:recursive] = true 51 | 52 | parser.parse! argv 53 | 54 | if options[:compile] 55 | out = options[:out] || '.' 56 | 57 | argv.each do |er| 58 | unless File.exist? er 59 | puts "no such file to load -- #{er}" 60 | next 61 | 62 | if File.directory? er 63 | unless options[:recursive] 64 | puts "Is a directory - #{er}" 65 | next 66 | # Unimolementation 67 | next 68 | 69 | rb = er 70 | if er =~ /^(.*)\.er$/ 71 | rb = $1 72 | rb = File.split(rb)[1] 73 | rb = File.join(out, "#{rb}.rb") 74 | compile er, rb 75 | elsif options[:decompile] 76 | out = options[:out] || '.' 77 | 78 | argv.each do |rb| 79 | unless File.exist? rb 80 | puts "no such file to load -- #{rb}" 81 | next 82 | 83 | if File.directory? rb 84 | unless options[:recursive] 85 | puts "Is a directory - #{rb}" 86 | next 87 | # Unimolementation 88 | next 89 | 90 | er = rb 91 | if rb =~ /^(.*)\.rb$/ 92 | er = $1 93 | er = File.split(er)[1] 94 | er = File.join(out, "#{er}.er") 95 | decompile rb, er 96 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/src/endlessruby/main.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | module EndlessRuby::Main 5 | 6 | extend self 7 | extend EndlessRuby 8 | include EndlessRuby 9 | 10 | # er ファイルから読み込みそれをピュアなRubyにコンパイルしてrbに書き出します 11 | def compile er, rb 12 | ER2PR({ :in => { :any => er }, :out => { :any => rb } }) 13 | 14 | # rbファイルを読み込みそれからすべてのendを取り除きます。 15 | def decompile rb, er 16 | PR2ER({ :in => { :any => rb }, :out => { :any => er } }) 17 | 18 | # EndlessRuby::Main.main と同じ動作をします。このモジュールをincludeした場合に使用します。 19 | def endlessruby argv 20 | EndlessRuby::Main.main argv 21 | 22 | # $ endlessruby.rb args とまったく同じ動作をします。argvはARGVと同じ形式でなければなりません。 23 | def self.main argv 24 | 25 | if argv.first && File.exist?(argv.first) 26 | $PROGRAM_NAME = argv.shift 27 | open $PROGRAM_NAME do |file| 28 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, $PROGRAM_NAME 29 | return true 30 | 31 | require 'optparse' 32 | 33 | options = { 34 | } 35 | 36 | parser = OptionParser.new do |opts| 37 | 38 | opts.version = EndlessRuby::VERSION 39 | 40 | opts.on '-o OUT', 'appoint output directory.' do |out| 41 | options[:out] = out 42 | 43 | opts.on '-c', '--compile', 'compile endlessruby source code to pure ruby' do |c| 44 | options[:compile] = true 45 | 46 | opts.on '-d', '--decompile', 'decompile pure ruby source code to endless ruby' do |d| 47 | options[:decompile] = true 48 | 49 | opts.on '-r', 'unimplemented' do |r| 50 | options[:recursive] = true 51 | 52 | parser.parse! argv 53 | 54 | if options[:compile] 55 | out = options[:out] || '.' 56 | 57 | argv.each do |er| 58 | unless File.exist? er 59 | puts "no such file to load -- #{er}" 60 | next 61 | 62 | if File.directory? er 63 | unless options[:recursive] 64 | puts "Is a directory - #{er}" 65 | next 66 | # Unimolementation 67 | next 68 | 69 | rb = er 70 | if er =~ /^(.*)\.er$/ 71 | rb = $1 72 | rb = File.split(rb)[1] 73 | rb = File.join(out, "#{rb}.rb") 74 | compile er, rb 75 | elsif options[:decompile] 76 | out = options[:out] || '.' 77 | 78 | argv.each do |rb| 79 | unless File.exist? rb 80 | puts "no such file to load -- #{rb}" 81 | next 82 | 83 | if File.directory? rb 84 | unless options[:recursive] 85 | puts "Is a directory - #{rb}" 86 | next 87 | # Unimolementation 88 | next 89 | 90 | er = rb 91 | if rb =~ /^(.*)\.rb$/ 92 | er = $1 93 | er = File.split(er)[1] 94 | er = File.join(out, "#{er}.er") 95 | decompile rb, er 96 | -------------------------------------------------------------------------------- /test/test_simply.rb: -------------------------------------------------------------------------------- 1 | class TestEndlessRuby 2 | 3 | def test_1 4 | er2rb_right_output?(< { :any => er }, :out => { :any => rb } }) 13 | end 14 | 15 | # rbファイルを読み込みそれからすべてのendを取り除きます。 16 | def decompile rb, er 17 | PR2ER({ :in => { :any => rb }, :out => { :any => er } }) 18 | end 19 | 20 | # EndlessRuby::Main.main と同じ動作をします。このモジュールをincludeした場合に使用します。 21 | def endlessruby argv 22 | EndlessRuby::Main.main argv 23 | end 24 | 25 | # $ endlessruby.rb args とまったく同じ動作をします。argvはARGVと同じ形式でなければなりません。 26 | def self.main argv 27 | 28 | if argv.first && File.exist?(argv.first) 29 | $PROGRAM_NAME = argv.shift 30 | open $PROGRAM_NAME do |file| 31 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, $PROGRAM_NAME 32 | end 33 | return true 34 | end 35 | 36 | require 'optparse' 37 | 38 | options = { 39 | } 40 | 41 | parser = OptionParser.new do |opts| 42 | 43 | opts.version = EndlessRuby::VERSION 44 | 45 | opts.on '-o OUT', 'appoint output directory.' do |out| 46 | options[:out] = out 47 | end 48 | 49 | opts.on '-c', '--compile', 'compile endlessruby source code to pure ruby' do |c| 50 | options[:compile] = true 51 | end 52 | 53 | opts.on '-d', '--decompile', 'decompile pure ruby source code to endless ruby' do |d| 54 | options[:decompile] = true 55 | end 56 | 57 | opts.on '-r', 'unimplemented' do |r| 58 | options[:recursive] = true 59 | end 60 | end 61 | 62 | parser.parse! argv 63 | 64 | if options[:compile] 65 | out = options[:out] || '.' 66 | 67 | argv.each do |er| 68 | unless File.exist? er 69 | puts "no such file to load -- #{er}" 70 | next 71 | end 72 | 73 | if File.directory? er 74 | unless options[:recursive] 75 | puts "Is a directory - #{er}" 76 | next 77 | end 78 | # Unimolementation 79 | next 80 | end 81 | 82 | rb = er 83 | if er =~ /^(.*)\.er$/ 84 | rb = $1 85 | end 86 | rb = File.split(rb)[1] 87 | rb = File.join(out, "#{rb}.rb") 88 | compile er, rb 89 | end 90 | elsif options[:decompile] 91 | out = options[:out] || '.' 92 | 93 | argv.each do |rb| 94 | unless File.exist? rb 95 | puts "no such file to load -- #{rb}" 96 | next 97 | end 98 | 99 | if File.directory? rb 100 | unless options[:recursive] 101 | puts "Is a directory - #{rb}" 102 | next 103 | end 104 | # Unimolementation 105 | next 106 | end 107 | 108 | er = rb 109 | if rb =~ /^(.*)\.rb$/ 110 | er = $1 111 | end 112 | er = File.split(er)[1] 113 | er = File.join(out, "#{er}.er") 114 | decompile rb, er 115 | end 116 | end 117 | end 118 | end -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/lib/endlessruby/main.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | module EndlessRuby::Main 5 | 6 | extend self 7 | extend EndlessRuby 8 | include EndlessRuby 9 | 10 | # er ファイルから読み込みそれをピュアなRubyにコンパイルしてrbに書き出します 11 | def compile er, rb 12 | ER2PR({ :in => { :any => er }, :out => { :any => rb } }) 13 | end 14 | 15 | # rbファイルを読み込みそれからすべてのendを取り除きます。 16 | def decompile rb, er 17 | PR2ER({ :in => { :any => rb }, :out => { :any => er } }) 18 | end 19 | 20 | # EndlessRuby::Main.main と同じ動作をします。このモジュールをincludeした場合に使用します。 21 | def endlessruby argv 22 | EndlessRuby::Main.main argv 23 | end 24 | 25 | # $ endlessruby.rb args とまったく同じ動作をします。argvはARGVと同じ形式でなければなりません。 26 | def self.main argv 27 | 28 | if argv.first && File.exist?(argv.first) 29 | $PROGRAM_NAME = argv.shift 30 | open $PROGRAM_NAME do |file| 31 | EndlessRuby.ereval file.read, TOPLEVEL_BINDING, $PROGRAM_NAME 32 | end 33 | return true 34 | end 35 | 36 | require 'optparse' 37 | 38 | options = { 39 | } 40 | 41 | parser = OptionParser.new do |opts| 42 | 43 | opts.version = EndlessRuby::VERSION 44 | 45 | opts.on '-o OUT', 'appoint output directory.' do |out| 46 | options[:out] = out 47 | end 48 | 49 | opts.on '-c', '--compile', 'compile endlessruby source code to pure ruby' do |c| 50 | options[:compile] = true 51 | end 52 | 53 | opts.on '-d', '--decompile', 'decompile pure ruby source code to endless ruby' do |d| 54 | options[:decompile] = true 55 | end 56 | 57 | opts.on '-r', 'unimplemented' do |r| 58 | options[:recursive] = true 59 | end 60 | end 61 | 62 | parser.parse! argv 63 | 64 | if options[:compile] 65 | out = options[:out] || '.' 66 | 67 | argv.each do |er| 68 | unless File.exist? er 69 | puts "no such file to load -- #{er}" 70 | next 71 | end 72 | 73 | if File.directory? er 74 | unless options[:recursive] 75 | puts "Is a directory - #{er}" 76 | next 77 | end 78 | # Unimolementation 79 | next 80 | end 81 | 82 | rb = er 83 | if er =~ /^(.*)\.er$/ 84 | rb = $1 85 | end 86 | rb = File.split(rb)[1] 87 | rb = File.join(out, "#{rb}.rb") 88 | compile er, rb 89 | end 90 | elsif options[:decompile] 91 | out = options[:out] || '.' 92 | 93 | argv.each do |rb| 94 | unless File.exist? rb 95 | puts "no such file to load -- #{rb}" 96 | next 97 | end 98 | 99 | if File.directory? rb 100 | unless options[:recursive] 101 | puts "Is a directory - #{rb}" 102 | next 103 | end 104 | # Unimolementation 105 | next 106 | end 107 | 108 | er = rb 109 | if rb =~ /^(.*)\.rb$/ 110 | er = $1 111 | end 112 | er = File.split(er)[1] 113 | er = File.join(out, "#{er}.er") 114 | decompile rb, er 115 | end 116 | end 117 | end 118 | end -------------------------------------------------------------------------------- /doc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | RDoc Documentation 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |

RDoc Documentation

23 | 24 | 25 |

This is the API documentation for 'RDoc Documentation'.

26 | 27 | 28 | 29 | 30 | 31 |

Classes/Modules

32 | 41 | 42 |

Methods

43 | 78 | 79 |
80 |

[Validate]

81 |

Generated with the Darkfish 82 | Rdoc Generator 1.1.6.

83 |
84 | 85 | 86 | -------------------------------------------------------------------------------- /examples/decompile/endlessruby.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | $:.unshift(File.dirname(__FILE__)) unless 5 | $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) 6 | 7 | require 'endlessruby/extensions' 8 | 9 | # EndlessRubyはRubyをendを取り除いて書けます。 10 | # 11 | # erファイルをrequire 12 | # require 'homuhomu.er' | require 'homuhomu' 13 | # 14 | # erファイルを実行 15 | # $ path/to/endlessruby.rb homuhomu.er 16 | # 17 | # erファイルをコンパイル 18 | # $ path/to/endlessruby.rb -c src/homuhomu.er -o lib 19 | # # => src/homuhomu.er をコンパイルして lib/homuhomu.rb を書き出します。 20 | # # -o が省略された場合はカレントディレクトリに書き出します。 21 | # 22 | # Example: 23 | # class EndlessRubyWorld 24 | # 25 | # def self.hello! 26 | # puts "hello!" 27 | # 28 | # 29 | # [-2, -1, 0, 1, 2].reject do |x| 30 | # x < 0 31 | # end.each do |n| 32 | # puts n 33 | # 34 | module EndlessRuby 35 | 36 | # EndlessRuby のバージョンです 37 | VERSION = "0.0.1" 38 | 39 | extend self 40 | 41 | private 42 | 43 | # 内部で使用します。空業かどうか判定します。 44 | def blank_line? line 45 | return true unless line 46 | (line.chomp.gsub /\s+?/, '') == "" 47 | 48 | # 内部で使用します。インデントを取り除きます 49 | def unindent line 50 | line =~ /^\s*?(\S.*?)$/ 51 | $1 52 | # 内部で使用します。インデントします 53 | def indent line, level, indent=" " 54 | "#{indent * level}#{line}" 55 | 56 | # 内部で使用します。インデントの数を数えます。 57 | def indent_count line, indent=" " 58 | return 0 unless line 59 | if line =~ /^#{indent}(.*?)$/ 60 | 1 + (indent_count $1, indent) 61 | else 62 | 0 63 | 64 | # 内部で使用します。ブロックを作るキーワード群です。 65 | BLOCK_KEYWORDS = [ 66 | [/^if(:?\s|\().*?$/, /^elsif(:?\s|\().*?$/, /^else(?:$|\s+)/], 67 | [/^unless(:?\s|\().*?$/, /^elsif(:?\s|\().*?$/, /^else(?:$|\s+)/], 68 | [/^while(:?\s|\().*?$/], 69 | [/^until(:?\s|\().*?$/], 70 | [/^case(:?\s|\().*?$/, /^when(:?\s|\().*?$/, /^else(?:$|\s+)/], 71 | [/^def\s.*?$/, /^rescue(:?$|\s|\().*?$/, /^else(?:$|\s+)/, /^ensure(?:$|\s+)/], 72 | [/^class\s.*?$/], 73 | [/^module\s.*?$/], 74 | [/^begin(?:$|\s+)/, /^rescue(:?$|\s|\().*?$/, /^else(?:$|\s+)/, /^ensure(?:$|\s+)/], 75 | [/^.*?\s+do(:?$|\s|\|)/] 76 | ] 77 | 78 | public 79 | 80 | # 文字列をEndlessRubyの構文として実行します。引数の意味はKernel#evalと同じです 81 | def ereval(src, binding=TOPLEVEL_BINDING, filename=__FILE__, lineno=1) 82 | at = caller 83 | eval(ER2PR(src), binding, filename, lineno) 84 | rescue Exception => e 85 | $@ = at 86 | raise e 87 | 88 | # 廃止予定です 89 | def ercompile(er, rb) 90 | open(er) do |erfile| 91 | open(rb, "w") do |rbfile| 92 | rbfile.write(endless_ruby_to_pure_ruby(erfile.read)) 93 | 94 | # Rubyの構文をEndlessRubyの構文に変換します。 95 | def pure_ruby_to_endless_ruby src 96 | @decompile = true 97 | ER2RB(src) 98 | 99 | alias RB2ER pure_ruby_to_endless_ruby 100 | alias PR2ER pure_ruby_to_endless_ruby 101 | 102 | # EndlessRubyの構文をピュアなRubyの構文に変換します。 103 | def endless_ruby_to_pure_ruby src 104 | endless = src.split "\n" 105 | 106 | pure = [] 107 | i = 0 108 | while i < endless.length 109 | pure << (currently_line = endless[i]) 110 | 111 | if currently_line =~ /(.*)(?:^|(?:(?!\\).))\#(?!\{).*$/ 112 | currently_line = $1 113 | 114 | if blank_line? currently_line 115 | i += 1 116 | next 117 | 118 | # ブロックを作らない構文なら単に無視する 119 | next i += 1 unless BLOCK_KEYWORDS.any? { |k| k[0] =~ unindent(currently_line) } 120 | 121 | # ブロックに入る 122 | keyword = BLOCK_KEYWORDS.each { |k| break k if k[0] =~ unindent(currently_line) } 123 | 124 | currently_indent_depth = indent_count currently_line 125 | base_indent_depth = currently_indent_depth 126 | 127 | inner_statements = [] 128 | comment_count = 0 129 | in_here_document = nil 130 | while i < endless.length 131 | 132 | inner_currently_line = endless[i + 1] 133 | 134 | if inner_currently_line =~ /(.*)(?:^|(?:(?!\\).))\#(?!\{).*$/ 135 | if blank_line?($1) && currently_indent_depth >= indent_count(inner_currently_line) 136 | comment_count += 1 137 | inner_currently_line = $1 138 | elsif blank_line? inner_currently_line 139 | comment_count += 1 140 | 141 | if blank_line? inner_currently_line 142 | inner_statements << endless[i + 1] 143 | i += 1 144 | next 145 | 146 | just_after_indent_depth = indent_count inner_currently_line 147 | 148 | if base_indent_depth < just_after_indent_depth 149 | comment_count = 0 150 | 151 | if in_here_document 152 | if inner_currently_line =~ /^#{in_here_document}\s*$/ 153 | in_here_document = nil 154 | inner_statements << endless[i + 1] 155 | i += 1 156 | next 157 | else 158 | inner_statements << endless[i + 1] 159 | i += 1 160 | next 161 | 162 | if inner_currently_line =~ /^.*?\<\<\-?(\w+)(?!\w).*$/ 163 | in_here_document = $1 164 | 165 | if base_indent_depth > indent_count(inner_currently_line) 166 | break 167 | 168 | if base_indent_depth == indent_count(inner_currently_line) 169 | unless keyword[1..-1].any? { |k| k =~ unindent(inner_currently_line) } 170 | break 171 | 172 | inner_statements << endless[i + 1] 173 | i += 1 174 | 175 | # endをコメントより上の行へ持ち上げる 176 | if 0 < comment_count 177 | comment_count.times do 178 | inner_statements.pop 179 | i -= comment_count 180 | 181 | pure += ER2PR(inner_statements.join("\n")).split "\n" 182 | # 次の行がendならばendを補完しない(ワンライナーのため) 183 | unless @decompile 184 | unless endless[i + 1] && endless[i + 1] =~ /^\s*end(?!\w).*$/ 185 | pure << "#{' '*currently_indent_depth}end" 186 | else 187 | if endless[i + 1] && endless[i + 1] =~ /^\s*end(?:\s|$)\s*$/ 188 | i += 1 189 | 190 | i += 1 191 | pure.join "\n" 192 | 193 | alias to_pure_ruby endless_ruby_to_pure_ruby 194 | alias ER2PR endless_ruby_to_pure_ruby 195 | alias ER2RB endless_ruby_to_pure_ruby 196 | 197 | if __FILE__ == $PROGRAM_NAME 198 | require 'endlessruby/main' 199 | EndlessRuby::Main.main ARGV -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/src/endlessruby.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | $:.unshift(File.dirname(__FILE__)) unless 5 | $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) 6 | 7 | require 'endlessruby/extensions' 8 | 9 | # EndlessRubyはRubyをendを取り除いて書けます。 10 | # 11 | # erファイルをrequire 12 | # require 'homuhomu.er' | require 'homuhomu' 13 | # 14 | # erファイルを実行 15 | # $ path/to/endlessruby.rb homuhomu.er 16 | # 17 | # erファイルをコンパイル 18 | # $ path/to/endlessruby.rb -c src/homuhomu.er -o lib 19 | # # => src/homuhomu.er をコンパイルして lib/homuhomu.rb を書き出します。 20 | # # -o が省略された場合はカレントディレクトリに書き出します。 21 | # 22 | # Example: 23 | # class EndlessRubyWorld 24 | # 25 | # def self.hello! 26 | # puts "hello!" 27 | # 28 | # 29 | # [-2, -1, 0, 1, 2].reject do |x| 30 | # x < 0 31 | # end.each do |n| 32 | # puts n 33 | # 34 | module EndlessRuby 35 | 36 | # EndlessRuby のバージョンです 37 | VERSION = "0.0.1" 38 | 39 | extend self 40 | 41 | private 42 | 43 | # 内部で使用します。空業かどうか判定します。 44 | def blank_line? line 45 | return true unless line 46 | (line.chomp.gsub /\s+?/, '') == "" 47 | 48 | # 内部で使用します。インデントを取り除きます 49 | def unindent line 50 | line =~ /^\s*?(\S.*?)$/ 51 | $1 52 | # 内部で使用します。インデントします 53 | def indent line, level, indent=" " 54 | "#{indent * level}#{line}" 55 | 56 | # 内部で使用します。インデントの数を数えます。 57 | def indent_count line, indent=" " 58 | return 0 unless line 59 | if line =~ /^#{indent}(.*?)$/ 60 | 1 + (indent_count $1, indent) 61 | else 62 | 0 63 | 64 | # 内部で使用します。ブロックを作るキーワード群です。 65 | BLOCK_KEYWORDS = [ 66 | [/^if(:?\s|\().*?$/, /^elsif(:?\s|\().*?$/, /^else(?:$|\s+)/], 67 | [/^unless(:?\s|\().*?$/, /^elsif(:?\s|\().*?$/, /^else(?:$|\s+)/], 68 | [/^while(:?\s|\().*?$/], 69 | [/^until(:?\s|\().*?$/], 70 | [/^case(:?\s|\().*?$/, /^when(:?\s|\().*?$/, /^else(?:$|\s+)/], 71 | [/^def\s.*?$/, /^rescue(:?$|\s|\().*?$/, /^else(?:$|\s+)/, /^ensure(?:$|\s+)/], 72 | [/^class\s.*?$/], 73 | [/^module\s.*?$/], 74 | [/^begin(?:$|\s+)/, /^rescue(:?$|\s|\().*?$/, /^else(?:$|\s+)/, /^ensure(?:$|\s+)/], 75 | [/^.*?\s+do(:?$|\s|\|)/] 76 | ] 77 | 78 | public 79 | 80 | # 文字列をEndlessRubyの構文として実行します。引数の意味はKernel#evalと同じです 81 | def ereval(src, binding=TOPLEVEL_BINDING, filename=__FILE__, lineno=1) 82 | at = caller 83 | eval(ER2PR(src), binding, filename, lineno) 84 | rescue Exception => e 85 | $@ = at 86 | raise e 87 | 88 | # Rubyの構文をEndlessRubyの構文に変換します。 89 | def pure_ruby_to_endless_ruby src 90 | @decompile = true 91 | s = ER2RB(src) 92 | @decompile = nil 93 | s 94 | 95 | 96 | alias RB2ER pure_ruby_to_endless_ruby 97 | alias PR2ER pure_ruby_to_endless_ruby 98 | 99 | # EndlessRubyの構文をピュアなRubyの構文に変換します。 100 | def endless_ruby_to_pure_ruby src 101 | endless = src.split "\n" 102 | 103 | pure = [] 104 | i = 0 105 | while i < endless.length 106 | pure << (currently_line = endless[i]) 107 | 108 | if currently_line =~ /(.*)(?:^|(?:(?!\\).))\#(?!\{).*$/ 109 | currently_line = $1 110 | 111 | if blank_line? currently_line 112 | i += 1 113 | next 114 | 115 | # ブロックを作らない構文なら単に無視する 116 | next i += 1 unless BLOCK_KEYWORDS.any? { |k| k[0] =~ unindent(currently_line) } 117 | 118 | # ブロックに入る 119 | keyword = BLOCK_KEYWORDS.each { |k| break k if k[0] =~ unindent(currently_line) } 120 | 121 | currently_indent_depth = indent_count currently_line 122 | base_indent_depth = currently_indent_depth 123 | 124 | inner_statements = [] 125 | # def method1 126 | # statemetns 127 | # # document of method2 128 | # def method2 129 | # statements 130 | # のような場合にコメントの部分はmethod1内に含まないようにする。 131 | # def method1 132 | # statemetns 133 | # # comment 134 | # return 135 | # のような場合と区別するため。 136 | comment_count = 0 137 | in_here_document = nil 138 | while i < endless.length 139 | 140 | inner_currently_line = endless[i + 1] 141 | 142 | if inner_currently_line =~ /(.*)(?:^|(?:(?!\\).))\#(?!\{).*$/ 143 | if blank_line?($1) && currently_indent_depth >= indent_count(inner_currently_line) 144 | comment_count += 1 145 | inner_currently_line = $1 146 | elsif blank_line? inner_currently_line 147 | comment_count += 1 148 | 149 | if blank_line? inner_currently_line 150 | inner_statements << endless[i + 1] 151 | i += 1 152 | next 153 | 154 | just_after_indent_depth = indent_count inner_currently_line 155 | 156 | # 次の行がendならば意図のあるものなのでendを持ちあ揚げない 157 | if inner_currently_line =~ /^\s*end(?!\w).*$/ 158 | comment_count = 0 159 | 160 | if base_indent_depth < just_after_indent_depth 161 | comment_count = 0 162 | 163 | if in_here_document 164 | if (in_here_document[0] == '' && inner_currently_line =~ /^#{in_here_document[1]}\s*$/) || # < indent_count(inner_currently_line) 179 | break 180 | 181 | if base_indent_depth == indent_count(inner_currently_line) 182 | unless keyword[1..-1].any? { |k| k =~ unindent(inner_currently_line) } 183 | break 184 | 185 | inner_statements << endless[i + 1] 186 | i += 1 187 | 188 | # endをコメントより上の行へ持ち上げる 189 | if 0 < comment_count 190 | comment_count.times do 191 | inner_statements.pop 192 | i -= comment_count 193 | 194 | pure += ER2PR(inner_statements.join("\n")).split "\n" 195 | # 次の行がendならばendを補完しない(ワンライナーのため) 196 | unless @decompile 197 | unless endless[i + 1] && endless[i + 1] =~ /^\s*end(?!\w).*$/ 198 | pure << "#{' '*currently_indent_depth}end" 199 | else 200 | # メソッドチェインは削除しない 201 | if endless[i + 1] && endless[i + 1] =~ /^\s*end(?:\s|$)\s*$/ 202 | i += 1 203 | 204 | i += 1 205 | pure.join "\n" 206 | 207 | alias to_pure_ruby endless_ruby_to_pure_ruby 208 | alias ER2PR endless_ruby_to_pure_ruby 209 | alias ER2RB endless_ruby_to_pure_ruby 210 | 211 | if __FILE__ == $PROGRAM_NAME 212 | require 'endlessruby/main' 213 | EndlessRuby::Main.main ARGV 214 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.0.1/lib/endlessruby.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | $:.unshift(File.dirname(__FILE__)) unless 5 | $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) 6 | 7 | require 'endlessruby/extensions' 8 | 9 | # EndlessRubyはRubyをendを取り除いて書けます。 10 | # 11 | # erファイルをrequire 12 | # require 'homuhomu.er' | require 'homuhomu' 13 | # 14 | # erファイルを実行 15 | # $ path/to/endlessruby.rb homuhomu.er 16 | # 17 | # erファイルをコンパイル 18 | # $ path/to/endlessruby.rb -c src/homuhomu.er -o lib 19 | # # => src/homuhomu.er をコンパイルして lib/homuhomu.rb を書き出します。 20 | # # -o が省略された場合はカレントディレクトリに書き出します。 21 | # 22 | # Example: 23 | # class EndlessRubyWorld 24 | # 25 | # def self.hello! 26 | # puts "hello!" 27 | # 28 | # 29 | # [-2, -1, 0, 1, 2].reject do |x| 30 | # x < 0 31 | # end.each do |n| 32 | # puts n 33 | # 34 | module EndlessRuby 35 | 36 | # EndlessRuby のバージョンです 37 | VERSION = "0.0.1" 38 | 39 | extend self 40 | 41 | private 42 | 43 | # 内部で使用します。空業かどうか判定します。 44 | def blank_line? line 45 | return true unless line 46 | (line.chomp.gsub /\s+?/, '') == "" 47 | end 48 | 49 | # 内部で使用します。インデントを取り除きます 50 | def unindent line 51 | line =~ /^\s*?(\S.*?)$/ 52 | $1 53 | end 54 | # 内部で使用します。インデントします 55 | def indent line, level, indent=" " 56 | "#{indent * level}#{line}" 57 | end 58 | 59 | # 内部で使用します。インデントの数を数えます。 60 | def indent_count line, indent=" " 61 | return 0 unless line 62 | if line =~ /^#{indent}(.*?)$/ 63 | 1 + (indent_count $1, indent) 64 | else 65 | 0 66 | end 67 | end 68 | 69 | # 内部で使用します。ブロックを作るキーワード群です。 70 | BLOCK_KEYWORDS = [ 71 | [/^if(:?\s|\().*?$/, /^elsif(:?\s|\().*?$/, /^else(?:$|\s+)/], 72 | [/^unless(:?\s|\().*?$/, /^elsif(:?\s|\().*?$/, /^else(?:$|\s+)/], 73 | [/^while(:?\s|\().*?$/], 74 | [/^until(:?\s|\().*?$/], 75 | [/^case(:?\s|\().*?$/, /^when(:?\s|\().*?$/, /^else(?:$|\s+)/], 76 | [/^def\s.*?$/, /^rescue(:?$|\s|\().*?$/, /^else(?:$|\s+)/, /^ensure(?:$|\s+)/], 77 | [/^class\s.*?$/], 78 | [/^module\s.*?$/], 79 | [/^begin(?:$|\s+)/, /^rescue(:?$|\s|\().*?$/, /^else(?:$|\s+)/, /^ensure(?:$|\s+)/], 80 | [/^.*?\s+do(:?$|\s|\|)/] 81 | ] 82 | 83 | public 84 | 85 | # 文字列をEndlessRubyの構文として実行します。引数の意味はKernel#evalと同じです 86 | def ereval(src, binding=TOPLEVEL_BINDING, filename=__FILE__, lineno=1) 87 | at = caller 88 | eval(ER2PR(src), binding, filename, lineno) 89 | rescue Exception => e 90 | $@ = at 91 | raise e 92 | end 93 | 94 | # Rubyの構文をEndlessRubyの構文に変換します。 95 | def pure_ruby_to_endless_ruby src 96 | @decompile = true 97 | s = ER2RB(src) 98 | @decompile = nil 99 | s 100 | end 101 | 102 | 103 | alias RB2ER pure_ruby_to_endless_ruby 104 | alias PR2ER pure_ruby_to_endless_ruby 105 | 106 | # EndlessRubyの構文をピュアなRubyの構文に変換します。 107 | def endless_ruby_to_pure_ruby src 108 | endless = src.split "\n" 109 | 110 | pure = [] 111 | i = 0 112 | while i < endless.length 113 | pure << (currently_line = endless[i]) 114 | 115 | if currently_line =~ /(.*)(?:^|(?:(?!\\).))\#(?!\{).*$/ 116 | currently_line = $1 117 | end 118 | 119 | if blank_line? currently_line 120 | i += 1 121 | next 122 | end 123 | 124 | # ブロックを作らない構文なら単に無視する 125 | next i += 1 unless BLOCK_KEYWORDS.any? { |k| k[0] =~ unindent(currently_line) } 126 | 127 | # ブロックに入る 128 | keyword = BLOCK_KEYWORDS.each { |k| break k if k[0] =~ unindent(currently_line) } 129 | 130 | currently_indent_depth = indent_count currently_line 131 | base_indent_depth = currently_indent_depth 132 | 133 | inner_statements = [] 134 | # def method1 135 | # statemetns 136 | # # document of method2 137 | # def method2 138 | # statements 139 | # のような場合にコメントの部分はmethod1内に含まないようにする。 140 | # def method1 141 | # statemetns 142 | # # comment 143 | # return 144 | # のような場合と区別するため。 145 | comment_count = 0 146 | in_here_document = nil 147 | while i < endless.length 148 | 149 | inner_currently_line = endless[i + 1] 150 | 151 | if inner_currently_line =~ /(.*)(?:^|(?:(?!\\).))\#(?!\{).*$/ 152 | if blank_line?($1) && currently_indent_depth >= indent_count(inner_currently_line) 153 | comment_count += 1 154 | end 155 | inner_currently_line = $1 156 | elsif blank_line? inner_currently_line 157 | comment_count += 1 158 | end 159 | 160 | if blank_line? inner_currently_line 161 | inner_statements << endless[i + 1] 162 | i += 1 163 | next 164 | end 165 | 166 | just_after_indent_depth = indent_count inner_currently_line 167 | 168 | # 次の行がendならば意図のあるものなのでendを持ちあ揚げない 169 | if inner_currently_line =~ /^\s*end(?!\w).*$/ 170 | comment_count = 0 171 | end 172 | 173 | if base_indent_depth < just_after_indent_depth 174 | comment_count = 0 175 | end 176 | 177 | if in_here_document 178 | if (in_here_document[0] == '' && inner_currently_line =~ /^#{in_here_document[1]}\s*$/) || # < indent_count(inner_currently_line) 196 | break 197 | end 198 | 199 | if base_indent_depth == indent_count(inner_currently_line) 200 | unless keyword[1..-1].any? { |k| k =~ unindent(inner_currently_line) } 201 | break 202 | end 203 | end 204 | 205 | inner_statements << endless[i + 1] 206 | i += 1 207 | end 208 | 209 | # endをコメントより上の行へ持ち上げる 210 | if 0 < comment_count 211 | comment_count.times do 212 | inner_statements.pop 213 | end 214 | i -= comment_count 215 | end 216 | 217 | pure += ER2PR(inner_statements.join("\n")).split "\n" 218 | # 次の行がendならばendを補完しない(ワンライナーのため) 219 | unless @decompile 220 | unless endless[i + 1] && endless[i + 1] =~ /^\s*end(?!\w).*$/ 221 | pure << "#{' '*currently_indent_depth}end" 222 | end 223 | else 224 | # メソッドチェインは削除しない 225 | if endless[i + 1] && endless[i + 1] =~ /^\s*end(?:\s|$)\s*$/ 226 | i += 1 227 | end 228 | end 229 | 230 | i += 1 231 | end 232 | pure.join "\n" 233 | end 234 | 235 | alias to_pure_ruby endless_ruby_to_pure_ruby 236 | alias ER2PR endless_ruby_to_pure_ruby 237 | alias ER2RB endless_ruby_to_pure_ruby 238 | end 239 | 240 | if __FILE__ == $PROGRAM_NAME 241 | require 'endlessruby/main' 242 | EndlessRuby::Main.main ARGV 243 | end -------------------------------------------------------------------------------- /src/endlessruby.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | $:.unshift(File.dirname(__FILE__)) unless 5 | $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) 6 | 7 | require 'endlessruby/custom_require' 8 | require "tempfile" 9 | require "irb" 10 | 11 | # EndlessRubyはRubyをendを取り除いて書けます。 12 | # 13 | # erファイルをrequire 14 | # require 'homuhomu.er' | require 'homuhomu' 15 | # 16 | # erファイルを実行 17 | # $ path/to/endlessruby.rb homuhomu.er 18 | # 19 | # erファイルをコンパイル 20 | # $ path/to/endlessruby.rb -c src/homuhomu.er -o lib 21 | # # => src/homuhomu.er をコンパイルして lib/homuhomu.rb を書き出します。 22 | # # -o が省略された場合はカレントディレクトリに書き出します。 23 | # 24 | # Example: 25 | # class EndlessRubyWorld 26 | # 27 | # def self.hello! 28 | # puts "hello!" 29 | # 30 | # 31 | # [-2, -1, 0, 1, 2].reject do |x| 32 | # x < 0 33 | # end.each do |n| 34 | # puts n 35 | # 36 | module EndlessRuby 37 | 38 | # EndlessRuby のバージョンです 39 | VERSION = "0.1.0" 40 | 41 | extend self 42 | 43 | public 44 | 45 | # 文字列をEndlessRubyの構文として実行します。引数の意味はKernel#evalと同じです 46 | def ereval(src, binding=TOPLEVEL_BINDING, filename=__FILE__, lineno=1) 47 | eval(ER2PR(src), binding, filename, lineno) 48 | 49 | # EndlessRubyの構文をピュアなRubyの構文に変換します。
50 | # options: オプションを表すHashまたはto_hashを実装したオブジェクト、構文を読み出すIOまたはto_ioを実装したオブジェクト、EndlessRubyの構文を表すStringまたはto_strを実装したオブジェクト、またはファイルのパス
51 | # optionsが文字列ならばそれをピュアなRubyの構文にします。それがIOならばIOから読み出してそれをピュアなRubyの構文にします。
52 | # ファイルのパスならばそのファイルかあ読み込みます 53 | # それがHashならばそれはオプションです。それぞれHashを指定します。
54 | # options: { 55 | # in: { 56 | # io: optionsにIOを指定した場合と同じです 57 | # any: それが存在するファイルのパスを表す文字列ならばそのファイルから読み出します。この場合のanyはoptionsにそのような文字列を指定するのと同じ意味です。 58 | # そうでない文字列ならばそれ自体をEndlessRubyの構文として読み出します。この場合のanyはoptionsに文字列を指定するのと同じ意味です。 59 | # それがIOならばそのIOから読み出します。この場合のany はin.ioを直接指定するのと同じです。 60 | # } 61 | # out: { 62 | # io: このIOに結果を書き出します。 63 | # any: ファイルのパスかIOです。ファイルのパスならばそのファイルに書き出します。IOならばそのIOに書き出します。 64 | # } 65 | # decompile: trueならばコンパイルではなくてでコンパイルします。 66 | # } 67 | # 68 | # opts[:out][:io] には書き出すioを指定します。
69 | # from a file on disk:
70 | # EndlessRuby.ER2RB("filename.er") 71 | #
72 | # from string that is source code:
73 | # EndlessRuby.ER2RB(< 77 | # from IO:
78 | # file = open 'filename.er' 79 | # EndlessRuby.ER2RB(file) 80 | # 81 | # appoint input file and output file: 82 | # ER2PR({ :in => { :any => 'filename.er' }, :out => { :any => 'filename.rb' } }) 83 | # ER2PR({ :in => { :io => in_io }, :out => { :io => out_io } }) 84 | def endless_ruby_to_pure_ruby options 85 | converting_helper options 86 | 87 | alias to_pure_ruby endless_ruby_to_pure_ruby 88 | alias ER2PR endless_ruby_to_pure_ruby 89 | alias ER2RB endless_ruby_to_pure_ruby 90 | 91 | # Rubyの構文をEndlessRubyの構文に変換します。optionsはendlessruby_to_pure_rubyと同じです。 92 | def pure_ruby_to_endless_ruby options 93 | options = merge_options options 94 | options[:decompile] = true 95 | converting_helper options 96 | 97 | alias RB2ER pure_ruby_to_endless_ruby 98 | alias PR2ER pure_ruby_to_endless_ruby 99 | 100 | private 101 | 102 | def merge_options options 103 | 104 | opts = { 105 | :in => {}, :out => {} 106 | } 107 | 108 | if options.respond_to? :to_hash 109 | opts = opts.merge options.to_hash 110 | elsif options.respond_to?(:to_io) || options.respond_to?(:to_str) 111 | opts[:in][:any] = options 112 | else 113 | raise ArgumentError, "options is IO, String, or Hash" 114 | 115 | if opts[:in][:any] 116 | if opts[:in][:any].respond_to?(:to_str) && File.exist?(opts[:in][:any].to_str) # from a file on the disk. 117 | opts[:in] = { 118 | :io => (in_io = open opts[:in][:any].to_str), 119 | :ensure => proc { in_io.close } 120 | } 121 | elsif opts[:in][:any].respond_to? :to_io # from IO that can read source code. 122 | opts[:in] = { 123 | :io => options.to_io, 124 | :ensure => proc {} 125 | } 126 | elsif opts[:in][:any].respond_to? :to_str # from String that is source code. 127 | in_io = Tempfile.new "endlessruby from temp file" 128 | in_io.write options.to_str 129 | in_io.seek 0 130 | opts[:in] = { 131 | :io => in_io, 132 | :ensure => proc { in_io.close } 133 | } 134 | else 135 | raise ArgumentError, "options[:in][:any] is IO, String which is path, or String which is source code" 136 | 137 | opts[:in][:any] = nil 138 | 139 | if opts[:out][:any] 140 | if opts[:out][:any].respond_to?(:to_str) # to a file on the disk. 141 | opts[:out] = { 142 | :io => (out_io = open opts[:out][:any].to_str, "w+"), 143 | :ensure => proc { out_io.close } 144 | } 145 | elsif opts[:out][:any].respond_to? :to_io # to IO that can read source code. 146 | opts[:out] = { 147 | :io => options.to_io, 148 | :ensure => proc {} 149 | } 150 | else 151 | raise ArgumentError, "options[:out][:any] is IO, or String which is Path" 152 | elsif !opts[:out][:io] 153 | opts[:out] = { :io => (out_io = Tempfile.new("endlessruby pure temp file")), :ensure => proc { out_io.close } } 154 | 155 | opts[:out][:any] = nil 156 | opts 157 | 158 | def converting_helper options 159 | opts = merge_options options 160 | 161 | io = opts[:in][:io] 162 | 163 | r = RubyLex.new 164 | r.set_input io 165 | r.skip_space = false 166 | 167 | pure = opts[:out][:io] 168 | 169 | indent = [] 170 | pass = [] 171 | bol = true 172 | last = [0, 0] 173 | bol_indent = 0 174 | 175 | while t = r.token 176 | 177 | if bol && !(RubyToken::TkSPACE === t) && !(RubyToken::TkNL === t) 178 | 179 | bol_indent = this_indent = t.char_no 180 | while (indent.last && pass.last) && ((this_indent < indent.last) || (this_indent <= indent.last && !pass.last.include?(t.class))) 181 | if RubyToken::TkEND === t && this_indent == indent.last 182 | break 183 | 184 | _indent = indent.pop 185 | pass.pop 186 | idt = [] 187 | loop do 188 | pure.seek pure.pos - 1 189 | if RUBY_VERSION < "1.9" # 1.8 190 | c = pure.read(1) 191 | else 192 | c = pure.getc 193 | break if pure.pos == 0 || !(["\n", ' '].include?(c)) 194 | pure.seek pure.pos - 1 195 | idt.unshift c 196 | if idt.first == "\n" 197 | pure.write idt.shift 198 | pure.write "#{' '*_indent}end\n" 199 | pure.write idt.join 200 | bol = false 201 | 202 | case t 203 | when RubyToken::TkNL 204 | bol = true 205 | when RubyToken::TkEND 206 | indent.pop 207 | pass.pop 208 | if opts[:decompile] 209 | last[0] += 3 210 | last[1] += 3 211 | next 212 | when RubyToken::TkIF, RubyToken::TkUNLESS 213 | pass << [RubyToken::TkELSE, RubyToken::TkELSIF] 214 | indent << t.char_no 215 | when RubyToken::TkFOR 216 | pass << [] 217 | indent << t.char_no 218 | when RubyToken::TkWHILE, RubyToken::TkUNTIL 219 | pass << [] 220 | indent << t.char_no 221 | when RubyToken::TkBEGIN 222 | pass << [RubyToken::TkRESCUE, RubyToken::TkELSE, RubyToken::TkENSURE] 223 | indent << t.char_no 224 | when RubyToken::TkDEF 225 | pass << [RubyToken::TkRESCUE, RubyToken::TkELSE, RubyToken::TkENSURE] 226 | indent << t.char_no 227 | when RubyToken::TkCLASS, RubyToken::TkMODULE 228 | pass << [] 229 | indent << t.char_no 230 | when RubyToken::TkCASE 231 | pass << [RubyToken::TkWHEN, RubyToken::TkELSE] 232 | indent << t.char_no 233 | when RubyToken::TkDO 234 | pass << [] 235 | indent << bol_indent 236 | when RubyToken::TkSPACE 237 | 238 | 239 | pos = io.pos 240 | io.seek pos 241 | 242 | pos = io.pos 243 | 244 | if RUBY_VERSION < "1.9" # 1.8 245 | io.seek t.seek 246 | pure.write io.read(r.seek - t.seek) 247 | else # 1.9 248 | io.seek last[0] 249 | (r.seek - last[1]).times do 250 | pure.write io.getc 251 | last = [io.pos, r.seek] 252 | 253 | io.seek pos 254 | 255 | until opts[:decompile] || (indent.empty? && pass.empty?) 256 | _indent = indent.pop 257 | pass.pop 258 | pure.seek pure.pos - 1 259 | if RUBY_VERSION < "1.9" # 1.8 260 | c = pure.read 1 261 | else 262 | c = pure.getc 263 | if c == "\n" 264 | pure.write "#{' '*_indent}end" 265 | else 266 | pure.write "\n#{' '*_indent}end" 267 | 268 | pure.seek 0 269 | ret = pure.read.chomp 270 | pure.seek 0 271 | 272 | opts[:out][:ensure] && opts[:out][:ensure].call 273 | opts[:in][:ensure] && opts[:in][:ensure].call 274 | 275 | ret 276 | 277 | if __FILE__ == $PROGRAM_NAME 278 | require 'endlessruby/main' 279 | EndlessRuby::Main.main ARGV 280 | -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/src/endlessruby.er: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | $:.unshift(File.dirname(__FILE__)) unless 5 | $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) 6 | 7 | require 'endlessruby/custom_require' 8 | require "tempfile" 9 | require "irb" 10 | 11 | # EndlessRubyはRubyをendを取り除いて書けます。 12 | # 13 | # erファイルをrequire 14 | # require 'homuhomu.er' | require 'homuhomu' 15 | # 16 | # erファイルを実行 17 | # $ path/to/endlessruby.rb homuhomu.er 18 | # 19 | # erファイルをコンパイル 20 | # $ path/to/endlessruby.rb -c src/homuhomu.er -o lib 21 | # # => src/homuhomu.er をコンパイルして lib/homuhomu.rb を書き出します。 22 | # # -o が省略された場合はカレントディレクトリに書き出します。 23 | # 24 | # Example: 25 | # class EndlessRubyWorld 26 | # 27 | # def self.hello! 28 | # puts "hello!" 29 | # 30 | # 31 | # [-2, -1, 0, 1, 2].reject do |x| 32 | # x < 0 33 | # end.each do |n| 34 | # puts n 35 | # 36 | module EndlessRuby 37 | 38 | # EndlessRuby のバージョンです 39 | VERSION = "0.1.0" 40 | 41 | extend self 42 | 43 | public 44 | 45 | # 文字列をEndlessRubyの構文として実行します。引数の意味はKernel#evalと同じです 46 | def ereval(src, binding=TOPLEVEL_BINDING, filename=__FILE__, lineno=1) 47 | eval(ER2PR(src), binding, filename, lineno) 48 | 49 | # EndlessRubyの構文をピュアなRubyの構文に変換します。
50 | # options: オプションを表すHashまたはto_hashを実装したオブジェクト、構文を読み出すIOまたはto_ioを実装したオブジェクト、EndlessRubyの構文を表すStringまたはto_strを実装したオブジェクト、またはファイルのパス
51 | # optionsが文字列ならばそれをピュアなRubyの構文にします。それがIOならばIOから読み出してそれをピュアなRubyの構文にします。
52 | # ファイルのパスならばそのファイルかあ読み込みます 53 | # それがHashならばそれはオプションです。それぞれHashを指定します。
54 | # options: { 55 | # in: { 56 | # io: optionsにIOを指定した場合と同じです 57 | # any: それが存在するファイルのパスを表す文字列ならばそのファイルから読み出します。この場合のanyはoptionsにそのような文字列を指定するのと同じ意味です。 58 | # そうでない文字列ならばそれ自体をEndlessRubyの構文として読み出します。この場合のanyはoptionsに文字列を指定するのと同じ意味です。 59 | # それがIOならばそのIOから読み出します。この場合のany はin.ioを直接指定するのと同じです。 60 | # } 61 | # out: { 62 | # io: このIOに結果を書き出します。 63 | # any: ファイルのパスかIOです。ファイルのパスならばそのファイルに書き出します。IOならばそのIOに書き出します。 64 | # } 65 | # decompile: trueならばコンパイルではなくてでコンパイルします。 66 | # } 67 | # 68 | # opts[:out][:io] には書き出すioを指定します。
69 | # from a file on disk:
70 | # EndlessRuby.ER2RB("filename.er") 71 | #
72 | # from string that is source code:
73 | # EndlessRuby.ER2RB(< 77 | # from IO:
78 | # file = open 'filename.er' 79 | # EndlessRuby.ER2RB(file) 80 | # 81 | # appoint input file and output file: 82 | # ER2PR({ :in => { :any => 'filename.er' }, :out => { :any => 'filename.rb' } }) 83 | # ER2PR({ :in => { :io => in_io }, :out => { :io => out_io } }) 84 | def endless_ruby_to_pure_ruby options 85 | converting_helper options 86 | 87 | alias to_pure_ruby endless_ruby_to_pure_ruby 88 | alias ER2PR endless_ruby_to_pure_ruby 89 | alias ER2RB endless_ruby_to_pure_ruby 90 | 91 | # Rubyの構文をEndlessRubyの構文に変換します。optionsはendlessruby_to_pure_rubyと同じです。 92 | def pure_ruby_to_endless_ruby options 93 | options = merge_options options 94 | options[:decompile] = true 95 | converting_helper options 96 | 97 | alias RB2ER pure_ruby_to_endless_ruby 98 | alias PR2ER pure_ruby_to_endless_ruby 99 | 100 | private 101 | 102 | def merge_options options 103 | 104 | opts = { 105 | :in => {}, :out => {} 106 | } 107 | 108 | if options.respond_to? :to_hash 109 | opts = opts.merge options.to_hash 110 | elsif options.respond_to?(:to_io) || options.respond_to?(:to_str) 111 | opts[:in][:any] = options 112 | else 113 | raise ArgumentError, "options is IO, String, or Hash" 114 | 115 | if opts[:in][:any] 116 | if opts[:in][:any].respond_to?(:to_str) && File.exist?(opts[:in][:any].to_str) # from a file on the disk. 117 | opts[:in] = { 118 | :io => (in_io = open opts[:in][:any].to_str), 119 | :ensure => proc { in_io.close } 120 | } 121 | elsif opts[:in][:any].respond_to? :to_io # from IO that can read source code. 122 | opts[:in] = { 123 | :io => options.to_io, 124 | :ensure => proc {} 125 | } 126 | elsif opts[:in][:any].respond_to? :to_str # from String that is source code. 127 | in_io = Tempfile.new "endlessruby from temp file" 128 | in_io.write options.to_str 129 | in_io.seek 0 130 | opts[:in] = { 131 | :io => in_io, 132 | :ensure => proc { in_io.close } 133 | } 134 | else 135 | raise ArgumentError, "options[:in][:any] is IO, String which is path, or String which is source code" 136 | 137 | opts[:in][:any] = nil 138 | 139 | if opts[:out][:any] 140 | if opts[:out][:any].respond_to?(:to_str) # to a file on the disk. 141 | opts[:out] = { 142 | :io => (out_io = open opts[:out][:any].to_str, "w+"), 143 | :ensure => proc { out_io.close } 144 | } 145 | elsif opts[:out][:any].respond_to? :to_io # to IO that can read source code. 146 | opts[:out] = { 147 | :io => options.to_io, 148 | :ensure => proc {} 149 | } 150 | else 151 | raise ArgumentError, "options[:out][:any] is IO, or String which is Path" 152 | elsif !opts[:out][:io] 153 | opts[:out] = { :io => (out_io = Tempfile.new("endlessruby pure temp file")), :ensure => proc { out_io.close } } 154 | 155 | opts[:out][:any] = nil 156 | opts 157 | 158 | def converting_helper options 159 | opts = merge_options options 160 | 161 | io = opts[:in][:io] 162 | 163 | r = RubyLex.new 164 | r.set_input io 165 | r.skip_space = false 166 | 167 | pure = opts[:out][:io] 168 | 169 | indent = [] 170 | pass = [] 171 | bol = true 172 | last = [0, 0] 173 | bol_indent = 0 174 | 175 | while t = r.token 176 | 177 | if bol && !(RubyToken::TkSPACE === t) && !(RubyToken::TkNL === t) 178 | 179 | bol_indent = this_indent = t.char_no 180 | while (indent.last && pass.last) && ((this_indent < indent.last) || (this_indent <= indent.last && !pass.last.include?(t.class))) 181 | if RubyToken::TkEND === t && this_indent == indent.last 182 | break 183 | 184 | _indent = indent.pop 185 | pass.pop 186 | idt = [] 187 | loop do 188 | pure.seek pure.pos - 1 189 | if RUBY_VERSION < "1.9" # 1.8 190 | c = pure.read(1) 191 | else 192 | c = pure.getc 193 | break if pure.pos == 0 || !(["\n", ' '].include?(c)) 194 | pure.seek pure.pos - 1 195 | idt.unshift c 196 | if idt.first == "\n" 197 | pure.write idt.shift 198 | pure.write "#{' '*_indent}end\n" 199 | pure.write idt.join 200 | bol = false 201 | 202 | case t 203 | when RubyToken::TkNL 204 | bol = true 205 | when RubyToken::TkEND 206 | indent.pop 207 | pass.pop 208 | if opts[:decompile] 209 | last[0] += 3 210 | last[1] += 3 211 | next 212 | when RubyToken::TkIF, RubyToken::TkUNLESS 213 | pass << [RubyToken::TkELSE, RubyToken::TkELSIF] 214 | indent << t.char_no 215 | when RubyToken::TkFOR 216 | pass << [] 217 | indent << t.char_no 218 | when RubyToken::TkWHILE, RubyToken::TkUNTIL 219 | pass << [] 220 | indent << t.char_no 221 | when RubyToken::TkBEGIN 222 | pass << [RubyToken::TkRESCUE, RubyToken::TkELSE, RubyToken::TkENSURE] 223 | indent << t.char_no 224 | when RubyToken::TkDEF 225 | pass << [RubyToken::TkRESCUE, RubyToken::TkELSE, RubyToken::TkENSURE] 226 | indent << t.char_no 227 | when RubyToken::TkCLASS, RubyToken::TkMODULE 228 | pass << [] 229 | indent << t.char_no 230 | when RubyToken::TkCASE 231 | pass << [RubyToken::TkWHEN, RubyToken::TkELSE] 232 | indent << t.char_no 233 | when RubyToken::TkDO 234 | pass << [] 235 | indent << bol_indent 236 | when RubyToken::TkSPACE 237 | 238 | 239 | pos = io.pos 240 | io.seek pos 241 | 242 | pos = io.pos 243 | 244 | if RUBY_VERSION < "1.9" # 1.8 245 | io.seek t.seek 246 | pure.write io.read(r.seek - t.seek) 247 | else # 1.9 248 | io.seek last[0] 249 | (r.seek - last[1]).times do 250 | pure.write io.getc 251 | last = [io.pos, r.seek] 252 | 253 | io.seek pos 254 | 255 | until opts[:decompile] || (indent.empty? && pass.empty?) 256 | _indent = indent.pop 257 | pass.pop 258 | pure.seek pure.pos - 1 259 | if RUBY_VERSION < "1.9" # 1.8 260 | c = pure.read 1 261 | else 262 | c = pure.getc 263 | if c == "\n" 264 | pure.write "#{' '*_indent}end" 265 | else 266 | pure.write "\n#{' '*_indent}end" 267 | 268 | pure.seek 0 269 | ret = pure.read.chomp 270 | pure.seek 0 271 | 272 | opts[:out][:ensure] && opts[:out][:ensure].call 273 | opts[:in][:ensure] && opts[:in][:ensure].call 274 | 275 | ret 276 | 277 | if __FILE__ == $PROGRAM_NAME 278 | require 'endlessruby/main' 279 | EndlessRuby::Main.main ARGV 280 | -------------------------------------------------------------------------------- /lib/endlessruby.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | $:.unshift(File.dirname(__FILE__)) unless 5 | $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) 6 | 7 | require 'endlessruby/custom_require' 8 | require "tempfile" 9 | require "irb" 10 | 11 | # EndlessRubyはRubyをendを取り除いて書けます。 12 | # 13 | # erファイルをrequire 14 | # require 'homuhomu.er' | require 'homuhomu' 15 | # 16 | # erファイルを実行 17 | # $ path/to/endlessruby.rb homuhomu.er 18 | # 19 | # erファイルをコンパイル 20 | # $ path/to/endlessruby.rb -c src/homuhomu.er -o lib 21 | # # => src/homuhomu.er をコンパイルして lib/homuhomu.rb を書き出します。 22 | # # -o が省略された場合はカレントディレクトリに書き出します。 23 | # 24 | # Example: 25 | # class EndlessRubyWorld 26 | # 27 | # def self.hello! 28 | # puts "hello!" 29 | # 30 | # 31 | # [-2, -1, 0, 1, 2].reject do |x| 32 | # x < 0 33 | # end.each do |n| 34 | # puts n 35 | # 36 | module EndlessRuby 37 | 38 | # EndlessRuby のバージョンです 39 | VERSION = "0.1.0" 40 | 41 | extend self 42 | 43 | public 44 | 45 | # 文字列をEndlessRubyの構文として実行します。引数の意味はKernel#evalと同じです 46 | def ereval(src, binding=TOPLEVEL_BINDING, filename=__FILE__, lineno=1) 47 | eval(ER2PR(src), binding, filename, lineno) 48 | end 49 | 50 | # EndlessRubyの構文をピュアなRubyの構文に変換します。
51 | # options: オプションを表すHashまたはto_hashを実装したオブジェクト、構文を読み出すIOまたはto_ioを実装したオブジェクト、EndlessRubyの構文を表すStringまたはto_strを実装したオブジェクト、またはファイルのパス
52 | # optionsが文字列ならばそれをピュアなRubyの構文にします。それがIOならばIOから読み出してそれをピュアなRubyの構文にします。
53 | # ファイルのパスならばそのファイルかあ読み込みます 54 | # それがHashならばそれはオプションです。それぞれHashを指定します。
55 | # options: { 56 | # in: { 57 | # io: optionsにIOを指定した場合と同じです 58 | # any: それが存在するファイルのパスを表す文字列ならばそのファイルから読み出します。この場合のanyはoptionsにそのような文字列を指定するのと同じ意味です。 59 | # そうでない文字列ならばそれ自体をEndlessRubyの構文として読み出します。この場合のanyはoptionsに文字列を指定するのと同じ意味です。 60 | # それがIOならばそのIOから読み出します。この場合のany はin.ioを直接指定するのと同じです。 61 | # } 62 | # out: { 63 | # io: このIOに結果を書き出します。 64 | # any: ファイルのパスかIOです。ファイルのパスならばそのファイルに書き出します。IOならばそのIOに書き出します。 65 | # } 66 | # decompile: trueならばコンパイルではなくてでコンパイルします。 67 | # } 68 | # 69 | # opts[:out][:io] には書き出すioを指定します。
70 | # from a file on disk:
71 | # EndlessRuby.ER2RB("filename.er") 72 | #
73 | # from string that is source code:
74 | # EndlessRuby.ER2RB(< 78 | # from IO:
79 | # file = open 'filename.er' 80 | # EndlessRuby.ER2RB(file) 81 | # 82 | # appoint input file and output file: 83 | # ER2PR({ :in => { :any => 'filename.er' }, :out => { :any => 'filename.rb' } }) 84 | # ER2PR({ :in => { :io => in_io }, :out => { :io => out_io } }) 85 | def endless_ruby_to_pure_ruby options 86 | converting_helper options 87 | end 88 | 89 | alias to_pure_ruby endless_ruby_to_pure_ruby 90 | alias ER2PR endless_ruby_to_pure_ruby 91 | alias ER2RB endless_ruby_to_pure_ruby 92 | 93 | # Rubyの構文をEndlessRubyの構文に変換します。optionsはendlessruby_to_pure_rubyと同じです。 94 | def pure_ruby_to_endless_ruby options 95 | options = merge_options options 96 | options[:decompile] = true 97 | converting_helper options 98 | end 99 | 100 | alias RB2ER pure_ruby_to_endless_ruby 101 | alias PR2ER pure_ruby_to_endless_ruby 102 | 103 | private 104 | 105 | def merge_options options 106 | 107 | opts = { 108 | :in => {}, :out => {} 109 | } 110 | 111 | if options.respond_to? :to_hash 112 | opts = opts.merge options.to_hash 113 | elsif options.respond_to?(:to_io) || options.respond_to?(:to_str) 114 | opts[:in][:any] = options 115 | else 116 | raise ArgumentError, "options is IO, String, or Hash" 117 | end 118 | 119 | if opts[:in][:any] 120 | if opts[:in][:any].respond_to?(:to_str) && File.exist?(opts[:in][:any].to_str) # from a file on the disk. 121 | opts[:in] = { 122 | :io => (in_io = open opts[:in][:any].to_str), 123 | :ensure => proc { in_io.close } 124 | } 125 | elsif opts[:in][:any].respond_to? :to_io # from IO that can read source code. 126 | opts[:in] = { 127 | :io => options.to_io, 128 | :ensure => proc {} 129 | } 130 | elsif opts[:in][:any].respond_to? :to_str # from String that is source code. 131 | in_io = Tempfile.new "endlessruby from temp file" 132 | in_io.write options.to_str 133 | in_io.seek 0 134 | opts[:in] = { 135 | :io => in_io, 136 | :ensure => proc { in_io.close } 137 | } 138 | else 139 | raise ArgumentError, "options[:in][:any] is IO, String which is path, or String which is source code" 140 | end 141 | end 142 | 143 | opts[:in][:any] = nil 144 | 145 | if opts[:out][:any] 146 | if opts[:out][:any].respond_to?(:to_str) # to a file on the disk. 147 | opts[:out] = { 148 | :io => (out_io = open opts[:out][:any].to_str, "w+"), 149 | :ensure => proc { out_io.close } 150 | } 151 | elsif opts[:out][:any].respond_to? :to_io # to IO that can read source code. 152 | opts[:out] = { 153 | :io => options.to_io, 154 | :ensure => proc {} 155 | } 156 | else 157 | raise ArgumentError, "options[:out][:any] is IO, or String which is Path" 158 | end 159 | elsif !opts[:out][:io] 160 | opts[:out] = { :io => (out_io = Tempfile.new("endlessruby pure temp file")), :ensure => proc { out_io.close } } 161 | end 162 | 163 | opts[:out][:any] = nil 164 | opts 165 | end 166 | 167 | def converting_helper options 168 | opts = merge_options options 169 | 170 | io = opts[:in][:io] 171 | 172 | r = RubyLex.new 173 | r.set_input io 174 | r.skip_space = false 175 | 176 | pure = opts[:out][:io] 177 | 178 | indent = [] 179 | pass = [] 180 | bol = true 181 | last = [0, 0] 182 | bol_indent = 0 183 | 184 | while t = r.token 185 | 186 | if bol && !(RubyToken::TkSPACE === t) && !(RubyToken::TkNL === t) 187 | 188 | bol_indent = this_indent = t.char_no 189 | while (indent.last && pass.last) && ((this_indent < indent.last) || (this_indent <= indent.last && !pass.last.include?(t.class))) 190 | if RubyToken::TkEND === t && this_indent == indent.last 191 | break 192 | end 193 | 194 | _indent = indent.pop 195 | pass.pop 196 | idt = [] 197 | loop do 198 | pure.seek pure.pos - 1 199 | if RUBY_VERSION < "1.9" # 1.8 200 | c = pure.read(1) 201 | else 202 | c = pure.getc 203 | end 204 | break if pure.pos == 0 || !(["\n", ' '].include?(c)) 205 | pure.seek pure.pos - 1 206 | idt.unshift c 207 | end 208 | if idt.first == "\n" 209 | pure.write idt.shift 210 | end 211 | pure.write "#{' '*_indent}end\n" 212 | pure.write idt.join 213 | end 214 | bol = false 215 | end 216 | 217 | case t 218 | when RubyToken::TkNL 219 | bol = true 220 | when RubyToken::TkEND 221 | indent.pop 222 | pass.pop 223 | if opts[:decompile] 224 | last[0] += 3 225 | last[1] += 3 226 | next 227 | end 228 | when RubyToken::TkIF, RubyToken::TkUNLESS 229 | pass << [RubyToken::TkELSE, RubyToken::TkELSIF] 230 | indent << t.char_no 231 | when RubyToken::TkFOR 232 | pass << [] 233 | indent << t.char_no 234 | when RubyToken::TkWHILE, RubyToken::TkUNTIL 235 | pass << [] 236 | indent << t.char_no 237 | when RubyToken::TkBEGIN 238 | pass << [RubyToken::TkRESCUE, RubyToken::TkELSE, RubyToken::TkENSURE] 239 | indent << t.char_no 240 | when RubyToken::TkDEF 241 | pass << [RubyToken::TkRESCUE, RubyToken::TkELSE, RubyToken::TkENSURE] 242 | indent << t.char_no 243 | when RubyToken::TkCLASS, RubyToken::TkMODULE 244 | pass << [] 245 | indent << t.char_no 246 | when RubyToken::TkCASE 247 | pass << [RubyToken::TkWHEN, RubyToken::TkELSE] 248 | indent << t.char_no 249 | when RubyToken::TkDO 250 | pass << [] 251 | indent << bol_indent 252 | when RubyToken::TkSPACE 253 | end 254 | 255 | 256 | pos = io.pos 257 | io.seek pos 258 | 259 | pos = io.pos 260 | 261 | if RUBY_VERSION < "1.9" # 1.8 262 | io.seek t.seek 263 | pure.write io.read(r.seek - t.seek) 264 | else # 1.9 265 | io.seek last[0] 266 | (r.seek - last[1]).times do 267 | pure.write io.getc 268 | end 269 | last = [io.pos, r.seek] 270 | end 271 | 272 | io.seek pos 273 | end 274 | 275 | until opts[:decompile] || (indent.empty? && pass.empty?) 276 | _indent = indent.pop 277 | pass.pop 278 | pure.seek pure.pos - 1 279 | if RUBY_VERSION < "1.9" # 1.8 280 | c = pure.read 1 281 | else 282 | c = pure.getc 283 | end 284 | if c == "\n" 285 | pure.write "#{' '*_indent}end" 286 | else 287 | pure.write "\n#{' '*_indent}end" 288 | end 289 | end 290 | 291 | pure.seek 0 292 | ret = pure.read.chomp 293 | pure.seek 0 294 | 295 | opts[:out][:ensure] && opts[:out][:ensure].call 296 | opts[:in][:ensure] && opts[:in][:ensure].call 297 | 298 | ret 299 | end 300 | end 301 | 302 | if __FILE__ == $PROGRAM_NAME 303 | require 'endlessruby/main' 304 | EndlessRuby::Main.main ARGV 305 | end -------------------------------------------------------------------------------- /pkg/endlessruby-0.1.0/lib/endlessruby.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # -*- coding: utf-8 -*- 3 | 4 | $:.unshift(File.dirname(__FILE__)) unless 5 | $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) 6 | 7 | require 'endlessruby/custom_require' 8 | require "tempfile" 9 | require "irb" 10 | 11 | # EndlessRubyはRubyをendを取り除いて書けます。 12 | # 13 | # erファイルをrequire 14 | # require 'homuhomu.er' | require 'homuhomu' 15 | # 16 | # erファイルを実行 17 | # $ path/to/endlessruby.rb homuhomu.er 18 | # 19 | # erファイルをコンパイル 20 | # $ path/to/endlessruby.rb -c src/homuhomu.er -o lib 21 | # # => src/homuhomu.er をコンパイルして lib/homuhomu.rb を書き出します。 22 | # # -o が省略された場合はカレントディレクトリに書き出します。 23 | # 24 | # Example: 25 | # class EndlessRubyWorld 26 | # 27 | # def self.hello! 28 | # puts "hello!" 29 | # 30 | # 31 | # [-2, -1, 0, 1, 2].reject do |x| 32 | # x < 0 33 | # end.each do |n| 34 | # puts n 35 | # 36 | module EndlessRuby 37 | 38 | # EndlessRuby のバージョンです 39 | VERSION = "0.1.0" 40 | 41 | extend self 42 | 43 | public 44 | 45 | # 文字列をEndlessRubyの構文として実行します。引数の意味はKernel#evalと同じです 46 | def ereval(src, binding=TOPLEVEL_BINDING, filename=__FILE__, lineno=1) 47 | eval(ER2PR(src), binding, filename, lineno) 48 | end 49 | 50 | # EndlessRubyの構文をピュアなRubyの構文に変換します。
51 | # options: オプションを表すHashまたはto_hashを実装したオブジェクト、構文を読み出すIOまたはto_ioを実装したオブジェクト、EndlessRubyの構文を表すStringまたはto_strを実装したオブジェクト、またはファイルのパス
52 | # optionsが文字列ならばそれをピュアなRubyの構文にします。それがIOならばIOから読み出してそれをピュアなRubyの構文にします。
53 | # ファイルのパスならばそのファイルかあ読み込みます 54 | # それがHashならばそれはオプションです。それぞれHashを指定します。
55 | # options: { 56 | # in: { 57 | # io: optionsにIOを指定した場合と同じです 58 | # any: それが存在するファイルのパスを表す文字列ならばそのファイルから読み出します。この場合のanyはoptionsにそのような文字列を指定するのと同じ意味です。 59 | # そうでない文字列ならばそれ自体をEndlessRubyの構文として読み出します。この場合のanyはoptionsに文字列を指定するのと同じ意味です。 60 | # それがIOならばそのIOから読み出します。この場合のany はin.ioを直接指定するのと同じです。 61 | # } 62 | # out: { 63 | # io: このIOに結果を書き出します。 64 | # any: ファイルのパスかIOです。ファイルのパスならばそのファイルに書き出します。IOならばそのIOに書き出します。 65 | # } 66 | # decompile: trueならばコンパイルではなくてでコンパイルします。 67 | # } 68 | # 69 | # opts[:out][:io] には書き出すioを指定します。
70 | # from a file on disk:
71 | # EndlessRuby.ER2RB("filename.er") 72 | #
73 | # from string that is source code:
74 | # EndlessRuby.ER2RB(< 78 | # from IO:
79 | # file = open 'filename.er' 80 | # EndlessRuby.ER2RB(file) 81 | # 82 | # appoint input file and output file: 83 | # ER2PR({ :in => { :any => 'filename.er' }, :out => { :any => 'filename.rb' } }) 84 | # ER2PR({ :in => { :io => in_io }, :out => { :io => out_io } }) 85 | def endless_ruby_to_pure_ruby options 86 | converting_helper options 87 | end 88 | 89 | alias to_pure_ruby endless_ruby_to_pure_ruby 90 | alias ER2PR endless_ruby_to_pure_ruby 91 | alias ER2RB endless_ruby_to_pure_ruby 92 | 93 | # Rubyの構文をEndlessRubyの構文に変換します。optionsはendlessruby_to_pure_rubyと同じです。 94 | def pure_ruby_to_endless_ruby options 95 | options = merge_options options 96 | options[:decompile] = true 97 | converting_helper options 98 | end 99 | 100 | alias RB2ER pure_ruby_to_endless_ruby 101 | alias PR2ER pure_ruby_to_endless_ruby 102 | 103 | private 104 | 105 | def merge_options options 106 | 107 | opts = { 108 | :in => {}, :out => {} 109 | } 110 | 111 | if options.respond_to? :to_hash 112 | opts = opts.merge options.to_hash 113 | elsif options.respond_to?(:to_io) || options.respond_to?(:to_str) 114 | opts[:in][:any] = options 115 | else 116 | raise ArgumentError, "options is IO, String, or Hash" 117 | end 118 | 119 | if opts[:in][:any] 120 | if opts[:in][:any].respond_to?(:to_str) && File.exist?(opts[:in][:any].to_str) # from a file on the disk. 121 | opts[:in] = { 122 | :io => (in_io = open opts[:in][:any].to_str), 123 | :ensure => proc { in_io.close } 124 | } 125 | elsif opts[:in][:any].respond_to? :to_io # from IO that can read source code. 126 | opts[:in] = { 127 | :io => options.to_io, 128 | :ensure => proc {} 129 | } 130 | elsif opts[:in][:any].respond_to? :to_str # from String that is source code. 131 | in_io = Tempfile.new "endlessruby from temp file" 132 | in_io.write options.to_str 133 | in_io.seek 0 134 | opts[:in] = { 135 | :io => in_io, 136 | :ensure => proc { in_io.close } 137 | } 138 | else 139 | raise ArgumentError, "options[:in][:any] is IO, String which is path, or String which is source code" 140 | end 141 | end 142 | 143 | opts[:in][:any] = nil 144 | 145 | if opts[:out][:any] 146 | if opts[:out][:any].respond_to?(:to_str) # to a file on the disk. 147 | opts[:out] = { 148 | :io => (out_io = open opts[:out][:any].to_str, "w+"), 149 | :ensure => proc { out_io.close } 150 | } 151 | elsif opts[:out][:any].respond_to? :to_io # to IO that can read source code. 152 | opts[:out] = { 153 | :io => options.to_io, 154 | :ensure => proc {} 155 | } 156 | else 157 | raise ArgumentError, "options[:out][:any] is IO, or String which is Path" 158 | end 159 | elsif !opts[:out][:io] 160 | opts[:out] = { :io => (out_io = Tempfile.new("endlessruby pure temp file")), :ensure => proc { out_io.close } } 161 | end 162 | 163 | opts[:out][:any] = nil 164 | opts 165 | end 166 | 167 | def converting_helper options 168 | opts = merge_options options 169 | 170 | io = opts[:in][:io] 171 | 172 | r = RubyLex.new 173 | r.set_input io 174 | r.skip_space = false 175 | 176 | pure = opts[:out][:io] 177 | 178 | indent = [] 179 | pass = [] 180 | bol = true 181 | last = [0, 0] 182 | bol_indent = 0 183 | 184 | while t = r.token 185 | 186 | if bol && !(RubyToken::TkSPACE === t) && !(RubyToken::TkNL === t) 187 | 188 | bol_indent = this_indent = t.char_no 189 | while (indent.last && pass.last) && ((this_indent < indent.last) || (this_indent <= indent.last && !pass.last.include?(t.class))) 190 | if RubyToken::TkEND === t && this_indent == indent.last 191 | break 192 | end 193 | 194 | _indent = indent.pop 195 | pass.pop 196 | idt = [] 197 | loop do 198 | pure.seek pure.pos - 1 199 | if RUBY_VERSION < "1.9" # 1.8 200 | c = pure.read(1) 201 | else 202 | c = pure.getc 203 | end 204 | break if pure.pos == 0 || !(["\n", ' '].include?(c)) 205 | pure.seek pure.pos - 1 206 | idt.unshift c 207 | end 208 | if idt.first == "\n" 209 | pure.write idt.shift 210 | end 211 | pure.write "#{' '*_indent}end\n" 212 | pure.write idt.join 213 | end 214 | bol = false 215 | end 216 | 217 | case t 218 | when RubyToken::TkNL 219 | bol = true 220 | when RubyToken::TkEND 221 | indent.pop 222 | pass.pop 223 | if opts[:decompile] 224 | last[0] += 3 225 | last[1] += 3 226 | next 227 | end 228 | when RubyToken::TkIF, RubyToken::TkUNLESS 229 | pass << [RubyToken::TkELSE, RubyToken::TkELSIF] 230 | indent << t.char_no 231 | when RubyToken::TkFOR 232 | pass << [] 233 | indent << t.char_no 234 | when RubyToken::TkWHILE, RubyToken::TkUNTIL 235 | pass << [] 236 | indent << t.char_no 237 | when RubyToken::TkBEGIN 238 | pass << [RubyToken::TkRESCUE, RubyToken::TkELSE, RubyToken::TkENSURE] 239 | indent << t.char_no 240 | when RubyToken::TkDEF 241 | pass << [RubyToken::TkRESCUE, RubyToken::TkELSE, RubyToken::TkENSURE] 242 | indent << t.char_no 243 | when RubyToken::TkCLASS, RubyToken::TkMODULE 244 | pass << [] 245 | indent << t.char_no 246 | when RubyToken::TkCASE 247 | pass << [RubyToken::TkWHEN, RubyToken::TkELSE] 248 | indent << t.char_no 249 | when RubyToken::TkDO 250 | pass << [] 251 | indent << bol_indent 252 | when RubyToken::TkSPACE 253 | end 254 | 255 | 256 | pos = io.pos 257 | io.seek pos 258 | 259 | pos = io.pos 260 | 261 | if RUBY_VERSION < "1.9" # 1.8 262 | io.seek t.seek 263 | pure.write io.read(r.seek - t.seek) 264 | else # 1.9 265 | io.seek last[0] 266 | (r.seek - last[1]).times do 267 | pure.write io.getc 268 | end 269 | last = [io.pos, r.seek] 270 | end 271 | 272 | io.seek pos 273 | end 274 | 275 | until opts[:decompile] || (indent.empty? && pass.empty?) 276 | _indent = indent.pop 277 | pass.pop 278 | pure.seek pure.pos - 1 279 | if RUBY_VERSION < "1.9" # 1.8 280 | c = pure.read 1 281 | else 282 | c = pure.getc 283 | end 284 | if c == "\n" 285 | pure.write "#{' '*_indent}end" 286 | else 287 | pure.write "\n#{' '*_indent}end" 288 | end 289 | end 290 | 291 | pure.seek 0 292 | ret = pure.read.chomp 293 | pure.seek 0 294 | 295 | opts[:out][:ensure] && opts[:out][:ensure].call 296 | opts[:in][:ensure] && opts[:in][:ensure].call 297 | 298 | ret 299 | end 300 | end 301 | 302 | if __FILE__ == $PROGRAM_NAME 303 | require 'endlessruby/main' 304 | EndlessRuby::Main.main ARGV 305 | end -------------------------------------------------------------------------------- /spec/simply_spec.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/spec_helper.rb' 2 | 3 | describe "simply example case" do 4 | 5 | it "supplimented its source code with 'end'" do 6 | 7 | ER2RB(< e 532 | pass 533 | DEFINE 534 | < e 538 | pass 539 | end 540 | DEFINE 541 | end 542 | 543 | 544 | it "rescue LoadError and SyntaxError" do 545 | ER2RB(< e 532 | pass 533 | DEFINE 534 | < e 538 | pass 539 | end 540 | DEFINE 541 | end 542 | 543 | 544 | it "rescue LoadError and SyntaxError" do 545 | ER2RB(< e 532 | pass 533 | DEFINE 534 | < e 538 | pass 539 | end 540 | DEFINE 541 | end 542 | 543 | 544 | it "rescue LoadError and SyntaxError" do 545 | ER2RB(< 2 | 4 | 5 | 6 | 7 | 8 | Module: Kernel 9 | 10 | 11 | 12 | 14 | 16 | 18 | 20 | 21 | 22 | 23 | 24 |
25 |
26 |
27 |

28 | Home 29 | Classes 30 | Methods 31 |

32 |
33 |
34 | 35 |
36 |
37 |

In Files

38 |
39 | 45 |
46 |
47 | 48 | 49 |
50 | 51 |
52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |

Methods

63 | 70 |
71 | 72 | 73 | 74 | 75 |
76 | 77 |
78 | 79 | 80 | 81 |
82 |

Class Index 83 | [+]

86 |
87 |
88 | Quicksearch 89 | 91 |
92 |
93 | 94 | 103 | 104 |
105 | 106 | 107 |
108 |
109 | 110 |
111 |

Kernel

112 | 113 |
114 | 115 |
116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 |
126 |

Public Instance Methods

127 | 128 | 129 |
130 | 131 | 132 |
133 | 134 | endlessruby_original_require(path) 136 | click to toggle source 137 | 138 |
139 | 140 |
141 | 142 | 143 | 144 | 145 | 146 |
147 | 148 | 149 | 150 | 151 |
152 | Alias for: require 153 |
154 | 155 |
156 | 157 | 158 |
159 | 160 | 161 |
162 | 163 | require(path) 165 | click to toggle source 166 | 167 |
168 | 169 |
170 | 171 |

172 | EndlessRuby によって再定義された require です。 173 | たいていのこのrequireはオリジナルなrequireまたはrubygemsのrequireがSyntaxErrorによって失敗した場合のみ機能します。 174 | SytanxError 175 | によってrequireが失敗した場合、pathを探してpathまたはpath.erの名前のファイルをEndlessRubyの構文として評価します。 176 | pathが./または/で以外で始まる場合は$LOAD_PATHと$:をそれぞれ参照してpathを探します。 177 | もしpathがそれらで始まる場合はそれぞれ参照しません。(つまり通常のrequireの動作と同じです) 178 |

179 | 180 | 181 | 182 |
184 |
185 |     # File lib/endlessruby/custom_require.rb, line 15
186 | 15:   def require path
187 | 16:     endlessruby_original_require path
188 | 17:   rescue SyntaxError, LoadError
189 | 18: 
190 | 19:     load = lambda do |path, abspath|
191 | 20: 
192 | 21:       if !File.exist?(abspath) || File.directory?(abspath)
193 | 22:         if File.exist? "#{abspath}.er"
194 | 23:           abspath = "#{abspath}.er"
195 | 24:         else
196 | 25:           raise LoadError, "no such file to load -- #{path}"
197 | 26:         end
198 | 27:       end
199 | 28: 
200 | 29:       return false if $".include? abspath
201 | 30: 
202 | 31:       if File.directory? abspath
203 | 32:         raise LoadError, "Is a directory - #{path}"
204 | 33:       end
205 | 34: 
206 | 35:       open(abspath) do |file|
207 | 36:         EndlessRuby.ereval file.read, TOPLEVEL_BINDING, abspath
208 | 37:         $" << abspath
209 | 38:         return true
210 | 39:       end
211 | 40:     end
212 | 41: 
213 | 42:     case path
214 | 43:     when /^\~(.*?)$/
215 | 44:       load.call path, File.join(ENV['HOME'], $1)
216 | 45:     when /^\.\/.*?$/, /^\/.*?$/
217 | 46:       load.call path, path
218 | 47:     else
219 | 48:       is_that_dir = false
220 | 49:       $:.each do |load_path|
221 | 50:         abspath = File.join load_path, path
222 | 51:         begin
223 | 52:           return load.call path, abspath
224 | 53:         rescue SyntaxError => e
225 | 54:           $stderr.puts "*ENDLESSRUBY BUG*"
226 | 55:           raise e
227 | 56:         rescue LoadError => e
228 | 57:           raise e if load_path == $:.last
229 | 58:         end
230 | 59:       end
231 | 60:     end
232 | 61:   end
233 |
234 | 235 |
236 | 237 | 238 |
239 | Also aliased as: endlessruby_original_require 240 |
241 | 242 | 243 | 244 |
245 | 246 | 247 |
248 | 249 | 250 |
251 | 252 | 253 |
254 | 255 |

Disabled; run with --debug to generate this.

256 | 257 |
258 | 259 |
260 |

[Validate]

261 |

Generated with the Darkfish 262 | Rdoc Generator 1.1.6.

263 |
264 | 265 | 266 | 267 | 268 | --------------------------------------------------------------------------------