Sha256: 383e79acde6c6690ae8b28c6a7bd53060e8144c0f6b713fedce71b18ba6da151
Contents?: true
Size: 1.24 KB
Versions: 5
Compression:
Stored size: 1.24 KB
Contents
require "attributable" require "metamorpher/rewriter/traverser" module Metamorpher module Rewriter class Rule extend Attributable attributes :pattern, :replacement, traverser: Traverser.new def apply(ast, &block) rewrite_all(ast, matches_for(ast).take(1), &block) end def reduce(ast, &block) rewrite_all(ast, matches_for(ast), &block) end private def rewrite_all(ast, matches, &block) matches.reduce(ast) { |a, e| rewrite(a, e, &block) } end def rewrite(ast, match, &block) original = match.root substitution = substitution_with_special_values(match) rewritten = replacement.substitute(substitution) block.call(original, rewritten) if block ast.replace(original.path, rewritten) end def substitution_with_special_values(match) match.substitution.dup.tap do |substitution| substitution[:&] = match.root.dup # add the "whole match" special variable (&) end end def matches_for(ast) traverser.traverse(ast) .lazy # only compute the next match when needed .map { |current| pattern.match(current) } .select(&:matches?) end end end end
Version data entries
5 entries across 5 versions & 1 rubygems