public
Created

Mirah REPL -- hacked together

  • Download Gist
mirah_repl.rb
Ruby
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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
#
# Mirah REPL -- hacked to bits
#
# assuming your ruby is jruby,
# $ gem install mirah
# $ ruby -rubygems repl.rb
# m> class Foo
# m> def bar
# m> 12
# m> end
# m> end
# ...
# m> puts Foo.new.bar
# 12
#
#
require 'mirah'
 
include Mirah::Util::ProcessErrors
 
# global grumble brumble--implicit state in commands
Mirah::AST.type_factory = Mirah::JVM::Types::TypeFactory.new
@tmp_classes = []
buffer=""
while true
print " m> "
line = gets
 
break if line.chomp == "exit"
 
buffer += line
# from commands/base.rb & commands/parse.rb
@state = Mirah::Util::CompilationState.new
@state.command =:parse
@state.save_extensions = false
parser = Mirah::Parser.new(@state, false)
 
# OMG! instance_variable_get
transformer = parser.instance_variable_get :@transformer
# from parser.rb + rescue
begin
ast = parser.parse_and_transform 'RePl'+Time.now.to_i.to_s, buffer
rescue Mirah::SyntaxError => e
if e.message =~ /expected \w+ before '<EOF>'/
next
else
raise e
end
rescue NameError => e
puts e
next
end
buffer = ""
p ast
 
begin
# from test/jvm/bytecode_test_helper.rb
typer = Mirah::JVM::Typer.new(transformer)
ast.infer(typer, true)
typer.resolve(true)
rescue Mirah::InferenceError => ex
# from process_errors.rb
puts ex
if ex.node
Mirah.print_error(ex.message, ex.position)
else
puts ex.message
end
next
end
 
begin
compiler = Mirah::JVM::Compiler::JVMBytecode.new
compiler.compile(ast)
rescue Mirah::MirahError => ex
# from process_errors.rb
puts ex
if ex.node
Mirah.print_error(ex.message, ex.position)
else
puts ex.message
end
next
end
puts "compiled"
 
classes = {}
 
compiler.generate do |filename, builder|
bytes = builder.generate
FileUtils.mkdir_p(File.dirname(filename))
open("#{filename}", "wb") do |f|
f << bytes
end
classes[filename[0..-7]] = Mirah::Util::ClassLoader.binary_string bytes
end
puts "generated"
loader = Mirah::Util::ClassLoader.new(JRuby.runtime.jruby_class_loader, classes)
klasses = classes.keys.map do |name|
cls = loader.load_class(name.tr('/', '.'))
proxy = JavaUtilities.get_proxy_class(cls.name)
@tmp_classes << "# {name}.class"
proxy
end
puts "loaded"
 
if klasses.size == 1 && klasses[0].name.start_with?("Java::Default::RePl")
klasses[0].main(nil)
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.