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,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,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
|