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