koi-vm-ruby 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/README.rdoc +64 -0
- data/Rakefile +42 -0
- data/VERSION +1 -0
- data/architecture.rdoc +112 -0
- data/examples/blastoff.rb +20 -0
- data/examples/hello_world.rb +8 -0
- data/koi-vm.gemspec +198 -0
- data/lib/.gitkeep +0 -0
- data/lib/koi-vm-ruby.rb +10 -0
- data/lib/koi-vm-ruby/accessors.rb +63 -0
- data/lib/koi-vm-ruby/core.rb +48 -0
- data/lib/koi-vm-ruby/exceptions.rb +8 -0
- data/lib/koi-vm-ruby/helpers.rb +5 -0
- data/lib/koi-vm-ruby/opcodes/_opcode_constants.rb +68 -0
- data/lib/koi-vm-ruby/opcodes/_value_constants.rb +11 -0
- data/lib/koi-vm-ruby/opcodes/comparative_operations/equal.rb +11 -0
- data/lib/koi-vm-ruby/opcodes/comparative_operations/greater_than.rb +14 -0
- data/lib/koi-vm-ruby/opcodes/comparative_operations/invert.rb +12 -0
- data/lib/koi-vm-ruby/opcodes/comparative_operations/less_than.rb +14 -0
- data/lib/koi-vm-ruby/opcodes/control_operations/exit.rb +10 -0
- data/lib/koi-vm-ruby/opcodes/control_operations/no_op.rb +9 -0
- data/lib/koi-vm-ruby/opcodes/flow_control_operations/jump.rb +11 -0
- data/lib/koi-vm-ruby/opcodes/flow_control_operations/jump_if.rb +16 -0
- data/lib/koi-vm-ruby/opcodes/flow_control_operations/jump_unless.rb +16 -0
- data/lib/koi-vm-ruby/opcodes/function_operations/call.rb +13 -0
- data/lib/koi-vm-ruby/opcodes/function_operations/push_function.rb +19 -0
- data/lib/koi-vm-ruby/opcodes/function_operations/return.rb +11 -0
- data/lib/koi-vm-ruby/opcodes/function_operations/tailcall.rb +12 -0
- data/lib/koi-vm-ruby/opcodes/hash_operations/get_key.rb +14 -0
- data/lib/koi-vm-ruby/opcodes/hash_operations/has_key.rb +18 -0
- data/lib/koi-vm-ruby/opcodes/hash_operations/length.rb +19 -0
- data/lib/koi-vm-ruby/opcodes/hash_operations/num_pairs.rb +12 -0
- data/lib/koi-vm-ruby/opcodes/hash_operations/pairs.rb +22 -0
- data/lib/koi-vm-ruby/opcodes/hash_operations/push_hash.rb +10 -0
- data/lib/koi-vm-ruby/opcodes/hash_operations/set_key.rb +14 -0
- data/lib/koi-vm-ruby/opcodes/io_operations/gets.rb +10 -0
- data/lib/koi-vm-ruby/opcodes/io_operations/print.rb +13 -0
- data/lib/koi-vm-ruby/opcodes/math_operations/add.rb +14 -0
- data/lib/koi-vm-ruby/opcodes/math_operations/divide.rb +14 -0
- data/lib/koi-vm-ruby/opcodes/math_operations/multiply.rb +14 -0
- data/lib/koi-vm-ruby/opcodes/math_operations/subtract.rb +14 -0
- data/lib/koi-vm-ruby/opcodes/push_operations/push_bool.rb +12 -0
- data/lib/koi-vm-ruby/opcodes/push_operations/push_float.rb +12 -0
- data/lib/koi-vm-ruby/opcodes/push_operations/push_int.rb +12 -0
- data/lib/koi-vm-ruby/opcodes/push_operations/push_nil.rb +10 -0
- data/lib/koi-vm-ruby/opcodes/push_operations/push_string.rb +12 -0
- data/lib/koi-vm-ruby/opcodes/stack_operations/dup.rb +11 -0
- data/lib/koi-vm-ruby/opcodes/stack_operations/pop.rb +11 -0
- data/lib/koi-vm-ruby/opcodes/stack_operations/stksize.rb +10 -0
- data/lib/koi-vm-ruby/opcodes/stack_operations/swap.rb +11 -0
- data/lib/koi-vm-ruby/opcodes/stack_operations/top.rb +13 -0
- data/lib/koi-vm-ruby/opcodes/stack_operations/typeof.rb +18 -0
- data/lib/koi-vm-ruby/opcodes/string_operations/concat.rb +12 -0
- data/lib/koi-vm-ruby/opcodes/string_operations/strlen.rb +12 -0
- data/lib/koi-vm-ruby/opcodes/string_operations/to_string.rb +16 -0
- data/lib/koi-vm-ruby/opcodes/variable_operations/get_global.rb +10 -0
- data/lib/koi-vm-ruby/opcodes/variable_operations/get_local.rb +10 -0
- data/lib/koi-vm-ruby/opcodes/variable_operations/set_global.rb +11 -0
- data/lib/koi-vm-ruby/opcodes/variable_operations/set_local.rb +11 -0
- data/test/.gitkeep +0 -0
- data/test/performance/.gitignore +1 -0
- data/test/performance/simple_benchmark.rb +87 -0
- data/test/setup/test_unit_extensions.rb +21 -0
- data/test/test_helper.rb +13 -0
- data/test/unit/opcodes/comparative_operations/equal_test.rb +116 -0
- data/test/unit/opcodes/comparative_operations/greater_than_test.rb +53 -0
- data/test/unit/opcodes/comparative_operations/invert_test.rb +44 -0
- data/test/unit/opcodes/comparative_operations/less_than_test.rb +53 -0
- data/test/unit/opcodes/control_operations/exit_test.rb +20 -0
- data/test/unit/opcodes/control_operations/no_op_test.rb +17 -0
- data/test/unit/opcodes/flow_control_operations/jump_if_test.rb +50 -0
- data/test/unit/opcodes/flow_control_operations/jump_test.rb +36 -0
- data/test/unit/opcodes/flow_control_operations/jump_unless_test.rb +50 -0
- data/test/unit/opcodes/function_operations/call_test.rb +39 -0
- data/test/unit/opcodes/function_operations/push_function_test.rb +41 -0
- data/test/unit/opcodes/function_operations/return_test.rb +31 -0
- data/test/unit/opcodes/function_operations/tailcall_test.rb +41 -0
- data/test/unit/opcodes/hash_operations/get_key_test.rb +56 -0
- data/test/unit/opcodes/hash_operations/has_key_test.rb +56 -0
- data/test/unit/opcodes/hash_operations/length_test.rb +46 -0
- data/test/unit/opcodes/hash_operations/num_pairs_test.rb +46 -0
- data/test/unit/opcodes/hash_operations/pairs_test.rb +67 -0
- data/test/unit/opcodes/hash_operations/push_hash_test.rb +16 -0
- data/test/unit/opcodes/hash_operations/set_key_test.rb +56 -0
- data/test/unit/opcodes/io_operations/gets_test.rb +38 -0
- data/test/unit/opcodes/io_operations/print_test.rb +42 -0
- data/test/unit/opcodes/math_operations/add_test.rb +62 -0
- data/test/unit/opcodes/math_operations/divide_test.rb +62 -0
- data/test/unit/opcodes/math_operations/multiply_test.rb +62 -0
- data/test/unit/opcodes/math_operations/subtract_test.rb +62 -0
- data/test/unit/opcodes/push_operations/push_bool_test.rb +36 -0
- data/test/unit/opcodes/push_operations/push_float_test.rb +27 -0
- data/test/unit/opcodes/push_operations/push_int_test.rb +27 -0
- data/test/unit/opcodes/push_operations/push_nil_test.rb +16 -0
- data/test/unit/opcodes/push_operations/push_string_test.rb +27 -0
- data/test/unit/opcodes/stack_operations/dup_test.rb +25 -0
- data/test/unit/opcodes/stack_operations/pop_test.rb +28 -0
- data/test/unit/opcodes/stack_operations/stksize_test.rb +20 -0
- data/test/unit/opcodes/stack_operations/swap_test.rb +36 -0
- data/test/unit/opcodes/stack_operations/top_test.rb +45 -0
- data/test/unit/opcodes/stack_operations/typeof_test.rb +79 -0
- data/test/unit/opcodes/string_operations/concat_test.rb +65 -0
- data/test/unit/opcodes/string_operations/strlen_test.rb +44 -0
- data/test/unit/opcodes/string_operations/to_string_test.rb +70 -0
- data/test/unit/opcodes/variable_operations/get_global_test.rb +18 -0
- data/test/unit/opcodes/variable_operations/get_local_test.rb +18 -0
- data/test/unit/opcodes/variable_operations/set_global_test.rb +27 -0
- data/test/unit/opcodes/variable_operations/set_local_test.rb +27 -0
- data/test/unit/vm_initialization_test.rb +86 -0
- metadata +224 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class CallTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should pass execution to function and push return position on the return stack" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.data_stack = [[FUNCTION_, 101]]
|
10
|
+
vm.run [
|
11
|
+
CALL
|
12
|
+
]
|
13
|
+
assert_equal [], vm.data_stack
|
14
|
+
assert_equal [1], vm.return_stack
|
15
|
+
assert_equal 101, vm.instruction_pointer
|
16
|
+
assert_equal 1, vm.level
|
17
|
+
end
|
18
|
+
|
19
|
+
test "should raise StackError if there are no items on the stack" do
|
20
|
+
assert_raises StackError do
|
21
|
+
vm = VM.new
|
22
|
+
vm.run [
|
23
|
+
CALL
|
24
|
+
]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
test "should raise StackError if topmost stack item is not a function" do
|
29
|
+
assert_raises StackError do
|
30
|
+
vm = VM.new
|
31
|
+
vm.data_stack = [[INTEGER_, 101]]
|
32
|
+
vm.run [
|
33
|
+
CALL
|
34
|
+
]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class PushFunctionTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should push function reference onto stack" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.run [
|
10
|
+
PUSH_FUNCTION, 1,
|
11
|
+
NO_OP,
|
12
|
+
NO_OP,
|
13
|
+
RETURN,
|
14
|
+
END_FUNCTION, 0,
|
15
|
+
END_FUNCTION, 1
|
16
|
+
]
|
17
|
+
assert_equal [[FUNCTION_, 2]], vm.data_stack
|
18
|
+
assert_equal 9, vm.instruction_pointer
|
19
|
+
end
|
20
|
+
|
21
|
+
test "should push function reference onto stack that contains nested function definition" do
|
22
|
+
vm = VM.new
|
23
|
+
vm.run [
|
24
|
+
PUSH_FUNCTION, 6,
|
25
|
+
NO_OP,
|
26
|
+
PUSH_FUNCTION, 2,
|
27
|
+
NO_OP,
|
28
|
+
RETURN,
|
29
|
+
END_FUNCTION, 0,
|
30
|
+
END_FUNCTION, 2,
|
31
|
+
NO_OP,
|
32
|
+
RETURN,
|
33
|
+
END_FUNCTION, 0,
|
34
|
+
END_FUNCTION, 6
|
35
|
+
]
|
36
|
+
assert_equal [[FUNCTION_, 2]], vm.data_stack
|
37
|
+
assert_equal 17, vm.instruction_pointer
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class ReturnTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should pass execution to topmost address on return stack and decrement scope" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.return_stack = [101]
|
10
|
+
assert_equal [101], vm.return_stack
|
11
|
+
vm.level = 1
|
12
|
+
vm.run [
|
13
|
+
RETURN
|
14
|
+
]
|
15
|
+
assert_equal [], vm.data_stack
|
16
|
+
assert_equal [], vm.return_stack
|
17
|
+
assert_equal 101, vm.instruction_pointer
|
18
|
+
assert_equal 0, vm.level
|
19
|
+
end
|
20
|
+
|
21
|
+
test "should raise ReturnStackError if there are no items on the return stack" do
|
22
|
+
assert_raises ReturnStackError do
|
23
|
+
vm = VM.new
|
24
|
+
vm.run [
|
25
|
+
RETURN
|
26
|
+
]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class TailcallTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should pass execution to new function without altering return stack, and reload scope" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.data_stack = [[FUNCTION_, 101]]
|
10
|
+
vm.level = 1
|
11
|
+
vm.return_stack = [1]
|
12
|
+
vm.run [
|
13
|
+
TAILCALL
|
14
|
+
]
|
15
|
+
assert_equal [], vm.data_stack
|
16
|
+
assert_equal [1], vm.return_stack
|
17
|
+
assert_equal 101, vm.instruction_pointer
|
18
|
+
assert_equal 1, vm.level
|
19
|
+
end
|
20
|
+
|
21
|
+
test "should raise StackError if there are no items on the stack" do
|
22
|
+
assert_raises StackError do
|
23
|
+
vm = VM.new
|
24
|
+
vm.run [
|
25
|
+
TAILCALL
|
26
|
+
]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
test "should raise StackError if topmost stack item is not a function" do
|
31
|
+
assert_raises StackError do
|
32
|
+
vm = VM.new
|
33
|
+
vm.data_stack = [[INTEGER_, 101]]
|
34
|
+
vm.run [
|
35
|
+
TAILCALL
|
36
|
+
]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class GetKeyTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should get key in hash" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.data_stack = [[HASH_, {[INTEGER_, 1] => [STRING_, "yay"]}], [INTEGER_, 1]]
|
10
|
+
vm.run [
|
11
|
+
GET_KEY
|
12
|
+
]
|
13
|
+
assert_equal [[STRING_, "yay"]], vm.data_stack
|
14
|
+
assert_equal 1, vm.instruction_pointer
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should get unset key in hash" do
|
18
|
+
vm = VM.new
|
19
|
+
vm.data_stack = [[HASH_, {}], [INTEGER_, 1]]
|
20
|
+
vm.run [
|
21
|
+
GET_KEY
|
22
|
+
]
|
23
|
+
assert_equal [[NIL_, nil]], vm.data_stack
|
24
|
+
assert_equal 1, vm.instruction_pointer
|
25
|
+
end
|
26
|
+
|
27
|
+
test "should raise StackError if stack[-2] is not a hash" do
|
28
|
+
assert_raises StackError do
|
29
|
+
vm = VM.new
|
30
|
+
vm.data_stack = [[INTEGER_, 1], [INTEGER_, 1]]
|
31
|
+
vm.run [
|
32
|
+
GET_KEY
|
33
|
+
]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
test "should raise StackError if there is only 1 item on the stack" do
|
38
|
+
assert_raises StackError do
|
39
|
+
vm = VM.new
|
40
|
+
vm.data_stack = [[HASH_, {}]]
|
41
|
+
vm.run [
|
42
|
+
GET_KEY
|
43
|
+
]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
test "should raise StackError if there are no items on the stack" do
|
48
|
+
assert_raises StackError do
|
49
|
+
vm = VM.new
|
50
|
+
vm.run [
|
51
|
+
GET_KEY
|
52
|
+
]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class HasKeyTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should return true as hash has key" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.data_stack = [[HASH_, {[INTEGER_, 1] => [STRING_, "yay"]}], [INTEGER_, 1]]
|
10
|
+
vm.run [
|
11
|
+
HAS_KEY
|
12
|
+
]
|
13
|
+
assert_equal [[BOOL_, true]], vm.data_stack
|
14
|
+
assert_equal 1, vm.instruction_pointer
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should return false as hash does not have key" do
|
18
|
+
vm = VM.new
|
19
|
+
vm.data_stack = [[HASH_, {}], [INTEGER_, 1]]
|
20
|
+
vm.run [
|
21
|
+
HAS_KEY
|
22
|
+
]
|
23
|
+
assert_equal [[BOOL_, false]], vm.data_stack
|
24
|
+
assert_equal 1, vm.instruction_pointer
|
25
|
+
end
|
26
|
+
|
27
|
+
test "should raise StackError if stack[-2] is not a hash" do
|
28
|
+
assert_raises StackError do
|
29
|
+
vm = VM.new
|
30
|
+
vm.data_stack = [[INTEGER_, 1], [INTEGER_, 1]]
|
31
|
+
vm.run [
|
32
|
+
HAS_KEY
|
33
|
+
]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
test "should raise StackError if there is only 1 item on the stack" do
|
38
|
+
assert_raises StackError do
|
39
|
+
vm = VM.new
|
40
|
+
vm.data_stack = [[HASH_, {}]]
|
41
|
+
vm.run [
|
42
|
+
HAS_KEY
|
43
|
+
]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
test "should raise StackError if there are no items on the stack" do
|
48
|
+
assert_raises StackError do
|
49
|
+
vm = VM.new
|
50
|
+
vm.run [
|
51
|
+
HAS_KEY
|
52
|
+
]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class LengthTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should return value of highest integer key + 1" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.data_stack = [[HASH_, {[INTEGER_, 1] => [STRING_, "yay"], [INTEGER_, 2] => [STRING_, "yay"], [INTEGER_, 6] => [STRING_, "yay"]}]]
|
10
|
+
vm.run [
|
11
|
+
LENGTH
|
12
|
+
]
|
13
|
+
assert_equal [[INTEGER_, 7]], vm.data_stack
|
14
|
+
assert_equal 1, vm.instruction_pointer
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should return 0" do
|
18
|
+
vm = VM.new
|
19
|
+
vm.data_stack = [[HASH_, {[STRING_, "1"] => [STRING_, "yay"], [STRING_, "2"] => [STRING_, "yay"], [STRING_, "3"] => [STRING_, "yay"]}]]
|
20
|
+
vm.run [
|
21
|
+
LENGTH
|
22
|
+
]
|
23
|
+
assert_equal [[INTEGER_, 0]], vm.data_stack
|
24
|
+
assert_equal 1, vm.instruction_pointer
|
25
|
+
end
|
26
|
+
|
27
|
+
test "should raise StackError if stack[-1] is not a hash" do
|
28
|
+
assert_raises StackError do
|
29
|
+
vm = VM.new
|
30
|
+
vm.data_stack = [[INTEGER_, 1]]
|
31
|
+
vm.run [
|
32
|
+
LENGTH
|
33
|
+
]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
test "should raise StackError if there are no items on the stack" do
|
38
|
+
assert_raises StackError do
|
39
|
+
vm = VM.new
|
40
|
+
vm.run [
|
41
|
+
LENGTH
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class NumPairsTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should return number of key-value pairs in hash" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.data_stack = [[HASH_, {[INTEGER_, 1] => [STRING_, "yay"], [INTEGER_, 2] => [STRING_, "yay"], [INTEGER_, 6] => [STRING_, "yay"]}]]
|
10
|
+
vm.run [
|
11
|
+
NUM_PAIRS
|
12
|
+
]
|
13
|
+
assert_equal [[INTEGER_, 3]], vm.data_stack
|
14
|
+
assert_equal 1, vm.instruction_pointer
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should return 0" do
|
18
|
+
vm = VM.new
|
19
|
+
vm.data_stack = [[HASH_, {}]]
|
20
|
+
vm.run [
|
21
|
+
NUM_PAIRS
|
22
|
+
]
|
23
|
+
assert_equal [[INTEGER_, 0]], vm.data_stack
|
24
|
+
assert_equal 1, vm.instruction_pointer
|
25
|
+
end
|
26
|
+
|
27
|
+
test "should raise StackError if stack[-1] is not a hash" do
|
28
|
+
assert_raises StackError do
|
29
|
+
vm = VM.new
|
30
|
+
vm.data_stack = [[INTEGER_, 1]]
|
31
|
+
vm.run [
|
32
|
+
NUM_PAIRS
|
33
|
+
]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
test "should raise StackError if there are no items on the stack" do
|
38
|
+
assert_raises StackError do
|
39
|
+
vm = VM.new
|
40
|
+
vm.run [
|
41
|
+
NUM_PAIRS
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class PairsTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should return new hash containing all the pairs from the previous hash with numeric indices" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.data_stack = [
|
10
|
+
[HASH_, {
|
11
|
+
[INTEGER_, 1] => [STRING_, "yay"],
|
12
|
+
[INTEGER_, 2] => [STRING_, "yay"],
|
13
|
+
[INTEGER_, 6] => [STRING_, "yay"]
|
14
|
+
}]
|
15
|
+
]
|
16
|
+
vm.run [
|
17
|
+
PAIRS
|
18
|
+
]
|
19
|
+
assert_equal [
|
20
|
+
[HASH_, {
|
21
|
+
[INTEGER_, 0] => [ HASH_, {
|
22
|
+
[INTEGER_, 0] => [INTEGER_, 1],
|
23
|
+
[INTEGER_, 1] => [STRING_, "yay"]
|
24
|
+
}],
|
25
|
+
[INTEGER_, 1] => [ HASH_, {
|
26
|
+
[INTEGER_, 0] => [INTEGER_, 2],
|
27
|
+
[INTEGER_, 1] => [STRING_, "yay"]
|
28
|
+
}],
|
29
|
+
[INTEGER_, 2] => [ HASH_, {
|
30
|
+
[INTEGER_, 0] => [INTEGER_, 6],
|
31
|
+
[INTEGER_, 1] => [STRING_, "yay"]
|
32
|
+
}]
|
33
|
+
}]
|
34
|
+
], vm.data_stack
|
35
|
+
assert_equal 1, vm.instruction_pointer
|
36
|
+
end
|
37
|
+
|
38
|
+
test "should return empty hash" do
|
39
|
+
vm = VM.new
|
40
|
+
vm.data_stack = [[HASH_, {}]]
|
41
|
+
vm.run [
|
42
|
+
PAIRS
|
43
|
+
]
|
44
|
+
assert_equal [[HASH_, {}]], vm.data_stack
|
45
|
+
assert_equal 1, vm.instruction_pointer
|
46
|
+
end
|
47
|
+
|
48
|
+
test "should raise StackError if stack[-1] is not a hash" do
|
49
|
+
assert_raises StackError do
|
50
|
+
vm = VM.new
|
51
|
+
vm.data_stack = [[INTEGER_, 1]]
|
52
|
+
vm.run [
|
53
|
+
PAIRS
|
54
|
+
]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
test "should raise StackError if there are no items on the stack" do
|
59
|
+
assert_raises StackError do
|
60
|
+
vm = VM.new
|
61
|
+
vm.run [
|
62
|
+
PAIRS
|
63
|
+
]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper.rb'))
|
2
|
+
|
3
|
+
class PushHashTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
include KoiVMRuby
|
6
|
+
|
7
|
+
test "should push hash onto stack" do
|
8
|
+
vm = VM.new
|
9
|
+
vm.run [
|
10
|
+
PUSH_HASH
|
11
|
+
]
|
12
|
+
assert_equal [[HASH_, {}]], vm.data_stack
|
13
|
+
assert_equal 1, vm.instruction_pointer
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|