riml 0.3.4 → 0.3.5
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.
- data/bin/riml +27 -27
- data/lib/riml.rb +32 -13
- data/lib/riml/ast_rewriter.rb +67 -26
- data/lib/riml/compiler.rb +12 -14
- data/lib/riml/file_rollback.rb +75 -0
- data/lib/riml/get_sid_function.vim +5 -1
- data/lib/riml/grammar.y +13 -1
- data/lib/riml/lexer.rb +11 -5
- data/lib/riml/nodes.rb +15 -41
- data/lib/riml/parser.rb +13 -1
- data/lib/riml/path_cache.rb +2 -2
- data/lib/riml/rewritten_ast_cache.rb +2 -2
- data/lib/riml/walker.rb +9 -2
- data/version.rb +2 -2
- metadata +4 -3
    
        data/bin/riml
    CHANGED
    
    | @@ -8,21 +8,20 @@ module Riml | |
| 8 8 | 
             
              require 'riml'
         | 
| 9 9 |  | 
| 10 10 | 
             
              require 'optparse'
         | 
| 11 | 
            -
              require 'ostruct'
         | 
| 12 11 |  | 
| 13 12 | 
             
              class Options
         | 
| 14 13 | 
             
                def self.parse(argv)
         | 
| 15 14 | 
             
                  argv << '--help' if argv.size.zero?
         | 
| 16 15 |  | 
| 17 16 | 
             
                  # defaults
         | 
| 18 | 
            -
                  options =  | 
| 19 | 
            -
                  options | 
| 20 | 
            -
                  options | 
| 21 | 
            -
                  options | 
| 22 | 
            -
                  options | 
| 23 | 
            -
                  options | 
| 24 | 
            -
                  options | 
| 25 | 
            -
                  options | 
| 17 | 
            +
                  options = {}
         | 
| 18 | 
            +
                  options[:compile_files] = []
         | 
| 19 | 
            +
                  options[:check_syntax_files] = []
         | 
| 20 | 
            +
                  options[:repl] = false
         | 
| 21 | 
            +
                  options[:vi_readline] = false
         | 
| 22 | 
            +
                  options[:allow_undefined_global_classes] = DEFAULT_PARSE_OPTIONS[:allow_undefined_global_classes]
         | 
| 23 | 
            +
                  options[:readable] = DEFAULT_COMPILE_OPTIONS[:readable]
         | 
| 24 | 
            +
                  options[:output_dir] = DEFAULT_COMPILE_FILES_OPTIONS[:output_dir]
         | 
| 26 25 |  | 
| 27 26 | 
             
                  OptionParser.new do |opts|
         | 
| 28 27 | 
             
                    opts.banner = "Usage: riml [options] [file1][,file2]..."
         | 
| @@ -30,15 +29,15 @@ module Riml | |
| 30 29 | 
             
                    opts.separator "Specific options:"
         | 
| 31 30 |  | 
| 32 31 | 
             
                    opts.on("-c", "--compile FILES", Array, "Compiles riml file(s) to VimL.") do |filenames|
         | 
| 33 | 
            -
                      append_filenames_to_list_if_valid(options | 
| 32 | 
            +
                      append_filenames_to_list_if_valid(options[:compile_files], *filenames)
         | 
| 34 33 | 
             
                    end
         | 
| 35 34 |  | 
| 36 35 | 
             
                    opts.on("-s", "--stdio", "Takes riml from stdin and outputs VimL to stdout.") do
         | 
| 37 | 
            -
                      options | 
| 36 | 
            +
                      options[:stdio] = true
         | 
| 38 37 | 
             
                    end
         | 
| 39 38 |  | 
| 40 39 | 
             
                    opts.on("-k", "--check FILES", Array, "Checks syntax of file(s). Because Riml is (mostly) compatible with VimL, this can also be used to check VimL syntax.") do |filenames|
         | 
| 41 | 
            -
                      append_filenames_to_list_if_valid(options | 
| 40 | 
            +
                      append_filenames_to_list_if_valid(options[:check_syntax_files], *filenames)
         | 
| 42 41 | 
             
                    end
         | 
| 43 42 |  | 
| 44 43 | 
             
                    opts.on("-S", "--source-path PATH", "Colon-separated path riml uses to find files for `riml_source`. Defaults to pwd.") do |path|
         | 
| @@ -58,23 +57,23 @@ module Riml | |
| 58 57 | 
             
                    end
         | 
| 59 58 |  | 
| 60 59 | 
             
                    opts.on("-a", "--allow-undef-global-classes", "Continue compilation when encountering undefined global class(es).") do
         | 
| 61 | 
            -
                      options | 
| 60 | 
            +
                      options[:allow_undefined_global_classes] = true
         | 
| 62 61 | 
             
                    end
         | 
| 63 62 |  | 
| 64 63 | 
             
                    opts.on("-o", "--output-dir DIR", "Output all .vim files in specified directory.") do |dir|
         | 
| 65 | 
            -
                      options | 
| 64 | 
            +
                      options[:output_dir] = dir
         | 
| 66 65 | 
             
                    end
         | 
| 67 66 |  | 
| 68 67 | 
             
                    opts.on("-d", "--condensed", "Omit readability improvements such as blank lines.") do
         | 
| 69 | 
            -
                      options | 
| 68 | 
            +
                      options[:readable] = false
         | 
| 70 69 | 
             
                    end
         | 
| 71 70 |  | 
| 72 71 | 
             
                    opts.on("-i", "--interactive", "Start an interactive riml session (REPL).") do
         | 
| 73 | 
            -
                      options | 
| 72 | 
            +
                      options[:repl] = true
         | 
| 74 73 | 
             
                    end
         | 
| 75 74 |  | 
| 76 75 | 
             
                    opts.on("--vi", "Use vi readline settings during interactive session.") do
         | 
| 77 | 
            -
                      options | 
| 76 | 
            +
                      options[:vi_readline] = options[:repl] =  true
         | 
| 78 77 | 
             
                    end
         | 
| 79 78 |  | 
| 80 79 | 
             
                    opts.on_tail("-v", "--version", "Show riml version.") do
         | 
| @@ -113,25 +112,26 @@ module Riml | |
| 113 112 | 
             
                  def start
         | 
| 114 113 | 
             
                    options = Options.parse(ARGV)
         | 
| 115 114 | 
             
                    compile_options = {
         | 
| 116 | 
            -
                      :readable => options | 
| 117 | 
            -
                      :allow_undefined_global_classes => options | 
| 115 | 
            +
                      :readable => options[:readable],
         | 
| 116 | 
            +
                      :allow_undefined_global_classes => options[:allow_undefined_global_classes]
         | 
| 118 117 | 
             
                    }
         | 
| 119 118 | 
             
                    compile_files_options = compile_options.merge(
         | 
| 120 | 
            -
                      :output_dir => options | 
| 119 | 
            +
                      :output_dir => options[:output_dir]
         | 
| 121 120 | 
             
                    )
         | 
| 122 | 
            -
                    if options | 
| 121 | 
            +
                    if options[:stdio]
         | 
| 123 122 | 
             
                      puts Riml.compile($stdin.read, compile_options)
         | 
| 124 | 
            -
                    elsif options | 
| 125 | 
            -
                       | 
| 126 | 
            -
             | 
| 127 | 
            -
             | 
| 123 | 
            +
                    elsif options[:compile_files].any?
         | 
| 124 | 
            +
                      FileRollback.trap(:INT, :QUIT, :KILL) { print("\n"); exit 1 }
         | 
| 125 | 
            +
                      Riml.compile_files(*options[:compile_files], compile_files_options)
         | 
| 126 | 
            +
                    elsif options[:check_syntax_files].any?
         | 
| 127 | 
            +
                      files = options[:check_syntax_files].uniq
         | 
| 128 128 | 
             
                      Riml.check_syntax_files(*files)
         | 
| 129 129 | 
             
                      size = files.size
         | 
| 130 130 | 
             
                      # "ok (1 file)" OR "ok (2 files)"
         | 
| 131 131 | 
             
                      puts "ok (#{size} file#{'s' if size > 1})"
         | 
| 132 | 
            -
                    elsif options | 
| 132 | 
            +
                    elsif options[:repl]
         | 
| 133 133 | 
             
                      require 'riml/repl'
         | 
| 134 | 
            -
                      Riml::Repl.new(options | 
| 134 | 
            +
                      Riml::Repl.new(options[:vi_readline], compile_options).run
         | 
| 135 135 | 
             
                    else
         | 
| 136 136 | 
             
                      ARGV.replace ['--help']
         | 
| 137 137 | 
             
                      start
         | 
    
        data/lib/riml.rb
    CHANGED
    
    | @@ -10,6 +10,7 @@ require 'riml/warning_buffer' | |
| 10 10 | 
             
            require 'riml/include_cache'
         | 
| 11 11 | 
             
            require 'riml/path_cache'
         | 
| 12 12 | 
             
            require 'riml/rewritten_ast_cache'
         | 
| 13 | 
            +
            require 'riml/file_rollback'
         | 
| 13 14 |  | 
| 14 15 | 
             
            module Riml
         | 
| 15 16 |  | 
| @@ -106,26 +107,28 @@ module Riml | |
| 106 107 | 
             
                # compile files using one thread per file, max 4 threads at once
         | 
| 107 108 | 
             
                if filenames.size > 1
         | 
| 108 109 | 
             
                  threads = []
         | 
| 109 | 
            -
                   | 
| 110 | 
            -
                     | 
| 111 | 
            -
             | 
| 112 | 
            -
                       | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
             | 
| 116 | 
            -
                         | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 110 | 
            +
                  with_file_rollback do
         | 
| 111 | 
            +
                    while filenames.any?
         | 
| 112 | 
            +
                      to_compile = filenames.shift(4)
         | 
| 113 | 
            +
                      to_compile.each do |fname|
         | 
| 114 | 
            +
                        _parser, _compiler = Parser.new, Compiler.new
         | 
| 115 | 
            +
                        _compiler.options = compiler.options.dup
         | 
| 116 | 
            +
                        _parser.options = parser.options.dup
         | 
| 117 | 
            +
                        threads << Thread.new do
         | 
| 118 | 
            +
                          f = File.open(fname)
         | 
| 119 | 
            +
                          # `do_compile` will close file handle
         | 
| 120 | 
            +
                          do_compile(f, _parser, _compiler)
         | 
| 121 | 
            +
                        end
         | 
| 119 122 | 
             
                      end
         | 
| 123 | 
            +
                      threads.each(&:join)
         | 
| 124 | 
            +
                      threads.clear
         | 
| 120 125 | 
             
                    end
         | 
| 121 | 
            -
                    threads.each(&:join)
         | 
| 122 | 
            -
                    threads.clear
         | 
| 123 126 | 
             
                  end
         | 
| 124 127 | 
             
                elsif filenames.size == 1
         | 
| 125 128 | 
             
                  fname = filenames.first
         | 
| 126 129 | 
             
                  f = File.open(fname)
         | 
| 127 130 | 
             
                  # `do_compile` will close file handle
         | 
| 128 | 
            -
                  do_compile(f, parser, compiler)
         | 
| 131 | 
            +
                  with_file_rollback { do_compile(f, parser, compiler) }
         | 
| 129 132 | 
             
                else
         | 
| 130 133 | 
             
                  raise ArgumentError, "need filenames to compile"
         | 
| 131 134 | 
             
                end
         | 
| @@ -184,6 +187,21 @@ module Riml | |
| 184 187 | 
             
              end
         | 
| 185 188 | 
             
              @rewritten_ast_cache = RewrittenASTCache.new
         | 
| 186 189 |  | 
| 190 | 
            +
              def self.clear_caches
         | 
| 191 | 
            +
                @include_cache.clear
         | 
| 192 | 
            +
                @path_cache.clear
         | 
| 193 | 
            +
                @rewritten_ast_cache.clear
         | 
| 194 | 
            +
              end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
              # if error is thrown, all files that were created will be rolled back
         | 
| 197 | 
            +
              # to their previous state. If the file existed previously, it will be
         | 
| 198 | 
            +
              # the same as it was. If the file didn't exist, it will be removed if
         | 
| 199 | 
            +
              # it was created.
         | 
| 200 | 
            +
              def self.with_file_rollback(&block)
         | 
| 201 | 
            +
                FileRollback.guard(&block)
         | 
| 202 | 
            +
              end
         | 
| 203 | 
            +
             | 
| 204 | 
            +
              # turn warnings on/off
         | 
| 187 205 | 
             
              class << self
         | 
| 188 206 | 
             
                attr_accessor :warnings
         | 
| 189 207 | 
             
              end
         | 
| @@ -276,6 +294,7 @@ module Riml | |
| 276 294 | 
             
                if output[-2..-1] == "\n\n"
         | 
| 277 295 | 
             
                  output.chomp!
         | 
| 278 296 | 
             
                end
         | 
| 297 | 
            +
                FileRollback.creating_file(full_path)
         | 
| 279 298 | 
             
                File.open(full_path, 'w') do |f|
         | 
| 280 299 | 
             
                  f.write FILE_HEADER + output
         | 
| 281 300 | 
             
                end
         | 
    
        data/lib/riml/ast_rewriter.rb
    CHANGED
    
    | @@ -28,7 +28,7 @@ module Riml | |
| 28 28 | 
             
                def rewrite(filename = nil, included = false)
         | 
| 29 29 | 
             
                  if filename && (rewritten_ast = Riml.rewritten_ast_cache[filename])
         | 
| 30 30 | 
             
                    rewrite_included_and_sourced_files!(filename)
         | 
| 31 | 
            -
                    rewritten_ast
         | 
| 31 | 
            +
                    return rewritten_ast
         | 
| 32 32 | 
             
                  end
         | 
| 33 33 | 
             
                  if @options && @options[:allow_undefined_global_classes] && !@classes.has_global_import?
         | 
| 34 34 | 
             
                    @classes.globbed_imports.unshift(ImportedClass.new('*'))
         | 
| @@ -70,7 +70,7 @@ module Riml | |
| 70 70 | 
             
                end
         | 
| 71 71 |  | 
| 72 72 | 
             
                def rewrite_on_match(node = ast)
         | 
| 73 | 
            -
                  Walker.walk_node(node, method(:do_rewrite_on_match),  | 
| 73 | 
            +
                  Walker.walk_node(node, method(:do_rewrite_on_match), max_recursion_lvl)
         | 
| 74 74 | 
             
                end
         | 
| 75 75 |  | 
| 76 76 | 
             
                def do_rewrite_on_match(node)
         | 
| @@ -85,8 +85,7 @@ module Riml | |
| 85 85 | 
             
                # node in order to compile it on the spot.
         | 
| 86 86 | 
             
                def rewrite_included_and_sourced_files!(filename)
         | 
| 87 87 | 
             
                  old_ast = ast
         | 
| 88 | 
            -
                  ast.children.each do |node|
         | 
| 89 | 
            -
                    next unless RimlFileCommandNode === node
         | 
| 88 | 
            +
                  ast.children.grep(RimlFileCommandNode).each do |node|
         | 
| 90 89 | 
             
                    action = node.name == 'riml_include' ? 'include' : 'source'
         | 
| 91 90 |  | 
| 92 91 | 
             
                    node.each_existing_file! do |file, fullpath|
         | 
| @@ -117,21 +116,20 @@ module Riml | |
| 117 116 | 
             
                end
         | 
| 118 117 |  | 
| 119 118 | 
             
                def watch_for_class_pickup
         | 
| 120 | 
            -
                  before_class_names = classes.class_names
         | 
| 119 | 
            +
                  before_class_names = @classes.class_names
         | 
| 121 120 | 
             
                  ast = yield
         | 
| 122 | 
            -
                  after_class_names = classes.class_names
         | 
| 121 | 
            +
                  after_class_names = @classes.class_names
         | 
| 123 122 | 
             
                  diff_class_names = after_class_names - before_class_names
         | 
| 124 123 | 
             
                  class_diff = diff_class_names.inject({}) do |hash, class_name|
         | 
| 125 | 
            -
                    hash[class_name] = classes[class_name]
         | 
| 124 | 
            +
                    hash[class_name] = @classes[class_name]
         | 
| 126 125 | 
             
                    hash
         | 
| 127 126 | 
             
                  end
         | 
| 128 127 | 
             
                  # no classes were picked up, it could be that the cache was hit. Let's
         | 
| 129 128 | 
             
                  # register the cached classes for this ast, if there are any
         | 
| 130 129 | 
             
                  if class_diff.empty?
         | 
| 131 130 | 
             
                    real_diff = Riml.rewritten_ast_cache.fetch_classes_registered(ast)
         | 
| 132 | 
            -
                    return if real_diff.empty?
         | 
| 133 131 | 
             
                    real_diff.each do |k,v|
         | 
| 134 | 
            -
                      classes[k] = v unless classes.safe_fetch(k)
         | 
| 132 | 
            +
                      @classes[k] = v unless @classes.safe_fetch(k)
         | 
| 135 133 | 
             
                    end
         | 
| 136 134 | 
             
                  # new classes were picked up, let's save them with this ast as the key
         | 
| 137 135 | 
             
                  else
         | 
| @@ -139,8 +137,9 @@ module Riml | |
| 139 137 | 
             
                  end
         | 
| 140 138 | 
             
                end
         | 
| 141 139 |  | 
| 142 | 
            -
                 | 
| 143 | 
            -
             | 
| 140 | 
            +
                # recurse until no more children
         | 
| 141 | 
            +
                def max_recursion_lvl
         | 
| 142 | 
            +
                  -1
         | 
| 144 143 | 
             
                end
         | 
| 145 144 |  | 
| 146 145 | 
             
                # Add SID function if this is the main file and it has defined classes, or
         | 
| @@ -166,11 +165,21 @@ module Riml | |
| 166 165 | 
             
                  fchild = ast.nodes.first
         | 
| 167 166 | 
             
                  return false if DefNode === fchild && fchild.name == 'SID' && fchild.scope_modifier == 's:'
         | 
| 168 167 | 
             
                  fn = DefNode.new('!', nil, 's:', 'SID', [], nil, Nodes.new([
         | 
| 169 | 
            -
                       | 
| 168 | 
            +
                      IfNode.new(
         | 
| 169 | 
            +
                        CallNode.new(nil, 'exists', [StringNode.new('s:SID_VALUE', :s)]),
         | 
| 170 | 
            +
                        Nodes.new([
         | 
| 171 | 
            +
                          ReturnNode.new(GetVariableNode.new('s:', 'SID_VALUE'))
         | 
| 172 | 
            +
                        ])
         | 
| 173 | 
            +
                      ),
         | 
| 174 | 
            +
                      AssignNode.new(
         | 
| 175 | 
            +
                        '=',
         | 
| 176 | 
            +
                        GetVariableNode.new('s:', 'SID_VALUE'),
         | 
| 177 | 
            +
                        CallNode.new(nil, 'matchstr', [
         | 
| 170 178 | 
             
                        CallNode.new(nil, 'expand', [StringNode.new('<sfile>', :s)]),
         | 
| 171 179 | 
             
                        StringNode.new('<SNR>\zs\d\+\ze_SID$', :s)
         | 
| 172 180 | 
             
                      ]
         | 
| 173 | 
            -
                      ))
         | 
| 181 | 
            +
                      )),
         | 
| 182 | 
            +
                      ReturnNode.new(GetVariableNode.new('s:', 'SID_VALUE'))
         | 
| 174 183 | 
             
                    ])
         | 
| 175 184 | 
             
                  )
         | 
| 176 185 | 
             
                  fn.parent = ast.nodes
         | 
| @@ -196,6 +205,10 @@ module Riml | |
| 196 205 | 
             
                    end
         | 
| 197 206 | 
             
                    node.remove
         | 
| 198 207 | 
             
                  end
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                  def max_recursion_lvl
         | 
| 210 | 
            +
                    1
         | 
| 211 | 
            +
                  end
         | 
| 199 212 | 
             
                end
         | 
| 200 213 |  | 
| 201 214 | 
             
                class RegisterDefinedClasses < AST_Rewriter
         | 
| @@ -208,6 +221,10 @@ module Riml | |
| 208 221 | 
             
                    n.instance_variable_set("@registered_state", true)
         | 
| 209 222 | 
             
                    classes[node.full_name] = n
         | 
| 210 223 | 
             
                  end
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                  def max_recursion_lvl
         | 
| 226 | 
            +
                    1
         | 
| 227 | 
            +
                  end
         | 
| 211 228 | 
             
                end
         | 
| 212 229 |  | 
| 213 230 | 
             
                class StrictEqualsComparisonOperator < AST_Rewriter
         | 
| @@ -257,8 +274,8 @@ module Riml | |
| 257 274 | 
             
                  def replace(node)
         | 
| 258 275 | 
             
                    classes[node.full_name] = node
         | 
| 259 276 |  | 
| 260 | 
            -
                    RegisterPrivateFunctions.new(node, classes).rewrite_on_match
         | 
| 261 | 
            -
                    DefNodeToPrivateFunction.new(node, classes).rewrite_on_match
         | 
| 277 | 
            +
                    RegisterPrivateFunctions.new(node.expressions, classes).rewrite_on_match
         | 
| 278 | 
            +
                    DefNodeToPrivateFunction.new(node.expressions, classes).rewrite_on_match
         | 
| 262 279 | 
             
                    InsertInitializeMethod.new(node, classes).rewrite_on_match
         | 
| 263 280 | 
             
                    constructor = node.constructor
         | 
| 264 281 | 
             
                    constructor.name = node.constructor_name
         | 
| @@ -266,7 +283,7 @@ module Riml | |
| 266 283 | 
             
                    constructor.scope_modifier = node.scope_modifier
         | 
| 267 284 | 
             
                    # set up dictionary variable at top of function
         | 
| 268 285 | 
             
                    dict_name = node.constructor_obj_name
         | 
| 269 | 
            -
                    constructor.expressions.unshift(
         | 
| 286 | 
            +
                    constructor.expressions.nodes.unshift(
         | 
| 270 287 | 
             
                      AssignNode.new('=', GetVariableNode.new(nil, dict_name), DictionaryNode.new({}))
         | 
| 271 288 | 
             
                    )
         | 
| 272 289 |  | 
| @@ -277,19 +294,27 @@ module Riml | |
| 277 294 | 
             
                    PrivateFunctionCallToPassObjExplicitly.new(node, classes).rewrite_on_match
         | 
| 278 295 | 
             
                    SplatsToExecuteInCallingContext.new(node, classes).rewrite_on_match
         | 
| 279 296 |  | 
| 280 | 
            -
                    constructor.expressions.push(
         | 
| 297 | 
            +
                    constructor.expressions.nodes.push(
         | 
| 281 298 | 
             
                      ReturnNode.new(GetVariableNode.new(nil, dict_name))
         | 
| 282 299 | 
             
                    )
         | 
| 283 300 | 
             
                    reestablish_parents(constructor)
         | 
| 284 301 | 
             
                  end
         | 
| 285 302 |  | 
| 303 | 
            +
                  def max_recursion_lvl
         | 
| 304 | 
            +
                    1
         | 
| 305 | 
            +
                  end
         | 
| 306 | 
            +
             | 
| 286 307 | 
             
                  class RegisterPrivateFunctions < AST_Rewriter
         | 
| 287 308 | 
             
                    def match?(node)
         | 
| 288 309 | 
             
                      node.instance_of?(DefNode) && node.name != 'initialize'
         | 
| 289 310 | 
             
                    end
         | 
| 290 311 |  | 
| 291 312 | 
             
                    def replace(node)
         | 
| 292 | 
            -
                      ast.private_function_names << node.name
         | 
| 313 | 
            +
                      ast.parent.private_function_names << node.name
         | 
| 314 | 
            +
                    end
         | 
| 315 | 
            +
             | 
| 316 | 
            +
                    def max_recursion_lvl
         | 
| 317 | 
            +
                      1
         | 
| 293 318 | 
             
                    end
         | 
| 294 319 | 
             
                  end
         | 
| 295 320 |  | 
| @@ -468,7 +493,7 @@ module Riml | |
| 468 493 | 
             
                    end
         | 
| 469 494 |  | 
| 470 495 | 
             
                    def replace(node)
         | 
| 471 | 
            -
                      class_node = ast
         | 
| 496 | 
            +
                      class_node = ast.parent
         | 
| 472 497 | 
             
                      class_name = class_node.name
         | 
| 473 498 | 
             
                      node.scope_modifier = 's:'
         | 
| 474 499 | 
             
                      node.original_name = node.name
         | 
| @@ -481,6 +506,10 @@ module Riml | |
| 481 506 | 
             
                      self_to_obj_argument.rewrite_on_match
         | 
| 482 507 | 
             
                      reestablish_parents(node)
         | 
| 483 508 | 
             
                    end
         | 
| 509 | 
            +
             | 
| 510 | 
            +
                    def max_recursion_lvl
         | 
| 511 | 
            +
                      1
         | 
| 512 | 
            +
                    end
         | 
| 484 513 | 
             
                  end
         | 
| 485 514 |  | 
| 486 515 | 
             
                  class PrivateFunctionCallToPassObjExplicitly < AST_Rewriter
         | 
| @@ -517,7 +546,7 @@ module Riml | |
| 517 546 | 
             
                    def replace(node)
         | 
| 518 547 | 
             
                      def_node = node.to_def_node
         | 
| 519 548 | 
             
                      class_expressions = ast.expressions
         | 
| 520 | 
            -
                      class_expressions.insert_after(class_expressions.last, def_node)
         | 
| 549 | 
            +
                      class_expressions.insert_after(class_expressions.nodes.last, def_node)
         | 
| 521 550 | 
             
                      def_node.parent = class_expressions
         | 
| 522 551 | 
             
                      # to remove it
         | 
| 523 552 | 
             
                      node.parent = class_expressions
         | 
| @@ -559,6 +588,10 @@ module Riml | |
| 559 588 | 
             
                      constructor.expressions << extension
         | 
| 560 589 | 
             
                      extension.parent = constructor.expressions
         | 
| 561 590 | 
             
                    end
         | 
| 591 | 
            +
             | 
| 592 | 
            +
                    def max_recursion_lvl
         | 
| 593 | 
            +
                      2
         | 
| 594 | 
            +
                    end
         | 
| 562 595 | 
             
                  end
         | 
| 563 596 |  | 
| 564 597 | 
             
                  class SelfToDictName < AST_Rewriter
         | 
| @@ -599,7 +632,7 @@ module Riml | |
| 599 632 | 
             
                          '!', nil, nil, "initialize", [], nil, Nodes.new([])
         | 
| 600 633 | 
             
                        )
         | 
| 601 634 | 
             
                      end
         | 
| 602 | 
            -
                      class_node.expressions.unshift(def_node)
         | 
| 635 | 
            +
                      class_node.expressions.nodes.unshift(def_node)
         | 
| 603 636 | 
             
                      reestablish_parents(class_node)
         | 
| 604 637 | 
             
                    end
         | 
| 605 638 |  | 
| @@ -611,8 +644,8 @@ module Riml | |
| 611 644 | 
             
                      classes.superclass(ast.full_name).imported?
         | 
| 612 645 | 
             
                    end
         | 
| 613 646 |  | 
| 614 | 
            -
                    def  | 
| 615 | 
            -
                       | 
| 647 | 
            +
                    def max_recursion_lvl
         | 
| 648 | 
            +
                      1
         | 
| 616 649 | 
             
                    end
         | 
| 617 650 | 
             
                  end
         | 
| 618 651 |  | 
| @@ -668,8 +701,8 @@ module Riml | |
| 668 701 | 
             
                      end
         | 
| 669 702 | 
             
                    end
         | 
| 670 703 |  | 
| 671 | 
            -
                    def  | 
| 672 | 
            -
                       | 
| 704 | 
            +
                    def max_recursion_lvl
         | 
| 705 | 
            +
                      1
         | 
| 673 706 | 
             
                    end
         | 
| 674 707 | 
             
                  end
         | 
| 675 708 |  | 
| @@ -824,7 +857,7 @@ module Riml | |
| 824 857 | 
             
                      def_node.parameters.delete_if(&DefNode::DEFAULT_PARAMS)
         | 
| 825 858 | 
             
                      def_node.parameters << SPLAT_LITERAL unless def_node.splat
         | 
| 826 859 | 
             
                    end
         | 
| 827 | 
            -
                    def_node.expressions.insert(insert_idx, if_expression)
         | 
| 860 | 
            +
                    def_node.expressions.nodes.insert(insert_idx, if_expression)
         | 
| 828 861 | 
             
                    reestablish_parents(def_node)
         | 
| 829 862 | 
             
                  end
         | 
| 830 863 |  | 
| @@ -841,6 +874,10 @@ module Riml | |
| 841 874 | 
             
                      ])
         | 
| 842 875 | 
             
                    )
         | 
| 843 876 | 
             
                  end
         | 
| 877 | 
            +
             | 
| 878 | 
            +
                  def max_recursion_lvl
         | 
| 879 | 
            +
                    3
         | 
| 880 | 
            +
                  end
         | 
| 844 881 | 
             
                end
         | 
| 845 882 |  | 
| 846 883 | 
             
                class DeserializeVarAssignment < AST_Rewriter
         | 
| @@ -883,6 +920,10 @@ module Riml | |
| 883 920 | 
             
                    new_node.keywords = keywords
         | 
| 884 921 | 
             
                    node.replace_with(new_node)
         | 
| 885 922 | 
             
                  end
         | 
| 923 | 
            +
             | 
| 924 | 
            +
                  def max_recursion_lvl
         | 
| 925 | 
            +
                    1
         | 
| 926 | 
            +
                  end
         | 
| 886 927 | 
             
                end
         | 
| 887 928 |  | 
| 888 929 | 
             
              end
         | 
    
        data/lib/riml/compiler.rb
    CHANGED
    
    | @@ -79,8 +79,7 @@ module Riml | |
| 79 79 | 
             
                      end
         | 
| 80 80 | 
             
                    end
         | 
| 81 81 | 
             
                    node.compiled_output << "\n" unless node.compiled_output[-1] == "\n"
         | 
| 82 | 
            -
                    node. | 
| 83 | 
            -
                    node.compiled_output << "endif"
         | 
| 82 | 
            +
                    node.compiled_output << "endif\n"
         | 
| 84 83 | 
             
                  end
         | 
| 85 84 | 
             
                end
         | 
| 86 85 |  | 
| @@ -113,8 +112,7 @@ module Riml | |
| 113 112 | 
             
                    node.body.compiled_output.each_line do |line|
         | 
| 114 113 | 
             
                      node.compiled_output << node.indent + line
         | 
| 115 114 | 
             
                    end
         | 
| 116 | 
            -
                    node. | 
| 117 | 
            -
                    node.compiled_output << "endwhile"
         | 
| 115 | 
            +
                    node.compiled_output << "endwhile\n"
         | 
| 118 116 | 
             
                  end
         | 
| 119 117 | 
             
                end
         | 
| 120 118 |  | 
| @@ -479,7 +477,7 @@ module Riml | |
| 479 477 | 
             
                    body = ""
         | 
| 480 478 | 
             
                    unless node.expressions.compiled_output.empty?
         | 
| 481 479 | 
             
                      node.expressions.compiled_output.each_line do |line|
         | 
| 482 | 
            -
                        body << node.indent  | 
| 480 | 
            +
                        body << node.indent << line
         | 
| 483 481 | 
             
                      end
         | 
| 484 482 | 
             
                    end
         | 
| 485 483 | 
             
                    node.compiled_output = declaration << body << "endfunction\n"
         | 
| @@ -565,14 +563,14 @@ module Riml | |
| 565 563 | 
             
                    node.compiled_output << ")" unless node.builtin_command?
         | 
| 566 564 | 
             
                    unless node.descendant_of_control_structure? ||
         | 
| 567 565 | 
             
                           node.descendant_of_call_node? ||
         | 
| 568 | 
            -
                           node. | 
| 566 | 
            +
                           node.descendant_of_dict_get_dot_node? ||
         | 
| 567 | 
            +
                           node.descendant_of_dictionary_node? ||
         | 
| 569 568 | 
             
                           node.descendant_of_list_node? ||
         | 
| 570 569 | 
             
                           node.descendant_of_list_or_dict_get_node? ||
         | 
| 571 570 | 
             
                           node.descendant_of_operator_node? ||
         | 
| 572 571 | 
             
                           node.descendant_of_wrap_in_parens_node? ||
         | 
| 573 572 | 
             
                           node.descendant_of_sublist_node? ||
         | 
| 574 | 
            -
                           node. | 
| 575 | 
            -
                           node.descendant_of_dictionary_node? ||
         | 
| 573 | 
            +
                           node.descendant_of_object_instantiation_node? ||
         | 
| 576 574 | 
             
                           node.descendant_of_curly_brace_part?
         | 
| 577 575 | 
             
                      node.force_newline = true
         | 
| 578 576 | 
             
                    end
         | 
| @@ -646,7 +644,7 @@ module Riml | |
| 646 644 | 
             
                    node.expressions.accept(NodesVisitor.new :propagate_up_tree => false)
         | 
| 647 645 | 
             
                    body = node.expressions.compiled_output
         | 
| 648 646 | 
             
                    body.each_line do |line|
         | 
| 649 | 
            -
                      node.compiled_output << node.indent  | 
| 647 | 
            +
                      node.compiled_output << node.indent << line
         | 
| 650 648 | 
             
                    end
         | 
| 651 649 | 
             
                    node.compiled_output << "endfor\n"
         | 
| 652 650 | 
             
                  end
         | 
| @@ -659,7 +657,7 @@ module Riml | |
| 659 657 | 
             
                    node.compiled_output = "try\n"
         | 
| 660 658 | 
             
                    try.accept(visitor_for_node(try, :propagate_up_tree => false))
         | 
| 661 659 | 
             
                    try.compiled_output.each_line do |line|
         | 
| 662 | 
            -
                      node.compiled_output << node.indent  | 
| 660 | 
            +
                      node.compiled_output << node.indent << line
         | 
| 663 661 | 
             
                    end
         | 
| 664 662 |  | 
| 665 663 | 
             
                    catches.each do |c|
         | 
| @@ -667,9 +665,9 @@ module Riml | |
| 667 665 | 
             
                      c.compiled_output.each_line do |line|
         | 
| 668 666 | 
             
                        outdent = line =~ /\A\s*catch/
         | 
| 669 667 | 
             
                        if outdent && c.non_nested?
         | 
| 670 | 
            -
                          node.compiled_output << node.outdent  | 
| 668 | 
            +
                          node.compiled_output << node.outdent << line
         | 
| 671 669 | 
             
                        else
         | 
| 672 | 
            -
                          node.compiled_output << node.indent  | 
| 670 | 
            +
                          node.compiled_output << node.indent << line
         | 
| 673 671 | 
             
                        end
         | 
| 674 672 | 
             
                      end
         | 
| 675 673 | 
             
                    end if catches
         | 
| @@ -678,7 +676,7 @@ module Riml | |
| 678 676 | 
             
                      node.compiled_output << "finally\n"
         | 
| 679 677 | 
             
                      finally.accept(visitor_for_node(finally, :propagate_up_tree => false))
         | 
| 680 678 | 
             
                      finally.compiled_output.each_line do |line|
         | 
| 681 | 
            -
                        node.compiled_output << node.indent  | 
| 679 | 
            +
                        node.compiled_output << node.indent << line
         | 
| 682 680 | 
             
                      end
         | 
| 683 681 | 
             
                    end
         | 
| 684 682 | 
             
                    node.compiled_output << "endtry\n"
         | 
| @@ -787,7 +785,7 @@ module Riml | |
| 787 785 | 
             
                    root_node = parser.parse(source, parser.ast_rewriter, file_basepath, true)
         | 
| 788 786 | 
             
                    included_files_compiled << file_basepath
         | 
| 789 787 | 
             
                    output = compile(root_node)
         | 
| 790 | 
            -
                    (Riml::INCLUDE_COMMENT_FMT % file_basepath)  | 
| 788 | 
            +
                    (Riml::INCLUDE_COMMENT_FMT % file_basepath) << output
         | 
| 791 789 | 
             
                  end
         | 
| 792 790 | 
             
                end
         | 
| 793 791 |  | 
| @@ -0,0 +1,75 @@ | |
| 1 | 
            +
            require 'set'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Riml
         | 
| 4 | 
            +
              class FileRollback
         | 
| 5 | 
            +
                @files_created = Set.new
         | 
| 6 | 
            +
                # { 'main.vim' => nil, 'existed.vim' => "\nsource code..." }
         | 
| 7 | 
            +
                @previous_file_states = {}
         | 
| 8 | 
            +
                @guarding = 0
         | 
| 9 | 
            +
                @m = Mutex.new
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                # NOTE: Used only in main thread.
         | 
| 12 | 
            +
                # Only call this method in one thread at a time. It's okay if
         | 
| 13 | 
            +
                # `&block` launches threads, and they compile files though.
         | 
| 14 | 
            +
                def self.guard(&block)
         | 
| 15 | 
            +
                  @guarding += 1
         | 
| 16 | 
            +
                  block.call
         | 
| 17 | 
            +
                rescue
         | 
| 18 | 
            +
                  rollback!
         | 
| 19 | 
            +
                  raise
         | 
| 20 | 
            +
                ensure
         | 
| 21 | 
            +
                  @guarding -= 1
         | 
| 22 | 
            +
                  if @guarding == 0
         | 
| 23 | 
            +
                    clear
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def self.trap(*signals, &block)
         | 
| 28 | 
            +
                  signals.each do |sig|
         | 
| 29 | 
            +
                    Signal.trap(sig) do
         | 
| 30 | 
            +
                      rollback! if @guarding > 0
         | 
| 31 | 
            +
                      block.call if block
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def self.creating_file(full_path)
         | 
| 37 | 
            +
                  @m.synchronize do
         | 
| 38 | 
            +
                    return unless @guarding > 0
         | 
| 39 | 
            +
                    previous_state = File.file?(full_path) ? File.read(full_path) : nil
         | 
| 40 | 
            +
                    @previous_file_states[full_path] ||= previous_state
         | 
| 41 | 
            +
                    @files_created << full_path
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def self.clear
         | 
| 46 | 
            +
                  @m.synchronize do
         | 
| 47 | 
            +
                    @files_created = Set.new
         | 
| 48 | 
            +
                    @previous_file_states.clear
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def self.rollback!
         | 
| 53 | 
            +
                  @m.synchronize do
         | 
| 54 | 
            +
                    @files_created.each do |path|
         | 
| 55 | 
            +
                      rollback_file!(path)
         | 
| 56 | 
            +
                    end
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                private
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def self.rollback_file!(file_path)
         | 
| 63 | 
            +
                  if !@previous_file_states.key?(file_path)
         | 
| 64 | 
            +
                    return false
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
                  prev_state = @previous_file_states[file_path]
         | 
| 67 | 
            +
                  if prev_state.nil?
         | 
| 68 | 
            +
                    File.delete(file_path) if File.exists?(file_path)
         | 
| 69 | 
            +
                  else
         | 
| 70 | 
            +
                    File.open(file_path, 'w') { |f| f.write(prev_state) }
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                  prev_state
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
            end
         | 
    
        data/lib/riml/grammar.y
    CHANGED
    
    | @@ -567,8 +567,14 @@ end | |
| 567 567 | 
             
                @options ||= {}
         | 
| 568 568 | 
             
              end
         | 
| 569 569 |  | 
| 570 | 
            +
              @@ast_cache = {}
         | 
| 571 | 
            +
             | 
| 570 572 | 
             
              # parses tokens or code into output nodes
         | 
| 571 573 | 
             
              def parse(object, ast_rewriter = Riml::AST_Rewriter.new, filename = nil, included = false)
         | 
| 574 | 
            +
                #if @@ast_cache[filename]
         | 
| 575 | 
            +
                  #return @@ast_cache[filename]
         | 
| 576 | 
            +
                #end
         | 
| 577 | 
            +
             | 
| 572 578 | 
             
                if tokens?(object)
         | 
| 573 579 | 
             
                  @tokens = object
         | 
| 574 580 | 
             
                elsif code?(object)
         | 
| @@ -588,11 +594,17 @@ end | |
| 588 594 | 
             
                  raise Riml::ParseError, error_msg
         | 
| 589 595 | 
             
                end
         | 
| 590 596 |  | 
| 597 | 
            +
             | 
| 591 598 | 
             
                @ast_rewriter ||= ast_rewriter
         | 
| 592 | 
            -
                 | 
| 599 | 
            +
                unless @ast_rewriter
         | 
| 600 | 
            +
                  #@@ast_cache[filename] = ast if filename
         | 
| 601 | 
            +
                  return ast
         | 
| 602 | 
            +
                end
         | 
| 593 603 | 
             
                @ast_rewriter.ast = ast
         | 
| 594 604 | 
             
                @ast_rewriter.options ||= options
         | 
| 595 605 | 
             
                @ast_rewriter.rewrite(filename, included)
         | 
| 606 | 
            +
                #@@ast_cache[filename] = @ast_rewriter.ast if filename
         | 
| 607 | 
            +
                #@ast_rewriter.ast
         | 
| 596 608 | 
             
              end
         | 
| 597 609 |  | 
| 598 610 | 
             
              # get the next token from either the list of tokens provided, or
         | 
    
        data/lib/riml/lexer.rb
    CHANGED
    
    | @@ -11,9 +11,9 @@ module Riml | |
| 11 11 | 
             
                ANCHORED_INTERPOLATION_REGEX = /\A#{INTERPOLATION_REGEX}/m
         | 
| 12 12 | 
             
                INTERPOLATION_SPLIT_REGEX = /(\#\{.*?\})/m
         | 
| 13 13 |  | 
| 14 | 
            -
                attr_reader :tokens, :prev_token, : | 
| 15 | 
            -
                  : | 
| 16 | 
            -
             | 
| 14 | 
            +
                attr_reader :tokens, :prev_token, :chunk, :current_indent,
         | 
| 15 | 
            +
                  :invalid_keyword, :filename, :parser_info
         | 
| 16 | 
            +
                attr_accessor :lineno
         | 
| 17 17 | 
             
                # for REPL
         | 
| 18 18 | 
             
                attr_accessor :ignore_indentation_check
         | 
| 19 19 |  | 
| @@ -139,7 +139,7 @@ module Riml | |
| 139 139 |  | 
| 140 140 | 
             
                      @token_buf << [token_name.intern, identifier]
         | 
| 141 141 |  | 
| 142 | 
            -
                    elsif BUILTIN_COMMANDS.include?(identifier) &&  | 
| 142 | 
            +
                    elsif BUILTIN_COMMANDS.include?(identifier) && peek(identifier.size) != '('
         | 
| 143 143 | 
             
                      @token_buf << [:BUILTIN_COMMAND, identifier]
         | 
| 144 144 | 
             
                    elsif RIML_FILE_COMMANDS.include? identifier
         | 
| 145 145 | 
             
                      @token_buf << [:RIML_FILE_COMMAND, identifier]
         | 
| @@ -330,7 +330,9 @@ module Riml | |
| 330 330 | 
             
                end
         | 
| 331 331 |  | 
| 332 332 | 
             
                def tokenize_without_moving_pos(code)
         | 
| 333 | 
            -
                  Lexer.new(code). | 
| 333 | 
            +
                  Lexer.new(code, filename, false).tap do |l|
         | 
| 334 | 
            +
                    l.lineno = lineno
         | 
| 335 | 
            +
                  end.tokenize
         | 
| 334 336 | 
             
                end
         | 
| 335 337 |  | 
| 336 338 | 
             
                def statement_modifier?
         | 
| @@ -350,5 +352,9 @@ module Riml | |
| 350 352 | 
             
                def more_code_to_tokenize?
         | 
| 351 353 | 
             
                  @i < @code.size
         | 
| 352 354 | 
             
                end
         | 
| 355 | 
            +
             | 
| 356 | 
            +
                def peek(n = 1)
         | 
| 357 | 
            +
                  @chunk[n]
         | 
| 358 | 
            +
                end
         | 
| 353 359 | 
             
              end
         | 
| 354 360 | 
             
            end
         | 
    
        data/lib/riml/nodes.rb
    CHANGED
    
    | @@ -29,23 +29,25 @@ module Riml | |
| 29 29 | 
             
                  "#{filename}:#{parser_info[:lineno]}"
         | 
| 30 30 | 
             
                end
         | 
| 31 31 |  | 
| 32 | 
            -
                 | 
| 33 | 
            -
                 | 
| 34 | 
            -
                 | 
| 35 | 
            -
                 | 
| 36 | 
            -
                 | 
| 37 | 
            -
                 | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 32 | 
            +
                %w(
         | 
| 33 | 
            +
                control_structure
         | 
| 34 | 
            +
                call_node
         | 
| 35 | 
            +
                object_instantiation_node
         | 
| 36 | 
            +
                list_node
         | 
| 37 | 
            +
                list_or_dict_get_node
         | 
| 38 | 
            +
                operator_node
         | 
| 39 | 
            +
                wrap_in_parens_node
         | 
| 40 | 
            +
                sublist_node
         | 
| 41 | 
            +
                dict_get_dot_node
         | 
| 42 | 
            +
                dictionary_node
         | 
| 43 | 
            +
                curly_brace_part
         | 
| 44 | 
            +
                ).each do |node_name|
         | 
| 45 | 
            +
                  define_method "descendant_of_#{node_name}?" do
         | 
| 46 | 
            +
                    parent_node_name = node_name.split('_').map(&:capitalize).join
         | 
| 40 47 | 
             
                    parent_node = Riml.const_get parent_node_name
         | 
| 41 48 | 
             
                    parent_node === self.parent_node
         | 
| 42 | 
            -
                  else
         | 
| 43 | 
            -
                    super
         | 
| 44 49 | 
             
                  end
         | 
| 45 50 | 
             
                end
         | 
| 46 | 
            -
                def respond_to?(method, include_private = false)
         | 
| 47 | 
            -
                  super || method =~ DESCENDANT_OF_REGEX
         | 
| 48 | 
            -
                end
         | 
| 49 51 | 
             
              end
         | 
| 50 52 |  | 
| 51 53 | 
             
              module Walkable
         | 
| @@ -189,19 +191,6 @@ module Riml | |
| 189 191 | 
             
                  self
         | 
| 190 192 | 
             
                end
         | 
| 191 193 |  | 
| 192 | 
            -
                # forward missing methods to `nodes` array
         | 
| 193 | 
            -
                def method_missing(method, *args, &block)
         | 
| 194 | 
            -
                  if nodes.respond_to?(method)
         | 
| 195 | 
            -
                    nodes.send(method, *args, &block)
         | 
| 196 | 
            -
                  else
         | 
| 197 | 
            -
                    super
         | 
| 198 | 
            -
                  end
         | 
| 199 | 
            -
                end
         | 
| 200 | 
            -
             | 
| 201 | 
            -
                def respond_to?(method, include_private = false)
         | 
| 202 | 
            -
                  super || nodes.respond_to?(method, include_private)
         | 
| 203 | 
            -
                end
         | 
| 204 | 
            -
             | 
| 205 194 | 
             
                def children
         | 
| 206 195 | 
             
                  nodes
         | 
| 207 196 | 
             
                end
         | 
| @@ -759,14 +748,6 @@ module Riml | |
| 759 748 | 
             
                  end
         | 
| 760 749 | 
             
                  children.concat(default_param_nodes)
         | 
| 761 750 | 
             
                end
         | 
| 762 | 
            -
             | 
| 763 | 
            -
                def method_missing(method, *args, &blk)
         | 
| 764 | 
            -
                  if children.respond_to?(method)
         | 
| 765 | 
            -
                    children.send(method, *args, &blk)
         | 
| 766 | 
            -
                  else
         | 
| 767 | 
            -
                    super
         | 
| 768 | 
            -
                  end
         | 
| 769 | 
            -
                end
         | 
| 770 751 | 
             
              end
         | 
| 771 752 |  | 
| 772 753 | 
             
              class DefaultParamNode < Struct.new(:parameter, :expression)
         | 
| @@ -792,13 +773,6 @@ module Riml | |
| 792 773 |  | 
| 793 774 | 
             
                alias function? function
         | 
| 794 775 |  | 
| 795 | 
            -
                def initialize_copy(source)
         | 
| 796 | 
            -
                  super
         | 
| 797 | 
            -
                  self.for_node_variable_names = for_node_variable_names.dup
         | 
| 798 | 
            -
                  self.argument_variable_names = argument_variable_names.dup
         | 
| 799 | 
            -
                  self.function = source.function
         | 
| 800 | 
            -
                end
         | 
| 801 | 
            -
             | 
| 802 776 | 
             
                def merge(other)
         | 
| 803 777 | 
             
                  dup.merge! other
         | 
| 804 778 | 
             
                end
         | 
    
        data/lib/riml/parser.rb
    CHANGED
    
    | @@ -24,8 +24,14 @@ module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 560) | |
| 24 24 | 
             
                @options ||= {}
         | 
| 25 25 | 
             
              end
         | 
| 26 26 |  | 
| 27 | 
            +
              @@ast_cache = {}
         | 
| 28 | 
            +
             | 
| 27 29 | 
             
              # parses tokens or code into output nodes
         | 
| 28 30 | 
             
              def parse(object, ast_rewriter = Riml::AST_Rewriter.new, filename = nil, included = false)
         | 
| 31 | 
            +
                #if @@ast_cache[filename]
         | 
| 32 | 
            +
                  #return @@ast_cache[filename]
         | 
| 33 | 
            +
                #end
         | 
| 34 | 
            +
             | 
| 29 35 | 
             
                if tokens?(object)
         | 
| 30 36 | 
             
                  @tokens = object
         | 
| 31 37 | 
             
                elsif code?(object)
         | 
| @@ -45,11 +51,17 @@ module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 560) | |
| 45 51 | 
             
                  raise Riml::ParseError, error_msg
         | 
| 46 52 | 
             
                end
         | 
| 47 53 |  | 
| 54 | 
            +
             | 
| 48 55 | 
             
                @ast_rewriter ||= ast_rewriter
         | 
| 49 | 
            -
                 | 
| 56 | 
            +
                unless @ast_rewriter
         | 
| 57 | 
            +
                  #@@ast_cache[filename] = ast if filename
         | 
| 58 | 
            +
                  return ast
         | 
| 59 | 
            +
                end
         | 
| 50 60 | 
             
                @ast_rewriter.ast = ast
         | 
| 51 61 | 
             
                @ast_rewriter.options ||= options
         | 
| 52 62 | 
             
                @ast_rewriter.rewrite(filename, included)
         | 
| 63 | 
            +
                #@@ast_cache[filename] = @ast_rewriter.ast if filename
         | 
| 64 | 
            +
                #@ast_rewriter.ast
         | 
| 53 65 | 
             
              end
         | 
| 54 66 |  | 
| 55 67 | 
             
              # get the next token from either the list of tokens provided, or
         | 
    
        data/lib/riml/path_cache.rb
    CHANGED
    
    
| @@ -21,11 +21,11 @@ module Riml | |
| 21 21 | 
             
                end
         | 
| 22 22 |  | 
| 23 23 | 
             
                def save_classes_registered(ast, class_diff)
         | 
| 24 | 
            -
                  @ast_classes_registered_cache[ast] = class_diff
         | 
| 24 | 
            +
                  @ast_classes_registered_cache[ast.object_id] = class_diff
         | 
| 25 25 | 
             
                end
         | 
| 26 26 |  | 
| 27 27 | 
             
                def fetch_classes_registered(ast)
         | 
| 28 | 
            -
                  @ast_classes_registered_cache[ast] || {}
         | 
| 28 | 
            +
                  @ast_classes_registered_cache[ast.object_id] || {}
         | 
| 29 29 | 
             
                end
         | 
| 30 30 | 
             
              end
         | 
| 31 31 | 
             
            end
         | 
    
        data/lib/riml/walker.rb
    CHANGED
    
    | @@ -1,14 +1,21 @@ | |
| 1 1 | 
             
            module Riml
         | 
| 2 2 | 
             
              class Walker
         | 
| 3 | 
            -
                 | 
| 3 | 
            +
                MAX_RECURSION_LVL_ACTUAL = 1_000_000
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def self.walk_node(node, method, max_recursion_lvl = -1)
         | 
| 6 | 
            +
                  if max_recursion_lvl == -1
         | 
| 7 | 
            +
                    max_recursion_lvl = MAX_RECURSION_LVL_ACTUAL
         | 
| 8 | 
            +
                  end
         | 
| 4 9 | 
             
                  # breadth-first walk
         | 
| 5 10 | 
             
                  to_visit = [node]
         | 
| 11 | 
            +
                  lvl = 0
         | 
| 6 12 | 
             
                  while to_visit.length > 0
         | 
| 7 13 | 
             
                    cur_node = to_visit.shift
         | 
| 8 14 | 
             
                    cur_node.children.each do |child|
         | 
| 9 15 | 
             
                      to_visit << child
         | 
| 10 | 
            -
                    end if cur_node.respond_to?(:children) | 
| 16 | 
            +
                    end if lvl < max_recursion_lvl && cur_node.respond_to?(:children)
         | 
| 11 17 | 
             
                    method.call(cur_node)
         | 
| 18 | 
            +
                    lvl += 1
         | 
| 12 19 | 
             
                  end
         | 
| 13 20 | 
             
                end
         | 
| 14 21 | 
             
              end
         | 
    
        data/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: riml
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.3. | 
| 4 | 
            +
              version: 0.3.5
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2013-10- | 
| 12 | 
            +
            date: 2013-10-20 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: racc
         | 
| @@ -106,6 +106,7 @@ files: | |
| 106 106 | 
             
            - version.rb
         | 
| 107 107 | 
             
            - lib/riml.rb
         | 
| 108 108 | 
             
            - lib/riml/parser.rb
         | 
| 109 | 
            +
            - lib/riml/file_rollback.rb
         | 
| 109 110 | 
             
            - lib/riml/get_sid_function.vim
         | 
| 110 111 | 
             
            - lib/riml/walker.rb
         | 
| 111 112 | 
             
            - lib/riml/rewritten_ast_cache.rb
         | 
| @@ -150,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 150 151 | 
             
                  version: '0'
         | 
| 151 152 | 
             
                  segments:
         | 
| 152 153 | 
             
                  - 0
         | 
| 153 | 
            -
                  hash:  | 
| 154 | 
            +
                  hash: 3731001160727385716
         | 
| 154 155 | 
             
            requirements: []
         | 
| 155 156 | 
             
            rubyforge_project: 
         | 
| 156 157 | 
             
            rubygems_version: 1.8.25
         |