gisele-vm 0.6.0

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.
Files changed (185) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +18 -0
  3. data/Gemfile.lock +46 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +15 -0
  6. data/README.md +10 -0
  7. data/Rakefile +11 -0
  8. data/bin/gvm +9 -0
  9. data/gisele-vm.gemspec +191 -0
  10. data/gisele-vm.noespec +31 -0
  11. data/lib/gisele-vm.rb +4 -0
  12. data/lib/gisele-vm/loader.rb +5 -0
  13. data/lib/gisele-vm/version.rb +16 -0
  14. data/lib/gisele/compiling.rb +3 -0
  15. data/lib/gisele/compiling/gisele2gts.rb +143 -0
  16. data/lib/gisele/compiling/gts.rb +74 -0
  17. data/lib/gisele/compiling/gts2bytecode.rb +127 -0
  18. data/lib/gisele/vm.rb +87 -0
  19. data/lib/gisele/vm/bytecode.rb +84 -0
  20. data/lib/gisele/vm/bytecode/builder.rb +77 -0
  21. data/lib/gisele/vm/bytecode/grammar.citrus +116 -0
  22. data/lib/gisele/vm/bytecode/grammar.rb +19 -0
  23. data/lib/gisele/vm/bytecode/grammar.sexp.yml +113 -0
  24. data/lib/gisele/vm/bytecode/printer.rb +35 -0
  25. data/lib/gisele/vm/command.rb +140 -0
  26. data/lib/gisele/vm/component.rb +91 -0
  27. data/lib/gisele/vm/console.rb +58 -0
  28. data/lib/gisele/vm/enacter.rb +29 -0
  29. data/lib/gisele/vm/errors.rb +26 -0
  30. data/lib/gisele/vm/event.rb +11 -0
  31. data/lib/gisele/vm/event_manager.rb +65 -0
  32. data/lib/gisele/vm/kernel.rb +58 -0
  33. data/lib/gisele/vm/kernel/macros.gvm +214 -0
  34. data/lib/gisele/vm/kernel/opcodes.rb +212 -0
  35. data/lib/gisele/vm/kernel/runner.rb +63 -0
  36. data/lib/gisele/vm/lifecycle.rb +72 -0
  37. data/lib/gisele/vm/logging.rb +18 -0
  38. data/lib/gisele/vm/null_object.rb +19 -0
  39. data/lib/gisele/vm/prog.rb +63 -0
  40. data/lib/gisele/vm/prog_list.rb +55 -0
  41. data/lib/gisele/vm/prog_list/memory.rb +74 -0
  42. data/lib/gisele/vm/prog_list/sqldb.rb +123 -0
  43. data/lib/gisele/vm/prog_list/storage.rb +31 -0
  44. data/lib/gisele/vm/proxy.rb +14 -0
  45. data/lib/gisele/vm/proxy/client.rb +64 -0
  46. data/lib/gisele/vm/proxy/server.rb +29 -0
  47. data/lib/gisele/vm/registry.rb +57 -0
  48. data/lib/gisele/vm/robustness.rb +31 -0
  49. data/lib/gisele/vm/simulator/resumer.rb +32 -0
  50. data/spec/command/gvm_compile.cmd +1 -0
  51. data/spec/command/gvm_compile.stdout +111 -0
  52. data/spec/command/gvm_gts.cmd +1 -0
  53. data/spec/command/gvm_gts.stdout +101 -0
  54. data/spec/command/gvm_help.cmd +1 -0
  55. data/spec/command/gvm_help.stdout +30 -0
  56. data/spec/command/gvm_version.cmd +1 -0
  57. data/spec/command/gvm_version.stdout +2 -0
  58. data/spec/command/test_command.rb +29 -0
  59. data/spec/fixtures/complete.gis +13 -0
  60. data/spec/fixtures/fake_component.rb +24 -0
  61. data/spec/fixtures/kernel.rb +39 -0
  62. data/spec/fixtures/ts.adl +11 -0
  63. data/spec/fixtures/ts.gts +20 -0
  64. data/spec/fixtures/ts.gvm +19 -0
  65. data/spec/spec_helper.rb +86 -0
  66. data/spec/test_examples.rb +29 -0
  67. data/spec/test_gisele-vm.rb +8 -0
  68. data/spec/unit/bytecode/builder/test_at.rb +56 -0
  69. data/spec/unit/bytecode/builder/test_helpers.rb +36 -0
  70. data/spec/unit/bytecode/builder/test_instruction.rb +35 -0
  71. data/spec/unit/bytecode/builder/test_to_a.rb +53 -0
  72. data/spec/unit/bytecode/bytecode.gvm +1 -0
  73. data/spec/unit/bytecode/grammar/fixtures/comments.gvm +16 -0
  74. data/spec/unit/bytecode/grammar/fixtures/every.gvm +46 -0
  75. data/spec/unit/bytecode/grammar/fixtures/singleblock.gvm +2 -0
  76. data/spec/unit/bytecode/grammar/fixtures/twoblocks.gvm +4 -0
  77. data/spec/unit/bytecode/grammar/fixtures/with_end.gvm +5 -0
  78. data/spec/unit/bytecode/grammar/test_array.rb +24 -0
  79. data/spec/unit/bytecode/grammar/test_block.rb +35 -0
  80. data/spec/unit/bytecode/grammar/test_boolean.rb +20 -0
  81. data/spec/unit/bytecode/grammar/test_constant.rb +20 -0
  82. data/spec/unit/bytecode/grammar/test_eol.rb +20 -0
  83. data/spec/unit/bytecode/grammar/test_eol_comment.rb +36 -0
  84. data/spec/unit/bytecode/grammar/test_file.rb +38 -0
  85. data/spec/unit/bytecode/grammar/test_hash.rb +33 -0
  86. data/spec/unit/bytecode/grammar/test_instruction.rb +32 -0
  87. data/spec/unit/bytecode/grammar/test_int.rb +24 -0
  88. data/spec/unit/bytecode/grammar/test_label.rb +24 -0
  89. data/spec/unit/bytecode/grammar/test_opcode.rb +23 -0
  90. data/spec/unit/bytecode/grammar/test_string.rb +25 -0
  91. data/spec/unit/bytecode/grammar/test_symbol.rb +30 -0
  92. data/spec/unit/bytecode/test_build.rb +36 -0
  93. data/spec/unit/bytecode/test_coerce.rb +41 -0
  94. data/spec/unit/bytecode/test_fetch.rb +20 -0
  95. data/spec/unit/bytecode/test_grammar.rb +30 -0
  96. data/spec/unit/bytecode/test_parse.rb +22 -0
  97. data/spec/unit/bytecode/test_plus.rb +27 -0
  98. data/spec/unit/bytecode/test_to_a.rb +19 -0
  99. data/spec/unit/bytecode/test_to_s.rb +32 -0
  100. data/spec/unit/command/code.gis +3 -0
  101. data/spec/unit/command/test_vm.rb +51 -0
  102. data/spec/unit/compiling/gisele2gts/test_on_par_st.rb +51 -0
  103. data/spec/unit/compiling/gisele2gts/test_on_seq_st.rb +46 -0
  104. data/spec/unit/compiling/gisele2gts/test_on_task_call_st.rb +37 -0
  105. data/spec/unit/compiling/gisele2gts/test_on_task_def.rb +49 -0
  106. data/spec/unit/compiling/gisele2gts/test_on_unit_def.rb +35 -0
  107. data/spec/unit/compiling/gts2bytecode/test_on_end.rb +31 -0
  108. data/spec/unit/compiling/gts2bytecode/test_on_event.rb +37 -0
  109. data/spec/unit/compiling/gts2bytecode/test_on_fork.rb +41 -0
  110. data/spec/unit/compiling/gts2bytecode/test_on_join.rb +42 -0
  111. data/spec/unit/compiling/gts2bytecode/test_on_listen.rb +36 -0
  112. data/spec/unit/compiling/gts2bytecode/test_on_nop.rb +30 -0
  113. data/spec/unit/component/test_component_name.rb +16 -0
  114. data/spec/unit/component/test_logging.rb +36 -0
  115. data/spec/unit/enacter/test_component.rb +11 -0
  116. data/spec/unit/event/test_to_s.rb +12 -0
  117. data/spec/unit/event_manager/test_component.rb +9 -0
  118. data/spec/unit/event_manager/test_subscribe.rb +40 -0
  119. data/spec/unit/event_manager/test_unsubscribe.rb +39 -0
  120. data/spec/unit/kernel/macros/test_fork.rb +37 -0
  121. data/spec/unit/kernel/macros/test_join.rb +43 -0
  122. data/spec/unit/kernel/macros/test_listen.rb +37 -0
  123. data/spec/unit/kernel/macros/test_notify.rb +57 -0
  124. data/spec/unit/kernel/macros/test_react.rb +47 -0
  125. data/spec/unit/kernel/macros/test_schedule_at.rb +30 -0
  126. data/spec/unit/kernel/opcodes/test_op_del.rb +42 -0
  127. data/spec/unit/kernel/opcodes/test_op_event.rb +25 -0
  128. data/spec/unit/kernel/opcodes/test_op_fetch.rb +27 -0
  129. data/spec/unit/kernel/opcodes/test_op_flip.rb +17 -0
  130. data/spec/unit/kernel/opcodes/test_op_fold.rb +29 -0
  131. data/spec/unit/kernel/opcodes/test_op_fork.rb +63 -0
  132. data/spec/unit/kernel/opcodes/test_op_forka.rb +51 -0
  133. data/spec/unit/kernel/opcodes/test_op_get.rb +62 -0
  134. data/spec/unit/kernel/opcodes/test_op_getr.rb +48 -0
  135. data/spec/unit/kernel/opcodes/test_op_ifenil.rb +41 -0
  136. data/spec/unit/kernel/opcodes/test_op_ifezero.rb +32 -0
  137. data/spec/unit/kernel/opcodes/test_op_invoke.rb +34 -0
  138. data/spec/unit/kernel/opcodes/test_op_nop.rb +18 -0
  139. data/spec/unit/kernel/opcodes/test_op_parent.rb +39 -0
  140. data/spec/unit/kernel/opcodes/test_op_pop.rb +22 -0
  141. data/spec/unit/kernel/opcodes/test_op_push.rb +17 -0
  142. data/spec/unit/kernel/opcodes/test_op_save.rb +32 -0
  143. data/spec/unit/kernel/opcodes/test_op_savea.rb +34 -0
  144. data/spec/unit/kernel/opcodes/test_op_self.rb +20 -0
  145. data/spec/unit/kernel/opcodes/test_op_send.rb +20 -0
  146. data/spec/unit/kernel/opcodes/test_op_set.rb +61 -0
  147. data/spec/unit/kernel/opcodes/test_op_then.rb +50 -0
  148. data/spec/unit/kernel/opcodes/test_op_unfold.rb +22 -0
  149. data/spec/unit/kernel/opcodes/test_op_uuid.rb +16 -0
  150. data/spec/unit/kernel/runner/test_pop.rb +26 -0
  151. data/spec/unit/kernel/runner/test_stack.rb +28 -0
  152. data/spec/unit/kernel/test_progress.rb +47 -0
  153. data/spec/unit/kernel/test_resume.rb +53 -0
  154. data/spec/unit/kernel/test_start.rb +36 -0
  155. data/spec/unit/prog/test_to_hash.rb +29 -0
  156. data/spec/unit/prog/test_waitlist_eq.rb +20 -0
  157. data/spec/unit/prog_list/memory/test_component.rb +9 -0
  158. data/spec/unit/prog_list/memory/test_fetch.rb +40 -0
  159. data/spec/unit/prog_list/memory/test_pick.rb +39 -0
  160. data/spec/unit/prog_list/memory/test_save.rb +91 -0
  161. data/spec/unit/prog_list/memory/test_to_relation.rb +17 -0
  162. data/spec/unit/prog_list/sqldb/test_component.rb +11 -0
  163. data/spec/unit/prog_list/sqldb/test_connect.rb +46 -0
  164. data/spec/unit/prog_list/test_memory.rb +9 -0
  165. data/spec/unit/prog_list/test_sqldb.rb +13 -0
  166. data/spec/unit/prog_list/test_storage.rb +51 -0
  167. data/spec/unit/registry/test_component.rb +9 -0
  168. data/spec/unit/registry/test_connect.rb +53 -0
  169. data/spec/unit/registry/test_disconnect.rb +51 -0
  170. data/spec/unit/registry/test_registration.rb +44 -0
  171. data/spec/unit/shared/a_component.rb +49 -0
  172. data/spec/unit/shared/a_storage.rb +114 -0
  173. data/spec/unit/test_logging.rb +46 -0
  174. data/spec/unit/test_prog.rb +57 -0
  175. data/spec/unit/test_prog_list.rb +22 -0
  176. data/spec/unit/vm/test_event_facace.rb +11 -0
  177. data/spec/unit/vm/test_initialize.rb +59 -0
  178. data/spec/unit/vm/test_proglist_facade.rb +21 -0
  179. data/tasks/debug_mail.rake +75 -0
  180. data/tasks/debug_mail.txt +13 -0
  181. data/tasks/gem.rake +73 -0
  182. data/tasks/spec_test.rake +71 -0
  183. data/tasks/unit_test.rake +76 -0
  184. data/tasks/yard.rake +51 -0
  185. metadata +493 -0
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_getr" do
5
+
6
+ before do
7
+ runner.stack = [ receiver ]
8
+ end
9
+
10
+ context 'with a hash' do
11
+ let(:receiver){ {:hello => "World"} }
12
+
13
+ it 'pushes the result on the stack and removes the receiver' do
14
+ runner.op_getr(:hello)
15
+ runner.stack.should eq(["World"])
16
+ end
17
+
18
+ it 'takes the attribute name from the stack if unspecified' do
19
+ runner.op_push :hello
20
+ runner.op_getr
21
+ runner.stack.should eq(["World"])
22
+ end
23
+ end
24
+
25
+ context 'with an object' do
26
+ let(:receiver){ Prog.new(:pc => 12) }
27
+
28
+ it 'pushes the result on the stack and removes the receiver' do
29
+ runner.op_getr(:pc)
30
+ runner.stack.should eq([12])
31
+ end
32
+
33
+ it 'takes the attribute name from the stack if unspecified' do
34
+ runner.op_push :pc
35
+ runner.op_getr
36
+ runner.stack.should eq([12])
37
+ end
38
+
39
+ it 'raises an Error if no such method' do
40
+ lambda{
41
+ runner.op_getr(:nosuchone)
42
+ }.should raise_error(VM::Error)
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_ifenil" do
5
+
6
+ subject do
7
+ runner.opcodes = [ [:ifenil], [:push, 12], [:push, 24] ]
8
+ runner.run(nil, stack)
9
+ runner.stack
10
+ end
11
+
12
+ context 'when nil on the stack' do
13
+ let(:stack){ [ nil ] }
14
+
15
+ it 'skips the second op' do
16
+ subject.should eq([ nil, 12 ])
17
+ end
18
+
19
+ end
20
+
21
+ context 'when stack is empty' do
22
+ let(:stack){ [ ] }
23
+
24
+ it 'skips the second op' do
25
+ subject.should eq([ 12 ])
26
+ end
27
+
28
+ end
29
+
30
+ context 'when peek is not nil' do
31
+ let(:stack){ [ 56 ] }
32
+
33
+ it 'skips the first op' do
34
+ subject.should eq([ 56, 24 ])
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_ifezero" do
5
+
6
+ subject do
7
+ runner.opcodes = [ [:ifezero], [:push, 12], [:push, 24] ]
8
+ runner.run(nil, stack)
9
+ runner.stack
10
+ end
11
+
12
+ context 'when zero is on the stack' do
13
+ let(:stack){ [ 0 ] }
14
+
15
+ it 'skips the second op' do
16
+ subject.should eq([ 0, 12 ])
17
+ end
18
+
19
+ end
20
+
21
+ context 'when peek is not zero' do
22
+ let(:stack){ [ 56 ] }
23
+
24
+ it 'skips the first op' do
25
+ subject.should eq([ 56, 24 ])
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_invoke" do
5
+
6
+ def hello(*args)
7
+ @args = args
8
+ end
9
+
10
+ before do
11
+ runner.stack = [ self, [ "world", "!" ] ]
12
+ end
13
+
14
+ after do
15
+ @args.should eq(["world", "!"])
16
+ end
17
+
18
+ it 'invoke as expected' do
19
+ runner.op_invoke(:hello)
20
+ end
21
+
22
+ it 'does not push back on the stack' do
23
+ runner.op_invoke(:hello)
24
+ runner.stack.should eq([])
25
+ end
26
+
27
+ it 'takes the method name from the stack if unspecified' do
28
+ runner.op_push :hello
29
+ runner.op_invoke
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_nop" do
5
+
6
+ subject do
7
+ runner.op_nop
8
+ runner.stack
9
+ end
10
+
11
+ it 'does nothing' do
12
+ runner.stack = [ 12 ]
13
+ subject.should eq([ 12 ])
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_parent" do
5
+
6
+ let(:runn){ runner(@child) }
7
+
8
+ context 'with a parent' do
9
+
10
+ before do
11
+ @parent = list.save Prog.new
12
+ @child = list.save Prog.new(:parent => @parent)
13
+ end
14
+
15
+ it 'puts the parent of the current prog on the stack' do
16
+ runn.stack = [ ]
17
+ runn.op_parent
18
+ runn.stack.should eq([ list.fetch(@parent) ])
19
+ end
20
+
21
+ end
22
+
23
+ context 'without parent' do
24
+
25
+ before do
26
+ @child = list.save Prog.new
27
+ end
28
+
29
+ it 'puts the parent of the current prog on the stack' do
30
+ runn.stack = [ ]
31
+ runn.op_parent
32
+ runn.stack.should eq([ nil ])
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_pop" do
5
+
6
+ before do
7
+ runner.stack = [ 1, 2 ]
8
+ end
9
+
10
+ it 'fetches with the puid' do
11
+ runner.op_pop
12
+ runner.stack.should eq([ 1 ])
13
+ end
14
+
15
+ it 'allows specifying the number of pops to do' do
16
+ runner.op_pop(2)
17
+ runner.stack.should eq([ ])
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_push" do
5
+
6
+ before do
7
+ runner.stack = [ 1 ]
8
+ end
9
+
10
+ it 'fetches with the puid' do
11
+ runner.op_push 'hello'
12
+ runner.stack.should eq([ 1, 'hello' ])
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_save" do
5
+
6
+ before do
7
+ @puid0 = list.save Prog.new
8
+ @puid1 = list.save Prog.new
9
+ @at0 = list.fetch(@puid0)
10
+ @at1 = list.fetch(@puid1)
11
+ runner.stack = [ @at0, @at1 ]
12
+ end
13
+
14
+ it 'saves the prog on the top of the stack' do
15
+ runner.peek.pc = :s13
16
+ list.fetch(@puid1).pc.should eq(:main)
17
+ runner.op_save
18
+ list.fetch(@puid1).pc.should eq(:s13)
19
+ runner.stack.should eq([ @at0, @at1.puid ])
20
+ end
21
+
22
+ it 'allows specifying the number of progs to save' do
23
+ runner.stack.each_with_index{|prog,i| prog.pc = :"s#{i}"}
24
+ runner.op_save 2
25
+ list.fetch(@puid0).pc.should eq(:s0)
26
+ list.fetch(@puid1).pc.should eq(:s1)
27
+ runner.stack.should eq([ @at0.puid, @at1.puid ])
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_save" do
5
+
6
+ before do
7
+ @puid0 = list.save Prog.new
8
+ @puid1 = list.save Prog.new
9
+ @at0 = list.fetch(@puid0)
10
+ @at1 = list.fetch(@puid1)
11
+ runner.stack = [ [ @at0, @at1 ] ]
12
+ runner.peek.each{|p| p.pc = :s18}
13
+ end
14
+
15
+ subject do
16
+ runner.op_savea
17
+ end
18
+
19
+ after do
20
+ top = runner.peek
21
+ top.each do |puid|
22
+ list.fetch(puid).pc.should eq(:s18)
23
+ end
24
+ end
25
+
26
+ it 'puts the saved puid back on the stack' do
27
+ subject
28
+ runner.stack.size.should eq(1)
29
+ runner.peek.should be_a(Array)
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_self" do
5
+
6
+ let(:runn){ runner(@puid) }
7
+
8
+ before do
9
+ @puid = list.save Prog.new
10
+ end
11
+
12
+ it 'puts the current prog on the stack' do
13
+ runn.stack = [ ]
14
+ runn.op_self
15
+ runn.stack.should eq([ list.fetch(@puid) ])
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_send" do
5
+
6
+ it 'pushes the result on the stack' do
7
+ runner.stack = [ 1, [ 2 ] ]
8
+ runner.op_send(:+)
9
+ runner.stack.should eq([ 3 ])
10
+ end
11
+
12
+ it 'takes the method name from the stack when unspecified' do
13
+ runner.stack = [ 1, [ 2 ], :+ ]
14
+ runner.op_send
15
+ runner.stack.should eq([ 3 ])
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_set" do
5
+
6
+ after do
7
+ runner.stack.first.should eq(receiver)
8
+ end
9
+
10
+ context 'with a hash' do
11
+ let(:receiver){ {} }
12
+
13
+ before do
14
+ runner.stack = [ receiver, "World" ]
15
+ end
16
+
17
+ after do
18
+ runner.stack.last[:hello].should eq("World")
19
+ end
20
+
21
+ it 'sets the attribute under the specified key' do
22
+ runner.op_set(:hello)
23
+ end
24
+
25
+ it 'takes the attribute name from the stack if unspecified' do
26
+ runner.op_push :hello
27
+ runner.op_set
28
+ end
29
+ end
30
+
31
+ context 'with an object' do
32
+ let(:receiver){ Prog.new }
33
+
34
+ before do
35
+ runner.stack = [ receiver, 12 ]
36
+ end
37
+
38
+ after do
39
+ runner.stack.last.pc.should eq(12)
40
+ end
41
+
42
+ it 'sets the value under the attribute' do
43
+ runner.op_set(:pc)
44
+ end
45
+
46
+ it 'takes the attribute name from the stack if unspecified' do
47
+ runner.op_push :pc
48
+ runner.op_set
49
+ end
50
+
51
+ it 'raises an Error if no such method' do
52
+ lambda{
53
+ runner.op_set(:nosuchone)
54
+ }.should raise_error(VM::Error)
55
+ runner.stack.first.pc = 12 ## for after block
56
+ end
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_then" do
5
+
6
+ let(:bc){
7
+ Bytecode.coerce <<-BC.gsub(/^\s*/, '').strip
8
+ hello: push 12
9
+ BC
10
+ }
11
+ let(:runn){ runner(bc) }
12
+
13
+ before do
14
+ runn.opcodes = [ [:nop] ]
15
+ end
16
+
17
+ after do
18
+ runn.opcodes.should eq([[:nop], [:push, 12]])
19
+ runn.stack.should eq([:prev])
20
+ end
21
+
22
+ context 'without argument' do
23
+
24
+ subject do
25
+ runn.op_then
26
+ end
27
+
28
+ it 'pushes opcodes on the code stack' do
29
+ runn.stack = [ :prev, :hello ]
30
+ subject
31
+ end
32
+
33
+ end # without argument
34
+
35
+ context 'without an argument' do
36
+
37
+ subject do
38
+ runn.op_then(:hello)
39
+ end
40
+
41
+ it 'pushes opcodes on the code stack' do
42
+ runn.stack = [ :prev ]
43
+ subject
44
+ end
45
+
46
+ end # with an argument
47
+
48
+ end
49
+ end
50
+ end