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,20 @@
|
|
|
1
|
+
Stamina::Automaton.new do
|
|
2
|
+
add_state :kind => :listen, :initial => true
|
|
3
|
+
add_state :kind => :fork
|
|
4
|
+
add_state :kind => :event
|
|
5
|
+
add_state :kind => :end
|
|
6
|
+
add_state :kind => :event
|
|
7
|
+
add_state :kind => :end
|
|
8
|
+
add_state :kind => :join
|
|
9
|
+
add_state :kind => :end
|
|
10
|
+
connect 0, 1, :symbol => :ping
|
|
11
|
+
connect 1, 2, nil
|
|
12
|
+
connect 2, 3, :symbol => :pong
|
|
13
|
+
connect 1, 4, nil
|
|
14
|
+
connect 4, 5, :symbol => :pang
|
|
15
|
+
connect 3, 6, nil
|
|
16
|
+
connect 5, 6, nil
|
|
17
|
+
connect 6, 0, nil
|
|
18
|
+
connect 0, 7, :symbol => :exit
|
|
19
|
+
connect 1, 6, :symbol => :"(wait)"
|
|
20
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
main: then :s0
|
|
2
|
+
s0: push {:ping=>:s1, :exit=>:s7}
|
|
3
|
+
then :listen
|
|
4
|
+
s1: push :s6
|
|
5
|
+
push [:s2, :s4]
|
|
6
|
+
then :fork
|
|
7
|
+
s2: then :s3
|
|
8
|
+
then :e2
|
|
9
|
+
e2: push []
|
|
10
|
+
event :pong
|
|
11
|
+
s3: then :notify
|
|
12
|
+
s4: then :s5
|
|
13
|
+
then :e4
|
|
14
|
+
e4: push []
|
|
15
|
+
event :pang
|
|
16
|
+
s5: then :notify
|
|
17
|
+
s6: push {:wake => :s0}
|
|
18
|
+
then :join
|
|
19
|
+
s7: then :notify
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
|
2
|
+
require 'gisele-vm'
|
|
3
|
+
require_relative 'fixtures/kernel'
|
|
4
|
+
require_relative 'fixtures/fake_component'
|
|
5
|
+
|
|
6
|
+
def fixtures
|
|
7
|
+
Path.dir/:fixtures
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
(Path.dir/'unit/shared').glob("**/*.rb").each{|f| require(f.without_extension)}
|
|
11
|
+
|
|
12
|
+
module SpecHelpers
|
|
13
|
+
|
|
14
|
+
class FakeEventManager < Gisele::VM::Component
|
|
15
|
+
attr_reader :events
|
|
16
|
+
def event(event)
|
|
17
|
+
@events ||= []
|
|
18
|
+
@events << event
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def observed_events
|
|
23
|
+
vm.event_manager.events
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def an_event
|
|
27
|
+
Gisele::VM::Event.new(Gisele::VM::Prog.new(:puid => 17), :hello, [ "world" ])
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def vm(bc = nil)
|
|
31
|
+
@vm ||= begin
|
|
32
|
+
vm = Gisele::VM.new(bc || [:gvm]) do |vm|
|
|
33
|
+
vm.proglist = Gisele::VM::ProgList.memory
|
|
34
|
+
vm.event_manager = FakeEventManager.new
|
|
35
|
+
end
|
|
36
|
+
vm.connect
|
|
37
|
+
vm.proglist.clear
|
|
38
|
+
vm
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def list
|
|
43
|
+
@list ||= vm.proglist
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def kernel(bc = nil)
|
|
47
|
+
@k ||= vm(bc).kernel
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def runner(*args)
|
|
51
|
+
bc = args.find{|x| Gisele::VM::Bytecode===x}
|
|
52
|
+
prog = args.find{|x| Integer===x or Gisele::VM::Prog===x}
|
|
53
|
+
prog = list.fetch(prog) if Integer===prog
|
|
54
|
+
@kernel ||= kernel(bc).runner(prog)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def capture_io
|
|
58
|
+
stdout, stderr = $stdout, $stderr
|
|
59
|
+
$stdout, $stderr = StringIO.new, StringIO.new
|
|
60
|
+
yield
|
|
61
|
+
[$stdout.string, $stderr.string]
|
|
62
|
+
ensure
|
|
63
|
+
$stdout, $stderr = stdout, stderr
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def measure
|
|
67
|
+
t1 = Time.now
|
|
68
|
+
yield
|
|
69
|
+
t2 = Time.now
|
|
70
|
+
puts "It took #{(t2-t1)} ms."
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def sqlite_protocol
|
|
74
|
+
Gisele::VM::ProgList::Sqldb.sqlite_protocol
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def sqlite_memory
|
|
78
|
+
{:uri => "#{sqlite_protocol}:memory"}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
RSpec.configure do |c|
|
|
84
|
+
c.extend SpecHelpers
|
|
85
|
+
c.include SpecHelpers
|
|
86
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele
|
|
3
|
+
class VM
|
|
4
|
+
|
|
5
|
+
shared_examples_for "A valid example file" do
|
|
6
|
+
|
|
7
|
+
it 'respect the .gvm grammar' do
|
|
8
|
+
Bytecode.coerce(subject).verify!
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end # A valid example file
|
|
12
|
+
|
|
13
|
+
examples = Path.backfind('.[examples]')/:examples
|
|
14
|
+
examples.glob("**/*.gvm").each do |file|
|
|
15
|
+
describe "the example #{file.basename}" do
|
|
16
|
+
subject{file}
|
|
17
|
+
it_behaves_like "A valid example file"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
fixtures.glob("**/*.gvm").each do |file|
|
|
22
|
+
describe "the fixture #{file.basename}" do
|
|
23
|
+
subject{file}
|
|
24
|
+
it_behaves_like "A valid example file"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele
|
|
3
|
+
class VM
|
|
4
|
+
class Bytecode
|
|
5
|
+
describe Builder, "at" do
|
|
6
|
+
|
|
7
|
+
let(:builder){ Builder.new }
|
|
8
|
+
|
|
9
|
+
it 'yields itself then returns the block' do
|
|
10
|
+
r = builder.at(:s0) do |b|
|
|
11
|
+
b.push 12
|
|
12
|
+
end
|
|
13
|
+
r.should eq([:block, :s0, [:push, 12]])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'allows a stack based usage' do
|
|
17
|
+
builder.at(:s0)
|
|
18
|
+
builder.instruction(:push, [12])
|
|
19
|
+
builder.end_block.should eq([:block, :s0, [:push, 12]])
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'allows no arg for main' do
|
|
23
|
+
builder.at
|
|
24
|
+
builder.end_block.should eq([:block, :main])
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'raises a BadUsageError if the previous block has not been dumped' do
|
|
28
|
+
builder.at(:s0)
|
|
29
|
+
lambda{
|
|
30
|
+
builder.at(:s1)
|
|
31
|
+
}.should raise_error(BadUsageError)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'when namespaced' do
|
|
35
|
+
let(:builder){ Builder.new('Somewhere') }
|
|
36
|
+
|
|
37
|
+
it 'use namespaced labels' do
|
|
38
|
+
builder.at(:s0)
|
|
39
|
+
builder.end_block.should eq([:block, :Somewhere_s0])
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'allows disabling auto labeling' do
|
|
43
|
+
builder.at(:s0, false)
|
|
44
|
+
builder.end_block.should eq([:block, :s0])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'uses the namespace for main' do
|
|
48
|
+
builder.at
|
|
49
|
+
builder.end_block.should eq([:block, :Somewhere])
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele
|
|
3
|
+
class VM
|
|
4
|
+
class Bytecode
|
|
5
|
+
describe Builder, "the pseudo method-missing helpers" do
|
|
6
|
+
|
|
7
|
+
let(:builder){ Builder.new("Somewhere") }
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
builder.at(:s0)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after do
|
|
14
|
+
builder.end_block
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'returns the instruction built' do
|
|
18
|
+
builder.push(12).should eq([:push, 12])
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'provides auto-labeling on :then' do
|
|
22
|
+
builder.then(:s1).should eq([:then, :Somewhere_s1])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'allows disabling auto-labeling on :then' do
|
|
26
|
+
builder.then(:s1, false).should eq([:then, :s1])
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'allows a O-adic :then' do
|
|
30
|
+
builder.then.should eq([:then])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele
|
|
3
|
+
class VM
|
|
4
|
+
class Bytecode
|
|
5
|
+
describe Builder, "instruction" do
|
|
6
|
+
|
|
7
|
+
let(:builder){ Builder.new }
|
|
8
|
+
|
|
9
|
+
it 'adds an instruction to the current block' do
|
|
10
|
+
builder.at(:s0) do |b|
|
|
11
|
+
b.instruction(:push, [12])
|
|
12
|
+
end
|
|
13
|
+
expected = [:gvm, [:block, :s0, [:push, 12]] ]
|
|
14
|
+
builder.to_a.should eq(expected)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'raises BadUsageError if no current block' do
|
|
18
|
+
lambda{
|
|
19
|
+
builder.instruction(:push, [ 12 ])
|
|
20
|
+
}.should raise_error(BadUsageError)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "raises InvalidBytecodeError if arguments don't match" do
|
|
24
|
+
lambda{
|
|
25
|
+
builder.instruction(:pop, ['blih'])
|
|
26
|
+
}.should raise_error(InvalidBytecodeError)
|
|
27
|
+
lambda{
|
|
28
|
+
builder.instruction(:push, [])
|
|
29
|
+
}.should raise_error(InvalidBytecodeError)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele
|
|
3
|
+
class VM
|
|
4
|
+
class Bytecode
|
|
5
|
+
describe Builder, "to_a" do
|
|
6
|
+
|
|
7
|
+
let(:builder){ Builder.new(namespace) }
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
builder.at(:s0) do |b|
|
|
11
|
+
b.then :s1
|
|
12
|
+
end
|
|
13
|
+
builder.at(:s1) do |b|
|
|
14
|
+
b.push 12
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'without namespace' do
|
|
19
|
+
let(:namespace){ nil }
|
|
20
|
+
|
|
21
|
+
it 'returns blocks' do
|
|
22
|
+
expected = [ :gvm,
|
|
23
|
+
[:block, :s0, [:then, :s1]],
|
|
24
|
+
[:block, :s1, [:push, 12 ]],
|
|
25
|
+
]
|
|
26
|
+
builder.to_a.should eq(expected)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'returns valid bytecode' do
|
|
30
|
+
(Grammar === builder.to_a).should be_true
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'without namespace' do
|
|
35
|
+
let(:namespace){ 'Somewhere' }
|
|
36
|
+
|
|
37
|
+
it 'uses namespaced labels' do
|
|
38
|
+
expected = [ :gvm,
|
|
39
|
+
[:block, :Somewhere_s0, [:then, :Somewhere_s1]],
|
|
40
|
+
[:block, :Somewhere_s1, [:push, 12 ]],
|
|
41
|
+
]
|
|
42
|
+
builder.to_a.should eq(expected)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'returns valid bytecode' do
|
|
46
|
+
(Grammar === builder.to_a).should be_true
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
s0: push 12
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# This file demonstrates the use of comments
|
|
2
|
+
# in .gvm files
|
|
3
|
+
|
|
4
|
+
# Below is the first block of instructions
|
|
5
|
+
0: puid
|
|
6
|
+
fetch # comments are allowed here
|
|
7
|
+
save # as well as here
|
|
8
|
+
|
|
9
|
+
# A second block here
|
|
10
|
+
1: puid
|
|
11
|
+
save # and here also
|
|
12
|
+
|
|
13
|
+
# trailing comments are allowed as well
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# as well as trailign spaces
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
0: fetch
|
|
2
|
+
fetch 1
|
|
3
|
+
fetch 'blah'
|
|
4
|
+
fork
|
|
5
|
+
fork 15
|
|
6
|
+
fork :a_label
|
|
7
|
+
forka
|
|
8
|
+
invoke
|
|
9
|
+
parent
|
|
10
|
+
pop
|
|
11
|
+
pop 2
|
|
12
|
+
push 12
|
|
13
|
+
push 'hello'
|
|
14
|
+
push Symbol
|
|
15
|
+
push []
|
|
16
|
+
push [12]
|
|
17
|
+
push [12, 'hello']
|
|
18
|
+
push {}
|
|
19
|
+
push { }
|
|
20
|
+
push {name: 'blah'}
|
|
21
|
+
push {name: 'blah', at: :A_start}
|
|
22
|
+
then
|
|
23
|
+
then 0
|
|
24
|
+
then :a_label
|
|
25
|
+
save
|
|
26
|
+
save 2
|
|
27
|
+
puid
|
|
28
|
+
send
|
|
29
|
+
fold
|
|
30
|
+
fold 3
|
|
31
|
+
unfold
|
|
32
|
+
event
|
|
33
|
+
event :hello
|
|
34
|
+
get
|
|
35
|
+
get :attrname
|
|
36
|
+
getr
|
|
37
|
+
getr :attrname
|
|
38
|
+
set
|
|
39
|
+
set :attrname
|
|
40
|
+
del
|
|
41
|
+
del :attrname
|
|
42
|
+
self
|
|
43
|
+
flip
|
|
44
|
+
nop
|
|
45
|
+
ifenil
|
|
46
|
+
ifezero
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele
|
|
3
|
+
class VM
|
|
4
|
+
describe Bytecode::Grammar, "array" do
|
|
5
|
+
|
|
6
|
+
def parse(src)
|
|
7
|
+
Bytecode::Grammar.parse(src, :root => :array)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'parses empty arrays correctly' do
|
|
11
|
+
parse("[ ]").value.should eq([])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'parses singletons correcttly' do
|
|
15
|
+
parse("[0]").value.should eq([0])
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'parses arrays correcttly' do
|
|
19
|
+
parse("[0, 'blah', :symb]").value.should eq([0, 'blah', :symb])
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|