diff --git a/lib/rubyx/rubyxc.rb b/lib/rubyx/rubyxc.rb index 93b21a0d..7aee2ea2 100644 --- a/lib/rubyx/rubyxc.rb +++ b/lib/rubyx/rubyxc.rb @@ -3,10 +3,12 @@ require "rubyx" require "risc/interpreter" class RubyXC < Thor + class_option :parfait , type: :numeric + + desc "compile FILE" , "Compile given FILE to binary" long_desc <<-LONGDESC - Very basic cli to compile ruby programs. - Currently only compile command supported without option. + Compile the give file name to binary object file (see long descr.) Output will be elf object file of the same name, with .o, in root directory. @@ -23,30 +25,33 @@ class RubyXC < Thor end puts "compiling #{file}" - linker = ::RubyX::RubyXCompiler.new({}).ruby_to_binary( ruby , :arm ) + linker = ::RubyX::RubyXCompiler.new(extract_options).ruby_to_binary( ruby , :arm ) writer = Elf::ObjectWriter.new(linker) outfile = file.split("/").last.gsub(".rb" , ".o") writer.save outfile + + return outfile end + desc "interpret FILE" , "Interpret given FILE " long_desc <<-LONGDESC - Compiles the given file to an intermediate RISC format, and runs the - Interpreter. + Compiles the given file to an intermediate RISC format, and runs the + Interpreter. - RISC is the last abstract layer inside the compiler. It is in nature - very close to arm (without quirks and much smaller). + RISC is the last abstract layer inside the compiler. It is in nature + very close to arm (without quirks and much smaller). - An interpreter was originally developed for the RISC layer for debugging purposes. - Running the interpreter is about 50k slower than binary, but it can be used - to veryfy simple programs. + An interpreter was originally developed for the RISC layer for debugging purposes. + Running the interpreter is about 50k slower than binary, but it can be used + to veryfy simple programs. - No output file will be generated, the only output is generated by the - given program. + No output file will be generated, the only output is generated by the + given program. - The program must define a main method on the Space class, which will be invoked. - LONGDESC + The program must define a main method on the Space class, which will be invoked. + LONGDESC def interpret(file) begin @@ -54,11 +59,7 @@ class RubyXC < Thor rescue fail MalformattedArgumentError , "No such file #{file}" end - options = { - parfait: { factory: 3*1024, }, - load_parfait: false , - } - compiler = RubyX::RubyXCompiler.new(options) + compiler = RubyX::RubyXCompiler.new(extract_options) linker = compiler.ruby_to_binary(ruby, :interpreter) puts "interpreting #{file}" @@ -68,4 +69,38 @@ class RubyXC < Thor interpreter.tick while(interpreter.instruction) end + + desc "execute FILE" , "Compile given FILE and execute resulting binary" + long_desc <<-LONGDESC + Just like the compile task, this compiles the file to an object/binary file. + + Then rubyxc will link and run the resulting object file. For this to work, + qemu needs to be set up correctly on the system. Specifically, because of + bug #13, arm-linux-gnueabihf-ld needs to exist (it's part of the cross compiled + arm binutils). + + The resulting a.out will be run via qemu-arm. This is part of the qemu "linux" package + and interprets the arm binary on the host, assuming a linux os. + + This whole approach should only be used for preliminary checking that no core-dumps + are generated by the program, or when no benchmarking (as the times will be whatever). + + For simple functional test though, it is a much much quicker way to run the binary + than transferring it to another machine. The a.out is left in place to be run again. + LONGDESC + + def execute(file) + outfile = compile(file) + system "arm-linux-gnueabihf-ld -N #{outfile}" + puts "Linked ok, now running #{file}" + system "qemu-arm ./a.out" + end + + private + def extract_options + opt = { factory: options[:parfait] || 1024 } + puts opt + return {parfait: opt} + end + end