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,181 @@
1
+ module Musa::Neumalang
2
+ module Neumas # Neumas serie
3
+ # TODO implementar | ???? neumas | neumas = parallel neumas, no?
4
+ end
5
+
6
+ module Neuma
7
+ module Parallel
8
+ include Neuma
9
+ end
10
+
11
+ def |(other)
12
+ if is_a?(Parallel)
13
+ clone.tap { |_| _[:parallel] << convert_to_parallel_element(other) }.extend(Parallel)
14
+ else
15
+ { kind: :parallel,
16
+ parallel: [clone, convert_to_parallel_element(other)]
17
+ }.extend(Parallel)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def convert_to_parallel_element(e)
24
+ case e
25
+ when String then { kind: :serie, serie: e.to_neumas }.extend(Neuma)
26
+ else
27
+ raise ArgumentError, "Dont know how to convert to neuma #{e}"
28
+ end
29
+ end
30
+ end
31
+
32
+ module Dataset
33
+ class Decorator
34
+ def process(element, base_duration:, tick_duration:)
35
+ element
36
+ end
37
+
38
+ def check(value_or_array, &block)
39
+ if block_given?
40
+ if value_or_array.is_a?(Array)
41
+ value_or_array.each { |value| yield value }
42
+ else
43
+ yield value_or_array
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ class TwoNeumasDecorator < Decorator
50
+ def process(element1, element2, base_duration:, tick_duration:)
51
+ element2
52
+ end
53
+ end
54
+
55
+ class Decorators
56
+ attr_reader :decorators
57
+ attr_accessor :appogiatura_decorator
58
+
59
+ def initialize(*decorators, appogiatura_decorator: nil, base_duration: nil, tick_duration: nil)
60
+ @base_duration = 1/4r
61
+ @tick_duration = tick_duration || 1/96r
62
+
63
+ @appogiatura_decorator = appogiatura_decorator
64
+ @decorators = decorators
65
+ end
66
+
67
+ def process(element)
68
+ if @appogiatura_decorator
69
+ element = @appogiatura_decorator.process(element, base_duration: @base_duration, tick_duration: @tick_duration)
70
+ end
71
+
72
+ @decorators.each do |processor|
73
+ if element
74
+ if element.is_a?(Array)
75
+ element = element.collect { |element_i| processor.process(element_i, base_duration: @base_duration, tick_duration: @tick_duration) }.flatten(1)
76
+ else
77
+ element = processor.process(element, base_duration: @base_duration, tick_duration: @tick_duration)
78
+ end
79
+ end
80
+ end
81
+
82
+ element
83
+ end
84
+ end
85
+
86
+ protected
87
+
88
+ def positive_sign_of(x)
89
+ x >= 0 ? '+' : ''
90
+ end
91
+
92
+ def sign_of(x)
93
+ '++-'[x <=> 0]
94
+ end
95
+
96
+ def velocity_of(x)
97
+ %w[ppp pp p mp mf f ff fff][x + 3]
98
+ end
99
+
100
+ def modificator_string(modificator, parameter_or_parameters)
101
+ case parameter_or_parameters
102
+ when true
103
+ modificator.to_s
104
+ when Array
105
+ "#{modificator.to_s}(#{parameter_or_parameters.collect { |p| parameter_to_string(p) }.join(', ')})"
106
+ else
107
+ "#{modificator.to_s}(#{parameter_to_string(parameter_or_parameters)})"
108
+ end
109
+ end
110
+
111
+ private
112
+
113
+ def parameter_to_string(parameter)
114
+ case parameter
115
+ when String
116
+ "\"#{parameter}\""
117
+ when Numeric
118
+ "#{parameter}"
119
+ when Symbol
120
+ "#{parameter}"
121
+ end
122
+ end
123
+ end
124
+
125
+ class ProtoDecoder
126
+ def subcontext
127
+ self
128
+ end
129
+
130
+ def decode(_element)
131
+ raise NotImplementedError
132
+ end
133
+ end
134
+
135
+ class DifferentialDecoder < ProtoDecoder
136
+ def decode(attributes)
137
+ parse attributes
138
+ end
139
+
140
+ def parse(_attributes)
141
+ raise NotImplementedError
142
+ end
143
+ end
144
+
145
+ class Decoder < DifferentialDecoder
146
+ def initialize(base, processor: nil)
147
+ @base = base
148
+ @last = base.clone
149
+
150
+ @processor = processor
151
+ end
152
+
153
+ attr_accessor :processor
154
+ attr_reader :base
155
+
156
+ def base=(base)
157
+ @base = base
158
+ @last = base.clone
159
+ end
160
+
161
+ def subcontext
162
+ Decoder.new @base
163
+ end
164
+
165
+ def decode(attributes)
166
+ result = apply parse(attributes), on: @last
167
+
168
+ @last = result.clone
169
+
170
+ if @processor
171
+ @processor.process(result)
172
+ else
173
+ result
174
+ end
175
+ end
176
+
177
+ def apply(_action, on:)
178
+ raise NotImplementedError
179
+ end
180
+ end
181
+ end
@@ -0,0 +1 @@
1
+ require 'musa-dsl/neuma/neuma'
@@ -0,0 +1,294 @@
1
+ grammar Neumalang
2
+
3
+ rule content
4
+ sentences
5
+ end
6
+
7
+ rule sentences
8
+ (spaces (sentence spaces)*) <Musa::Neumalang::Parser::Sentences>
9
+ end
10
+
11
+ rule sentence
12
+ expression
13
+ end
14
+
15
+ rule expression
16
+ variable_assign | call_methods_expression | object_expression | event
17
+ end
18
+
19
+ rule object_expression
20
+ braced_command | reference_expression | bracketed_expression | use_variable | constant | neuma
21
+ end
22
+
23
+ rule reference_expression
24
+ (ampersand spaces expression) <Musa::Neumalang::Parser::ReferenceExpression>
25
+ end
26
+
27
+ rule variable_assign
28
+ ((use_variable spaces equal spaces)+ expression) <Musa::Neumalang::Parser::VariableAssign>
29
+ end
30
+
31
+ rule event
32
+ (double_colon name parameters?) <Musa::Neumalang::Parser::Event>
33
+ end
34
+
35
+ rule braced_command
36
+ (lbrace spaces complex_command spaces rbrace parameters?) <Musa::Neumalang::Parser::BracedCommand>
37
+ end
38
+
39
+ rule call_methods_expression
40
+ (object_expression (dot method_call)+) <Musa::Neumalang::Parser::CallMethodsExpression>
41
+ end
42
+
43
+ rule bracketed_expression
44
+ bracketed_bar_sentences | bracketed_sentences
45
+ end
46
+
47
+ rule method_call
48
+ (name parameters?) { { method: capture(:name).value.to_sym }.merge(capture(:parameters) ? capture(:parameters).value : {}) }
49
+ end
50
+
51
+ rule neuma
52
+ appogiatura_neuma | simple_neuma
53
+ end
54
+
55
+ rule appogiatura_neuma
56
+ (lpar spaces a:simple_neuma spaces rpar spaces b:simple_neuma) { capture(:b).value.tap { |_| _[:neuma] << { appogiatura: capture(:a).value[:neuma] } } }
57
+ end
58
+
59
+ rule simple_neuma
60
+ neuma_as_dotted_attributes_beginning_with_dot | neuma_as_dotted_attributes_beginning_with_simple_attribute | neuma_between_angles_attributes
61
+ end
62
+
63
+ rule constant
64
+ number | symbol | string
65
+ end
66
+
67
+ rule bracketed_bar_sentences
68
+ (lbracket spaces aa:sentences (bar spaces bb:sentences)+ rbracket) <Musa::Neumalang::Parser::BracketedBarSentences>
69
+ end
70
+
71
+ rule bracketed_sentences
72
+ (lbracket spaces sentences rbracket) <Musa::Neumalang::Parser::BracketedSentences>
73
+ end
74
+
75
+ rule use_variable
76
+ (at name) <Musa::Neumalang::Parser::UseVariable>
77
+ end
78
+
79
+ rule parameters
80
+ parameters_a | parameters_b | parameters_c
81
+ end
82
+
83
+ rule parameters_a
84
+ (lpar positional_parameters comma key_parameters rpar) { { value_parameters: capture(:positional_parameters).value, key_parameters: capture(:key_parameters).value } }
85
+ end
86
+
87
+ rule parameters_b
88
+ (lpar key_parameters rpar) { { key_parameters: capture(:key_parameters).value } }
89
+ end
90
+
91
+ rule parameters_c
92
+ (lpar positional_parameters rpar) { { value_parameters: capture(:positional_parameters).value } }
93
+ end
94
+
95
+ rule positional_parameters
96
+ (spaces a:sentence (spaces comma spaces b:sentence spaces)* spaces) {
97
+ [ capture(:a).value ] + captures(:b).collect { |c| c.value }
98
+ }
99
+ end
100
+
101
+ rule key_parameters
102
+ (spaces a:key_value_parameter (spaces comma spaces b:key_value_parameter spaces)* spaces) {
103
+
104
+ result = capture(:a).value.clone
105
+
106
+ captures(:b).each { |c| result.merge! c.value }
107
+
108
+ result
109
+ }
110
+ end
111
+
112
+ rule key_value_parameter
113
+ (key:name colon spaces value:sentence) { { capture(:key).value.to_sym => capture(:value).value } }
114
+ end
115
+
116
+ rule complex_command
117
+ (everything_except_braces? lbrace spaces complex_command spaces rbrace)* everything_except_braces?
118
+ end
119
+
120
+
121
+ rule neuma_as_dotted_attributes_beginning_with_simple_attribute
122
+ (a:simple_attribute (dot b:attribute)*) <Musa::Neumalang::Parser::NeumaAsDottedAttributesBeginningWithSimpleAttribute>
123
+ end
124
+
125
+ rule neuma_as_dotted_attributes_beginning_with_dot
126
+ ((dot attribute)+ | dot) <Musa::Neumalang::Parser::NeumaAsDottedAttributesBeginningWithDot>
127
+ end
128
+
129
+ rule neuma_between_angles_attributes
130
+ (langle spaces simple_attribute? spaces (attribute spaces)* rangle) <Musa::Neumalang::Parser::NeumaBetweenAnglesAttributes>
131
+ end
132
+
133
+ rule attribute
134
+ (modifier_attribute | simple_attribute)
135
+ end
136
+
137
+ rule simple_attribute
138
+ everything_that_can_be_an_attribute !colon
139
+ end
140
+
141
+ rule modifier_attribute
142
+ modifier_call_without_parameters | modifier_call_with_parameters
143
+ end
144
+
145
+ rule modifier_call_without_parameters
146
+ (name &attribute_change) { { modifier: capture(:name).value.to_sym } }
147
+ end
148
+
149
+ rule modifier_call_with_parameters
150
+ (name modifier_parameters) { { modifier: capture(:name).value.to_sym }.merge(capture(:modifier_parameters) ? capture(:modifier_parameters).value : {}) }
151
+ end
152
+
153
+ rule modifier_parameters
154
+ (lpar modifier_positional_parameters rpar) { { parameters: capture(:modifier_positional_parameters).value } }
155
+ end
156
+
157
+ rule modifier_positional_parameters
158
+ (spaces a:modifier_parameter_constant (spaces comma spaces b:modifier_parameter_constant spaces)* spaces) {
159
+ if capture(:b)
160
+ [ capture(:a).value ] + captures(:b).collect { |c| c.value }
161
+ else
162
+ capture(:a).value
163
+ end
164
+ }
165
+ end
166
+
167
+ rule modifier_parameter_constant
168
+ raw_number | raw_symbol | raw_string
169
+ end
170
+
171
+ rule number
172
+ float | rational | integer
173
+ end
174
+
175
+ rule raw_number
176
+ raw_float | raw_rational | raw_integer
177
+ end
178
+
179
+ rule symbol
180
+ (colon name) <Musa::Neumalang::Parser::Symbol>
181
+ end
182
+
183
+ rule raw_symbol
184
+ (name &spaces) { capture(:name).value.to_sym }
185
+ end
186
+
187
+ rule string
188
+ (double_quote everything_except_double_quote double_quote) <Musa::Neumalang::Parser::String>
189
+ end
190
+
191
+ rule raw_string
192
+ (double_quote everything_except_double_quote double_quote) { capture(:everything_except_double_quote).value }
193
+ end
194
+
195
+ rule float
196
+ (single_quote str:(digits dot digits) spaces) <Musa::Neumalang::Parser::Float>
197
+ end
198
+
199
+ rule raw_float
200
+ (str:(digits dot digits) spaces) { capture(:str).value.to_f }
201
+ end
202
+
203
+ rule integer
204
+ (single_quote digits spaces) <Musa::Neumalang::Parser::Integer>
205
+ end
206
+
207
+ rule raw_integer
208
+ (digits spaces) { capture(:digits).value.to_i }
209
+ end
210
+
211
+ rule rational
212
+ (single_quote str:(digits slash digits) spaces) <Musa::Neumalang::Parser::Rational>
213
+ end
214
+
215
+ rule raw_rational
216
+ (str: (digits slash digits) spaces) { capture(:str).value.to_r }
217
+ end
218
+
219
+ rule comment
220
+ (lcomment complex_comment rcomment) | hash_comment
221
+ end
222
+
223
+ rule hash_comment
224
+ (hsh_at_start_of_line | space+) everything_until_eol
225
+ end
226
+
227
+ rule complex_comment
228
+ everything_except_comment? (lcomment complex_comment rcomment)* everything_except_comment?
229
+ end
230
+
231
+ rule digits
232
+ [0-9]+ ('_' [0-9]+)*
233
+ end
234
+
235
+ rule name
236
+ /[[:alpha:]]\w*/
237
+ end
238
+
239
+ rule everything_that_can_be_an_attribute
240
+ /[^({|}|\[|\]|\(|\)|\<|\>|.|,|:|=| |\t|\n|\r|\"|@|&|\|)]+/m
241
+ end
242
+
243
+ rule attribute_change
244
+ space | dot | rbracket | rpar | rbrace | eol
245
+ end
246
+
247
+ rule everything_until_eol
248
+ ~/$/
249
+ end
250
+
251
+ rule everything_except_comment
252
+ ~/((\*\/)|(\/\*))/m
253
+ end
254
+
255
+ rule everything_except_braces
256
+ ~/({|})/m
257
+ end
258
+
259
+ rule everything_except_double_quote
260
+ ~/(\")/m
261
+ end
262
+
263
+ rule hsh_at_start_of_line
264
+ /\A#/
265
+ end
266
+
267
+ rule double_quote '"' end
268
+ rule single_quote '\'' end
269
+ rule dot '.' end
270
+ rule comma ',' end
271
+ rule colon ':' end
272
+ rule double_colon '::' end
273
+ rule bar '|' end
274
+ rule slash '/' end
275
+ rule lpar '(' end
276
+ rule rpar ')' end
277
+ rule lbrace '{' end
278
+ rule rbrace '}' end
279
+ rule lbracket '[' end
280
+ rule rbracket ']' end
281
+ rule langle '<' end
282
+ rule rangle '>' end
283
+ rule at '@' end
284
+ rule ampersand '&' end
285
+ rule equal '=' end
286
+ rule lcomment '/*' end
287
+ rule rcomment '*/' end
288
+ rule hsh '#' end
289
+ rule eol /$/ end
290
+
291
+ rule space /[ \t\n\r]/m end
292
+ rule spaces (space | comment)* end
293
+
294
+ end
@@ -0,0 +1,179 @@
1
+ require 'musa-dsl/series'
2
+ require 'citrus'
3
+
4
+ module Musa::Neumalang
5
+ module Parser
6
+ module Sentences
7
+ include Musa::Series
8
+
9
+ def value
10
+ _SE(captures(:sentence).collect(&:value), extends: Neumas)
11
+ end
12
+ end
13
+
14
+ module BracketedBarSentences
15
+ include Musa::Series
16
+
17
+ def value
18
+ { kind: :parallel,
19
+ parallel: [{ kind: :serie, serie: S(*capture(:aa).value) }] + captures(:bb).collect { |c| { kind: :serie, serie: S(*c.value) } }
20
+ }.extend(Neuma::Parallel)
21
+ end
22
+ end
23
+
24
+ module BracketedSentences
25
+ include Musa::Series
26
+
27
+ def value
28
+ { kind: :serie,
29
+ serie: S(*capture(:sentences).value) }.extend Neuma
30
+ end
31
+ end
32
+
33
+ module ReferenceExpression
34
+ def value
35
+ { kind: :reference,
36
+ reference: capture(:expression).value }.extend Neuma
37
+ end
38
+ end
39
+
40
+ module VariableAssign
41
+ def value
42
+ { kind: :assign_to,
43
+ assign_to: captures(:use_variable).collect { |c| c.value[:use_variable] }, assign_value: capture(:expression).value
44
+ }.extend Neuma
45
+ end
46
+ end
47
+
48
+ module Event
49
+ def value
50
+ { kind: :event,
51
+ event: capture(:name).value.to_sym
52
+ }.merge(capture(:parameters) ? capture(:parameters).value : {}).extend Neuma
53
+ end
54
+ end
55
+
56
+ module BracedCommand
57
+ def value
58
+ { kind: :command,
59
+ command: eval("proc { #{capture(:complex_command).value.strip} }")
60
+ }.merge(capture(:parameters) ? capture(:parameters).value : {}).extend Neuma
61
+ end
62
+ end
63
+
64
+ module CallMethodsExpression
65
+ def value
66
+ { kind: :call_methods,
67
+ call_methods: captures(:method_call).collect(&:value),
68
+ on: capture(:object_expression).value }.extend Neuma
69
+ end
70
+ end
71
+
72
+ module UseVariable
73
+ def value
74
+ { kind: :use_variable,
75
+ use_variable: "@#{capture(:name).value}".to_sym }.extend Neuma
76
+ end
77
+ end
78
+
79
+ module NeumaAsDottedAttributesBeginningWithSimpleAttribute
80
+ def value
81
+ { kind: :neuma,
82
+ neuma: (capture(:a) ? [capture(:a).value] : []) + captures(:b).collect(&:value) }.extend Neuma
83
+ end
84
+ end
85
+
86
+ module NeumaAsDottedAttributesBeginningWithDot
87
+ def value
88
+ { kind: :neuma,
89
+ neuma: (capture(:attribute) ? [ nil ] : []) + captures(:attribute).collect(&:value) }.extend Neuma
90
+ end
91
+ end
92
+
93
+ module NeumaBetweenAnglesAttributes
94
+ def value
95
+ { kind: :neuma,
96
+ neuma: (capture(:simple_attribute) ? [capture(:simple_attribute).value] : []) + captures(:attribute).collect(&:value) }.extend Neuma
97
+ end
98
+ end
99
+
100
+ module Symbol
101
+ def value
102
+ { kind: :value,
103
+ value: capture(:name).value.to_sym }.extend Neuma
104
+ end
105
+ end
106
+
107
+ module String
108
+ def value
109
+ { kind: :value,
110
+ value: capture(:everything_except_double_quote).value }.extend Neuma
111
+ end
112
+ end
113
+
114
+ module Float
115
+ def value
116
+ { kind: :value,
117
+ value: capture(:str).value.to_f }.extend Neuma
118
+ end
119
+ end
120
+
121
+ module Integer
122
+ def value
123
+ { kind: :value,
124
+ value: capture(:digits).value.to_i }.extend Neuma
125
+ end
126
+ end
127
+
128
+ module Rational
129
+ def value
130
+ { kind: :value,
131
+ value: capture(:str).value.to_r }.extend Neuma
132
+ end
133
+ end
134
+ end
135
+
136
+ def self.register(grammar_path)
137
+ Citrus.load grammar_path
138
+ end
139
+
140
+ def self.parse(string_or_file, language: nil, decode_with: nil, debug: nil)
141
+ language ||= Neumalang
142
+
143
+ match = nil
144
+
145
+ if string_or_file.is_a? String
146
+ match = language.parse string_or_file
147
+
148
+ elsif string_or_file.is_a? File
149
+ match = language.parse string_or_file.read
150
+
151
+ else
152
+ raise ArgumentError, 'Only String or File allowed to be parsed'
153
+ end
154
+
155
+ match.dump if debug
156
+
157
+ serie = match.value
158
+
159
+ if decode_with
160
+ serie.eval do |e|
161
+ if e[:kind] == :neuma
162
+ decode_with.decode(e[:neuma])
163
+ else
164
+ raise ArgumentError, "Don't know how to convert #{e} to neuma"
165
+ end
166
+ end
167
+ else
168
+ serie
169
+ end
170
+ end
171
+
172
+ def self.parse_file(filename, decode_with: nil, debug: nil)
173
+ File.open filename do |file|
174
+ parse file, decode_with: decode_with, debug: debug
175
+ end
176
+ end
177
+
178
+ register File.join(File.dirname(__FILE__), 'neumalang')
179
+ end
@@ -0,0 +1,3 @@
1
+ require 'musa-dsl/neumalang/neumalang'
2
+
3
+