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