Created
January 30, 2011 03:42
-
-
Save paigeruten/802499 to your computer and use it in GitHub Desktop.
A very simple and rough and slow REPL for Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A very simple and rough and slow REPL for Java, but it's better than making a | |
# new Java program every time you want to test something. | |
class JavaREPL | |
def initialize(filename = "JavaREPL") | |
@filename = filename | |
reset | |
end | |
def repl | |
loop { java_print java_eval java_read } | |
end | |
def java_read | |
if @continued_line | |
print " ..> " | |
else | |
print "java> " | |
end | |
gets.chomp | |
end | |
def java_eval(input) | |
if java_cmd(input) | |
"" | |
elsif input[input.length - 1] == ?\\ | |
@program += "\n" + input[0, input.length - 1] | |
@continued_line = true | |
"" | |
else | |
@program += "\n" + input | |
@continued_line = false | |
@program = @program.strip | |
@program.gsub! /^\/\*JavaREPL\*\/System\.out\.println/, 'eat' | |
@program.sub! /^(.*?[^;])\z/, '/*JavaREPL*/System.out.println(\1);' | |
imports_str = @imports.map { |name| "import #{name};" }.join("\n") | |
java = " | |
#{imports_str} | |
public class #@filename { | |
public static void main(String[] args) { | |
#@program | |
} | |
public static void eat(Object obj) { | |
} | |
} | |
" | |
File.open("#@filename.java", "w") do |f| | |
f << java | |
end | |
javac_result = `javac #@filename.java 2>&1` | |
result = `java #@filename 2>&1` | |
`rm -f #@filename.java #@filename.class` | |
java_error(javac_result) || result | |
end | |
end | |
def java_print(result) | |
puts result unless result.empty? | |
end | |
def java_cmd(input) | |
case input.strip | |
when "exit" | |
raise StopIteration | |
true | |
when "reset" | |
@program = "" | |
true | |
when "list" | |
puts @program | |
true | |
when /^import (.+?)$/ | |
java_import($1) | |
true | |
when /^unimport (.+?)$/ | |
java_unimport($1) | |
true | |
when "error" | |
puts @error | |
true | |
else | |
false | |
end | |
end | |
def java_error(result) | |
if result =~ /\A#{Regexp.escape @filename}\.java:\d+:(.+?)$/ | |
error_msg = $1 | |
@error = result | |
@program.sub! /^.+\z/, '' | |
if error_msg == " 'void' type not allowed here" | |
"Java error: You were probably supposed to put a semicolon on that statement." | |
else | |
"Java error: #{error_msg}" | |
end | |
end | |
end | |
def java_import(name) | |
@imports << name unless @imports.include? name | |
end | |
def java_unimport(name) | |
@imports.delete name | |
end | |
def reset | |
@program = "" | |
@imports = [] | |
@continued_line = false | |
end | |
end | |
if __FILE__ == $0 | |
JavaREPL.new.repl | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment