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,35 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "block" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :block)
8
+ end
9
+
10
+ it 'parses a block with one instruction' do
11
+ expected = [:block, 0, [:dump] ]
12
+ parse(<<-BLOCK.strip).value.should eq(expected)
13
+ 0: dump
14
+ BLOCK
15
+ end
16
+
17
+ it 'parses a block with two instructions' do
18
+ expected = [:block, 0, [:dump], [:pop, 3] ]
19
+ parse(<<-BLOCK.strip).value.should eq(expected)
20
+ 0: dump
21
+ pop 3
22
+ BLOCK
23
+ end
24
+
25
+ it 'supports comments' do
26
+ expected = [:block, 0, [:dump], [:pop, 3] ]
27
+ parse(<<-BLOCK.strip).value.should eq(expected)
28
+ 0: dump # blah
29
+ pop 3 # blih
30
+ BLOCK
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "boolean" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :boolean)
8
+ end
9
+
10
+ it 'parses true' do
11
+ parse("true").value.should eq(true)
12
+ end
13
+
14
+ it 'parses false' do
15
+ parse("false").value.should eq(false)
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 Bytecode::Grammar, "constant" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :constant)
8
+ end
9
+
10
+ it 'parses single constants correctly' do
11
+ parse("Integer").value.should eq(Integer)
12
+ end
13
+
14
+ it 'parses qualified constants correctly' do
15
+ parse("Gisele::VM").value.should eq(Gisele::VM)
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 Bytecode::Grammar, "eol" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :eol)
8
+ end
9
+
10
+ it 'parses \n' do
11
+ parse("\n").value.should eq("\n")
12
+ end
13
+
14
+ it 'parses eof' do
15
+ parse("").value.should eq("")
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "eol_comment" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :eol_comment)
8
+ end
9
+
10
+ it 'parses a comment, including the \n' do
11
+ parse("# hello\n").should eq("# hello\n")
12
+ end
13
+
14
+ it 'parses a comment, if no \n but eof' do
15
+ parse("# hello").should eq("# hello")
16
+ end
17
+
18
+ it 'parses an empty comment' do
19
+ parse("#\n").should eq("#\n")
20
+ end
21
+
22
+ it 'raise a parse if trailing' do
23
+ lambda{
24
+ parse("bblh # hello\ntrailing")
25
+ }.should raise_error(Citrus::ParseError)
26
+ end
27
+
28
+ it 'raise a parse error otherwise' do
29
+ lambda{
30
+ parse("bblh # hello")
31
+ }.should raise_error(Citrus::ParseError)
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "file" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src)
8
+ end
9
+
10
+ it 'returns a [:gvm] array' do
11
+ expected = \
12
+ [:gvm,
13
+ [ :block, 0, [:dump], [:pop, 3] ],
14
+ [ :block, 1, [:hello] ] ]
15
+ parse(<<-BLOCK.strip).value.should eq(expected)
16
+ 0: dump
17
+ pop 3
18
+ 1: hello
19
+ BLOCK
20
+ end
21
+
22
+ (Path.dir/'fixtures').glob('*.gvm').each do |file|
23
+ context "the fixture #{File.basename(file)}" do
24
+ let(:sexpr){ Bytecode::Grammar.sexpr(file) }
25
+
26
+ it "is parsed correctly" do
27
+ sexpr.should be_a(Array)
28
+ end
29
+
30
+ it "respects the grammar" do
31
+ (Bytecode::Grammar === sexpr).should be_true
32
+ end
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "hash" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :hash)
8
+ end
9
+
10
+ it 'parses empty hashes correctly' do
11
+ parse("{}").value.should eq({})
12
+ end
13
+
14
+ it 'parses singletons correctly' do
15
+ parse("{key: 12}").value.should eq({:key => 12})
16
+ end
17
+
18
+ it 'parses hashes correctly' do
19
+ parse("{key: 12, name: 'blaj'}").value.should eq({:key => 12, :name => 'blaj'})
20
+ end
21
+
22
+ it 'parses event dict' do
23
+ expected = {:hello => :s2, :goodbye => :s3}
24
+ parse("{hello: :s2, goodbye: :s3}").value.should eq(expected)
25
+ end
26
+
27
+ it 'supports 1.8 syntax' do
28
+ parse("{:key => 12, :name => 'blaj'}").value.should eq({:key => 12, :name => 'blaj'})
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "instruction" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :instruction)
8
+ end
9
+
10
+ it 'parses an instruction without arg' do
11
+ parse("dump").value.should eq([:dump])
12
+ end
13
+
14
+ it 'parses an instruction with an arg' do
15
+ parse("dump 0").value.should eq([:dump, 0])
16
+ end
17
+
18
+ it 'parses an instruction with two args' do
19
+ parse("dump 0, 'blah'").value.should eq([:dump, 0, "blah"])
20
+ end
21
+
22
+ it 'supports tailing spaces' do
23
+ parse("dump 0, 'blah' ").value.should eq([:dump, 0, "blah"])
24
+ end
25
+
26
+ it 'supports comments' do
27
+ parse("dump 0, 'blah' # a comment").value.should eq([:dump, 0, "blah"])
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "int" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :int)
8
+ end
9
+
10
+ it 'parses positive integers correctly' do
11
+ parse("101").value.should eq(101)
12
+ end
13
+
14
+ it 'parses negative integers correctly' do
15
+ parse("-101").value.should eq(-101)
16
+ end
17
+
18
+ it 'parses 0' do
19
+ parse("0").value.should eq(0)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "label" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :label)
8
+ end
9
+
10
+ it 'parses a label, including the :' do
11
+ parse("alabel:").value.should eq(:alabel)
12
+ end
13
+
14
+ it 'allows pure numerics' do
15
+ parse("0:").value.should eq(0)
16
+ end
17
+
18
+ it 'allows pure alphanums' do
19
+ parse("blah0:").value.should eq(:blah0)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "opcode" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :opcode)
8
+ end
9
+
10
+ it 'parses typical opcodes' do
11
+ parse("dump").value.should eq(:dump)
12
+ parse("pop").value.should eq(:pop)
13
+ end
14
+
15
+ it 'does not allow numerics' do
16
+ lambda{
17
+ parse('pop0')
18
+ }.should raise_error(Citrus::ParseError)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "string" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :string)
8
+ end
9
+
10
+ it 'parses single quoted strings' do
11
+ parse("'hello'").value.should eq("hello")
12
+ end
13
+
14
+ it 'parses double quoted strings' do
15
+ parse('"hello"').value.should eq("hello")
16
+ end
17
+
18
+ it 'parses empty strings' do
19
+ parse("''").value.should eq("")
20
+ parse('""').value.should eq("")
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode::Grammar, "symbol" do
5
+
6
+ def parse(src)
7
+ Bytecode::Grammar.parse(src, :root => :symbol)
8
+ end
9
+
10
+ it 'parses alphabetic symbols' do
11
+ parse(":abc").value.should eq(:abc)
12
+ end
13
+
14
+ it 'parses alphanums' do
15
+ parse(":ab0c").value.should eq(:ab0c)
16
+ end
17
+
18
+ it 'allows capitals' do
19
+ parse(":AB0C").value.should eq(:AB0C)
20
+ end
21
+
22
+ it 'requires a letter as first char' do
23
+ lambda{
24
+ parse('0ab')
25
+ }.should raise_error(Citrus::ParseError)
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode, '.build' do
5
+
6
+ subject{
7
+ Bytecode.build(namespace) do |b|
8
+ b.at(:s0) do
9
+ b.push 12
10
+ end
11
+ end
12
+ }
13
+
14
+ context 'without namespace' do
15
+ let(:namespace){ nil }
16
+
17
+ it 'returns a Bytecode instance' do
18
+ subject.should be_a(Bytecode)
19
+ end
20
+
21
+ it 'builds bytecode' do
22
+ subject[:s0].should eq([ [:push, 12] ])
23
+ end
24
+ end
25
+
26
+ context 'with a namespace' do
27
+ let(:namespace){ "Somewhere" }
28
+
29
+ it 'uses namespaced labels' do
30
+ subject[:"Somewhere_s0"].should eq([ [:push, 12] ])
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ module Gisele
3
+ class VM
4
+ describe Bytecode, '.coerce' do
5
+
6
+ def coerce(source)
7
+ @result = Bytecode.coerce(source)
8
+ end
9
+
10
+ after do
11
+ @result.should be_a(Bytecode) if @result
12
+ end
13
+
14
+ it 'coerces bytecode' do
15
+ coerce(Bytecode.new [:gvm])
16
+ end
17
+
18
+ it 'coerces a String' do
19
+ coerce("s0: push 12")
20
+ end
21
+
22
+ it 'coerces a .gvm Path' do
23
+ coerce(fixtures/'ts.gvm')
24
+ end
25
+
26
+ it 'coerces a valid parse result' do
27
+ coerce(Bytecode::Grammar.sexpr(fixtures/'ts.gvm'))
28
+ end
29
+
30
+ it 'raises an InvalidBytecodeError when not recognized' do
31
+ lambda{
32
+ coerce(self)
33
+ }.should raise_error(ArgumentError)
34
+ lambda{
35
+ coerce([:gvm, [:block, :s0, [:puts]]])
36
+ }.should raise_error(ArgumentError)
37
+ end
38
+
39
+ end
40
+ end
41
+ end