Module: Rouge::REPL

Defined in:
lib/rouge/repl.rb

Defined Under Namespace

Modules: Completer

Class Method Summary collapse

Class Method Details

.run!(options = {:backtrace => true}) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rouge/repl.rb', line 6

def self.run!(options = {:backtrace => true})
  puts "Rouge #{Rouge::VERSION}"

  repl_error = lambda do |e|
    STDOUT.puts "!! #{e.class}: #{e.message}"

    if options[:backtrace]
      STDOUT.puts "#{e.backtrace.join "\n"}"
    end
  end

  context = Rouge::Context.new(Rouge[:user])
  count = 0
  chaining = false
  Readline.completion_proc = Completer.new(context.ns)

  while true

    if !chaining
      prompt = "#{context.ns.name}=> "
      input = Readline.readline(prompt, true)
    else
      prompt = "#{" " * [0, context.ns.name.length - 2].max}#_=> "
      input << "\n" + Readline.readline(prompt, true)
    end

    if input.nil?
      STDOUT.print "\n"
      break
    end

    begin
      form = context.ns.read(input)
    rescue Rouge::Reader::EOFError
      next
    rescue Rouge::Reader::EndOfDataError
      chaining = true
      next
    rescue Rouge::Reader::UnexpectedCharacterError => reader_err
      repl_error.call(reader_err)
    rescue Rouge::Reader::NumberFormatError => reader_err
      repl_error.call(reader_err)
    end

    chaining = false

    begin
      form = Rouge::Compiler.compile(context.ns,
                                     Set[*context.lexical_keys],
                                     form)

      result = context.eval(form)

      Rouge.print(result, STDOUT)
      STDOUT.puts

      count += 1 if count < 10
      count.downto(2) do |i|
        context.set_here :"*#{i}", context[:"*#{i - 1}"]
      end
      context.set_here :"*1", result
    rescue Rouge::Context::ChangeContextException => cce
      context = cce.context
      # Since completion is context sensitive, we need update the proc
      # whenever it changes.
      Readline.completion_proc = Completer.new(context.ns)
      count = 0
    rescue => e
      repl_error.call(e)
    end
  end
end