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,37 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "listen macro" do
5
+
6
+ let(:runn) { runner(@parent) }
7
+ let(:parent){ list.fetch(@parent) }
8
+ let(:wlist) { {:ping => :sPing, :pong => :sPong} }
9
+
10
+ before do
11
+ @parent = list.save Prog.new(:pc => :listen)
12
+ subject
13
+ end
14
+
15
+ subject do
16
+ runn.run(:listen, [ wlist ])
17
+ end
18
+
19
+ after do
20
+ runn.stack.should be_empty
21
+ end
22
+
23
+ it 'sets the events as waitlist' do
24
+ parent.waitlist.should eq(wlist)
25
+ end
26
+
27
+ it 'sets the program counter to :react' do
28
+ parent.pc.should eq(:react)
29
+ end
30
+
31
+ it 'unschedules the current Prog' do
32
+ parent.waitfor.should eq(:world)
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "notify macro" do
5
+
6
+ let(:runn) { runner(@child) }
7
+ let(:parent){ list.fetch(@parent) }
8
+ let(:child) { list.fetch(@child) }
9
+
10
+ subject do
11
+ runn.run(:notify, [ ])
12
+ end
13
+
14
+ after do
15
+ runn.stack.should be_empty
16
+ end
17
+
18
+ context 'when the child has a parent' do
19
+
20
+ before do
21
+ @parent = list.save Prog.new
22
+ @child = list.save Prog.new(:parent => @parent)
23
+ @child2 = list.save Prog.new(:parent => @parent)
24
+ list.save(Prog.new :puid => @parent, :waitlist => {@child => true, @child2 => true})
25
+ subject
26
+ end
27
+
28
+ it 'ends the child' do
29
+ child.pc.should eq(-1)
30
+ child.waitfor.should eq(:none)
31
+ end
32
+
33
+ it 'resumes the parent on a reduced waitlist' do
34
+ parent.waitlist.should eq(@child2 => true)
35
+ parent.waitfor.should eq(:enacter)
36
+ end
37
+
38
+ end # with a parent
39
+
40
+ context 'when the child has no parent' do
41
+
42
+ before do
43
+ @child = list.save Prog.new
44
+ subject
45
+ end
46
+
47
+ it 'ends the child' do
48
+ child.pc.should eq(-1)
49
+ child.waitlist.should eq({})
50
+ child.waitfor.should eq(:none)
51
+ end
52
+
53
+ end # withoutb a parent
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "react macro" do
5
+
6
+ let(:runn) { runner(@parent) }
7
+ let(:parent){ list.fetch(@parent) }
8
+ let(:wlist) { {:ping => :sPing, :pong => :sPong} }
9
+
10
+ before do
11
+ @parent = list.save Prog.new(:pc => :react, :waitlist => wlist, :waitfor => waitfor)
12
+ subject
13
+ end
14
+
15
+ subject do
16
+ runn.run(:react, [ event ])
17
+ end
18
+
19
+ after do
20
+ runn.stack.should be_empty
21
+ end
22
+
23
+ context 'when a recognized event' do
24
+ let(:event) { :ping }
25
+ let(:waitfor){ :world }
26
+
27
+ it 'schedules the current Prog correctly' do
28
+ parent.pc.should eq(:sPing)
29
+ parent.waitfor.should eq(:enacter)
30
+ parent.waitlist.should eq({})
31
+ end
32
+ end
33
+
34
+ context 'when an unrecognized event' do
35
+ let(:event) { :pang }
36
+ let(:waitfor){ :enacter }
37
+
38
+ it 'sleeps the current Prog' do
39
+ parent.pc.should eq(:react)
40
+ parent.waitfor.should eq(:world)
41
+ parent.waitlist.should eq(wlist)
42
+ end
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "schedule_at macro" do
5
+
6
+ let(:runn) { runner(@parent) }
7
+ let(:parent){ list.fetch(@parent) }
8
+
9
+ before do
10
+ @parent = list.save Prog.new(:waitfor => :none)
11
+ subject
12
+ end
13
+
14
+ subject do
15
+ runn.run(:schedule_at, [ :s16 ])
16
+ end
17
+
18
+ after do
19
+ runn.stack.should be_empty
20
+ end
21
+
22
+ it 'resumes the current Prog' do
23
+ parent.waitfor.should eq(:enacter)
24
+ parent.pc.should eq(:s16)
25
+ parent.waitlist.should eq({})
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_del" do
5
+
6
+ before do
7
+ runner.stack = [ receiver ]
8
+ end
9
+
10
+ context 'with a hash' do
11
+ let(:receiver){ {:hello => "World", :other => true} }
12
+
13
+ it 'removes the key from the hash' do
14
+ runner.op_del(:hello)
15
+ runner.stack.should eq([ {:other => true} ])
16
+ end
17
+
18
+ it 'takes the attribute name from the stack if unspecified' do
19
+ runner.op_push :hello
20
+ runner.op_del
21
+ runner.stack.should eq([ {:other => true} ])
22
+ end
23
+ end
24
+
25
+ context 'with an array' do
26
+ let(:receiver){ [:hello, :world] }
27
+
28
+ it 'pushes the result on the stack' do
29
+ runner.op_del(:hello)
30
+ runner.stack.should eq([[:world]])
31
+ end
32
+
33
+ it 'takes the attribute name from the stack if unspecified' do
34
+ runner.op_push :hello
35
+ runner.op_del
36
+ runner.stack.should eq([[:world]])
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_event" do
5
+
6
+ let(:runn){ runner(Prog.new(:puid => 17)) }
7
+
8
+ before do
9
+ runn.stack = [ ["world"] ]
10
+ end
11
+
12
+ it 'calls the event interface' do
13
+ runn.op_event(:hello)
14
+ observed_events.include?(an_event).should be_true
15
+ end
16
+
17
+ it 'can take the event kind from the stack' do
18
+ runn.op_push :hello
19
+ runn.op_event
20
+ observed_events.include?(an_event).should be_true
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_fetch" do
5
+
6
+ before do
7
+ @parent = list.save Prog.new
8
+ @child = list.save Prog.new
9
+ @at1 = list.fetch(@child)
10
+ end
11
+
12
+ after do
13
+ runner.stack.should eq([ @at1 ])
14
+ end
15
+
16
+ it 'fetches the correct Prog with an arg' do
17
+ runner.op_fetch(@child)
18
+ end
19
+
20
+ it 'supports taking the puid from the stack' do
21
+ runner.stack = [ @child ]
22
+ runner.op_fetch
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_flip" do
5
+
6
+ before do
7
+ runner.stack = [ 1, 2, 3 ]
8
+ end
9
+
10
+ it 'flips the two top elements' do
11
+ runner.op_flip
12
+ runner.stack.should eq([ 1, 3, 2 ])
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_fold" do
5
+
6
+ before do
7
+ runner.stack = [ :a, :b, :c ]
8
+ end
9
+
10
+ it 'pushes an array with the specified number of elements' do
11
+ runner.op_fold(2)
12
+ runner.stack.should eq([:a, [:b, :c]])
13
+ end
14
+
15
+ it 'supports traking n from the stack' do
16
+ runner.op_push 2
17
+ runner.op_fold
18
+ runner.stack.should eq([:a, [:b, :c]])
19
+ end
20
+
21
+ it 'supports 0' do
22
+ runner.op_push 0
23
+ runner.op_fold
24
+ runner.stack.should eq([:a, :b, :c, []])
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_fork" do
5
+
6
+ let(:runn){ runner(Prog.new :puid => 17, :root => 16) }
7
+
8
+ context 'with a label' do
9
+
10
+ before do
11
+ runn.stack = [ ]
12
+ runn.op_fork(:somewhere)
13
+ end
14
+
15
+ subject{
16
+ runn.stack.size.should eq(1)
17
+ runn.stack.last
18
+ }
19
+
20
+ it 'sets the resulting prog on the stack' do
21
+ subject.should be_a(Prog)
22
+ end
23
+
24
+ it 'is a child Prog' do
25
+ subject.parent.should eq(17)
26
+ subject.root.should eq(16)
27
+ end
28
+
29
+ it 'is scheduled' do
30
+ subject.waitfor.should eq(:enacter)
31
+ end
32
+
33
+ it 'has the correct program counter' do
34
+ subject.pc.should eq(:somewhere)
35
+ end
36
+
37
+ it 'is not registered yet' do
38
+ subject.puid.should be_nil
39
+ end
40
+
41
+ end # with a label
42
+
43
+ context 'without label' do
44
+
45
+ before do
46
+ runn.stack = [ :somewhere_else ]
47
+ runn.op_fork
48
+ end
49
+
50
+ subject{
51
+ runn.stack.size.should eq(1)
52
+ runn.stack.last
53
+ }
54
+
55
+ it 'takes the label from the stack' do
56
+ subject.pc.should eq(:somewhere_else)
57
+ end
58
+
59
+ end # without label
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_fork" do
5
+
6
+ let(:runn){ runner(Prog.new :puid => 17) }
7
+
8
+ after do
9
+ top = runn.stack.last
10
+ top.should be_a(Array)
11
+ top.size.should eq(2)
12
+ top.each{|p| p.should be_a(Prog)}
13
+ top.each{|p|
14
+ p.parent.should eq(17)
15
+ p.waitfor.should eq(:enacter)
16
+ p.puid.should be_nil
17
+ }
18
+ top.map{|p| p.pc}.should eq([:s0, :s1])
19
+ end
20
+
21
+ context 'with an array of labels' do
22
+
23
+ subject do
24
+ runn.stack = [ ]
25
+ runn.op_forka([ :s0, :s1 ])
26
+ end
27
+
28
+ it 'puts the resulting array on the stack' do
29
+ subject
30
+ runn.stack.size.should eq(1)
31
+ end
32
+
33
+ end # with a label
34
+
35
+ context 'without argument' do
36
+
37
+ subject do
38
+ runn.stack = [ [:s0, :s1] ]
39
+ runn.op_forka
40
+ end
41
+
42
+ it 'takes the labels from the stack' do
43
+ subject
44
+ runn.stack.size.should eq(1)
45
+ end
46
+
47
+ end # without label
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Kernel, "op_get" do
5
+
6
+ before do
7
+ runner.stack = [ receiver ]
8
+ end
9
+
10
+ after do
11
+ runner.stack.first.should eq(receiver)
12
+ end
13
+
14
+ context 'with a hash' do
15
+ let(:receiver){ {:hello => "World"} }
16
+
17
+ it 'pushes the result on the stack' do
18
+ runner.op_get(:hello)
19
+ runner.stack.last.should eq("World")
20
+ end
21
+
22
+ it 'takes the attribute name from the stack if unspecified' do
23
+ runner.op_push :hello
24
+ runner.op_get
25
+ runner.stack.last.should eq("World")
26
+ end
27
+
28
+ it 'supports getting nil' do
29
+ runner.op_get(:nosuchone)
30
+ runner.stack.last.should be_nil
31
+ end
32
+
33
+ it 'does not try to call methods' do
34
+ runner.op_get(:fetch)
35
+ runner.stack.last.should be_nil
36
+ end
37
+ end
38
+
39
+ context 'with an object' do
40
+ let(:receiver){ Prog.new(:pc => 12) }
41
+
42
+ it 'pushes the result on the stack' do
43
+ runner.op_get(:pc)
44
+ runner.stack.last.should eq(12)
45
+ end
46
+
47
+ it 'takes the attribute name from the stack if unspecified' do
48
+ runner.op_push :pc
49
+ runner.op_get
50
+ runner.stack.last.should eq(12)
51
+ end
52
+
53
+ it 'raises an Error if no such method' do
54
+ lambda{
55
+ runner.op_get(:nosuchone)
56
+ }.should raise_error(VM::Error)
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end