lib/qed/evaluator.rb in qed-2.4.0 vs lib/qed/evaluator.rb in qed-2.5.0

- old
+ new

@@ -96,10 +96,11 @@ pass!(step) end end # TODO: Not sure how to handle loading links in --comment runner mode. + # TODO: Do not think Scope should be reuseud by imported demo. def evaluate_links(step) step.text.scan(/\[qed:\/\/(.*?)\]/) do |match| file = $1 # relative to demo script if File.exist?(File.join(@script.directory,file)) @@ -108,11 +109,11 @@ # ruby or another demo case File.extname(file) when '.rb' import!(file) else - Demo.new(file, @script.applique, :scope=>@script.scope).run + Demo.new(file, :scope=>@script.scope).run end end end # @@ -140,22 +141,128 @@ end # Dispatch event to observers and advice. def advise!(signal, *args) @observers.each{ |o| o.update(signal, *args) } - @script.advise(signal, *args) + + #@script.advise(signal, *args) + case signal + when :when + call_matchers(*args) + else + call_signals(signal, *args) + end end # #def advise_when!(match) # @advice.call_when(match) #end + # React to an event. + # + # TODO: Should events short circuit on finding first match? + # In other words, should there be only one of each type of signal + # ragardless of how many applique layers? + def call_signals(type, *args) + @script.applique.each do |a| + signals = a.__signals__ + proc = signals[type.to_sym] + #signals.each do |set| + #proc = set[type.to_sym] + #proc.call(*args) if proc + @script.scope.instance_exec(*args, &proc) if proc + #end + end + + #@script.applique.each do |a| + # signals = a.__signals__ + # proc = signals[type.to_sym] + # if proc + # @script.scope.instance_exec(*args, &proc) + # break + # end + #end + + #meth = "qed_#{type}" + #if @script.scope.respond_to?(meth) + # meth = @script.scope.method(meth) + # if meth.arity == 0 + # meth.call + # else + # meth.call(*args) + # end + #end + + #@script.scope.__send__(meth, *args) + end + + # + def call_matchers(section) + match = section.text + args = section.arguments + @script.applique.each do |a| + matchers = a.__matchers__ + matchers.each do |(patterns, proc)| + compare = match + matched = true + params = [] + patterns.each do |pattern| + case pattern + when Regexp + regex = pattern + else + regex = match_string_to_regexp(pattern) + end + if md = regex.match(compare) + params.concat(md[1..-1]) + compare = md.post_match + else + matched = false + break + end + end + if matched + params += args + #proc.call(*params) + @script.scope.instance_exec(*params, &proc) + end + end + end + end + + # Convert matching string into a regular expression. If the string + # contains double parenthesis, such as ((.*?)), then the text within + # them is treated as in regular expression and kept verbatium. + # + # TODO: Better way to isolate regexp. Maybe ?:(.*?) or /(.*?)/. + # + # TODO: Now that we can use multi-patterns, do we still need this? + # + def match_string_to_regexp(str) + str = str.split(/(\(\(.*?\)\))(?!\))/).map{ |x| + x =~ /\A\(\((.*)\)\)\Z/ ? $1 : Regexp.escape(x) + }.join + str = str.gsub(/\\\s+/, '\s+') + Regexp.new(str, Regexp::IGNORECASE) + + #rexps = [] + #str = str.gsub(/\(\((.*?)\)\)/) do |m| + # rexps << '(' + $1 + ')' + # "\0" + #end + #str = Regexp.escape(str) + #rexps.each do |r| + # str = str.sub("\0", r) + #end + #str = str.gsub(/(\\\ )+/, '\s+') + #Regexp.new(str, Regexp::IGNORECASE) + end + ## #def method_missing(s, *a) # super(s, *a) unless /^tag/ =~ s.to_s #end end end -