2018-04-26 11:33:19 +02:00
|
|
|
require_relative '../helper'
|
|
|
|
|
|
|
|
module Mains
|
2020-03-26 19:28:59 +01:00
|
|
|
module MainsHelper
|
|
|
|
include Preloader
|
|
|
|
include ScopeHelper
|
|
|
|
|
|
|
|
def setup
|
|
|
|
@qemu = ENV["qemu-arm"] || "qemu-arm"
|
|
|
|
@linker = ENV["arm-linux-gnu-ld"] || "arm-linux-gnu-ld" #on fedora
|
|
|
|
@arm = ENV["TEST_ARM"] or ENV["TEST_ALL"]
|
|
|
|
#@linker = "arm-linux-gnueabi-ld" # on ubuntu
|
|
|
|
# ENV["TEST_ARM"] = "DEBUG"
|
|
|
|
end
|
|
|
|
|
|
|
|
def assert_result( exit_code , stdout , name = nil)
|
|
|
|
name = caller_locations.first.label unless name
|
|
|
|
input = preload + @input
|
|
|
|
code , out = run_interpreter( input , name)
|
|
|
|
assert_equal exit_code , code , "interpreter code for #{name}"
|
|
|
|
assert_equal stdout , out , "interpreter stdout for #{name}"
|
|
|
|
return unless @arm
|
|
|
|
code , out = run_arm( input , name)
|
|
|
|
assert_equal exit_code , code , "arm code for #{name}"
|
|
|
|
assert_equal stdout , out , "arm stdout for #{name}"
|
|
|
|
end
|
|
|
|
|
|
|
|
# runnable_methods is called by minitest to determine which tests to run
|
|
|
|
def self.runnable_methods
|
|
|
|
all = Dir["test/mains/source/*_*.rb"]
|
|
|
|
tests =[]
|
|
|
|
return tests unless has_qemu
|
|
|
|
all.each do |file_name|
|
|
|
|
fullname = file_name.split("/").last.split(".").first
|
|
|
|
order , name , stdout , exit_code = fullname.split("_")
|
|
|
|
method_name = "test_#{order}_#{name}"
|
|
|
|
input = File.read(file_name)
|
|
|
|
tests << method_name
|
|
|
|
self.send(:define_method, method_name ) do
|
|
|
|
out , code = run_code(input , "#{order}_#{name}")
|
|
|
|
assert_equal stdout , out , "Wrong stdout #{name}"
|
|
|
|
assert_equal exit_code , code.to_s , "Wrong exit code #{name}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
tests
|
|
|
|
end
|
|
|
|
|
|
|
|
def run_arm(input , name )
|
|
|
|
puts "Compiling #{name}" if ENV["TEST_ARM"] == "DEBUG"
|
|
|
|
linker = ::RubyX::RubyXCompiler.new({}).ruby_to_binary( input , :arm )
|
|
|
|
writer = Elf::ObjectWriter.new(linker)
|
|
|
|
writer.save "mains.o"
|
|
|
|
puts "Linking #{name}" if ENV["TEST_ARM"] == "DEBUG"
|
|
|
|
`#{@linker} -N mains.o`
|
|
|
|
assert_equal 0 , $?.exitstatus , "Linking #{name} failed #{$?}"
|
|
|
|
puts "Running #{name}" if ENV["TEST_ARM"] == "DEBUG"
|
|
|
|
stdout = `#{@qemu} ./a.out`
|
|
|
|
exit_code = $?.exitstatus
|
|
|
|
puts "Arm #{stdout} #{exit_code}" if ENV["TEST_ARM"] == "DEBUG"
|
|
|
|
return exit_code , stdout
|
|
|
|
end
|
|
|
|
|
|
|
|
def run_interpreter(input , name )
|
|
|
|
puts "Interpreting #{name}" if ENV["TEST_ARM"] == "DEBUG"
|
|
|
|
compiler = RubyX::RubyXCompiler.new(RubyX.default_test_options)
|
|
|
|
linker = compiler.ruby_to_binary(input , :interpreter)
|
|
|
|
interpreter = Risc::Interpreter.new(linker)
|
|
|
|
interpreter.start_program
|
|
|
|
interpreter.tick while(interpreter.instruction)
|
|
|
|
saved_in = interpreter.std_reg(:saved_message)
|
|
|
|
assert_equal Parfait::Message , interpreter.get_register(saved_in).class
|
|
|
|
ret = interpreter.get_register(interpreter.std_reg(:syscall_1))
|
|
|
|
puts "Interpret #{interpreter.stdout} #{ret}" if ENV["TEST_ARM"] == "DEBUG"
|
|
|
|
return ret , interpreter.stdout
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2018-04-26 11:33:19 +02:00
|
|
|
end
|