lib/qed/evaluator.rb in qed-2.1.1 vs lib/qed/evaluator.rb in qed-2.2.0
- old
+ new
@@ -1,107 +1,98 @@
module QED
- require 'tilt'
- require 'nokogiri'
require 'qed/scope'
- # = Demo Script Evaluator
- #
- #--
- # TODO: Currently the Evaluator class uses #traverse to work
- # thru the HTML document and trigger events accordingly. This
- # works well enough for simple HTML documents --the kind produced
- # by typical wiki-markup formats. However, for complex HTML it
- # it will not produce ideal output (although the code segements
- # should still run just fine). To counter this weakness, we will
- # have to swtich to a more complex SAX parser in the future.
- #--
+ # = Demonstrandum Evaluator
class Evaluator
#
def initialize(script, *observers)
@script = script
@file = script.file
- @root = script.root
+ @ast = script.parse
@scope = script.scope
@binding = script.binding
@advice = script.advice
@observers = observers
end
#
def run
- Dir.chdir(File.dirname(@file)) do
- advise!(:before_document, @script)
- @root.traverse do |element|
- call_tag(element)
- end
- advise!(:after_document, @script)
- end
+ advise!(:before_document, @script)
+ process
+ advise!(:after_document, @script)
end
#
- def call_tag(element)
- advise!(:tag, element)
- __send__("tag_#{element.name}", element)
- end
-
- # T A G S
-
- #
- def tag_a(element)
- case element['href']
- when /qed:\/\/(.*?)$/
- file = $1
- case File.extname(file)
- when '.rb'
- import!(file)
- else
- Script.new(file, scope).run
+ def process
+ @ast.each do |section|
+ case section.type
+ when :code
+ evaluate_code(section)
+ when :text
+ evaluate_text(section)
end
end
end
#
- def tag_pre(element)
- advise!(:before_code, element, @file)
+ def evaluate_code(section)
+ advise!(:before_code, section, @file)
begin
- eval(element.text, @binding, @file, element.line)
- pass!(element)
+ advise!(:code, section)
+ eval(section.text, @binding, @file, section.line)
+ #@scope.module_eval(section.text, @file, section.line)
+ pass!(section)
rescue Assertion => exception
- fail!(element, exception)
+ fail!(section, exception)
rescue Exception => exception
- error!(element, exception)
+ error!(section, exception)
end
- advise!(:after_code, element, @file)
+ advise!(:after_code, section, @file)
end
#
- def tag_p(element)
- advise!(:when, element.text)
+ def evaluate_text(section)
+ advise!(:text, section)
+ evaluate_links(section)
+ advise!(:when, section)
end
#
- def method_missing(s, *a)
- super(s, *a) unless /^tag/ =~ s.to_s
+ def evaluate_links(section)
+ section.text.scan(/\[qed:\/\/(.*?)\]/) do |match|
+ file = $1
+ # relative to demo script
+ if File.exist?(File.join(@script.directory,file))
+ file = File.join(@script.directory,file)
+ end
+ # ruby or another demo
+ case File.extname(file)
+ when '.rb'
+ import!(file)
+ else
+ Script.new(@script.applique, file, @script.scope).run
+ end
+ end
end
#
- def pass!(element)
- advise!(:pass, element)
+ def pass!(section)
+ advise!(:pass, section)
end
#
- def fail!(element, exception)
- advise!(:fail, element, exception)
+ def fail!(section, exception)
+ advise!(:fail, section, exception)
#raise exception
end
#
- def error!(element, exception)
- advise!(:error, element, exception)
+ def error!(section, exception)
+ advise!(:error, section, exception)
#raise exception
end
#
def import!(file)
@@ -112,15 +103,20 @@
#
def advise!(signal, *args)
@observers.each{ |o| o.update(signal, *args) }
#@scope.__advice__.call(signal, *args)
- @advice.call(signal, *args)
+ @advice.call(@scope, signal, *args)
end
#
#def advise_when!(match)
# @advice.call_when(match)
+ #end
+
+ ##
+ #def method_missing(s, *a)
+ # super(s, *a) unless /^tag/ =~ s.to_s
#end
end
end