class Rus3::Repl

Provides a very simple Read Eval Print Loop mechanism of Rus3.

Features:

Each evaluated value is recorded into the value history.

  _, _last_value       : retrieves the last evaluated value
  _his(n), _history(n) : retrieves the n-th value in the
  history.
  _his, _history       : prints all values in the history

Short usage:

require "rus3"
Rus3::Repl.start

Constants

COMPONENTS

Hods major component names of the REPL.

FAREWELL_MESSAGE

A message to print at exitting.

PROMPT

Prompt for input.

REPL_VERSION

Indicates the version of the Repl class.

Public Class Methods

new(evaluator: nil, verbose: false) click to toggle source
# File lib/rus3/repl.rb, line 54
def initialize(evaluator: nil, verbose: false)
  comps = COMPONENTS.dup

  comps[:evaluator] = Evaluator.const_get("#{evaluator.capitalize}Evaluator") if evaluator

  comps.each { |name, klass|
    instance_variable_set("@#{name}", klass.new)
  }

  @prompt = PROMPT

  @verbose = verbose
  @evaluator.verbose = verbose
  @printer.verbose = verbose

  define_constants
  define_help_feature
  define_history_feature
  define_load_feature

  greeting
end
start(evaluator: nil, verbose: false) click to toggle source

Starts REPL.

# File lib/rus3/repl.rb, line 29
def start(evaluator: nil, verbose: false)
  repl = Repl.new(evaluator: evaluator, verbose: verbose)
  repl.loop
end

Public Instance Methods

greeting() click to toggle source

Shows the greeting message.

# File lib/rus3/repl.rb, line 103
def greeting
  puts "A simple REPL to run Rus3:"
  return unless @verbose

  vmsg =  "(rus3 :version #{Rus3::VERSION} :release #{Rus3::RELEASE}\n"
  vmsg += "  (repl :version #{REPL_VERSION}\n"

  comp_vmsgs = []
  COMPONENTS.keys.each { |comp_name|
    comp_vmsgs << "    (#{version_message(comp_name)})"
  }
  vmsg += comp_vmsgs.join("\n")
  vmsg += "))"

  puts vmsg
end
loop() click to toggle source
# File lib/rus3/repl.rb, line 77
def loop
  msg = Kernel.loop {       # LOOP
    begin
      source = read(STDIN)  # READ
      break FAREWELL_MESSAGE if source.nil?
      ast = @parser.parse(Rbscmlex::Lexer.new(source))
    rescue SchemeSyntaxError => e
      puts "ERROR" + (@verbose ? "(READ)" : "")  + ": %s" % e
      next
    end

    begin
      value = @evaluator.eval(ast) # EVAL
    rescue SyntaxError, StandardError => e
      puts "ERROR" + (@verbose ? "(EVAL)" : "")  + ": %s" % e
      next
    end

    history_push(value)

    @printer.print(value)   # PRINT
  }
  puts "#{msg}" unless msg.nil?
end