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