rewrite 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,76 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'parse_tree'
5
+ require 'sexp_processor'
6
+ require 'sexp'
7
+
8
+ module Rewrite
9
+
10
+ class VariableRewriter < SexpProcessor
11
+
12
+ attr_reader :replacement_sexp
13
+
14
+ def initialize symbol, replacement_sexp
15
+ @symbol, @replacement_sexp = symbol, replacement_sexp
16
+ super()
17
+ end
18
+
19
+ #missing: rewriting assignment. Hmmm.
20
+
21
+ def subprocess (something)
22
+ process(something) if something
23
+ end
24
+
25
+ def process_dvar(exp)
26
+ exp.shift
27
+ variable = exp.shift
28
+ if @symbol == variable
29
+ replacement_sexp # not a deep copy. problem? replace with a block call??
30
+ else
31
+ s(:dvar, variable)
32
+ end
33
+ end
34
+
35
+ def process_iter(exp) # don't handle subtrees where we redefine the variable, including lambda and proc
36
+ original = exp.to_a.dup
37
+ exp.shift
38
+ callee_expr = exp.shift # we process in our context
39
+ params_exp = exp.shift
40
+ block_body = exp.shift
41
+ params = if params_exp.nil?
42
+ []
43
+ elsif params_exp.first == :dasgn || params_exp.first == :dasgn_curr
44
+ [ params_exp[1] ]
45
+ elsif params_exp.first == :masgn
46
+ raise "Can't handle #{original.inspect}" unless params_exp[1].first == :array
47
+ params_exp[1][1..-1].map { |assignment| assignment[1] }
48
+ else
49
+ raise "Can't handle #{original.inspect}"
50
+ end
51
+ if params.include? @symbol
52
+ s(:iter, subprocess(callee_expr), params_exp, block_body) # we're DONE
53
+ else
54
+ s(:iter, subprocess(callee_expr), params_exp, subprocess(block_body)) # we're still in play
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ class RewriteVariablesAsThunkCalls
61
+
62
+ attr_reader :list_of_variables
63
+
64
+ def initialize(*list_of_variables)
65
+ @list_of_variables = list_of_variables
66
+ end
67
+
68
+ def process(sexp)
69
+ list_of_variables().inject(sexp) { |result, variable|
70
+ VariableRewriter.new(variable, s(:call, s(:dvar, variable), :call)).process(result)
71
+ }
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,9 @@
1
+ module Rewrite #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 2
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,49 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ require 'ruby2ruby'
5
+
6
+ module Rewrite
7
+
8
+ module With
9
+
10
+ def self.with(*sexp_processors, &body)
11
+ rewritten = sexp_processors.flatten.inject(body.to_sexp.last) { |sexp, sexp_processor_parameter|
12
+ if sexp_processor_parameter.respond_to?(:new) && sexp_processor_parameter.kind_of?(Class)
13
+ sexp_processor = sexp_processor_parameter.new
14
+ else
15
+ sexp_processor = sexp_processor_parameter
16
+ end
17
+ sexp_processor.process(sexp)
18
+ }
19
+ rewritten = eval(rewritten.to_s) # i don't know why i need this!!
20
+ ruby = Ruby2Ruby.new.process(rewritten)
21
+ eval(ruby, body.binding())
22
+ end
23
+
24
+ module ClassMethods
25
+
26
+ def with(*sexp_processors, &body)
27
+ Rewrite::With.with(sexp_processors, &body)
28
+ end
29
+
30
+ end
31
+
32
+ module InstanceMethods
33
+
34
+ def with(*sexp_processors, &body)
35
+ Rewrite::With.with(sexp_processors, &body)
36
+ end
37
+
38
+ end
39
+
40
+ def self.included(receiver)
41
+ receiver.extend ClassMethods
42
+ receiver.send :include, InstanceMethods
43
+ end
44
+
45
+ end
46
+
47
+ include With
48
+
49
+ end
data/lib/rewrite.rb ADDED
@@ -0,0 +1,60 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'rubygems'
5
+ require 'ruby2ruby'
6
+
7
+ Dir["#{File.dirname(__FILE__)}/rewrite/*.rb"].each do |element|
8
+ require element
9
+ end
10
+
11
+ module Rewrite
12
+
13
+ module ClassMethods
14
+
15
+ #--
16
+ # I really want to express this somehow as pattern {
17
+ # lambda { _ }
18
+ # }
19
+ # and have it extract _ automatically, and somehow also
20
+ # use the exact same pattern to compose a sexp, much as
21
+ # I used to have binary pattern expressions
22
+ def sexp_for &proc
23
+ sexp = proc.to_sexp
24
+ return if sexp.length != 3
25
+ return if sexp[0] != :proc
26
+ return unless sexp[1].nil?
27
+ sexp[2]
28
+ end
29
+
30
+ def arr_for &proc
31
+ sexp_for(&proc).to_a
32
+ end
33
+
34
+ end
35
+ extend ClassMethods
36
+
37
+ # Provide a symbol that is extremely unlikely to be used elsewhere.
38
+ #
39
+ # Rewriters use this when they need to name something. For example,
40
+ # Andand converts code like this:
41
+ #
42
+ # numbers.andand.inject(&:+)
43
+ #
44
+ # Into:
45
+ #
46
+ # lambda { |__1234567890__|
47
+ # if __1234567890__.nil?
48
+ # nil
49
+ # else
50
+ # __1234567890__.inject(&:+)
51
+ # end
52
+ # }.call(numbers)
53
+ #
54
+ # It uses Rewrite.gensym to generate __1234567890__.
55
+ #
56
+ def self.gensym
57
+ :"__#{Time.now.to_i}#{rand(100000)}__"
58
+ end
59
+
60
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/rewrite.rb'}"
9
+ puts "Loading rewrite gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.join(File.dirname(__FILE__), '..')
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.join(File.dirname(__FILE__), '..')
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
data/script/txt2html ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ GEM_NAME = 'rewrite' # what ppl will type to install your gem
4
+ RUBYFORGE_PROJECT = 'rewrite'
5
+
6
+ require 'rubygems'
7
+ begin
8
+ require 'newgem'
9
+ require 'rubyforge'
10
+ rescue LoadError
11
+ puts "\n\nGenerating the website requires the newgem RubyGem"
12
+ puts "Install: gem install newgem\n\n"
13
+ exit(1)
14
+ end
15
+ require 'redcloth'
16
+ require 'syntax/convertors/html'
17
+ require 'erb'
18
+ require File.dirname(__FILE__) + "/../lib/#{GEM_NAME}/version.rb"
19
+
20
+ version = Rewrite::VERSION::STRING
21
+ download = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
22
+
23
+ def rubyforge_project_id
24
+ RubyForge.new.autoconfig["group_ids"][RUBYFORGE_PROJECT]
25
+ end
26
+
27
+ class Fixnum
28
+ def ordinal
29
+ # teens
30
+ return 'th' if (10..19).include?(self % 100)
31
+ # others
32
+ case self % 10
33
+ when 1: return 'st'
34
+ when 2: return 'nd'
35
+ when 3: return 'rd'
36
+ else return 'th'
37
+ end
38
+ end
39
+ end
40
+
41
+ class Time
42
+ def pretty
43
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
44
+ end
45
+ end
46
+
47
+ def convert_syntax(syntax, source)
48
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
49
+ end
50
+
51
+ if ARGV.length >= 1
52
+ src, template = ARGV
53
+ template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
54
+ else
55
+ puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
56
+ exit!
57
+ end
58
+
59
+ template = ERB.new(File.open(template).read)
60
+
61
+ title = nil
62
+ body = nil
63
+ File.open(src) do |fsrc|
64
+ title_text = fsrc.readline
65
+ body_text_template = fsrc.read
66
+ body_text = ERB.new(body_text_template).result(binding)
67
+ syntax_items = []
68
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
69
+ ident = syntax_items.length
70
+ element, syntax, source = $1, $2, $3
71
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
72
+ "syntax-temp-#{ident}"
73
+ }
74
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
75
+ body = RedCloth.new(body_text).to_html
76
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
77
+ end
78
+ stat = File.stat(src)
79
+ created = stat.ctime
80
+ modified = stat.mtime
81
+
82
+ $stdout << template.result(binding)