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.
- data/CHANGELOG.md +5 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +46 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +15 -0
- data/README.md +10 -0
- data/Rakefile +11 -0
- data/bin/gvm +9 -0
- data/gisele-vm.gemspec +191 -0
- data/gisele-vm.noespec +31 -0
- data/lib/gisele-vm.rb +4 -0
- data/lib/gisele-vm/loader.rb +5 -0
- data/lib/gisele-vm/version.rb +16 -0
- data/lib/gisele/compiling.rb +3 -0
- data/lib/gisele/compiling/gisele2gts.rb +143 -0
- data/lib/gisele/compiling/gts.rb +74 -0
- data/lib/gisele/compiling/gts2bytecode.rb +127 -0
- data/lib/gisele/vm.rb +87 -0
- data/lib/gisele/vm/bytecode.rb +84 -0
- data/lib/gisele/vm/bytecode/builder.rb +77 -0
- data/lib/gisele/vm/bytecode/grammar.citrus +116 -0
- data/lib/gisele/vm/bytecode/grammar.rb +19 -0
- data/lib/gisele/vm/bytecode/grammar.sexp.yml +113 -0
- data/lib/gisele/vm/bytecode/printer.rb +35 -0
- data/lib/gisele/vm/command.rb +140 -0
- data/lib/gisele/vm/component.rb +91 -0
- data/lib/gisele/vm/console.rb +58 -0
- data/lib/gisele/vm/enacter.rb +29 -0
- data/lib/gisele/vm/errors.rb +26 -0
- data/lib/gisele/vm/event.rb +11 -0
- data/lib/gisele/vm/event_manager.rb +65 -0
- data/lib/gisele/vm/kernel.rb +58 -0
- data/lib/gisele/vm/kernel/macros.gvm +214 -0
- data/lib/gisele/vm/kernel/opcodes.rb +212 -0
- data/lib/gisele/vm/kernel/runner.rb +63 -0
- data/lib/gisele/vm/lifecycle.rb +72 -0
- data/lib/gisele/vm/logging.rb +18 -0
- data/lib/gisele/vm/null_object.rb +19 -0
- data/lib/gisele/vm/prog.rb +63 -0
- data/lib/gisele/vm/prog_list.rb +55 -0
- data/lib/gisele/vm/prog_list/memory.rb +74 -0
- data/lib/gisele/vm/prog_list/sqldb.rb +123 -0
- data/lib/gisele/vm/prog_list/storage.rb +31 -0
- data/lib/gisele/vm/proxy.rb +14 -0
- data/lib/gisele/vm/proxy/client.rb +64 -0
- data/lib/gisele/vm/proxy/server.rb +29 -0
- data/lib/gisele/vm/registry.rb +57 -0
- data/lib/gisele/vm/robustness.rb +31 -0
- data/lib/gisele/vm/simulator/resumer.rb +32 -0
- data/spec/command/gvm_compile.cmd +1 -0
- data/spec/command/gvm_compile.stdout +111 -0
- data/spec/command/gvm_gts.cmd +1 -0
- data/spec/command/gvm_gts.stdout +101 -0
- data/spec/command/gvm_help.cmd +1 -0
- data/spec/command/gvm_help.stdout +30 -0
- data/spec/command/gvm_version.cmd +1 -0
- data/spec/command/gvm_version.stdout +2 -0
- data/spec/command/test_command.rb +29 -0
- data/spec/fixtures/complete.gis +13 -0
- data/spec/fixtures/fake_component.rb +24 -0
- data/spec/fixtures/kernel.rb +39 -0
- data/spec/fixtures/ts.adl +11 -0
- data/spec/fixtures/ts.gts +20 -0
- data/spec/fixtures/ts.gvm +19 -0
- data/spec/spec_helper.rb +86 -0
- data/spec/test_examples.rb +29 -0
- data/spec/test_gisele-vm.rb +8 -0
- data/spec/unit/bytecode/builder/test_at.rb +56 -0
- data/spec/unit/bytecode/builder/test_helpers.rb +36 -0
- data/spec/unit/bytecode/builder/test_instruction.rb +35 -0
- data/spec/unit/bytecode/builder/test_to_a.rb +53 -0
- data/spec/unit/bytecode/bytecode.gvm +1 -0
- data/spec/unit/bytecode/grammar/fixtures/comments.gvm +16 -0
- data/spec/unit/bytecode/grammar/fixtures/every.gvm +46 -0
- data/spec/unit/bytecode/grammar/fixtures/singleblock.gvm +2 -0
- data/spec/unit/bytecode/grammar/fixtures/twoblocks.gvm +4 -0
- data/spec/unit/bytecode/grammar/fixtures/with_end.gvm +5 -0
- data/spec/unit/bytecode/grammar/test_array.rb +24 -0
- data/spec/unit/bytecode/grammar/test_block.rb +35 -0
- data/spec/unit/bytecode/grammar/test_boolean.rb +20 -0
- data/spec/unit/bytecode/grammar/test_constant.rb +20 -0
- data/spec/unit/bytecode/grammar/test_eol.rb +20 -0
- data/spec/unit/bytecode/grammar/test_eol_comment.rb +36 -0
- data/spec/unit/bytecode/grammar/test_file.rb +38 -0
- data/spec/unit/bytecode/grammar/test_hash.rb +33 -0
- data/spec/unit/bytecode/grammar/test_instruction.rb +32 -0
- data/spec/unit/bytecode/grammar/test_int.rb +24 -0
- data/spec/unit/bytecode/grammar/test_label.rb +24 -0
- data/spec/unit/bytecode/grammar/test_opcode.rb +23 -0
- data/spec/unit/bytecode/grammar/test_string.rb +25 -0
- data/spec/unit/bytecode/grammar/test_symbol.rb +30 -0
- data/spec/unit/bytecode/test_build.rb +36 -0
- data/spec/unit/bytecode/test_coerce.rb +41 -0
- data/spec/unit/bytecode/test_fetch.rb +20 -0
- data/spec/unit/bytecode/test_grammar.rb +30 -0
- data/spec/unit/bytecode/test_parse.rb +22 -0
- data/spec/unit/bytecode/test_plus.rb +27 -0
- data/spec/unit/bytecode/test_to_a.rb +19 -0
- data/spec/unit/bytecode/test_to_s.rb +32 -0
- data/spec/unit/command/code.gis +3 -0
- data/spec/unit/command/test_vm.rb +51 -0
- data/spec/unit/compiling/gisele2gts/test_on_par_st.rb +51 -0
- data/spec/unit/compiling/gisele2gts/test_on_seq_st.rb +46 -0
- data/spec/unit/compiling/gisele2gts/test_on_task_call_st.rb +37 -0
- data/spec/unit/compiling/gisele2gts/test_on_task_def.rb +49 -0
- data/spec/unit/compiling/gisele2gts/test_on_unit_def.rb +35 -0
- data/spec/unit/compiling/gts2bytecode/test_on_end.rb +31 -0
- data/spec/unit/compiling/gts2bytecode/test_on_event.rb +37 -0
- data/spec/unit/compiling/gts2bytecode/test_on_fork.rb +41 -0
- data/spec/unit/compiling/gts2bytecode/test_on_join.rb +42 -0
- data/spec/unit/compiling/gts2bytecode/test_on_listen.rb +36 -0
- data/spec/unit/compiling/gts2bytecode/test_on_nop.rb +30 -0
- data/spec/unit/component/test_component_name.rb +16 -0
- data/spec/unit/component/test_logging.rb +36 -0
- data/spec/unit/enacter/test_component.rb +11 -0
- data/spec/unit/event/test_to_s.rb +12 -0
- data/spec/unit/event_manager/test_component.rb +9 -0
- data/spec/unit/event_manager/test_subscribe.rb +40 -0
- data/spec/unit/event_manager/test_unsubscribe.rb +39 -0
- data/spec/unit/kernel/macros/test_fork.rb +37 -0
- data/spec/unit/kernel/macros/test_join.rb +43 -0
- data/spec/unit/kernel/macros/test_listen.rb +37 -0
- data/spec/unit/kernel/macros/test_notify.rb +57 -0
- data/spec/unit/kernel/macros/test_react.rb +47 -0
- data/spec/unit/kernel/macros/test_schedule_at.rb +30 -0
- data/spec/unit/kernel/opcodes/test_op_del.rb +42 -0
- data/spec/unit/kernel/opcodes/test_op_event.rb +25 -0
- data/spec/unit/kernel/opcodes/test_op_fetch.rb +27 -0
- data/spec/unit/kernel/opcodes/test_op_flip.rb +17 -0
- data/spec/unit/kernel/opcodes/test_op_fold.rb +29 -0
- data/spec/unit/kernel/opcodes/test_op_fork.rb +63 -0
- data/spec/unit/kernel/opcodes/test_op_forka.rb +51 -0
- data/spec/unit/kernel/opcodes/test_op_get.rb +62 -0
- data/spec/unit/kernel/opcodes/test_op_getr.rb +48 -0
- data/spec/unit/kernel/opcodes/test_op_ifenil.rb +41 -0
- data/spec/unit/kernel/opcodes/test_op_ifezero.rb +32 -0
- data/spec/unit/kernel/opcodes/test_op_invoke.rb +34 -0
- data/spec/unit/kernel/opcodes/test_op_nop.rb +18 -0
- data/spec/unit/kernel/opcodes/test_op_parent.rb +39 -0
- data/spec/unit/kernel/opcodes/test_op_pop.rb +22 -0
- data/spec/unit/kernel/opcodes/test_op_push.rb +17 -0
- data/spec/unit/kernel/opcodes/test_op_save.rb +32 -0
- data/spec/unit/kernel/opcodes/test_op_savea.rb +34 -0
- data/spec/unit/kernel/opcodes/test_op_self.rb +20 -0
- data/spec/unit/kernel/opcodes/test_op_send.rb +20 -0
- data/spec/unit/kernel/opcodes/test_op_set.rb +61 -0
- data/spec/unit/kernel/opcodes/test_op_then.rb +50 -0
- data/spec/unit/kernel/opcodes/test_op_unfold.rb +22 -0
- data/spec/unit/kernel/opcodes/test_op_uuid.rb +16 -0
- data/spec/unit/kernel/runner/test_pop.rb +26 -0
- data/spec/unit/kernel/runner/test_stack.rb +28 -0
- data/spec/unit/kernel/test_progress.rb +47 -0
- data/spec/unit/kernel/test_resume.rb +53 -0
- data/spec/unit/kernel/test_start.rb +36 -0
- data/spec/unit/prog/test_to_hash.rb +29 -0
- data/spec/unit/prog/test_waitlist_eq.rb +20 -0
- data/spec/unit/prog_list/memory/test_component.rb +9 -0
- data/spec/unit/prog_list/memory/test_fetch.rb +40 -0
- data/spec/unit/prog_list/memory/test_pick.rb +39 -0
- data/spec/unit/prog_list/memory/test_save.rb +91 -0
- data/spec/unit/prog_list/memory/test_to_relation.rb +17 -0
- data/spec/unit/prog_list/sqldb/test_component.rb +11 -0
- data/spec/unit/prog_list/sqldb/test_connect.rb +46 -0
- data/spec/unit/prog_list/test_memory.rb +9 -0
- data/spec/unit/prog_list/test_sqldb.rb +13 -0
- data/spec/unit/prog_list/test_storage.rb +51 -0
- data/spec/unit/registry/test_component.rb +9 -0
- data/spec/unit/registry/test_connect.rb +53 -0
- data/spec/unit/registry/test_disconnect.rb +51 -0
- data/spec/unit/registry/test_registration.rb +44 -0
- data/spec/unit/shared/a_component.rb +49 -0
- data/spec/unit/shared/a_storage.rb +114 -0
- data/spec/unit/test_logging.rb +46 -0
- data/spec/unit/test_prog.rb +57 -0
- data/spec/unit/test_prog_list.rb +22 -0
- data/spec/unit/vm/test_event_facace.rb +11 -0
- data/spec/unit/vm/test_initialize.rb +59 -0
- data/spec/unit/vm/test_proglist_facade.rb +21 -0
- data/tasks/debug_mail.rake +75 -0
- data/tasks/debug_mail.txt +13 -0
- data/tasks/gem.rake +73 -0
- data/tasks/spec_test.rake +71 -0
- data/tasks/unit_test.rake +76 -0
- data/tasks/yard.rake +51 -0
- 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
|