Skip to content

Instantly share code, notes, and snippets.

@paigeruten
Created January 30, 2011 03:42
Show Gist options
  • Save paigeruten/802499 to your computer and use it in GitHub Desktop.
Save paigeruten/802499 to your computer and use it in GitHub Desktop.
A very simple and rough and slow REPL for Java
# 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