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.
Files changed (185) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +18 -0
  3. data/Gemfile.lock +46 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +15 -0
  6. data/README.md +10 -0
  7. data/Rakefile +11 -0
  8. data/bin/gvm +9 -0
  9. data/gisele-vm.gemspec +191 -0
  10. data/gisele-vm.noespec +31 -0
  11. data/lib/gisele-vm.rb +4 -0
  12. data/lib/gisele-vm/loader.rb +5 -0
  13. data/lib/gisele-vm/version.rb +16 -0
  14. data/lib/gisele/compiling.rb +3 -0
  15. data/lib/gisele/compiling/gisele2gts.rb +143 -0
  16. data/lib/gisele/compiling/gts.rb +74 -0
  17. data/lib/gisele/compiling/gts2bytecode.rb +127 -0
  18. data/lib/gisele/vm.rb +87 -0
  19. data/lib/gisele/vm/bytecode.rb +84 -0
  20. data/lib/gisele/vm/bytecode/builder.rb +77 -0
  21. data/lib/gisele/vm/bytecode/grammar.citrus +116 -0
  22. data/lib/gisele/vm/bytecode/grammar.rb +19 -0
  23. data/lib/gisele/vm/bytecode/grammar.sexp.yml +113 -0
  24. data/lib/gisele/vm/bytecode/printer.rb +35 -0
  25. data/lib/gisele/vm/command.rb +140 -0
  26. data/lib/gisele/vm/component.rb +91 -0
  27. data/lib/gisele/vm/console.rb +58 -0
  28. data/lib/gisele/vm/enacter.rb +29 -0
  29. data/lib/gisele/vm/errors.rb +26 -0
  30. data/lib/gisele/vm/event.rb +11 -0
  31. data/lib/gisele/vm/event_manager.rb +65 -0
  32. data/lib/gisele/vm/kernel.rb +58 -0
  33. data/lib/gisele/vm/kernel/macros.gvm +214 -0
  34. data/lib/gisele/vm/kernel/opcodes.rb +212 -0
  35. data/lib/gisele/vm/kernel/runner.rb +63 -0
  36. data/lib/gisele/vm/lifecycle.rb +72 -0
  37. data/lib/gisele/vm/logging.rb +18 -0
  38. data/lib/gisele/vm/null_object.rb +19 -0
  39. data/lib/gisele/vm/prog.rb +63 -0
  40. data/lib/gisele/vm/prog_list.rb +55 -0
  41. data/lib/gisele/vm/prog_list/memory.rb +74 -0
  42. data/lib/gisele/vm/prog_list/sqldb.rb +123 -0
  43. data/lib/gisele/vm/prog_list/storage.rb +31 -0
  44. data/lib/gisele/vm/proxy.rb +14 -0
  45. data/lib/gisele/vm/proxy/client.rb +64 -0
  46. data/lib/gisele/vm/proxy/server.rb +29 -0
  47. data/lib/gisele/vm/registry.rb +57 -0
  48. data/lib/gisele/vm/robustness.rb +31 -0
  49. data/lib/gisele/vm/simulator/resumer.rb +32 -0
  50. data/spec/command/gvm_compile.cmd +1 -0
  51. data/spec/command/gvm_compile.stdout +111 -0
  52. data/spec/command/gvm_gts.cmd +1 -0
  53. data/spec/command/gvm_gts.stdout +101 -0
  54. data/spec/command/gvm_help.cmd +1 -0
  55. data/spec/command/gvm_help.stdout +30 -0
  56. data/spec/command/gvm_version.cmd +1 -0
  57. data/spec/command/gvm_version.stdout +2 -0
  58. data/spec/command/test_command.rb +29 -0
  59. data/spec/fixtures/complete.gis +13 -0
  60. data/spec/fixtures/fake_component.rb +24 -0
  61. data/spec/fixtures/kernel.rb +39 -0
  62. data/spec/fixtures/ts.adl +11 -0
  63. data/spec/fixtures/ts.gts +20 -0
  64. data/spec/fixtures/ts.gvm +19 -0
  65. data/spec/spec_helper.rb +86 -0
  66. data/spec/test_examples.rb +29 -0
  67. data/spec/test_gisele-vm.rb +8 -0
  68. data/spec/unit/bytecode/builder/test_at.rb +56 -0
  69. data/spec/unit/bytecode/builder/test_helpers.rb +36 -0
  70. data/spec/unit/bytecode/builder/test_instruction.rb +35 -0
  71. data/spec/unit/bytecode/builder/test_to_a.rb +53 -0
  72. data/spec/unit/bytecode/bytecode.gvm +1 -0
  73. data/spec/unit/bytecode/grammar/fixtures/comments.gvm +16 -0
  74. data/spec/unit/bytecode/grammar/fixtures/every.gvm +46 -0
  75. data/spec/unit/bytecode/grammar/fixtures/singleblock.gvm +2 -0
  76. data/spec/unit/bytecode/grammar/fixtures/twoblocks.gvm +4 -0
  77. data/spec/unit/bytecode/grammar/fixtures/with_end.gvm +5 -0
  78. data/spec/unit/bytecode/grammar/test_array.rb +24 -0
  79. data/spec/unit/bytecode/grammar/test_block.rb +35 -0
  80. data/spec/unit/bytecode/grammar/test_boolean.rb +20 -0
  81. data/spec/unit/bytecode/grammar/test_constant.rb +20 -0
  82. data/spec/unit/bytecode/grammar/test_eol.rb +20 -0
  83. data/spec/unit/bytecode/grammar/test_eol_comment.rb +36 -0
  84. data/spec/unit/bytecode/grammar/test_file.rb +38 -0
  85. data/spec/unit/bytecode/grammar/test_hash.rb +33 -0
  86. data/spec/unit/bytecode/grammar/test_instruction.rb +32 -0
  87. data/spec/unit/bytecode/grammar/test_int.rb +24 -0
  88. data/spec/unit/bytecode/grammar/test_label.rb +24 -0
  89. data/spec/unit/bytecode/grammar/test_opcode.rb +23 -0
  90. data/spec/unit/bytecode/grammar/test_string.rb +25 -0
  91. data/spec/unit/bytecode/grammar/test_symbol.rb +30 -0
  92. data/spec/unit/bytecode/test_build.rb +36 -0
  93. data/spec/unit/bytecode/test_coerce.rb +41 -0
  94. data/spec/unit/bytecode/test_fetch.rb +20 -0
  95. data/spec/unit/bytecode/test_grammar.rb +30 -0
  96. data/spec/unit/bytecode/test_parse.rb +22 -0
  97. data/spec/unit/bytecode/test_plus.rb +27 -0
  98. data/spec/unit/bytecode/test_to_a.rb +19 -0
  99. data/spec/unit/bytecode/test_to_s.rb +32 -0
  100. data/spec/unit/command/code.gis +3 -0
  101. data/spec/unit/command/test_vm.rb +51 -0
  102. data/spec/unit/compiling/gisele2gts/test_on_par_st.rb +51 -0
  103. data/spec/unit/compiling/gisele2gts/test_on_seq_st.rb +46 -0
  104. data/spec/unit/compiling/gisele2gts/test_on_task_call_st.rb +37 -0
  105. data/spec/unit/compiling/gisele2gts/test_on_task_def.rb +49 -0
  106. data/spec/unit/compiling/gisele2gts/test_on_unit_def.rb +35 -0
  107. data/spec/unit/compiling/gts2bytecode/test_on_end.rb +31 -0
  108. data/spec/unit/compiling/gts2bytecode/test_on_event.rb +37 -0
  109. data/spec/unit/compiling/gts2bytecode/test_on_fork.rb +41 -0
  110. data/spec/unit/compiling/gts2bytecode/test_on_join.rb +42 -0
  111. data/spec/unit/compiling/gts2bytecode/test_on_listen.rb +36 -0
  112. data/spec/unit/compiling/gts2bytecode/test_on_nop.rb +30 -0
  113. data/spec/unit/component/test_component_name.rb +16 -0
  114. data/spec/unit/component/test_logging.rb +36 -0
  115. data/spec/unit/enacter/test_component.rb +11 -0
  116. data/spec/unit/event/test_to_s.rb +12 -0
  117. data/spec/unit/event_manager/test_component.rb +9 -0
  118. data/spec/unit/event_manager/test_subscribe.rb +40 -0
  119. data/spec/unit/event_manager/test_unsubscribe.rb +39 -0
  120. data/spec/unit/kernel/macros/test_fork.rb +37 -0
  121. data/spec/unit/kernel/macros/test_join.rb +43 -0
  122. data/spec/unit/kernel/macros/test_listen.rb +37 -0
  123. data/spec/unit/kernel/macros/test_notify.rb +57 -0
  124. data/spec/unit/kernel/macros/test_react.rb +47 -0
  125. data/spec/unit/kernel/macros/test_schedule_at.rb +30 -0
  126. data/spec/unit/kernel/opcodes/test_op_del.rb +42 -0
  127. data/spec/unit/kernel/opcodes/test_op_event.rb +25 -0
  128. data/spec/unit/kernel/opcodes/test_op_fetch.rb +27 -0
  129. data/spec/unit/kernel/opcodes/test_op_flip.rb +17 -0
  130. data/spec/unit/kernel/opcodes/test_op_fold.rb +29 -0
  131. data/spec/unit/kernel/opcodes/test_op_fork.rb +63 -0
  132. data/spec/unit/kernel/opcodes/test_op_forka.rb +51 -0
  133. data/spec/unit/kernel/opcodes/test_op_get.rb +62 -0
  134. data/spec/unit/kernel/opcodes/test_op_getr.rb +48 -0
  135. data/spec/unit/kernel/opcodes/test_op_ifenil.rb +41 -0
  136. data/spec/unit/kernel/opcodes/test_op_ifezero.rb +32 -0
  137. data/spec/unit/kernel/opcodes/test_op_invoke.rb +34 -0
  138. data/spec/unit/kernel/opcodes/test_op_nop.rb +18 -0
  139. data/spec/unit/kernel/opcodes/test_op_parent.rb +39 -0
  140. data/spec/unit/kernel/opcodes/test_op_pop.rb +22 -0
  141. data/spec/unit/kernel/opcodes/test_op_push.rb +17 -0
  142. data/spec/unit/kernel/opcodes/test_op_save.rb +32 -0
  143. data/spec/unit/kernel/opcodes/test_op_savea.rb +34 -0
  144. data/spec/unit/kernel/opcodes/test_op_self.rb +20 -0
  145. data/spec/unit/kernel/opcodes/test_op_send.rb +20 -0
  146. data/spec/unit/kernel/opcodes/test_op_set.rb +61 -0
  147. data/spec/unit/kernel/opcodes/test_op_then.rb +50 -0
  148. data/spec/unit/kernel/opcodes/test_op_unfold.rb +22 -0
  149. data/spec/unit/kernel/opcodes/test_op_uuid.rb +16 -0
  150. data/spec/unit/kernel/runner/test_pop.rb +26 -0
  151. data/spec/unit/kernel/runner/test_stack.rb +28 -0
  152. data/spec/unit/kernel/test_progress.rb +47 -0
  153. data/spec/unit/kernel/test_resume.rb +53 -0
  154. data/spec/unit/kernel/test_start.rb +36 -0
  155. data/spec/unit/prog/test_to_hash.rb +29 -0
  156. data/spec/unit/prog/test_waitlist_eq.rb +20 -0
  157. data/spec/unit/prog_list/memory/test_component.rb +9 -0
  158. data/spec/unit/prog_list/memory/test_fetch.rb +40 -0
  159. data/spec/unit/prog_list/memory/test_pick.rb +39 -0
  160. data/spec/unit/prog_list/memory/test_save.rb +91 -0
  161. data/spec/unit/prog_list/memory/test_to_relation.rb +17 -0
  162. data/spec/unit/prog_list/sqldb/test_component.rb +11 -0
  163. data/spec/unit/prog_list/sqldb/test_connect.rb +46 -0
  164. data/spec/unit/prog_list/test_memory.rb +9 -0
  165. data/spec/unit/prog_list/test_sqldb.rb +13 -0
  166. data/spec/unit/prog_list/test_storage.rb +51 -0
  167. data/spec/unit/registry/test_component.rb +9 -0
  168. data/spec/unit/registry/test_connect.rb +53 -0
  169. data/spec/unit/registry/test_disconnect.rb +51 -0
  170. data/spec/unit/registry/test_registration.rb +44 -0
  171. data/spec/unit/shared/a_component.rb +49 -0
  172. data/spec/unit/shared/a_storage.rb +114 -0
  173. data/spec/unit/test_logging.rb +46 -0
  174. data/spec/unit/test_prog.rb +57 -0
  175. data/spec/unit/test_prog_list.rb +22 -0
  176. data/spec/unit/vm/test_event_facace.rb +11 -0
  177. data/spec/unit/vm/test_initialize.rb +59 -0
  178. data/spec/unit/vm/test_proglist_facade.rb +21 -0
  179. data/tasks/debug_mail.rake +75 -0
  180. data/tasks/debug_mail.txt +13 -0
  181. data/tasks/gem.rake +73 -0
  182. data/tasks/spec_test.rake +71 -0
  183. data/tasks/unit_test.rake +76 -0
  184. data/tasks/yard.rake +51 -0
  185. 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