lib/patternmatching/pattern.rb in patternmatching-0.2.2 vs lib/patternmatching/pattern.rb in patternmatching-0.2.3

- old
+ new

@@ -1,18 +1,93 @@ module PatternMatching - #Private Exception for stop matching - class NotMatched < Exception + # Domain Specific Language style methods for inside block + module DSL_INSIDE + #A pattern matches description inside block + #=== Usage + # seems as {some pattern...} do ... end + def as(&block) + block + end + + #A pattern restriction, must boolean + #=== Usage + # seems as {PATTERN}, with {CONDITION} do ... end + def with(&block) + block + end + + #A pattern matches anything + #=== Usage + # seems something do ... end + def something + proc {_} + end end - #Private class for build structured data - class NodeBuilder - private - def method_missing(name, *args) - Node.new(name, args) + # Domain Specific Language style methods for outside + module DSL_OUTSIDE + include DSL_INSIDE + #Build structured data + #=== Usage + # build {[foo(bar, 100), foo(buzz, "abc")]} + def build(&block) + NodeBuilder.new.instance_eval(&block) end + + #Build structured data + #=== Usage + # PatternMatching.build {[foo(bar, 100), foo(buzz, "abc")]} + def self.build(&block) + NodeBuilder.new.instance_eval(&block) + end + + #Do pattern matching + #===Usage + # make TARGET do + # seems as {PATTERN_1} do ACTION_1 end + # seems as {PATTERN_2} do ACTION_2 end + # seems something do ACTION_DEFAULT end + # end + def make(target, &block) + patterns = [] + PatternFragments.new(patterns).instance_eval(&block) + MatchExec.exec_as(target, patterns, self) + end + + #Define method as partial style + #=== Usage + # func(NAME).seems as {PATTERN_1} do ACTION_1 end + # func(NAME).seems as {PATTERN_2} do ACTION_2 end + # func(NAME).seems something do ACTION_DEFAULT end + # + #or + # + # func NAME do + # seems as {PATTERN_1} do ACTION_1 end + # seems as {PATTERN_2} do ACTION_2 end + # seems something do ACTION_DEFAULT end + # end + # + def func(name, &block) + pattern_name = ("@_pattern_" + name.to_s ).to_sym + unless method_defined?(name) + patterns = [] + instance_variable_set(pattern_name, patterns) + define_method(name) do |target| + MatchExec.exec_as(target, patterns, self) + end + end + patterns = instance_variable_get(pattern_name) + fragments = PatternFragments.new(patterns) + if block + fragments.instance_eval(&block) + end + fragments + end end + include DSL_OUTSIDE #Class for structured data/patterns class Node def initialize(name, children) @name = name @@ -25,10 +100,23 @@ def size @children.size end end + private + #Private Exception for stop matching + class NotMatched < Exception + end + + #Private class for build structured data + class NodeBuilder + private + def method_missing(name, *args) + Node.new(name, args) + end + end + #Private module for pattern matching and to collect var/val pairs module Collector def self.walk(source, target, list) case source when Symbol @@ -128,10 +216,11 @@ # Private class to access instance valiables of the receiver class InstanceVariableAccessor def initialize(receiver) @receiver = receiver end + private def method_missing(name, *args) begin @receiver.send(name, *args) rescue NameError if name.to_s[-1,1] == "=" @@ -157,115 +246,26 @@ @receiver end def the @wrapper end + private def method_missing(name, *args) return @args[name] if @args.key?(name) @receiver.send(name, *args) end end end #Private class for collecting pattern/action fragments class PatternFragments + include DSL_INSIDE + def initialize(patterns) @patterns = patterns end def seems(pattern, condition = nil, &action) @patterns << [pattern, action, condition] self end - def as(&block) - block - end - def with(&block) - block - end - def something - proc {_} - end end - - # Domain Specific Language style methods - module DSL - #Build structured data - #=== Usage - # build {[foo(bar, 100), foo(buzz, "abc")]} - def build(&block) - NodeBuilder.new.instance_eval(&block) - end - - #Build structured data - #=== Usage - # PatternMatching.build {[foo(bar, 100), foo(buzz, "abc")]} - def self.build(&block) - NodeBuilder.new.instance_eval(&block) - end - - #Do pattern matching - #===Usage - # make TARGET do - # seems as {PATTERN_1} do ACTION_1 end - # seems as {PATTERN_2} do ACTION_2 end - # seems something do ACTION_DEFAULT end - # end - def make(target, &block) - patterns = [] - PatternFragments.new(patterns).instance_eval(&block) - MatchExec.exec_as(target, patterns, self) - end - - #A pattern matches description inside block - #=== Usage - # seems as {some pattern...} do ... end - def as(&block) - block - end - - #A pattern restriction, must boolean - #=== Usage - # seems as {PATTERN}, with {CONDITION} do ... end - def with(&block) - block - end - - #A pattern matches anything - #=== Usage - # seems something do ... end - def something - proc {_} - end - - #Define method as partial style - #=== Usage - # func(NAME).seems as {PATTERN_1} do ACTION_1 end - # func(NAME).seems as {PATTERN_2} do ACTION_2 end - # func(NAME).seems something do ACTION_DEFAULT end - # - #or - # - # func NAME do - # seems as {PATTERN_1} do ACTION_1 end - # seems as {PATTERN_2} do ACTION_2 end - # seems something do ACTION_DEFAULT end - # end - # - def func(name, &block) - pattern_name = ("@_pattern_" + name.to_s ).to_sym - unless method_defined?(name) - patterns = [] - instance_variable_set(pattern_name, patterns) - define_method(name) do |target| - MatchExec.exec_as(target, patterns, self) - end - end - patterns = instance_variable_get(pattern_name) - fragments = PatternFragments.new(patterns) - if block - fragments.instance_eval(&block) - end - fragments - end - end - include DSL end