Skip to content

Instantly share code, notes, and snippets.

@tario
Created January 7, 2012 22:19
Show Gist options
  • Save tario/1576251 to your computer and use it in GitHub Desktop.
Save tario/1576251 to your computer and use it in GitHub Desktop.
chains
require "set"
require "sexp"
class Chain
def initialize
@groups = Hash.new
@enabled_groups = Set.new
enable :default
end
def enable(group_name)
@enabled_groups << group_name
end
def disable(group_name)
@enabled_groups.delete group_name
end
def process(x)
@enabled_groups.each do |grp|
group(grp).each do |l|
if l.condition.call(x)
return l.processor.call(x)
end
end
end
nil
end
def group(group_name)
@groups[group_name] = Array.new unless @groups[group_name]
@groups[group_name]
end
end
class Link
attr_accessor :condition, :processor
def process(&blk)
@processor = blk
self
end
end
def link(&blk)
l = Link.new
blk = proc{|x|true} unless blk
l.condition = blk
l
end
class SexpChain < Chain
def for_type(type_name, group_name = :default,&blk)
self.group(group_name) << link{|tree| tree.node_type == type_name}.process(&blk)
end
def default(group_name = :default,&blk)
self.group(group_name) << link.process(&blk)
end
end
chain = Chain.new
chain.group(:default) << link{|x| x==1 }.process{|x|9}
chain.group(:default) << link{|x| x==2 }.process{|x|19}
chain.group(:default) << link.process{|x|29}
p chain.process(1)
p chain.process(2)
p chain.process(3)
chain = SexpChain.new
chain.for_type(:if) do |x|
x[1]
end
chain.default do |x|
x.dup
x.map! do |subtree|
if subtree.respond_to? :node_type
chain.process subtree
else
subtree
end
end
end
require "ruby_parser"
tree = RubyParser.new.parse "while(1); if(a); b; end; end"
p chain.process(tree)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment