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,116 @@
|
|
|
1
|
+
grammar Gisele::VM::Bytecode::Grammar::Parser
|
|
2
|
+
|
|
3
|
+
rule file
|
|
4
|
+
((trailing_space block)+ end_of_file?){
|
|
5
|
+
[:gvm] + self[:block].map{|x| x.value}
|
|
6
|
+
}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
rule end_of_file
|
|
10
|
+
trailing_space ('__END__' .*)?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
rule block
|
|
14
|
+
(label (spacing instruction)+){
|
|
15
|
+
[:block, self[:label].first.value] + self[:instruction].map{|x| x.value}
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
rule instruction
|
|
20
|
+
(opcode (spaces arglist)? spacing (eol_comment | eol)){
|
|
21
|
+
[self[:opcode].first.value] + Array(self[:arglist].map{|x| x.value}.first)
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
rule arglist
|
|
26
|
+
(arg (spacing ',' spacing arg)*){ self[:arg].map{|x| x.value} }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
rule opcode
|
|
30
|
+
([a-z]+){ strip.to_sym }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
rule label
|
|
34
|
+
([0-9]+ ':'){ strip[0...-1].to_i }
|
|
35
|
+
| ([a-zA-Z0-9_-]+ ":"){ strip[0...-1].to_sym }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
rule arg
|
|
39
|
+
boolean | int | symbol | string | constant | array | hash
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
rule boolean
|
|
43
|
+
('true' | 'false'){ strip == 'true' }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
rule int
|
|
47
|
+
( [\-]? '0' | [\-]? [1-9] [0-9]*){ strip.to_i }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
rule symbol
|
|
51
|
+
(':' symbol_chars){ strip[1..-1].to_sym }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
rule string
|
|
55
|
+
(['] (!['] .)* [']){ strip[1...-1] }
|
|
56
|
+
| (["] (!["] .)* ["]){ strip[1...-1] }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
rule constant
|
|
60
|
+
([A-Z][A-Za-z]* ('::' [A-Z][A-Za-z]*)*){
|
|
61
|
+
strip.split('::').inject(::Kernel){|cur,c| cur.const_get(c)}
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
rule array
|
|
66
|
+
('[' spacing arglist spacing ']'){ self[:arglist].last.value }
|
|
67
|
+
| ('[' spacing ']'){ [] }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
rule hash
|
|
71
|
+
('{' spacing hash_entries spacing '}'){ Hash[self[:hash_entries].last.value] }
|
|
72
|
+
| ('{' spacing '}'){ Hash.new }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
rule hash_entries
|
|
76
|
+
(hash_entry (spacing ',' spacing hash_entry)*){ self[:hash_entry].map{|x| x.value} }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
rule hash_entry
|
|
80
|
+
(symbol_chars ':' spacing arg){
|
|
81
|
+
[ self[:symbol_chars].last.value, self[:arg].last.value ]
|
|
82
|
+
} |
|
|
83
|
+
(':' symbol_chars spacing '=>' spacing arg){
|
|
84
|
+
[ self[:symbol_chars].last.value, self[:arg].last.value ]
|
|
85
|
+
}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
rule symbol_chars
|
|
89
|
+
([a-zA-Z] [a-zA-Z0-9_]*){ strip.to_sym }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
rule trailing_space
|
|
93
|
+
(eol_comment | spaces | [\n])*
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
rule eol_comment
|
|
97
|
+
"#" (![\n] .)* eol
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
rule spaces
|
|
101
|
+
space+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
rule spacing
|
|
105
|
+
space*
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
rule space
|
|
109
|
+
[ \t]
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
rule eol
|
|
113
|
+
[\n] | !.
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
class VM
|
|
3
|
+
class Bytecode
|
|
4
|
+
|
|
5
|
+
# Load the Language through Sexpr
|
|
6
|
+
Grammar = Sexpr.load Path.dir/"grammar.sexp.yml"
|
|
7
|
+
|
|
8
|
+
# The Gisele bytecode language.
|
|
9
|
+
module Grammar
|
|
10
|
+
|
|
11
|
+
def instructions
|
|
12
|
+
grammar = YAML.load_file (Path.dir/"grammar.sexp.yml").to_s
|
|
13
|
+
grammar["rules"]["instruction"].map(&:to_sym)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end # module Grammar
|
|
17
|
+
end # class Bytecode
|
|
18
|
+
end # class VM
|
|
19
|
+
end # module Gisele
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
parser:
|
|
2
|
+
grammar.citrus
|
|
3
|
+
rules:
|
|
4
|
+
gvm:
|
|
5
|
+
- [ block* ]
|
|
6
|
+
block:
|
|
7
|
+
- [ label, instruction+ ]
|
|
8
|
+
label:
|
|
9
|
+
- '::Integer'
|
|
10
|
+
- '::Symbol'
|
|
11
|
+
instruction:
|
|
12
|
+
# generic
|
|
13
|
+
- send
|
|
14
|
+
- invoke
|
|
15
|
+
- get
|
|
16
|
+
- getr
|
|
17
|
+
- set
|
|
18
|
+
- del
|
|
19
|
+
# control
|
|
20
|
+
- nop
|
|
21
|
+
- then
|
|
22
|
+
- ifenil
|
|
23
|
+
- ifezero
|
|
24
|
+
# lifecycle
|
|
25
|
+
- puid
|
|
26
|
+
- self
|
|
27
|
+
- parent
|
|
28
|
+
- fetch
|
|
29
|
+
- fork
|
|
30
|
+
- forka
|
|
31
|
+
- save
|
|
32
|
+
- savea
|
|
33
|
+
# events
|
|
34
|
+
- event
|
|
35
|
+
# stack
|
|
36
|
+
- pop
|
|
37
|
+
- push
|
|
38
|
+
- flip
|
|
39
|
+
- fold
|
|
40
|
+
- unfold
|
|
41
|
+
# generic
|
|
42
|
+
send:
|
|
43
|
+
- [ 'symbol_arg?' ]
|
|
44
|
+
invoke:
|
|
45
|
+
- [ 'symbol_arg?' ]
|
|
46
|
+
get:
|
|
47
|
+
- [ 'symbol_arg?' ]
|
|
48
|
+
getr:
|
|
49
|
+
- [ 'symbol_arg?' ]
|
|
50
|
+
set:
|
|
51
|
+
- [ 'symbol_arg?' ]
|
|
52
|
+
del:
|
|
53
|
+
- [ 'symbol_arg?' ]
|
|
54
|
+
# control
|
|
55
|
+
nop:
|
|
56
|
+
- []
|
|
57
|
+
then:
|
|
58
|
+
- [ 'label_arg?' ]
|
|
59
|
+
ifenil:
|
|
60
|
+
- []
|
|
61
|
+
ifezero:
|
|
62
|
+
- []
|
|
63
|
+
# lifecycle
|
|
64
|
+
puid:
|
|
65
|
+
- []
|
|
66
|
+
self:
|
|
67
|
+
- []
|
|
68
|
+
parent:
|
|
69
|
+
- []
|
|
70
|
+
fetch:
|
|
71
|
+
- [ 'argument?' ]
|
|
72
|
+
fork:
|
|
73
|
+
- [ 'label_arg?' ]
|
|
74
|
+
forka:
|
|
75
|
+
- [ ]
|
|
76
|
+
save:
|
|
77
|
+
- [ 'integer_arg?' ]
|
|
78
|
+
savea:
|
|
79
|
+
- []
|
|
80
|
+
# stack
|
|
81
|
+
pop:
|
|
82
|
+
- [ 'integer_arg?' ]
|
|
83
|
+
push:
|
|
84
|
+
- [ argument ]
|
|
85
|
+
flip:
|
|
86
|
+
- []
|
|
87
|
+
fold:
|
|
88
|
+
- [ 'integer_arg?' ]
|
|
89
|
+
unfold:
|
|
90
|
+
- []
|
|
91
|
+
# events
|
|
92
|
+
event:
|
|
93
|
+
- [ 'symbol_arg?' ]
|
|
94
|
+
argument:
|
|
95
|
+
- boolean_arg
|
|
96
|
+
- symbol_arg
|
|
97
|
+
- integer_arg
|
|
98
|
+
- string_arg
|
|
99
|
+
- module_arg
|
|
100
|
+
- array_arg
|
|
101
|
+
- hash_arg
|
|
102
|
+
label_arg:
|
|
103
|
+
- symbol_arg
|
|
104
|
+
- integer_arg
|
|
105
|
+
boolean_arg:
|
|
106
|
+
- true
|
|
107
|
+
- false
|
|
108
|
+
symbol_arg: '::Symbol'
|
|
109
|
+
integer_arg: '::Integer'
|
|
110
|
+
string_arg: '::String'
|
|
111
|
+
module_arg: '::Module'
|
|
112
|
+
array_arg: '::Array'
|
|
113
|
+
hash_arg: '::Hash'
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
class VM
|
|
3
|
+
class Bytecode
|
|
4
|
+
class Printer < Sexpr::Rewriter
|
|
5
|
+
|
|
6
|
+
def on_gvm(sexpr)
|
|
7
|
+
z, *blocks = sexpr
|
|
8
|
+
max = blocks.inject(0){|m,bl|
|
|
9
|
+
length = bl[1].to_s.size
|
|
10
|
+
length > m ? length : m
|
|
11
|
+
}
|
|
12
|
+
@sep = "\n" + " "*(max + 2)
|
|
13
|
+
code = ""
|
|
14
|
+
code << blocks.map{|bl| apply(bl)}.join("\n")
|
|
15
|
+
code << "\n"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def on_block(sexpr)
|
|
19
|
+
z, label, *instr = sexpr
|
|
20
|
+
label = "#{label}: "
|
|
21
|
+
label << " "*(@sep.size - label.size - 1)
|
|
22
|
+
label << instr.map{|i| apply(i)}.join(@sep).strip
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def on_missing(sexpr)
|
|
26
|
+
iname, *args = sexpr
|
|
27
|
+
label = "#{iname} "
|
|
28
|
+
label << args.map{|arg| arg.inspect}.join(', ')
|
|
29
|
+
label.strip
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end # class Printer
|
|
33
|
+
end # class Bytecode
|
|
34
|
+
end # class VM
|
|
35
|
+
end # class Gisele
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
class VM
|
|
3
|
+
#
|
|
4
|
+
# The Gisele Virtual Machine
|
|
5
|
+
#
|
|
6
|
+
# SYNOPSIS
|
|
7
|
+
# gvm [--version] [--help]
|
|
8
|
+
# gvm [--drb-server] [options] GIS_FILE
|
|
9
|
+
# gvm --drb-client [options]
|
|
10
|
+
#
|
|
11
|
+
# OPTIONS
|
|
12
|
+
# #{summarized_options}
|
|
13
|
+
#
|
|
14
|
+
class Command < Quickl::Command(__FILE__, __LINE__)
|
|
15
|
+
|
|
16
|
+
# Install options
|
|
17
|
+
options do |opt|
|
|
18
|
+
opt.on('--help', "Show this help message") do
|
|
19
|
+
raise Quickl::Help
|
|
20
|
+
end
|
|
21
|
+
opt.on('--version', 'Show version and exit') do
|
|
22
|
+
raise Quickl::Exit, "gvm #{Gisele::VM::VERSION} (c) The University of Louvain"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
@mode = :run
|
|
26
|
+
opt.on('-c', '--compile', 'Compile the input file and output the VM bytecode') do
|
|
27
|
+
@mode = :compile
|
|
28
|
+
end
|
|
29
|
+
opt.on('-g', '--gts', 'Outputs a gisele transition system') do
|
|
30
|
+
@mode = :gts
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
opt.separator("\nStorage")
|
|
34
|
+
@storage = "memory"
|
|
35
|
+
opt.on('--storage=URI',
|
|
36
|
+
"Use the specified storage (defaults to 'memory')") do |uri|
|
|
37
|
+
@storage = uri
|
|
38
|
+
end
|
|
39
|
+
@truncate = false
|
|
40
|
+
opt.on('-t', '--truncate', 'Truncate process instances first') do
|
|
41
|
+
@truncate = true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
opt.separator("\nVM & Agents")
|
|
45
|
+
@interactive = false
|
|
46
|
+
opt.on('-i', '--interactive', 'Start a console in interactive VM mode') do
|
|
47
|
+
@interactive = true
|
|
48
|
+
end
|
|
49
|
+
@simulation = false
|
|
50
|
+
opt.on('-s', '--simulate', 'Use an agent simulating the environment') do
|
|
51
|
+
@simulation = true
|
|
52
|
+
end
|
|
53
|
+
@drb_server = false
|
|
54
|
+
opt.on('--drb-server', 'Register the VM as a DRb server') do
|
|
55
|
+
@drb_server = true
|
|
56
|
+
end
|
|
57
|
+
@drb_client = false
|
|
58
|
+
opt.on('--drb-client', 'Look for the virtual machine on DRb') do
|
|
59
|
+
@drb_client = true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
opt.separator("\nLogging")
|
|
63
|
+
@verbose = Logger::INFO
|
|
64
|
+
opt.on('-v', '--verbose', 'Log in verbose mode') do
|
|
65
|
+
@verbose = Logger::DEBUG
|
|
66
|
+
end
|
|
67
|
+
opt.on('--silent', 'Only show warnings and errors') do
|
|
68
|
+
@verbose = Logger::WARN
|
|
69
|
+
end
|
|
70
|
+
@log_file = $stdout
|
|
71
|
+
opt.on('--log=FILE', 'Use a specific log file') do |file|
|
|
72
|
+
@log_file = file
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def execute(args)
|
|
77
|
+
raise Quickl::Help if args.size > 1
|
|
78
|
+
@gis_file = Path(args.shift)
|
|
79
|
+
case @mode
|
|
80
|
+
when :run then start_vm
|
|
81
|
+
when :compile then puts VM.compile(@gis_file)
|
|
82
|
+
when :gts then puts VM.gts(@gis_file).to_dot
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def vm(gis_file = @gis_file)
|
|
87
|
+
@vm ||= @drb_client ? drb_vm : real_vm(gis_file)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
def real_vm(gis_file = @gis_file)
|
|
93
|
+
bc = VM.compile(gis_file)
|
|
94
|
+
VM.new(bc) do |vm|
|
|
95
|
+
vm.proglist = VM::ProgList.new VM::ProgList.storage(@storage)
|
|
96
|
+
vm.register VM::Enacter.new
|
|
97
|
+
populate(vm)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def drb_vm
|
|
102
|
+
require_relative 'proxy'
|
|
103
|
+
Proxy::Client.new{|vm| populate(vm) }
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def populate(vm)
|
|
107
|
+
# Install the logger
|
|
108
|
+
vm.logger = Logger.new(@log_file)
|
|
109
|
+
vm.logger.level = @verbose
|
|
110
|
+
|
|
111
|
+
# Add the simulation if required
|
|
112
|
+
if @simulation
|
|
113
|
+
require_relative 'simulator/resumer'
|
|
114
|
+
vm.register Simulator::Resumer.new
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Add the DRb server if required
|
|
118
|
+
if @drb_server
|
|
119
|
+
require_relative 'proxy'
|
|
120
|
+
vm.register Proxy::Server.new
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
if @interactive
|
|
124
|
+
vm.register Console.new
|
|
125
|
+
end
|
|
126
|
+
vm
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def start_vm
|
|
130
|
+
the_vm = vm
|
|
131
|
+
trap('INT'){
|
|
132
|
+
the_vm.info "Interrupt on user request (graceful shutdown)."
|
|
133
|
+
the_vm.stop
|
|
134
|
+
}
|
|
135
|
+
the_vm.run
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end # class Command
|
|
139
|
+
end # class VM
|
|
140
|
+
end # module Gisele
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
class VM
|
|
3
|
+
class Component
|
|
4
|
+
extend Forwardable
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@vm = nil
|
|
8
|
+
@connected = false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def vm
|
|
12
|
+
@vm || NullObject.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def registered(vm)
|
|
16
|
+
@vm = vm
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def unregistered
|
|
20
|
+
@vm = nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def registered?
|
|
24
|
+
!@vm.nil?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def registered!
|
|
28
|
+
raise InvalidStateError, "Not registered" unless registered?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def connect
|
|
32
|
+
registered!
|
|
33
|
+
raise InvalidStateError, "Already connected" if connected?
|
|
34
|
+
@connected = true
|
|
35
|
+
info(welcome_message)
|
|
36
|
+
EM.next_tick do
|
|
37
|
+
info(heartbeat_in_message)
|
|
38
|
+
enter_heartbeat
|
|
39
|
+
end if respond_to?(:enter_heartbeat)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def disconnect
|
|
43
|
+
raise InvalidStateError, "Not connected" unless connected?
|
|
44
|
+
if respond_to?(:leave_heartbeat)
|
|
45
|
+
info(heartbeat_out_message)
|
|
46
|
+
leave_heartbeat
|
|
47
|
+
end
|
|
48
|
+
@connected = false
|
|
49
|
+
info(goodbye_message)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def connected?
|
|
53
|
+
@connected
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def connected!
|
|
57
|
+
raise InvalidStateError, "Not connected" unless connected?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def_delegators :vm, :debug, :info, :warn, :error, :fatal
|
|
61
|
+
def_delegators :vm, :debug?, :info?, :warn?, :error?, :fatal?
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def component_name
|
|
66
|
+
self.class.name.to_s.split('::').last
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def welcome_message
|
|
70
|
+
"Component <#{component_name}> connecting."
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def heartbeat_in_message
|
|
74
|
+
"Component <#{component_name}> entering heartbeat."
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def heartbeat_out_message
|
|
78
|
+
"Component <#{component_name}> exiting heartbeat."
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def goodbye_message
|
|
82
|
+
"Component <#{component_name}> disconnected."
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def error_message(error, base = "An error occured:")
|
|
86
|
+
base.to_s << " " << error.message << "\n" << error.backtrace.join("\n")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end # class Component
|
|
90
|
+
end # class VM
|
|
91
|
+
end # module Gisele
|