2010-12-07 08:11:35 +00:00
|
|
|
require 'rubygems'
|
|
|
|
require 'readline'
|
|
|
|
require 'ruby_parser'
|
|
|
|
|
2010-12-08 00:19:55 +00:00
|
|
|
module Pry
|
|
|
|
module RubyParserExtension
|
|
|
|
def valid?(code)
|
|
|
|
new.parse(code)
|
|
|
|
rescue Racc::ParseError
|
|
|
|
false
|
2010-12-07 08:11:35 +00:00
|
|
|
else
|
2010-12-08 00:19:55 +00:00
|
|
|
true
|
2010-12-07 08:11:35 +00:00
|
|
|
end
|
2010-12-08 00:19:55 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.repl_loop(target=TOPLEVEL_BINDING)
|
|
|
|
repl(target, :loop => true)
|
|
|
|
end
|
2010-12-07 08:11:35 +00:00
|
|
|
|
2010-12-08 00:19:55 +00:00
|
|
|
def self.repl(target=TOPLEVEL_BINDING, options={:loop => false})
|
|
|
|
prompt = ""
|
|
|
|
code = proc do
|
2010-12-07 08:11:35 +00:00
|
|
|
eval_string = ""
|
2010-12-08 00:19:55 +00:00
|
|
|
while true
|
|
|
|
if eval_string.empty?
|
|
|
|
prompt = "> "
|
|
|
|
else
|
|
|
|
prompt = "* "
|
|
|
|
end
|
|
|
|
|
|
|
|
val = Readline.readline(prompt, true)
|
|
|
|
eval_string += "#{val}\n"
|
|
|
|
|
|
|
|
if val == "#"
|
|
|
|
elsif val == "#pop"
|
|
|
|
puts "Poppping back"
|
|
|
|
return
|
|
|
|
elsif (_, new_target = val.split(/#target\s*\=\s*/)).size > 1
|
|
|
|
target = target.eval(new_target)
|
|
|
|
eval_string = ""
|
|
|
|
puts "Context changed to #{target}"
|
|
|
|
break
|
|
|
|
end
|
|
|
|
|
|
|
|
abort if val == "abort"
|
|
|
|
exit if val == "exit"
|
|
|
|
exit if val == "quit"
|
|
|
|
|
|
|
|
break if RubyParser.valid?(eval_string)
|
|
|
|
end
|
|
|
|
begin
|
|
|
|
puts "=> #{target.eval(eval_string).inspect}"
|
|
|
|
rescue StandardError => e
|
|
|
|
puts "#{e.message}"
|
|
|
|
end
|
2010-12-07 08:11:35 +00:00
|
|
|
end
|
|
|
|
|
2010-12-08 00:19:55 +00:00
|
|
|
if options[:loop]
|
|
|
|
loop(&code)
|
|
|
|
else
|
|
|
|
code.call
|
|
|
|
end
|
2010-12-07 08:11:35 +00:00
|
|
|
end
|
|
|
|
end
|
2010-12-08 00:19:55 +00:00
|
|
|
|
|
|
|
class RubyParser
|
|
|
|
extend Pry::RubyParserExtension
|
|
|
|
end
|