require "util/eventable" require "risc/interpreter" require_relative "compiling" module Risc module Ticker include CompilerHelper def setup Risc.machine.boot do_clean_compile Vool::VoolCompiler.ruby_to_vool( @string_input ) Collector.collect_space @interpreter = Interpreter.new @interpreter.start Risc.machine.risc_init end alias :do_setup :setup # must be after boot, but before main compile, to define method def do_clean_compile end # check the given array of instructions is what the interpreter actually does # possible second argument ignores the given amount, usually up until main def check_chain( should , start_at = 0 ) ticks( start_at ) if start_at > 0 should.each_with_index do |name , index| got = ticks(1) assert_equal got.class ,name , "Wrong class for #{index + 1 - start_at}, expect #{name} , got #{got}" end end # check the main only, ignoring the __init instructions def check_main_chain( should ) check_chain( should , main_at) end # how many instruction up until the main starts, ie # ticks(main_at) will be the label for main def main_at 26 end def get_return assert_equal Parfait::Message , @interpreter.get_register(:r0).class @interpreter.get_register(:r0).return_value end # do as many as given ticks in the main, ie main_at more def main_ticks(num) ticks( main_at + num) end # do a certain number of steps in the interpreter and return the last executed instruction def ticks( num ) last = nil num.times do last = @interpreter.instruction @interpreter.tick end return last end # collect the classes of all executed istructions def all_classes classes = [] tick = 1 begin while true and (classes.length < 300) cl = ticks(1).class tick += 1 classes << cl break if cl == NilClass end rescue => e puts "Error at tick #{tick}" puts e puts e.backtrace end classes end # do the setup, compile and run the input to the end def run_all(input) @string_input = as_main(input) do_setup all_classes end # for chaning the tests quickly output all instructions that are executed def show_ticks classes = all_classes output_classes(classes) end # show all instructions of the main only def show_main_ticks classes = all_classes classes = classes.slice(main_at , 1000) output_classes(classes) end def output_classes(classes) str = classes.to_s.gsub("Risc::","") all = str.split(",").each_slice(5).collect {|line| " " + line.join(",")} puts all.join(",\n") puts "length = #{classes.length}" exit(1) end end end