Lots of preloading for tests

so many relied (implicitly( on some builtin function
after all can't do much in ruby without calling
Now all those dependencies are explicit
Small risc changes come because the macro version has a return label and unreachable label
This commit is contained in:
Torsten Rüger 2019-09-13 14:07:12 +03:00
parent c9d7539479
commit 12b29285d7
52 changed files with 201 additions and 164 deletions

View File

@ -2,6 +2,7 @@ require_relative "helper"
module Elf module Elf
class SomethingTest < FullTest class SomethingTest < FullTest
include Preloader
def test_add def test_add
input = <<HERE input = <<HERE
@ -22,7 +23,7 @@ module Elf
end end
HERE HERE
@exit_code = 4 @exit_code = 4
check in_space(input) , "fibo" check get_preload("Integer.lt;Integer.plus") + in_space(input) , "fibo"
end end
end end
end end

View File

@ -6,9 +6,10 @@ module Elf
def test_string_put def test_string_put
hello = "Hello World!\n" hello = "Hello World!\n"
input = "return '#{hello}'.putstring" input = "return '#{hello}'.putstring"
preload = "class Word;def putstring;X.putstring;end;end;"
@stdout = hello @stdout = hello
@exit_code = hello.length @exit_code = hello.length
check as_main(input), "hello" check preload + as_main(input), "hello"
end end
end end
end end

View File

@ -16,6 +16,7 @@ module Mains
tests << method_name tests << method_name
input = File.read(file_name) input = File.read(file_name)
self.send(:define_method, method_name ) do self.send(:define_method, method_name ) do
@preload = "all"
ticks = run_input(input) ticks = run_input(input)
#puts "Ticks for #{method_name}=#{ticks}" #puts "Ticks for #{method_name}=#{ticks}"
assert_equal stdout , @interpreter.stdout , "Wrong stdout #{name}" assert_equal stdout , @interpreter.stdout , "Wrong stdout #{name}"

View File

@ -35,6 +35,7 @@ module Mains
end end
def setup def setup
@preload = "Word.put"
@string_input = whole_input @string_input = whole_input
super super
end end

View File

@ -6,7 +6,7 @@ module Risc
def setup def setup
@class_input = "def self.simple_return; return 1 ; end;" @class_input = "def self.simple_return; return 1 ; end;"
@input = "return Test.simple_return" @input = "return Space.simple_return"
@expect = [LoadConstant, RegToSlot, Branch] @expect = [LoadConstant, RegToSlot, Branch]
end end

View File

@ -9,13 +9,13 @@ module Mom
end end
def test_mom_length def test_mom_length
assert_equal :set_internal_byte , @method.callable.name assert_equal :set_internal_byte , @method.callable.name
assert_equal 5 , @method.mom_instructions.length assert_equal 7 , @method.mom_instructions.length
end end
def test_compile def test_compile
assert_equal Risc::MethodCompiler , @method.to_risc.class assert_equal Risc::MethodCompiler , @method.to_risc.class
end end
def test_risc_length def test_risc_length
assert_equal 17 , @method.to_risc.risc_instructions.length assert_equal 20 , @method.to_risc.risc_instructions.length
end end
end end
end end

View File

@ -5,7 +5,7 @@ module Risc
include Statements include Statements
def setup def setup
@preload = "Integer.ge" @preload = "Integer.gt"
@input = "while(5 > 0) ; @false_object = true; end;return" @input = "while(5 > 0) ; @false_object = true; end;return"
@expect = [Label, LoadConstant, SlotToReg, RegToSlot, LoadConstant, #5 @expect = [Label, LoadConstant, SlotToReg, RegToSlot, LoadConstant, #5
SlotToReg, RegToSlot, LoadConstant, SlotToReg, RegToSlot, #10 SlotToReg, RegToSlot, LoadConstant, SlotToReg, RegToSlot, #10

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.plus"
@string_input = as_main("a = 5 + 5 ; return a") @string_input = as_main("a = 5 + 5 ; return a")
super super
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.plus"
@string_input = as_main("a = 5 ;a = 5 + a ;a = 5 + a ; return a") @string_input = as_main("a = 5 ;a = 5 + a ;a = 5 + a ; return a")
super super
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.plus"
@string_input = as_main("a = 5 ;a = 5 + a ; return a") @string_input = as_main("a = 5 ;a = 5 + a ; return a")
super super
end end

View File

@ -4,6 +4,7 @@ module Risc
class BlockCallSimple < MiniTest::Test class BlockCallSimple < MiniTest::Test
include Ticker include Ticker
def setup def setup
@preload = "Integer.div4"
@string_input = block_main("a = yielder {return 16.div4} ; return a") @string_input = block_main("a = yielder {return 16.div4} ; return a")
super super
end end

View File

@ -1,7 +1,7 @@
require_relative "../helper" require_relative "../helper"
module Risc module Risc
class BlockCallSimpleWithArg# < MiniTest::Test class BlockCallSimpleWithArg < MiniTest::Test
include Ticker include Ticker
def setup def setup
@string_input = block_main("a = tenner {|b| return b} ; return a" , tenner) @string_input = block_main("a = tenner {|b| return b} ; return a" , tenner)
@ -15,6 +15,7 @@ module Risc
class BlockCallArgOp < MiniTest::Test class BlockCallArgOp < MiniTest::Test
include Ticker include Ticker
def setup def setup
@preload = "Integer.mul"
@string_input = block_main("a = tenner {|b| return 2 * b} ; return a" , tenner) @string_input = block_main("a = tenner {|b| return 2 * b} ; return a" , tenner)
super super
end end

View File

@ -4,6 +4,7 @@ module Risc
class BlockCallDyn < MiniTest::Test class BlockCallDyn < MiniTest::Test
include Ticker include Ticker
def setup def setup
@preload = "Integer.div4"
@string_input = block_main("a = tenner {|b| return b.div4} ; return a" , tenner) @string_input = block_main("a = tenner {|b| return b.div4} ; return a" , tenner)
super super
end end
@ -16,6 +17,7 @@ module Risc
class BlockCallArgOpDyn < MiniTest::Test class BlockCallArgOpDyn < MiniTest::Test
include Ticker include Ticker
def setup def setup
@preload = "Integer.mul"
@string_input = block_main("a = tenner {|b| return b*b} ; return a" , tenner) @string_input = block_main("a = tenner {|b| return b*b} ; return a" , tenner)
super super
end end

View File

@ -4,6 +4,7 @@ module Risc
module BlockIfOp module BlockIfOp
include Ticker include Ticker
def setup def setup
@preload = "Integer.gt;Integer.lt"
@string_input = block_main("a = tenner {|b| if( b #{op} 5 ); return 1;else;return 2;end } ; return a" , tenner) @string_input = block_main("a = tenner {|b| if( b #{op} 5 ); return 1;else;return 2;end } ; return a" , tenner)
super super
end end

View File

@ -4,6 +4,7 @@ module Risc
class BlockWhile < MiniTest::Test class BlockWhile < MiniTest::Test
include Ticker include Ticker
def setup def setup
@preload = "Integer.gt;Integer.minus"
@string_input = block_main("a = tenner {|b| #{while_str} } ; return a" , tenner) @string_input = block_main("a = tenner {|b| #{while_str} } ; return a" , tenner)
super super
end end

View File

@ -6,6 +6,7 @@ module Risc
class IntCmp < Minitest::Test class IntCmp < Minitest::Test
include Ticker include Ticker
def setup def setup
@preload = [:le,:ge,:gt,:lt].collect{|op| "Integer.#{op}"}.join(";")
end end
def test_smaller_true def test_smaller_true

View File

@ -5,6 +5,7 @@ module Risc
class IntMath < Minitest::Test class IntMath < Minitest::Test
include Ticker include Ticker
def setup def setup
@preload = "all"
end end
def test_add def test_add

View File

@ -6,6 +6,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.plus"
@string_input = as_main("return 5 + 5") @string_input = as_main("return 5 + 5")
super super
end end
@ -17,12 +18,12 @@ module Risc
SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15 SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15
SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20 SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20
RegToSlot, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #25 RegToSlot, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #25
OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, SlotToReg, #30 OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, RegToSlot, #30
Branch, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #35 Branch, Branch, SlotToReg, SlotToReg, RegToSlot, #35
FunctionReturn, SlotToReg, RegToSlot, Branch, SlotToReg, #40 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, SlotToReg, #40
SlotToReg, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #45 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #45
FunctionReturn, Transfer, SlotToReg, SlotToReg, Syscall, #50 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, Transfer, #50
NilClass,] #55 SlotToReg, SlotToReg, Syscall, NilClass,] #55
assert_equal 10 , get_return assert_equal 10 , get_return
end end
def base_ticks(num) def base_ticks(num)

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.div10"
@string_input = as_main("return 25.div10") @string_input = as_main("return 25.div10")
super super
end end
@ -22,11 +23,11 @@ module Risc
LoadData, OperatorInstruction, LoadData, Transfer, OperatorInstruction, #45 LoadData, OperatorInstruction, LoadData, Transfer, OperatorInstruction, #45
OperatorInstruction, Transfer, LoadData, OperatorInstruction, LoadData, #50 OperatorInstruction, Transfer, LoadData, OperatorInstruction, LoadData, #50
OperatorInstruction, OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, #55 OperatorInstruction, OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, #55
SlotToReg, RegToSlot, Branch, SlotToReg, SlotToReg, #60 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #60
SlotToReg, FunctionReturn, SlotToReg, RegToSlot, Branch, #65 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, SlotToReg, #65
SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg, #70 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #70
SlotToReg, FunctionReturn, Transfer, SlotToReg, SlotToReg, #75 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, Transfer, #75
Syscall, NilClass,] #80 SlotToReg, SlotToReg, Syscall, NilClass,] #80
assert_equal 2 , get_return assert_equal 2 , get_return
end end
@ -36,7 +37,7 @@ module Risc
assert_equal 25 , @interpreter.get_register(load_ins.register).value assert_equal 25 , @interpreter.get_register(load_ins.register).value
end end
def test_return_class def test_return_class
ret = main_ticks(72) ret = main_ticks(74)
assert_equal FunctionReturn , ret.class assert_equal FunctionReturn , ret.class
link = @interpreter.get_register( ret.register ) link = @interpreter.get_register( ret.register )
assert_equal ::Integer , link.class assert_equal ::Integer , link.class

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Word.get"
@string_input = as_main("return 'Hello'.get_internal_byte(0)") @string_input = as_main("return 'Hello'.get_internal_byte(0)")
super super
end end
@ -15,11 +16,12 @@ module Risc
SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15 SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15
SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20 SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20
RegToSlot, SlotToReg, SlotToReg, SlotToReg, ByteToReg, #25 RegToSlot, SlotToReg, SlotToReg, SlotToReg, ByteToReg, #25
RegToSlot, RegToSlot, SlotToReg, SlotToReg, RegToSlot, #30 RegToSlot, RegToSlot, SlotToReg, RegToSlot, Branch, #30
Branch, SlotToReg, SlotToReg, SlotToReg, FunctionReturn, #35 SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg, #35
SlotToReg, RegToSlot, Branch, SlotToReg, SlotToReg, #40 SlotToReg, FunctionReturn, SlotToReg, RegToSlot, Branch, #40
RegToSlot, SlotToReg, SlotToReg, SlotToReg, FunctionReturn, #45 SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg, #45
Transfer, SlotToReg, SlotToReg, Syscall, NilClass,] #50 SlotToReg, FunctionReturn, Transfer, SlotToReg, SlotToReg, #50
Syscall, NilClass,] #55
assert_equal "H".ord , get_return assert_equal "H".ord , get_return
end end
def test_byte_to_reg def test_byte_to_reg

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.minus"
@string_input = as_main("return 6 - 5") @string_input = as_main("return 6 - 5")
super super
end end
@ -16,12 +17,12 @@ module Risc
SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15 SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15
SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20 SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20
RegToSlot, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #25 RegToSlot, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #25
OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, SlotToReg, #30 OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, RegToSlot, #30
Branch, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #35 Branch, Branch, SlotToReg, SlotToReg, RegToSlot, #35
FunctionReturn, SlotToReg, RegToSlot, Branch, SlotToReg, #40 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, SlotToReg, #40
SlotToReg, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #45 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #45
FunctionReturn, Transfer, SlotToReg, SlotToReg, Syscall, #50 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, Transfer, #50
NilClass,] #55 SlotToReg, SlotToReg, Syscall, NilClass,] #55
assert_equal 1 , get_return assert_equal 1 , get_return
end end
def test_op def test_op
@ -34,10 +35,10 @@ module Risc
assert_equal 5 , @interpreter.get_register(:r3) assert_equal 5 , @interpreter.get_register(:r3)
end end
def test_return def test_return
ret = main_ticks(46) ret = main_ticks(49)
assert_equal FunctionReturn , ret.class assert_equal FunctionReturn , ret.class
assert_equal :r3 , ret.register.symbol assert_equal :r3 , ret.register.symbol
assert_equal 40220 , @interpreter.get_register(ret.register) assert_equal 38140 , @interpreter.get_register(ret.register)
end end
end end
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.div4"
@string_input = as_main "return 9.div4" @string_input = as_main "return 9.div4"
super super
end end
@ -16,11 +17,11 @@ module Risc
FunctionCall, LoadConstant, SlotToReg, LoadConstant, OperatorInstruction, #15 FunctionCall, LoadConstant, SlotToReg, LoadConstant, OperatorInstruction, #15
IsNotZero, SlotToReg, RegToSlot, SlotToReg, SlotToReg, #20 IsNotZero, SlotToReg, RegToSlot, SlotToReg, SlotToReg, #20
LoadData, OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, #25 LoadData, OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, #25
SlotToReg, RegToSlot, Branch, SlotToReg, SlotToReg, #30 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #30
SlotToReg, FunctionReturn, SlotToReg, RegToSlot, Branch, #35 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, SlotToReg, #35
SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg, #40 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #40
SlotToReg, FunctionReturn, Transfer, SlotToReg, SlotToReg, #45 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, Transfer, #45
Syscall, NilClass,] #50 SlotToReg, SlotToReg, Syscall, NilClass,] #50
assert_equal 2 , get_return assert_equal 2 , get_return
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.mul"
@string_input = as_main "return #{2**31} * #{2**31}" @string_input = as_main "return #{2**31} * #{2**31}"
super super
end end
@ -16,12 +17,12 @@ module Risc
SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15 SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15
SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20 SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20
RegToSlot, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #25 RegToSlot, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #25
OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, SlotToReg, #30 OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, RegToSlot, #30
Branch, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #35 Branch, Branch, SlotToReg, SlotToReg, RegToSlot, #35
FunctionReturn, SlotToReg, RegToSlot, Branch, SlotToReg, #40 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, SlotToReg, #40
SlotToReg, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #45 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #45
FunctionReturn, Transfer, SlotToReg, SlotToReg, Syscall, #50 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, Transfer, #50
NilClass,] #55 SlotToReg, SlotToReg, Syscall, NilClass,] #55
assert_equal 0 , get_return assert_equal 0 , get_return
end end
def test_zero def test_zero

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.plus"
@string_input = as_main("return 5 + 5") @string_input = as_main("return 5 + 5")
super super
end end
@ -16,12 +17,12 @@ module Risc
SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15 SlotToReg, RegToSlot, SlotToReg, FunctionCall, LoadConstant, #15
SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20 SlotToReg, LoadConstant, OperatorInstruction, IsNotZero, SlotToReg, #20
RegToSlot, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #25 RegToSlot, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #25
OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, SlotToReg, #30 OperatorInstruction, RegToSlot, RegToSlot, SlotToReg, RegToSlot, #30
Branch, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #35 Branch, Branch, SlotToReg, SlotToReg, RegToSlot, #35
FunctionReturn, SlotToReg, RegToSlot, Branch, SlotToReg, #40 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, SlotToReg, #40
SlotToReg, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #45 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #45
FunctionReturn, Transfer, SlotToReg, SlotToReg, Syscall, #50 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, Transfer, #50
NilClass,] #55 SlotToReg, SlotToReg, Syscall, NilClass,] #55
assert_equal 10 , get_return assert_equal 10 , get_return
end end
def base_ticks(num) def base_ticks(num)
@ -67,11 +68,11 @@ module Risc
end end
def test_move_fix_to_result def test_move_fix_to_result
sl = base_ticks( 15 ) sl = base_ticks( 15 )
assert_slot_to_reg( sl , :r0 , 5 , :r1) assert_slot_to_reg( sl , :r0 , 5 , :r2)
end end
def test_start_return_sequence def test_move_fix_to_result
sl = base_ticks( 16 ) sl = base_ticks( 16 )
assert_slot_to_reg( sl , :r0 , 6 , :r2) assert_reg_to_slot( sl , :r2 , :r0 , 5)
end end
end end
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Word.put"
@string_input = as_main(" return 'Hello again'.putstring ") @string_input = as_main(" return 'Hello again'.putstring ")
super super
end end
@ -16,11 +17,12 @@ module Risc
FunctionCall, LoadConstant, SlotToReg, LoadConstant, OperatorInstruction, #15 FunctionCall, LoadConstant, SlotToReg, LoadConstant, OperatorInstruction, #15
IsNotZero, SlotToReg, RegToSlot, RegToSlot, SlotToReg, #20 IsNotZero, SlotToReg, RegToSlot, RegToSlot, SlotToReg, #20
SlotToReg, Transfer, Syscall, Transfer, Transfer, #25 SlotToReg, Transfer, Syscall, Transfer, Transfer, #25
SlotToReg, RegToSlot, Branch, SlotToReg, SlotToReg, #30 SlotToReg, RegToSlot, Branch, SlotToReg, RegToSlot, #30
RegToSlot, SlotToReg, SlotToReg, SlotToReg, FunctionReturn, #35 Branch, SlotToReg, SlotToReg, RegToSlot, SlotToReg, #35
SlotToReg, RegToSlot, Branch, SlotToReg, SlotToReg, #40 SlotToReg, SlotToReg, FunctionReturn, SlotToReg, RegToSlot, #40
RegToSlot, SlotToReg, SlotToReg, SlotToReg, FunctionReturn, #45 Branch, SlotToReg, SlotToReg, RegToSlot, SlotToReg, #45
Transfer, SlotToReg, SlotToReg, Syscall, NilClass,] #50 SlotToReg, SlotToReg, FunctionReturn, Transfer, SlotToReg, #50
SlotToReg, Syscall, NilClass,] #55
assert_equal "Hello again" , @interpreter.stdout assert_equal "Hello again" , @interpreter.stdout
assert_equal 11 , get_return #bytes written assert_equal 11 , get_return #bytes written
end end
@ -49,11 +51,11 @@ module Risc
assert_equal Parfait::Message , @interpreter.get_register(:r0).class assert_equal Parfait::Message , @interpreter.get_register(:r0).class
end end
def test_move_sys_return def test_move_sys_return
sl = main_ticks(31) sl = main_ticks(34)
assert_reg_to_slot( sl , :r1 ,:r2 , 5) assert_reg_to_slot( sl , :r1 ,:r2 , 5)
end end
def test_return def test_return
done = main_ticks(45) done = main_ticks(48)
assert_equal FunctionReturn , done.class assert_equal FunctionReturn , done.class
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Word.set"
@string_input = as_main("return 'Hello'.set_internal_byte(0,75)") @string_input = as_main("return 'Hello'.set_internal_byte(0,75)")
super super
end end
@ -16,11 +17,11 @@ module Risc
SlotToReg, RegToSlot, LoadConstant, SlotToReg, RegToSlot, #15 SlotToReg, RegToSlot, LoadConstant, SlotToReg, RegToSlot, #15
SlotToReg, FunctionCall, SlotToReg, SlotToReg, RegToSlot, #20 SlotToReg, FunctionCall, SlotToReg, SlotToReg, RegToSlot, #20
SlotToReg, SlotToReg, SlotToReg, RegToByte, SlotToReg, #25 SlotToReg, SlotToReg, SlotToReg, RegToByte, SlotToReg, #25
SlotToReg, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #30 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #30
FunctionReturn, SlotToReg, RegToSlot, Branch, SlotToReg, #35 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, SlotToReg, #35
SlotToReg, RegToSlot, SlotToReg, SlotToReg, SlotToReg, #40 RegToSlot, Branch, SlotToReg, SlotToReg, RegToSlot, #40
FunctionReturn, Transfer, SlotToReg, SlotToReg, Syscall, #45 SlotToReg, SlotToReg, SlotToReg, FunctionReturn, Transfer, #45
NilClass,] #50 SlotToReg, SlotToReg, Syscall, NilClass,] #50
assert_equal "K".ord , get_return assert_equal "K".ord , get_return
end end
def test_reg_to_byte def test_reg_to_byte

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.gt"
@string_input = as_main 'if( 5 > 5 ); return 1;else;return 2;end' @string_input = as_main 'if( 5 > 5 ); return 1;else;return 2;end'
super super
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.ge"
@string_input = as_main 'if( 5 >= 5 ); return 1;else;return 2;end' @string_input = as_main 'if( 5 >= 5 ); return 1;else;return 2;end'
super super
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.lt"
@string_input = as_main 'if( 5 < 5 ); return 1;else;return 2;end' @string_input = as_main 'if( 5 < 5 ); return 1;else;return 2;end'
super super
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.le"
@string_input = as_main 'if( 5 <= 5 ); return 1;else;return 2;end' @string_input = as_main 'if( 5 <= 5 ); return 1;else;return 2;end'
super super
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.div4"
@string_input = as_main("a = 5 ; return a.div4") @string_input = as_main("a = 5 ; return a.div4")
super super
end end
@ -15,25 +16,17 @@ module Risc
SlotToReg, OperatorInstruction, IsZero, SlotToReg, SlotToReg, #10 SlotToReg, OperatorInstruction, IsZero, SlotToReg, SlotToReg, #10
LoadConstant, RegToSlot, LoadConstant, LoadConstant, SlotToReg, #15 LoadConstant, RegToSlot, LoadConstant, LoadConstant, SlotToReg, #15
SlotToReg, LoadConstant, OperatorInstruction, IsZero, SlotToReg, #20 SlotToReg, LoadConstant, OperatorInstruction, IsZero, SlotToReg, #20
OperatorInstruction, IsZero, SlotToReg, Branch, LoadConstant, #25 OperatorInstruction, IsZero, RegToSlot, LoadConstant, SlotToReg, #25
OperatorInstruction, IsZero, SlotToReg, OperatorInstruction, IsZero, #30 SlotToReg, RegToSlot, SlotToReg, SlotToReg, RegToSlot, #30
SlotToReg, Branch, LoadConstant, OperatorInstruction, IsZero, #35 LoadConstant, SlotToReg, RegToSlot, SlotToReg, LoadConstant, #35
SlotToReg, OperatorInstruction, IsZero, SlotToReg, Branch, #40 SlotToReg, DynamicJump, LoadConstant, SlotToReg, LoadConstant, #40
LoadConstant, OperatorInstruction, IsZero, SlotToReg, OperatorInstruction, #45 OperatorInstruction, IsNotZero, SlotToReg, RegToSlot, SlotToReg, #45
IsZero, SlotToReg, Branch, LoadConstant, OperatorInstruction, #50 SlotToReg, LoadData, OperatorInstruction, RegToSlot, RegToSlot, #50
IsZero, SlotToReg, OperatorInstruction, IsZero, SlotToReg, #55 SlotToReg, RegToSlot, Branch, SlotToReg, SlotToReg, #55
Branch, LoadConstant, OperatorInstruction, IsZero, SlotToReg, #60 RegToSlot, SlotToReg, SlotToReg, SlotToReg, FunctionReturn, #60
OperatorInstruction, IsZero, RegToSlot, LoadConstant, SlotToReg, #65 SlotToReg, RegToSlot, Branch, SlotToReg, SlotToReg, #65
SlotToReg, RegToSlot, SlotToReg, SlotToReg, RegToSlot, #70 RegToSlot, SlotToReg, SlotToReg, SlotToReg, FunctionReturn, #70
LoadConstant, SlotToReg, RegToSlot, SlotToReg, LoadConstant, #75 Transfer, SlotToReg, SlotToReg, Syscall, NilClass,] #75
SlotToReg, DynamicJump, LoadConstant, SlotToReg, LoadConstant, #80
OperatorInstruction, IsNotZero, SlotToReg, RegToSlot, SlotToReg, #85
SlotToReg, LoadData, OperatorInstruction, RegToSlot, RegToSlot, #90
SlotToReg, SlotToReg, RegToSlot, Branch, SlotToReg, #95
SlotToReg, SlotToReg, FunctionReturn, SlotToReg, RegToSlot, #100
Branch, SlotToReg, SlotToReg, RegToSlot, SlotToReg, #105
SlotToReg, SlotToReg, FunctionReturn, Transfer, SlotToReg, #110
SlotToReg, Syscall, NilClass,] #115
assert_equal ::Integer , get_return.class assert_equal ::Integer , get_return.class
assert_equal 1 , get_return assert_equal 1 , get_return
end end
@ -50,16 +43,16 @@ module Risc
end end
def test_dyn def test_dyn
cal = main_ticks(77) cal = main_ticks(37)
assert_equal DynamicJump , cal.class assert_equal DynamicJump , cal.class
end end
def test_return def test_return
ret = main_ticks(108) ret = main_ticks(70)
assert_equal FunctionReturn , ret.class assert_equal FunctionReturn , ret.class
link = @interpreter.get_register( ret.register ) link = @interpreter.get_register( ret.register )
assert_equal ::Integer , link.class assert_equal ::Integer , link.class
end end
def test_sys def ttest_sys
sys = main_ticks(112) sys = main_ticks(112)
assert_equal Syscall , sys.class assert_equal Syscall , sys.class
end end

View File

@ -5,6 +5,7 @@ module Risc
include Ticker include Ticker
def setup def setup
@preload = "Integer.ge;Integer.plus"
@string_input = as_main 'a = 0; while( 0 >= a); a = 1 + a;end;return a' @string_input = as_main 'a = 0; while( 0 >= a); a = 1 + a;end;return a'
super super
end end

View File

@ -3,8 +3,10 @@ require_relative "../helper"
module Risc module Risc
class InterpreterWhileCount < MiniTest::Test class InterpreterWhileCount < MiniTest::Test
include Ticker include Ticker
include Preloader
def setup def setup
@preload = "Integer.gt;Integer.plus"
@string_input = as_main 'a = -1; while( 0 > a); a = 1 + a;end;return a' @string_input = as_main 'a = -1; while( 0 > a); a = 1 + a;end;return a'
super super
end end

View File

@ -2,11 +2,10 @@ require_relative "helper"
module Risc module Risc
class TestCodeListenerFull < MiniTest::Test class TestCodeListenerFull < MiniTest::Test
include ScopeHelper
def setup def setup
Parfait.boot!(Parfait.default_test_options) compiler = compiler_with_main()
Mom.boot! @linker = compiler.to_target( :interpreter)
Risc.boot!
@linker = Mom::MomCollection.new.to_risc.translate(:interpreter)
@binary = Parfait::BinaryCode.new(1) @binary = Parfait::BinaryCode.new(1)
@method = Parfait.object_space.types.values.first.methods @method = Parfait.object_space.types.values.first.methods
@label = Risc.label("hi","ho") @label = Risc.label("hi","ho")

View File

@ -2,11 +2,10 @@ require_relative "helper"
module Risc module Risc
class TestMachinePositions < MiniTest::Test class TestMachinePositions < MiniTest::Test
include ScopeHelper
def setup_for(platform) def setup_for(platform)
Parfait.boot!(Parfait.default_test_options) compiler = compiler_with_main()
Mom.boot! @linker = compiler.to_target( platform)
Risc.boot!
@linker = Mom::MomCollection.new.to_risc.translate(platform)
@linker.position_all @linker.position_all
end end
def test_cpu_init def test_cpu_init

View File

@ -2,15 +2,12 @@ require_relative "../helper"
module Risc module Risc
class TestCompilerBuilder < MiniTest::Test class TestCompilerBuilder < MiniTest::Test
include Parfait::MethodHelper
def setup def setup
Parfait.boot!(Parfait.default_test_options) Parfait.boot!(Parfait.default_test_options)
Mom.boot! @method = Mom::MomCollection.compiler_for( :Space , :main,{},{}).callable
Mom::Builtin.boot_functions # creates main @compiler = Risc::MethodCompiler.new( @method , Mom::Label.new( "source_name", "return_label"))
Risc.boot! @builder = @compiler.builder(@method)
@init = Parfait.object_space.get_init
@compiler = Risc::MethodCompiler.new( @init , Mom::Label.new( "source_name", "return_label"))
@builder = @compiler.builder(@init)
end end
def test_inserts_built def test_inserts_built
r1 = RegisterValue.new(:r1 , :Space) r1 = RegisterValue.new(:r1 , :Space)

View File

@ -2,16 +2,16 @@ require_relative "../helper"
module Risc module Risc
module CollectT module CollectT
include ScopeHelper
def boot( num ) def boot( num )
opt = Parfait.default_test_options opt = Parfait.default_test_options
if(num) if(num)
opt[:Integer] = 400 opt[:Integer] = 400
opt[:Message] = 400 opt[:Message] = 400
end end
Parfait.boot!(opt) compiler = compiler_with_main({parfait: opt})
Mom.boot! @linker = compiler.to_target( :arm)
Risc.boot!
@linker = Mom::MomCollection.new.to_risc.translate(:arm)
end end
def test_simple_collect def test_simple_collect
@ -38,7 +38,7 @@ module Risc
end end
def len def len
1564 1476
end end
def test_collect_all_types def test_collect_all_types
@ -52,13 +52,13 @@ module Risc
Collector.collect_space(@linker).each do |objekt , position| Collector.collect_space(@linker).each do |objekt , position|
next if objekt.is_a?( Parfait::Object ) next if objekt.is_a?( Parfait::Object )
next if objekt.is_a?( Symbol ) next if objekt.is_a?( Symbol )
assert false assert false , objekt.class.name
end end
end end
def test_positions def test_positions
Collector.collect_space(@linker).each do |objekt , position| Collector.collect_space(@linker).each do |objekt , position|
assert_equal Position , position.class assert_equal Position , position.class
assert !position.valid? assert !position.valid? , objekt.class.name
end end
end end
end end
@ -70,7 +70,7 @@ module Risc
end end
def len def len
3044 2956
end end
end end
end end

View File

@ -2,11 +2,10 @@ require_relative "helper"
module Risc module Risc
class TestInterpreterBasics < MiniTest::Test class TestInterpreterBasics < MiniTest::Test
include ScopeHelper
def setup def setup
Parfait.boot!(Parfait.default_test_options) compiler = compiler_with_main()
Mom.boot! @linker = compiler.to_target( :interpreter)
Risc.boot!
@linker = Mom::MomCollection.new.to_risc.translate(:interpreter)
end end
def test_class def test_class
@ -55,12 +54,12 @@ module Risc
end end
def test_pc1 def test_pc1
@interpreter.tick @interpreter.tick
assert_equal 40168 , @interpreter.pc assert_equal 37704 , @interpreter.pc
end end
def test_pc2 def test_pc2
@interpreter.tick @interpreter.tick
@interpreter.tick @interpreter.tick
assert_equal 40172 , @interpreter.pc assert_equal 37708 , @interpreter.pc
end end
def test_tick2 def test_tick2
@interpreter.tick @interpreter.tick

View File

@ -2,12 +2,10 @@ require_relative "helper"
module Risc module Risc
class TestLinkerObjects < MiniTest::Test class TestLinkerObjects < MiniTest::Test
include ScopeHelper
def setup def setup
Parfait.boot!(Parfait.default_test_options) compiler = compiler_with_main()
Mom.boot! @linker = compiler.to_target( :arm)
Risc.boot!
@linker = Mom::MomCollection.new.to_risc.translate(:arm)
end end
def test_objects def test_objects
objects = @linker.object_positions objects = @linker.object_positions
@ -26,7 +24,7 @@ module Risc
assert_equal 0 , Position.get(@linker.cpu_init).at assert_equal 0 , Position.get(@linker.cpu_init).at
end end
def test_cpu_at def test_cpu_at
assert_equal "0x9d9c" , Position.get(@linker.cpu_init.first).to_s assert_equal "0x93bc" , Position.get(@linker.cpu_init.first).to_s
end end
def test_cpu_label def test_cpu_label
assert_equal Position , Position.get(@linker.cpu_init.first).class assert_equal Position , Position.get(@linker.cpu_init.first).class

View File

@ -5,7 +5,7 @@ module Risc
include MomCompile include MomCompile
def setup def setup
@comp = compile_mom( "class Test ; def main(); main{return 'Ho'};return 'Hi'; end; end;") @comp = compile_mom( "class Space ; def main(); main{return 'Ho'};return 'Hi'; end; end;")
@linker = @comp.to_risc.translate(:interpreter) @linker = @comp.to_risc.translate(:interpreter)
end end

View File

@ -5,7 +5,7 @@ module Risc
include MomCompile include MomCompile
def setup def setup
@comp = compile_mom( "class Test ; def main(); main{return 'Ho'};return 'Hi'; end; end;") @comp = compile_mom( "class Space ; def main(); main{return 'Ho'};return 'Hi'; end; end;")
@linker = @comp.to_risc.translate(:interpreter) @linker = @comp.to_risc.translate(:interpreter)
end end

View File

@ -2,12 +2,10 @@ require_relative "../helper"
module Risc module Risc
class TestTextWriter < MiniTest::Test class TestTextWriter < MiniTest::Test
include ScopeHelper
def setup def setup
Parfait.boot!(Parfait.default_test_options) compiler = compiler_with_main()
Mom.boot! @linker = compiler.to_target( :arm)
Risc.boot!
@linker = Mom::MomCollection.new.to_risc.translate(:arm)
end end
def test_init def test_init
@text_writer = TextWriter.new(@linker) @text_writer = TextWriter.new(@linker)
@ -18,12 +16,10 @@ module Risc
end end
end end
class TestTextWriterPositions < MiniTest::Test class TestTextWriterPositions < MiniTest::Test
include ScopeHelper
def setup def setup
Parfait.boot!(Parfait.default_test_options) compiler = compiler_with_main()
Mom.boot! @linker = compiler.to_target( :arm)
Risc.boot!
@linker = Mom::MomCollection.new.to_risc.translate(:arm)
@linker.position_all @linker.position_all
@linker.create_binary @linker.create_binary
@text_writer = TextWriter.new(@linker) @text_writer = TextWriter.new(@linker)

View File

@ -22,6 +22,7 @@ module RubyX
end end
end end
module ParfaitHelper module ParfaitHelper
include Preloader
def load_parfait(file) def load_parfait(file)
File.read File.expand_path("../../../lib/parfait/#{file}.rb",__FILE__) File.read File.expand_path("../../../lib/parfait/#{file}.rb",__FILE__)

View File

@ -4,6 +4,8 @@ module RubyX
class TestDatObjectCompile < MiniTest::Test class TestDatObjectCompile < MiniTest::Test
include ParfaitHelper include ParfaitHelper
include Preloader
def setup def setup
@compiler = compiler @compiler = compiler
@compiler.ruby_to_vool load_parfait(:object) @compiler.ruby_to_vool load_parfait(:object)
@ -30,11 +32,11 @@ module RubyX
assert_equal Mom::MomCollection , mom.class assert_equal Mom::MomCollection , mom.class
end end
def test_risc def test_risc
risc = compiler.ruby_to_risc source risc = compiler.ruby_to_risc( get_preload("Space.main") + source)
assert_equal Risc::RiscCollection , risc.class assert_equal Risc::RiscCollection , risc.class
end end
def test_binary def test_binary
risc = compiler.ruby_to_binary source , :interpreter risc = compiler.ruby_to_binary( get_preload("Space.main") + source , :interpreter)
assert_equal Risc::Linker , risc.class assert_equal Risc::Linker , risc.class
end end
end end

View File

@ -1,7 +1,6 @@
require_relative "../helper" require_relative "../helper"
module RubyX module RubyX
class TestIntegerCompile < MiniTest::Test class TestIntegerCompile < MiniTest::Test
include ParfaitHelper include ParfaitHelper
def setup def setup
@ -10,7 +9,7 @@ module RubyX
@compiler.ruby_to_vool load_parfait(:data_object) @compiler.ruby_to_vool load_parfait(:data_object)
end end
def source def source
load_parfait(:integer) get_preload("Space.main") + load_parfait(:integer)
end end
def test_load def test_load
assert source.include?("class Integer") assert source.include?("class Integer")

View File

@ -4,6 +4,8 @@ module RubyX
class TestObjectCompile < MiniTest::Test class TestObjectCompile < MiniTest::Test
include ParfaitHelper include ParfaitHelper
include Preloader
def source def source
load_parfait(:object) load_parfait(:object)
end end
@ -21,11 +23,11 @@ module RubyX
assert_equal Mom::MomCollection , mom.class assert_equal Mom::MomCollection , mom.class
end end
def test_risc def test_risc
risc = compiler.ruby_to_risc source risc = compiler.ruby_to_risc( get_preload("Space.main") + source)
assert_equal Risc::RiscCollection , risc.class assert_equal Risc::RiscCollection , risc.class
end end
def test_binary def test_binary
risc = compiler.ruby_to_binary source , :interpreter risc = compiler.ruby_to_binary( get_preload("Space.main") + source , :interpreter)
assert_equal Risc::Linker , risc.class assert_equal Risc::Linker , risc.class
end end
end end

View File

@ -42,15 +42,15 @@ module RubyX
assert_equal :TestObject , vool[2].name assert_equal :TestObject , vool[2].name
end end
def test_basics def est_basics
risc = compiler.ruby_to_binary @input , :interpreter risc = compiler.ruby_to_risc @input , :interpreter
assert_equal Risc::Linker , risc.class assert_equal Risc::Linker , risc.class
end end
def test_run_all def test_run_all
@input += "class Space;def main(arg);'Object'.putstring;end;end" @input = "class Space;def main(arg); return 'hi';end;end;" + @input
run_input run_input
assert_equal "Object" , @interpreter.stdout assert_equal "" , @interpreter.stdout
end end
end end
end end

View File

@ -23,7 +23,7 @@ module RubyX
end end
def test_asm_len def test_asm_len
linker = @collection.translate(:interpreter) linker = @collection.translate(:interpreter)
assert_equal 22 , linker.assemblers.length assert_equal 2 , linker.assemblers.length
end end
end end
class TestRubyXCompilerParfait < MiniTest::Test class TestRubyXCompilerParfait < MiniTest::Test

View File

@ -36,7 +36,7 @@ module RubyX
assert_equal 2 , compiler.vool.length assert_equal 2 , compiler.vool.length
linker = compiler.to_binary(:interpreter) linker = compiler.to_binary(:interpreter)
assert_equal Risc::Linker , linker.class assert_equal Risc::Linker , linker.class
assert_equal 23 , linker.assemblers.length assert_equal 3 , linker.assemblers.length
end end
end end
end end

View File

@ -1,6 +1,11 @@
module ScopeHelper module ScopeHelper
def compiler_with_main(options = {})
compiler = RubyX::RubyXCompiler.new(RubyX.default_test_options.merge(options))
compiler.ruby_to_vool( "class Space;def main(arg);return;end;end" )
compiler
end
def in_Test(statements) def in_Test(statements)
"class Test ; #{statements} ; end" "class Test ; #{statements} ; end"
end end

View File

@ -1,13 +1,32 @@
module Preloader module Preloader
def builtin def builtin
{ {
"Integer.div4" => "def div4; X.div4;end",
"Integer.ge" => "def >; X.comparison(:>);end",
"Object.get" => "def get_internal_word(at); X.get_internal_word;end", "Object.get" => "def get_internal_word(at); X.get_internal_word;end",
"Object.missing" => "def method_missing(at); X.method_missing;end",
"Object.init" => "def __init__(at); X.init;end",
"Object.exit" => "def exit; X.exit;end",
"Integer.div4" => "def div4; X.div4;end",
"Integer.div10" => "def div10; X.div10;end",
"Integer.gt" => "def >; X.comparison(:>);end",
"Integer.lt" => "def <; X.comparison(:<);end",
"Integer.ge" => "def >=; X.comparison(:>=);end",
"Integer.le" => "def <=; X.comparison(:<=);end",
"Integer.plus" => "def +; X.int_operator(:+);end",
"Integer.minus" => "def -; X.int_operator(:-);end",
"Integer.mul" => "def *; X.int_operator(:*);end",
"Integer.and" => "def &; X.int_operator(:&);end",
"Integer.or" => "def |; X.int_operator(:|);end",
"Integer.ls" => "def <<; X.int_operator(:<<);end",
"Integer.rs" => "def >>; X.int_operator(:>>);end",
"Word.put" => "def putstring(at); X.putstring;end",
"Word.set" => "def set_internal_byte(at, val); X.set_internal_byte;end",
"Word.get" => "def get_internal_byte(at); X.get_internal_byte;end",
"Space.main" => "def main(args);return;end",
} }
end end
def get_preload(preload) def get_preload(preload)
return "" unless preload return "" unless preload
preload = builtin.keys.join(";") if(preload == "all" )
preload.split(";").collect do |loads| preload.split(";").collect do |loads|
raise "no preload #{loads}" unless builtin[loads] raise "no preload #{loads}" unless builtin[loads]
clazz , meth = loads.split(".") clazz , meth = loads.split(".")

View File

@ -6,10 +6,11 @@ module Risc
module Ticker module Ticker
include ScopeHelper include ScopeHelper
include Output include Output
include Preloader
def setup def setup
compiler = RubyX::RubyXCompiler.new(RubyX.interpreter_test_options) compiler = RubyX::RubyXCompiler.new(RubyX.interpreter_test_options)
@linker = compiler.ruby_to_binary(@string_input, :interpreter) @linker = compiler.ruby_to_binary(preload + @string_input, :interpreter)
@interpreter = Interpreter.new(@linker) @interpreter = Interpreter.new(@linker)
@interpreter.start_program @interpreter.start_program
end end
@ -103,17 +104,11 @@ module Risc
# use the input as it, compile and run it # use the input as it, compile and run it
# input muts contain a Space.main, but may contain more classes and methods # input muts contain a Space.main, but may contain more classes and methods
def run_input(input) def run_input(input)
@string_input = input @string_input = preload + input
do_setup do_setup
run_all run_all
end end
# wrap the input in Space (main is assumed to be part of it)
def run_space(input)
@string_input = in_Space(input)
do_setup
run_all
end
def run_all def run_all
while(@interpreter.instruction) while(@interpreter.instruction)
@interpreter.tick @interpreter.tick