musa-dsl 0.14.16

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 (72) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/Gemfile +20 -0
  4. data/LICENSE.md +157 -0
  5. data/README.md +8 -0
  6. data/lib/musa-dsl/core-ext/array-apply-get.rb +18 -0
  7. data/lib/musa-dsl/core-ext/array-explode-ranges.rb +29 -0
  8. data/lib/musa-dsl/core-ext/array-to-neumas.rb +28 -0
  9. data/lib/musa-dsl/core-ext/array-to-serie.rb +20 -0
  10. data/lib/musa-dsl/core-ext/arrayfy.rb +15 -0
  11. data/lib/musa-dsl/core-ext/as-context-run.rb +44 -0
  12. data/lib/musa-dsl/core-ext/duplicate.rb +134 -0
  13. data/lib/musa-dsl/core-ext/dynamic-proxy.rb +55 -0
  14. data/lib/musa-dsl/core-ext/inspect-nice.rb +28 -0
  15. data/lib/musa-dsl/core-ext/key-parameters-procedure-binder.rb +85 -0
  16. data/lib/musa-dsl/core-ext/proc-nice.rb +13 -0
  17. data/lib/musa-dsl/core-ext/send-nice.rb +21 -0
  18. data/lib/musa-dsl/core-ext/string-to-neumas.rb +27 -0
  19. data/lib/musa-dsl/core-ext.rb +13 -0
  20. data/lib/musa-dsl/datasets/gdv-decorators.rb +221 -0
  21. data/lib/musa-dsl/datasets/gdv.rb +499 -0
  22. data/lib/musa-dsl/datasets/pdv.rb +44 -0
  23. data/lib/musa-dsl/datasets.rb +5 -0
  24. data/lib/musa-dsl/generative/darwin.rb +145 -0
  25. data/lib/musa-dsl/generative/generative-grammar.rb +294 -0
  26. data/lib/musa-dsl/generative/markov.rb +78 -0
  27. data/lib/musa-dsl/generative/rules.rb +282 -0
  28. data/lib/musa-dsl/generative/variatio.rb +331 -0
  29. data/lib/musa-dsl/generative.rb +5 -0
  30. data/lib/musa-dsl/midi/midi-recorder.rb +83 -0
  31. data/lib/musa-dsl/midi/midi-voices.rb +274 -0
  32. data/lib/musa-dsl/midi.rb +2 -0
  33. data/lib/musa-dsl/music/chord-definition.rb +99 -0
  34. data/lib/musa-dsl/music/chord-definitions.rb +13 -0
  35. data/lib/musa-dsl/music/chords.rb +326 -0
  36. data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +204 -0
  37. data/lib/musa-dsl/music/scales.rb +584 -0
  38. data/lib/musa-dsl/music.rb +6 -0
  39. data/lib/musa-dsl/neuma/neuma.rb +181 -0
  40. data/lib/musa-dsl/neuma.rb +1 -0
  41. data/lib/musa-dsl/neumalang/neumalang.citrus +294 -0
  42. data/lib/musa-dsl/neumalang/neumalang.rb +179 -0
  43. data/lib/musa-dsl/neumalang.rb +3 -0
  44. data/lib/musa-dsl/repl/repl.rb +143 -0
  45. data/lib/musa-dsl/repl.rb +1 -0
  46. data/lib/musa-dsl/sequencer/base-sequencer-implementation-control.rb +189 -0
  47. data/lib/musa-dsl/sequencer/base-sequencer-implementation-play-helper.rb +354 -0
  48. data/lib/musa-dsl/sequencer/base-sequencer-implementation.rb +382 -0
  49. data/lib/musa-dsl/sequencer/base-sequencer-public.rb +261 -0
  50. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +94 -0
  51. data/lib/musa-dsl/sequencer/sequencer.rb +3 -0
  52. data/lib/musa-dsl/sequencer.rb +1 -0
  53. data/lib/musa-dsl/series/base-series.rb +245 -0
  54. data/lib/musa-dsl/series/hash-serie-splitter.rb +194 -0
  55. data/lib/musa-dsl/series/holder-serie.rb +87 -0
  56. data/lib/musa-dsl/series/main-serie-constructors.rb +726 -0
  57. data/lib/musa-dsl/series/main-serie-operations.rb +1151 -0
  58. data/lib/musa-dsl/series/proxy-serie.rb +69 -0
  59. data/lib/musa-dsl/series/queue-serie.rb +94 -0
  60. data/lib/musa-dsl/series/series.rb +8 -0
  61. data/lib/musa-dsl/series.rb +1 -0
  62. data/lib/musa-dsl/transport/clock.rb +36 -0
  63. data/lib/musa-dsl/transport/dummy-clock.rb +47 -0
  64. data/lib/musa-dsl/transport/external-tick-clock.rb +31 -0
  65. data/lib/musa-dsl/transport/input-midi-clock.rb +124 -0
  66. data/lib/musa-dsl/transport/timer-clock.rb +102 -0
  67. data/lib/musa-dsl/transport/timer.rb +40 -0
  68. data/lib/musa-dsl/transport/transport.rb +137 -0
  69. data/lib/musa-dsl/transport.rb +9 -0
  70. data/lib/musa-dsl.rb +17 -0
  71. data/musa-dsl.gemspec +17 -0
  72. metadata +174 -0
@@ -0,0 +1,143 @@
1
+ require 'socket'
2
+
3
+ module Musa
4
+ class REPL
5
+ @@repl_mutex = Mutex.new
6
+
7
+ def initialize(binder, port: nil, redirect_stderr: nil, after_eval: nil)
8
+ port ||= 1327
9
+ redirect_stderr ||= false
10
+
11
+ @block_source = nil
12
+
13
+ if binder.receiver.respond_to?(:sequencer) &&
14
+ binder.receiver.sequencer.respond_to?(:on_block_error)
15
+
16
+ binder.receiver.sequencer.on_block_error do |e|
17
+ send_exception e
18
+ end
19
+ end
20
+
21
+ @client_threads = []
22
+
23
+ @main_thread = Thread.new do
24
+ @server = TCPServer.new(port)
25
+ begin
26
+ while connection = @server.accept
27
+ @client_threads << Thread.new do
28
+ buffer = nil
29
+
30
+ begin
31
+ while line = connection.gets
32
+ line.chomp!
33
+ case line
34
+ when '#begin'
35
+ buffer = StringIO.new
36
+ when '#end'
37
+ @@repl_mutex.synchronize do
38
+ original_stdout = $stdout
39
+ original_stderr = $stderr
40
+
41
+ $stdout = connection
42
+ $stderr = connection if redirect_stderr
43
+
44
+ @block_source = buffer.string
45
+
46
+ begin
47
+ send_echo @block_source
48
+
49
+ binder.eval @block_source, "(repl)", 1
50
+ rescue StandardError, ScriptError => e
51
+ send_exception e
52
+ else
53
+ after_eval.call @block_source if after_eval
54
+ end
55
+
56
+ $stdout = original_stdout
57
+ $stderr = original_stderr if redirect_stderr
58
+ end
59
+ else
60
+ buffer.puts line
61
+ end
62
+ end
63
+ rescue IOError, Errno::ECONNRESET, Errno::EPIPE => e
64
+ warn e.message
65
+ end
66
+
67
+ connection.close
68
+ end
69
+ end
70
+ rescue Errno::ECONNRESET, Errno::EPIPE => e
71
+ warn e.message
72
+ retry
73
+ end
74
+ end
75
+ end
76
+
77
+ def stop
78
+ # TODO
79
+ end
80
+
81
+ private
82
+
83
+ def send_echo(e)
84
+ send command: '//echo'
85
+ send content: e
86
+ send command: '//end'
87
+ end
88
+
89
+ def send_exception(e)
90
+
91
+ send command: '//error'
92
+
93
+ selected_backtrace_locations = e.backtrace_locations.select { |bt| bt.path == '(repl)' }
94
+
95
+ if e.is_a?(ScriptError)
96
+ send content: e.class.name
97
+ send command: '//backtrace'
98
+ send content: e.message
99
+
100
+ elsif selected_backtrace_locations.empty?
101
+ send content: "#{e.class.name}: #{e.message}"
102
+ send command: '//backtrace'
103
+ send content: e.backtrace_locations.first.to_s
104
+
105
+ else
106
+ lines = @block_source.split("\n")
107
+
108
+ lineno = selected_backtrace_locations.first.lineno
109
+
110
+ source_before = lines[lineno - 2] if lineno >= 2
111
+ source_error = lines[lineno - 1]
112
+ source_after = lines[lineno]
113
+
114
+ send content: '***'
115
+ send content: "[#{lineno - 1}] #{source_before}" if source_before
116
+ send content: "[#{lineno}] #{source_error} \t\t<<< ERROR !!!"
117
+ send content: "[#{lineno + 1}] #{source_after}" if source_after
118
+ send content: '***'
119
+ send content: e.class.name
120
+ send content: e.message
121
+ send command: '//backtrace'
122
+ selected_backtrace_locations.each do |bt|
123
+ send content: bt.to_s
124
+ end
125
+ end
126
+ send content: ' '
127
+ send command: '//end'
128
+ end
129
+
130
+ def send(content: nil, command: nil)
131
+ puts escape(content) if content
132
+ puts command if command
133
+ end
134
+
135
+ def escape(text)
136
+ if text.start_with? '//'
137
+ "//#{text}"
138
+ else
139
+ text
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1 @@
1
+ require 'musa-dsl/repl/repl'
@@ -0,0 +1,189 @@
1
+ require 'forwardable'
2
+
3
+ class Musa::BaseSequencer
4
+ class EventHandler
5
+ attr_reader :stdout, :stderr
6
+ attr_accessor :continue_parameters
7
+
8
+ @@counter = 0
9
+
10
+ def initialize(parent = nil, capture_stdout: nil)
11
+ capture_stdout ||= false
12
+
13
+ @id = (@@counter += 1)
14
+
15
+ @parent = parent
16
+ @handlers = {}
17
+
18
+ @stop = false
19
+
20
+ if capture_stdout || !parent
21
+ @stdout = $stdout
22
+ @stderr = $stderr
23
+ else
24
+ @stdout = @parent.stdout
25
+ @stderr = @parent.stderr
26
+ end
27
+ end
28
+
29
+ def stop
30
+ @stop = true
31
+ end
32
+
33
+ def stopped?
34
+ @stop
35
+ end
36
+
37
+ def pause
38
+ raise NotImplementedError
39
+ end
40
+
41
+ def continue
42
+ @paused = false
43
+ end
44
+
45
+ def paused?
46
+ @paused
47
+ end
48
+
49
+ def on(event, name: nil, only_once: nil, &block)
50
+ only_once ||= false
51
+
52
+ @handlers[event] ||= {}
53
+
54
+ # TODO: add on_rescue: proc { |e| _rescue_block_error(e) } [this method is on Sequencer, not in EventHandler]
55
+ @handlers[event][name] = { block: KeyParametersProcedureBinder.new(block), only_once: only_once }
56
+ end
57
+
58
+ def launch(event, *value_parameters, **key_parameters)
59
+ _launch event, value_parameters, key_parameters
60
+ end
61
+
62
+ def _launch(event, value_parameters = nil, key_parameters = nil)
63
+ processed = false
64
+
65
+ if @handlers.key? event
66
+ @handlers[event].each do |name, handler|
67
+ handler[:block]._call value_parameters, key_parameters
68
+ @handlers[event].delete name if handler[:only_once]
69
+ processed = true
70
+ end
71
+ end
72
+
73
+ @parent._launch event, value_parameters, key_parameters if @parent && !processed
74
+ end
75
+
76
+ def inspect
77
+ "EventHandler #{id}"
78
+ end
79
+
80
+ def id
81
+ if @parent
82
+ "#{@parent.id}.#{self.class.name.split('::').last}-#{@id}"
83
+ else
84
+ "#{self.class.name.split('::').last}-#{@id.to_s}"
85
+ end
86
+ end
87
+
88
+ alias to_s inspect
89
+ end
90
+
91
+ private_constant :EventHandler
92
+
93
+ class PlayControl < EventHandler
94
+ attr_reader :do_after
95
+
96
+ def initialize(parent, capture_stdout: nil, after: nil)
97
+ super parent, capture_stdout: capture_stdout
98
+
99
+ @do_after = []
100
+
101
+ self.after &after if after
102
+ end
103
+
104
+ def pause
105
+ @paused = true
106
+ end
107
+
108
+ def store_continuation(sequencer:, serie:, nl_context:, mode:, decoder:, play_eval:, mode_args:)
109
+ @continuation_sequencer = sequencer
110
+ @continuation_parameters = {
111
+ serie: serie,
112
+ control: self,
113
+ nl_context: nl_context,
114
+ mode: mode,
115
+ decoder: decoder,
116
+ play_eval: play_eval,
117
+ mode_args: mode_args
118
+ }
119
+ end
120
+
121
+ def continue
122
+ super
123
+ @continuation_sequencer.continuation_play(@continuation_parameters) if @continuation_sequencer
124
+ end
125
+
126
+ def after(_bars = nil, &block)
127
+ # TODO implementar parámetro _bars (?)
128
+ @do_after << block
129
+ end
130
+ end
131
+
132
+ private_constant :PlayControl
133
+
134
+ class EveryControl < EventHandler
135
+ attr_reader :duration_value, :till_value, :condition_block, :do_on_stop, :do_after
136
+
137
+ attr_accessor :_start
138
+
139
+ def initialize(parent, capture_stdout: nil, duration: nil, till: nil, condition: nil, on_stop: nil, after_bars: nil, after: nil)
140
+ super parent, capture_stdout: capture_stdout
141
+
142
+ @duration_value = duration
143
+ @till_value = till
144
+ @condition_block = condition
145
+
146
+ @do_on_stop = []
147
+ @do_after = []
148
+
149
+ @do_on_stop << on_stop if on_stop
150
+
151
+ self.after after_bars, &after if after
152
+ end
153
+
154
+ def duration(value)
155
+ @duration_value = value.rationalize
156
+ end
157
+
158
+ def till(value)
159
+ @till_value = value.rationalize
160
+ end
161
+
162
+ def condition(&block)
163
+ @condition_block = block
164
+ end
165
+
166
+ def on_stop(&block)
167
+ @do_on_stop << block
168
+ end
169
+
170
+ def after(bars = nil, &block)
171
+ bars ||= 0
172
+ @do_after << { bars: bars.rationalize, block: block }
173
+ end
174
+ end
175
+
176
+ private_constant :EveryControl
177
+
178
+ class MoveControl
179
+ extend Forwardable
180
+
181
+ def initialize(every_control)
182
+ @every_control = every_control
183
+ end
184
+
185
+ def_delegators :@every_control, :stdout, :stderr, :on_stop, :after, :on, :launch, :stop
186
+ end
187
+
188
+ private_constant :MoveControl
189
+ end
@@ -0,0 +1,354 @@
1
+ class Musa::BaseSequencer
2
+ class PlayEval
3
+ def self.create(mode, block_procedure_binder, decoder, nl_context)
4
+ case mode
5
+ when :at
6
+ AtModePlayEval.new block_procedure_binder
7
+ when :wait
8
+ WaitModePlayEval.new block_procedure_binder
9
+ when :neumalang
10
+ NeumalangModePlayEval.new block_procedure_binder, decoder, nl_context
11
+ else
12
+ raise ArgumentError, "Mode #{mode} not allowed"
13
+ end
14
+ end
15
+
16
+ attr_reader :block_procedure_binder
17
+
18
+ def subcontext
19
+ self
20
+ end
21
+
22
+ def eval_element(_element)
23
+ raise NotImplementedError
24
+ end
25
+
26
+ def run_operation(_element)
27
+ raise NotImplementedError
28
+ end
29
+ end
30
+
31
+ private_constant :PlayEval
32
+
33
+ class AtModePlayEval < PlayEval
34
+ def initialize(block_procedure_binder)
35
+ @block_procedure_binder = block_procedure_binder
36
+ end
37
+
38
+ def run_operation(element)
39
+ value = nil
40
+
41
+ if element.is_a? Hash
42
+ value = {
43
+ current_operation: :block,
44
+ current_block: @block_procedure_binder,
45
+ current_parameter: element,
46
+ continue_operation: :at,
47
+ continue_parameter: element[:at]
48
+ }
49
+ end
50
+
51
+ value ||= {
52
+ current_operation: @block_procedure_binder,
53
+ current_parameter: element,
54
+ continue_operation: :at,
55
+ continue_parameter: position
56
+ }
57
+ end
58
+ end
59
+
60
+ private_constant :AtModePlayEval
61
+
62
+ class WaitModePlayEval < PlayEval
63
+ def initialize(block_procedure_binder)
64
+ @block_procedure_binder = block_procedure_binder
65
+ end
66
+
67
+ def run_operation(element)
68
+ value = nil
69
+
70
+ if element.is_a? Hash
71
+ if element.key? :duration
72
+ value = {
73
+ current_operation: :block,
74
+ current_block: @block_procedure_binder,
75
+ current_parameter: element,
76
+ continue_operation: :wait,
77
+ continue_parameter: element[:duration]
78
+ }
79
+ end
80
+
81
+ if element.key? :wait_event
82
+ value = {
83
+ current_operation: :block,
84
+ current_block: @block_procedure_binder,
85
+ current_parameter: element,
86
+ continue_operation: :on,
87
+ continue_parameter: element[:wait_event]
88
+ }
89
+ end
90
+ end
91
+
92
+ value ||= {
93
+ current_operation: :block,
94
+ current_block: @block_procedure_binder,
95
+ current_parameter: element,
96
+ continue_operation: :now
97
+ }
98
+
99
+ value
100
+ end
101
+ end
102
+
103
+ private_constant :WaitModePlayEval
104
+
105
+ class NeumalangModePlayEval < PlayEval
106
+ module Parallel end
107
+
108
+ @@id = 0
109
+
110
+ attr_reader :nl_context
111
+ attr_reader :block_procedure_binder
112
+
113
+ def initialize(block_procedure_binder, decoder, nl_context, parent: nil)
114
+ @id = @@id += 1
115
+ @parent = parent
116
+
117
+ @block_procedure_binder = block_procedure_binder
118
+ @decoder = decoder
119
+ @nl_context = nl_context
120
+ @nl_context ||= Object.new
121
+ end
122
+
123
+ def subcontext
124
+ NeumalangModePlayEval.new @block_procedure_binder, @decoder.subcontext, @nl_context, parent: self
125
+ end
126
+
127
+ def eval_element(element)
128
+ if element.is_a? Musa::Neumalang::Dataset
129
+ element
130
+ else
131
+ case element[:kind]
132
+ when :serie then eval_serie element[:serie]
133
+ when :parallel then eval_parallel element[:parallel]
134
+ when :assign_to then eval_assign_to element[:assign_to], element[:assign_value]
135
+ when :use_variable then eval_use_variable element[:use_variable]
136
+ when :command then eval_command element[:command], element[:value_parameters], element[:key_parameters]
137
+ when :value then eval_value element[:value]
138
+ when :neuma then eval_neuma element[:neuma]
139
+ when :call_methods then eval_call_methods element[:on], element[:call_methods]
140
+ when :indirection then eval_indirection element[:indirection]
141
+ when :reference then eval_reference element[:reference]
142
+ when :event then element
143
+ else
144
+ raise ArgumentError, "eval_element: don't know how to process #{element}"
145
+ end
146
+ end
147
+ end
148
+
149
+ def eval_value(value)
150
+ value
151
+ end
152
+
153
+ def eval_neuma(neuma)
154
+ @decoder.decode neuma
155
+ end
156
+
157
+ def eval_serie(serie)
158
+ context = subcontext
159
+ serie.instance.eval(on_restart: proc { context = subcontext }) { |e| context.eval_element e }
160
+ end
161
+
162
+ def eval_parallel(series)
163
+ context = subcontext
164
+ series.collect { |s| context.eval_serie s[:serie] }.extend Parallel
165
+ end
166
+
167
+ def eval_assign_to(variable_names, value)
168
+ _value = nil
169
+
170
+ variable_names.each do |var_name|
171
+ @nl_context.instance_variable_set var_name, _value = subcontext.eval_element(value)
172
+ end
173
+
174
+ _value
175
+ end
176
+
177
+ def eval_use_variable(variable_name)
178
+ if @nl_context.instance_variable_defined? variable_name
179
+ @nl_context.instance_variable_get(variable_name)
180
+ else
181
+ raise NameError, "Variable #{variable_name} is not defined in context #{@nl_context}"
182
+ end
183
+ end
184
+
185
+ def eval_command(block, value_parameters, key_parameters)
186
+ _value_parameters = value_parameters.collect { |e| subcontext.eval_element(e) } if value_parameters
187
+ _key_parameters = key_parameters.collect { |k, e| [k, subcontext.eval_element(e)] }.to_h if key_parameters
188
+
189
+ @nl_context._as_context_run block, _value_parameters, _key_parameters
190
+ end
191
+
192
+ def eval_call_methods(on, call_methods)
193
+ play_eval = subcontext
194
+
195
+ value = play_eval.eval_element on
196
+
197
+ if value.is_a? Parallel
198
+ value.collect do |_value|
199
+ call_methods.each do |methd|
200
+ value_parameters = methd[:value_parameters].collect { |e| play_eval.subcontext.eval_element(e) } if methd[:value_parameters]
201
+ key_parameters = methd[:key_parameters].collect { |k, e| [k, play_eval.subcontext.eval_element(e)] }.to_h if methd[:key_parameters]
202
+
203
+ _value = _value._send_nice methd[:method], value_parameters, key_parameters
204
+ end
205
+
206
+ _value
207
+ end.extend Parallel
208
+ else
209
+ call_methods.each do |methd|
210
+ value_parameters = methd[:value_parameters].collect { |e| play_eval.subcontext.eval_element(e) } if methd[:value_parameters]
211
+ key_parameters = methd[:key_parameters].collect { |k, e| [k, play_eval.subcontext.eval_element(e)] }.to_h if methd[:key_parameters]
212
+
213
+ value = value._send_nice methd[:method], value_parameters, key_parameters
214
+ end
215
+
216
+ value
217
+ end
218
+ end
219
+
220
+ def eval_reference(element)
221
+ if element.is_a?(Hash) && element.key?(:kind)
222
+ case element[:kind]
223
+ when :command
224
+ element[:command]
225
+ else
226
+ raise ArgumentError, "eval_reference(&): don't know how to process element #{element}"
227
+ end
228
+ else
229
+ raise ArgumentError, "eval_reference(&): don't know how to process element #{element}"
230
+ end
231
+ end
232
+
233
+ def run_operation(element)
234
+ case element
235
+ when nil
236
+ { current_operation: :none,
237
+ continue_operation: :now }
238
+
239
+ when Musa::Neumalang::Dataset
240
+ { current_operation: :block,
241
+ current_parameter: element,
242
+ continue_operation: :wait,
243
+ continue_parameter: element[:duration] }
244
+
245
+ when Musa::Serie
246
+ { current_operation: :play,
247
+ current_parameter: element.restart }
248
+
249
+ when Parallel
250
+ { current_operation: :parallel_play,
251
+ current_parameter: element.tap { |e| e.each(&:restart) } }
252
+
253
+ when Array
254
+ { current_operation: :no_eval_play,
255
+ current_parameter: S(*element) }
256
+ else
257
+ case element[:kind]
258
+ when :value
259
+
260
+ _value = eval_value element[:value]
261
+
262
+ if _value.is_a?(Hash) && _value.key?(:duration)
263
+ { current_operation: :block,
264
+ current_parameter: _value,
265
+ continue_operation: :wait,
266
+ continue_parameter: _value[:duration] }
267
+ else
268
+ { current_operation: :block,
269
+ current_parameter: _value,
270
+ continue_operation: :now }
271
+ end
272
+
273
+ when :neuma
274
+ _value = eval_neuma element[:neuma]
275
+
276
+ if _value.is_a?(Array)
277
+ { current_operation: :no_eval_play,
278
+ current_parameter: S(*_value) }
279
+ else
280
+ { current_operation: :block,
281
+ current_parameter: _value,
282
+ continue_operation: :wait,
283
+ continue_parameter: _value[:duration] }
284
+ end
285
+
286
+ when :serie
287
+
288
+ { current_operation: :play,
289
+ current_parameter: eval_serie(element[:serie]) }
290
+
291
+ when :parallel
292
+
293
+ { current_operation: :parallel_play,
294
+ current_parameter: eval_parallel(element[:parallel]) }
295
+
296
+ when :assign_to
297
+
298
+ eval_assign_to element[:assign_to], element[:assign_value]
299
+
300
+ { current_operation: :none,
301
+ continue_operation: :now }
302
+
303
+ when :use_variable
304
+
305
+ run_operation eval_use_variable(element[:use_variable])
306
+
307
+ when :event
308
+
309
+ value_parameters = key_parameters = nil
310
+
311
+ value_parameters = element[:value_parameters].collect { |e| subcontext.eval_element(e) } if element[:value_parameters]
312
+ key_parameters = element[:key_parameters].collect { |k, e| [k, subcontext.eval_element(e)] }.to_h if element[:key_parameters]
313
+
314
+ { current_operation: :event,
315
+ current_event: element[:event],
316
+ current_value_parameters: value_parameters,
317
+ current_key_parameters: key_parameters,
318
+ continue_operation: :now }
319
+
320
+ when :command
321
+
322
+ run_operation eval_command(element[:command], element[:value_parameters], element[:key_parameters])
323
+
324
+ when :call_methods
325
+
326
+ run_operation eval_call_methods(element[:on], element[:call_methods])
327
+
328
+ when :reference
329
+
330
+ run_operation eval_reference(element[:reference])
331
+
332
+ else
333
+ raise ArgumentError, "run_operation: don't know how to process #{element}"
334
+ end
335
+ end
336
+ end
337
+
338
+ def inspect
339
+ "NeumalangModePlayEval #{id} #{@decoder}"
340
+ end
341
+
342
+ def id
343
+ if @parent
344
+ "#{@parent.id}.#{@id}"
345
+ else
346
+ @id.to_s
347
+ end
348
+ end
349
+
350
+ alias to_s inspect
351
+ end
352
+
353
+ private_constant :NeumalangModePlayEval
354
+ end