diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-01-12 08:38:11 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-01-12 08:38:11 +0000 |
commit | 8a72c77c7920d129818b7b83bb4fa669cd7e3f7d (patch) | |
tree | e88e17811fdb1059cc3a63199c297582780c8497 /tool/ruby_vm/helpers | |
parent | 069e9ff52cbb01fe2c5821a9b6a8077ab59c26c7 (diff) |
tool/ruby_vm support for pre-2.1 BASERUBY
as requested by devs, support for BASERUBY prior to 2.1
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61786 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'tool/ruby_vm/helpers')
-rw-r--r-- | tool/ruby_vm/helpers/dumper.rb | 120 | ||||
-rw-r--r-- | tool/ruby_vm/helpers/scanner.rb | 21 |
2 files changed, 73 insertions, 68 deletions
diff --git a/tool/ruby_vm/helpers/dumper.rb b/tool/ruby_vm/helpers/dumper.rb index 8f14d90d1f..3ba7310f56 100644 --- a/tool/ruby_vm/helpers/dumper.rb +++ b/tool/ruby_vm/helpers/dumper.rb @@ -16,67 +16,69 @@ require_relative 'c_escape' class RubyVM::Dumper include RubyVM::CEscape + private + + def new_binding + # This `eval 'binding'` does not return the current binding + # but creates one on top of it. + return eval 'binding' + end + + def new_erb spec + path = Pathname.new __dir__ + path += '../views' + path += spec + src = path.read mode: 'rt:utf-8:utf-8' + rescue Errno::ENOENT + raise "don't know how to generate #{path}" + else + erb = ERB.new src, nil, '%-' + erb.filename = path.realpath.to_path + return erb + end - # I learned this handy "super-private" maneuver from @a_matsuda - # cf: https://github.com/rails/rails/pull/27363/files - using Module.new { - refine RubyVM::Dumper do - private - - def new_binding - # This `eval 'binding'` does not return the current binding - # but creates one on top of it. - return eval 'binding' - end - - def new_erb spec - path = Pathname.new __dir__ - path += '../views' - path += spec - src = path.read mode: 'rt:utf-8:utf-8' - rescue Errno::ENOENT - raise "don't know how to generate #{path}" - else - erb = ERB.new src, nil, '%-' - erb.filename = path.realpath.to_path - return erb - end - - def finderb spec - return @erb.fetch spec do |k| - erb = new_erb k - @erb[k] = erb - end - end - - def replace_pragma_line str, lineno - if str == "#pragma RubyVM reset source\n" then - return "#line #{lineno + 2} #{@file}\n" - else - return str - end - end - - public - - def do_render source, locals - erb = finderb source - bnd = @empty.dup - locals.each_pair do |k, v| - bnd.local_variable_set k, v - end - return erb.result bnd - end - - def replace_pragma str - return str \ - . each_line \ - . with_index \ - . map {|i, j| replace_pragma_line i, j } \ - . join - end + def finderb spec + return @erb.fetch spec do |k| + erb = new_erb k + @erb[k] = erb end - } + end + + def replace_pragma_line str, lineno + if str == "#pragma RubyVM reset source\n" then + return "#line #{lineno + 2} #{@file}\n" + else + return str + end + end + + def local_variable_set bnd, var, val + eval '__locals__ ||= {}', bnd + locals = eval '__locals__', bnd + locals[var] = val + eval "#{var} = __locals__[:#{var}]", bnd + test = eval "#{var}", bnd + raise unless test == val + end + + public + + def do_render source, locals + erb = finderb source + bnd = @empty.dup + locals.each_pair do |k, v| + local_variable_set bnd, k, v + end + return erb.result bnd + end + + def replace_pragma str + return str \ + . each_line \ + . with_index \ + . map {|i, j| replace_pragma_line i, j } \ + . join + end def initialize path @erb = {} diff --git a/tool/ruby_vm/helpers/scanner.rb b/tool/ruby_vm/helpers/scanner.rb index 3dce6ffdfe..5ae1363480 100644 --- a/tool/ruby_vm/helpers/scanner.rb +++ b/tool/ruby_vm/helpers/scanner.rb @@ -11,8 +11,10 @@ # details. require 'pathname' -require 'strscan' +# Poor man's StringScanner. +# Sadly https://bugs.ruby-lang.org/issues/8343 is not backported to 2.0. We +# have to do it by hand. class RubyVM::Scanner attr_reader :__FILE__ attr_reader :__LINE__ @@ -22,28 +24,29 @@ class RubyVM::Scanner src += path @__LINE__ = 1 @__FILE__ = src.realpath.to_path - str = src.read mode: 'rt:utf-8:utf-8' - @scanner = StringScanner.new str + @str = src.read mode: 'rt:utf-8:utf-8' + @pos = 0 end def eos? - @scanner.eos? + return @pos >= @str.length end def scan re ret = @__LINE__ - match = @scanner.scan re - return unless match - @__LINE__ += match.count "\n" + @last_match = @str.match re, @pos + return unless @last_match + @__LINE__ += @last_match.to_s.count "\n" + @pos = @last_match.end 0 return ret end def scan! re scan re or raise sprintf "parse error at %s:%d near:\n %s...", \ - @__FILE__, @__LINE__, @scanner.peek(32) + @__FILE__, @__LINE__, @str[pos, 32] end def [] key - return @scanner[key] + return @last_match[key] end end |