/
repl.rb
73 lines (63 loc) · 2.03 KB
/
repl.rb
1
2
3
4
5
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
load_assembly 'Microsoft.Scripting'
Hosting = Microsoft::Scripting::Hosting
Scripting = Microsoft::Scripting
class REPL
def initialize
@engine = IronRuby.create_engine
@scope = @engine.create_scope
@exception_service = @engine.method(:get_service).of(Hosting::ExceptionOperations).call
@language = "rb"
end
def run
while true
print "#@language> "
line = gets
break if line.nil?
if line[0] == ?#
execute_command line[1..-1].rstrip
else
execute_code read_code(line)
end
end
end
# Reads lines from standard input until a complete or invalid code snippet is entered.
# Returns ScriptSource that represents an interactive code.
def read_code first_line
code = first_line
while true
interactive_code = @engine.create_script_source_from_string(code, Scripting::SourceCodeKind.InteractiveCode)
case interactive_code.get_code_properties
when Scripting::ScriptCodeParseResult.Complete, Scripting::ScriptCodeParseResult.Invalid:
return interactive_code
else
print "#@language| "
next_line = gets
return interactive_code if next_line.nil? or next_line.strip.size == 0
code += next_line
end
end
end
# Executes given ScriptSource and prints any exceptions that it might raise.
def execute_code source
source.execute(@scope)
rescue Exception => e
message, name = @exception_service.get_exception_message(e)
puts "#{name}: #{message}"
end
def execute_command command
case command
when 'exit': exit
when 'ls?': display_languages
else puts "Unknown command '#{command}'" unless switch_language command
end
end
def display_languages
@engine.runtime.setup.language_setups.each { |ls| puts "#{ls.display_name}: #{ls.names.inspect}" }
end
def switch_language name
has_engine, engine = @engine.runtime.try_get_engine(name)
@language, @engine = name, engine if has_engine
has_engine
end
end
REPL.new.run