lib/nydp/runner.rb in nydp-0.0.4 vs lib/nydp/runner.rb in nydp-0.0.5

- old
+ new

@@ -1,7 +1,44 @@ +require 'readline' +require 'nydp/readline_history' + module Nydp - class Runner + class StringReader + def initialize string ; @string = string ; end + def nextline + s = @string ; @string = nil ; s + end + end + + class StreamReader + def initialize stream ; @stream = stream ; end + def nextline + @stream.readline unless @stream.eof? + end + end + + class ReadlineReader + include Nydp::ReadlineHistory + + def initialize stream, prompt + @prompt = prompt + setup_readline_history + end + + # with thanks to http://ruby-doc.org/stdlib-1.9.3/libdoc/readline/rdoc/Readline.html + # and http://bogojoker.com/readline/ + def nextline + line = Readline.readline(@prompt, true) + return nil if line.nil? + if line =~ /^\s*$/ or Readline::HISTORY.to_a[-2] == line + Readline::HISTORY.pop + end + line + end + end + + class Evaluator attr_accessor :vm, :ns def initialize vm, ns @vm = vm @ns = ns @@ -28,39 +65,36 @@ def evaluate expr compile_and_eval(pre_compile(expr)) end end - class StreamRunner < Runner - attr_accessor :stream, :parser - - def initialize vm, ns, stream + class Runner < Evaluator + def initialize vm, ns, stream, printer=nil super vm, ns - @stream = stream - @parser = Nydp::Parser.new(ns) - @tokens = Nydp::Tokeniser.new stream + @printer = printer + @parser = Nydp::Parser.new(ns) + @tokens = Nydp::Tokeniser.new stream end - def prompt *_ + def print val + @printer.puts val if @printer end def run res = Nydp.NIL - prompt while !@tokens.finished - expr = parser.expression(@tokens) + expr = @parser.expression(@tokens) unless expr.nil? - res = evaluate expr - prompt res + begin + print(res = evaluate(expr)) + rescue Exception => e + puts e.message + e.backtrace.each do |b| + puts b + end + end end end res - end - end - - class Repl < StreamRunner - def prompt val=nil - puts val if val - print "nydp > " end end end