class Interpreter

Public Class Methods

new() click to toggle source
# File lib/interpreter.rb, line 8
def initialize
  Readline.completion_append_character = nil
  Readline.completion_proc = lambda do |input|
    commands.grep(/^#{Regexp.escape(input)}/)
  end
end

Public Instance Methods

call() click to toggle source
# File lib/interpreter.rb, line 15
def call
  separator = ">"
  expression = ""
  begin
    expression += Readline.readline(prompt(separator), false)
    Readline::HISTORY << expression
    capture_stdout { eval(expression, TOPLEVEL_BINDING) }
  rescue SyntaxError => e
    if e.message =~ /syntax error, unexpected end-of-input/
      Readline::HISTORY.pop
      expression += "\n       "
      separator = "*"
      retry
    end
  rescue Exception => e
  end
  process(expression)
end

Private Instance Methods

capture_stdout(&block) click to toggle source
# File lib/interpreter.rb, line 104
def capture_stdout(&block)
  stdout = $stdout
  $stdout = StringIO.new
  block.call
ensure
  $stdout = stdout
end
command(expression) click to toggle source
# File lib/interpreter.rb, line 48
def command(expression)
  command, arguments = expression.split(" ", 2)
  send(command[1..-1], arguments)
rescue StandardError
  "#{red('ERROR')} #{command} command is not available"
end
commands() click to toggle source
# File lib/interpreter.rb, line 100
def commands
  %w[:exit :help :hist :quit :!]
end
evaluate(expression) click to toggle source
# File lib/interpreter.rb, line 94
def evaluate(expression)
  "#{bold('===>')} #{eval(expression, TOPLEVEL_BINDING)}"
rescue Exception => e
  "#{red('ERROR')} #{e.message}"
end
exit(_args) click to toggle source
# File lib/interpreter.rb, line 55
def exit(_args)
  exit!
end
Also aliased as: quit
help(_args) click to toggle source
# File lib/interpreter.rb, line 60
  def help(_args)
    <<-END.gsub(/^\s+\|/, "")
    |
    |Available commands:
    |  #{bold(':exit')}    Exit the shell
    |  #{bold(':help')}    Display this help message
    |  #{bold(':hist')}    Display edit-line history
    |  #{bold(':quit')}    Alias to #{bold(':exit')}
    |  #{bold(':')}number  Execute a specific expression from history
    |  #{bold(':!')} cmd   Execute a shell command à la Vim
    |
    END
  end
hist(_args) click to toggle source
# File lib/interpreter.rb, line 74
def hist(_args)
  "".tap do |history|
    Readline::HISTORY.to_a.each.with_index(1) do |command, index|
      history << "  #{bold('%03d' % index)}  #{command}\n"
    end
  end
end
method_missing(name, *_args) click to toggle source
# File lib/interpreter.rb, line 86
def method_missing(name, *_args)
  index = (name.to_s[1..-1].to_i - 1).tap { |index| raise StandardError if index == -1 }
  expression = Readline::HISTORY[index]
  Readline::HISTORY.pop
  Readline::HISTORY << expression
  process(expression)
end
process(expression) click to toggle source
# File lib/interpreter.rb, line 40
def process(expression)
  if expression.chr == ":"
    command(expression)
  else
    evaluate(expression)
  end
end
prompt(separator) click to toggle source
# File lib/interpreter.rb, line 36
def prompt(separator)
  "#{bold('ruby')}:#{format('%03d', (Readline::HISTORY.size + 1))}#{bold(separator)} "
end
quit(_args)
Alias for: exit