alda-rb 0.2.1 → 0.3.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +18 -0
- data/.gitignore +2 -2
- data/CHANGELOG.md +296 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +3 -2
- data/Gemfile.lock +56 -0
- data/README.md +58 -7
- data/Rakefile +2 -2
- data/alda-rb.gemspec +30 -25
- data/examples/bwv846_prelude.rb +3 -3
- data/examples/clapping_music.rb +1 -1
- data/examples/dot_accessor.rb +1 -1
- data/examples/dynamics.rb +22 -0
- data/examples/entropy.rb +2 -2
- data/examples/hanon.rb +2 -2
- data/examples/marriage_d_amour.rb +114 -0
- data/examples/multi_poly.rb +2 -2
- data/examples/track-volume.rb +32 -0
- data/examples/variables-2.rb +16 -0
- data/exe/alda-irb +32 -0
- data/lib/alda-rb/commandline.rb +176 -33
- data/lib/alda-rb/error.rb +93 -9
- data/lib/alda-rb/event.rb +441 -49
- data/lib/alda-rb/event_list.rb +57 -10
- data/lib/alda-rb/patches.rb +88 -14
- data/lib/alda-rb/repl.rb +330 -61
- data/lib/alda-rb/utils.rb +47 -0
- data/lib/alda-rb/version.rb +1 -1
- data/lib/alda-rb.rb +1 -0
- metadata +74 -8
data/lib/alda-rb/event_list.rb
CHANGED
@@ -15,6 +15,11 @@ module Alda::EventList
|
|
15
15
|
# The set containing the available variable names.
|
16
16
|
attr_accessor :variables
|
17
17
|
|
18
|
+
##
|
19
|
+
# When the module is included by a subclass of Alda::Event,
|
20
|
+
# this method overrides Alda::Event#on_contained.
|
21
|
+
# When invoked, calls the overridden method (if any) and then evaluates the block
|
22
|
+
# given when ::new was called.
|
18
23
|
def on_contained
|
19
24
|
super if defined? super
|
20
25
|
instance_eval &@block if @block
|
@@ -33,6 +38,9 @@ module Alda::EventList
|
|
33
38
|
#
|
34
39
|
# 2. Starting with 2 lowercase letters and
|
35
40
|
# ending with underline character: instrument. See Alda::Part.
|
41
|
+
# This will trigger a warning if we are using \Alda 2 because
|
42
|
+
# parts inside a sequence are not allowed in \Alda 2
|
43
|
+
# ({alda-lang/alda#441}[https://github.com/alda-lang/alda/discussions/441#discussioncomment-3825064]).
|
36
44
|
#
|
37
45
|
# 3. Starting with 2 lowercase letters: inline lisp code,
|
38
46
|
# set variable, or get variable.
|
@@ -82,14 +90,13 @@ module Alda::EventList
|
|
82
90
|
if args.first.is_a? String
|
83
91
|
Alda::Part.new [part], args.first
|
84
92
|
else
|
93
|
+
Alda::Utils.warn 'parts in sequence not allowed in v2' if Alda.v2? && !args.empty?
|
85
94
|
sequence_sugar.(Alda::Part.new [part])
|
86
95
|
end
|
87
96
|
when /\A[a-z][a-z].*\z/ =~ name
|
88
97
|
arg = args.first
|
89
98
|
if block || !has_variable?(name) && args.size == 1 && arg.is_a?(Alda::Event) &&
|
90
|
-
!arg.
|
91
|
-
!(arg.is_a?(Alda::EventContainer) &&
|
92
|
-
(arg.event.is_a?(Alda::InlineLisp) || arg.event.is_a?(Alda::LispIdentifier)))
|
99
|
+
!arg.is_event_of?(Alda::InlineLisp) && !arg.is_event_of?(Alda::LispIdentifier)
|
93
100
|
Alda::SetVariable.new name, *args, &block
|
94
101
|
elsif has_variable?(name) && (args.empty? || args.size == 1 && arg.is_a?(Alda::Event))
|
95
102
|
sequence_sugar.(Alda::GetVariable.new name)
|
@@ -145,8 +152,8 @@ module Alda::EventList
|
|
145
152
|
#
|
146
153
|
# Append the events of another Alda::EventList object here.
|
147
154
|
# This method covers the disadvantage of alda's being unable to
|
148
|
-
# import scores from other files
|
149
|
-
#
|
155
|
+
# import scores from other files
|
156
|
+
# ({alda-lang/alda-core#8}[https://github.com/alda-lang/alda-core/issues/8]).
|
150
157
|
def import event_list
|
151
158
|
@events.concat event_list.events
|
152
159
|
nil
|
@@ -156,7 +163,7 @@ module Alda::EventList
|
|
156
163
|
# :call-seq:
|
157
164
|
# new(&block) -> Alda::EventList
|
158
165
|
#
|
159
|
-
# +block+ is to be passed with the Alda::EventList object as +self+.
|
166
|
+
# The parameter +block+ is to be passed with the Alda::EventList object as +self+.
|
160
167
|
#
|
161
168
|
# Note that +block+ is not called immediately.
|
162
169
|
# It is instead called in #on_contained.
|
@@ -198,6 +205,16 @@ module Alda::EventList
|
|
198
205
|
def events_alda_codes delimiter = ' '
|
199
206
|
@events.map(&:to_alda_code).join delimiter
|
200
207
|
end
|
208
|
+
|
209
|
+
##
|
210
|
+
# :call-seq:
|
211
|
+
# event_list == other -> true or false
|
212
|
+
#
|
213
|
+
# Returns true if +other+ is of the same class as +event_list+
|
214
|
+
# and they have the same (in the sense of <tt>==</tt>) #events and #variables.
|
215
|
+
def == other
|
216
|
+
super || self.class == other.class && @events == other.events && @variables == other.variables
|
217
|
+
end
|
201
218
|
end
|
202
219
|
|
203
220
|
##
|
@@ -222,7 +239,7 @@ class Alda::Score
|
|
222
239
|
# Alda::Score.new { piano_; c; d; e }.play from: 1
|
223
240
|
# # (plays only an E note)
|
224
241
|
def play **opts
|
225
|
-
Alda.play code: self, **opts
|
242
|
+
Alda.env(ALDA_DISABLE_SPAWNING: :no) { Alda.play code: self, **opts }
|
226
243
|
end
|
227
244
|
|
228
245
|
##
|
@@ -270,13 +287,13 @@ class Alda::Score
|
|
270
287
|
|
271
288
|
##
|
272
289
|
# :call-seq:
|
273
|
-
# load(filename) -> Alda::
|
290
|
+
# load(filename) -> Alda::Raw
|
274
291
|
#
|
275
292
|
# Loads alda codes from a file.
|
276
293
|
#
|
277
|
-
# Actually appends a Alda::
|
294
|
+
# Actually appends a Alda::Raw event with the contents in the file +filename+.
|
278
295
|
def load filename
|
279
|
-
event = Alda::
|
296
|
+
event = Alda::Raw.new File.read filename
|
280
297
|
@events.push event
|
281
298
|
event
|
282
299
|
end
|
@@ -310,4 +327,34 @@ class Alda::Score
|
|
310
327
|
@variables.clear
|
311
328
|
nil
|
312
329
|
end
|
330
|
+
|
331
|
+
##
|
332
|
+
# :call-seq:
|
333
|
+
# raw(contents) -> Alda::Raw
|
334
|
+
#
|
335
|
+
# Adds an Alda::Raw event to the event list and returns it.
|
336
|
+
# The event is not contained by a container.
|
337
|
+
#
|
338
|
+
# Alda::Score.new { raw 'piano: c d e' }.to_s # => "piano: c d e"
|
339
|
+
def raw contents
|
340
|
+
Alda::Raw.new(contents).tap { @events.push _1 }
|
341
|
+
end
|
342
|
+
|
343
|
+
##
|
344
|
+
# :call-seq:
|
345
|
+
# l(head, *args) -> Alda::EventContainer
|
346
|
+
#
|
347
|
+
# Adds an Alda::EventContainer containing an Alda::InlineLisp event to the event list.
|
348
|
+
# In most cases, #method_misssing is a more convenient way to add an inline Lisp event.
|
349
|
+
# However, sometimes you may want to programmatically control which Lisp function to be called,
|
350
|
+
# or the function name is already a valid Ruby method name
|
351
|
+
# (for example, you want to use +f+ or +p+ as the dynamics but +f+ would be interpreted as a note
|
352
|
+
# and +p+ is already a Ruby method for printing)
|
353
|
+
# so that it cannot trigger #method_missing,
|
354
|
+
# then you should use this method.
|
355
|
+
#
|
356
|
+
# Alda::Score.new { piano_; l :p; c }.to_s # => "piano: (p ) c"
|
357
|
+
def l head, *args
|
358
|
+
Alda::EventContainer.new(Alda::InlineLisp.new(head, *args), self).tap { @events.push _1 }
|
359
|
+
end
|
313
360
|
end
|
data/lib/alda-rb/patches.rb
CHANGED
@@ -1,41 +1,89 @@
|
|
1
1
|
require 'stringio'
|
2
2
|
|
3
3
|
##
|
4
|
+
# Contains patches to Ruby's core classes.
|
5
|
+
class Thread
|
6
|
+
##
|
7
|
+
# Because \Alda 2 uses quoted lists to denote lists (vectors) of symbols,
|
8
|
+
# we have to keep track of whether we are inside a list already
|
9
|
+
# (because this notation is inconsistent for inner lists and outer lists).
|
10
|
+
attr_accessor :inside_alda_list
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Contains patches to Ruby's core classes.
|
4
15
|
class Array
|
5
16
|
|
6
17
|
##
|
18
|
+
# :call-seq:
|
19
|
+
# to_alda_code() -> String
|
20
|
+
#
|
7
21
|
# See Alda::Event#to_alda_code.
|
22
|
+
# Behaves differently for \Alda 1 and \Alda 2 (due to
|
23
|
+
# {a breaking change}[https://github.com/alda-lang/alda/blob/master/doc/alda-2-migration-guide.md#attribute-syntax-has-changed-in-some-cases]).
|
8
24
|
def to_alda_code
|
9
|
-
|
25
|
+
contents = -> { map(&:to_alda_code).join ' ' }
|
26
|
+
if Alda.v1?
|
27
|
+
"[#{contents.()}]"
|
28
|
+
else
|
29
|
+
thread = Thread.current
|
30
|
+
if thread.inside_alda_list
|
31
|
+
"(#{contents.()})"
|
32
|
+
else
|
33
|
+
thread.inside_alda_list = true
|
34
|
+
"'(#{contents.()})".tap { thread.inside_alda_list = false }
|
35
|
+
end
|
36
|
+
end
|
10
37
|
end
|
11
38
|
|
12
39
|
##
|
13
40
|
# See Alda::Event#detach_from_parent.
|
14
|
-
def detach_from_parent
|
15
|
-
reverse_each
|
41
|
+
def detach_from_parent(...)
|
42
|
+
reverse_each { _1.detach_from_parent(...) }
|
16
43
|
end
|
17
44
|
end
|
18
45
|
|
19
46
|
##
|
47
|
+
# Contains patches to Ruby's core classes.
|
20
48
|
class Hash
|
21
49
|
|
22
50
|
##
|
51
|
+
# :call-seq:
|
52
|
+
# to_alda_code() -> String
|
53
|
+
#
|
23
54
|
# See Alda::Event#to_alda_code.
|
55
|
+
# Behaves differently for \Alda 1 and \Alda 2 (due to
|
56
|
+
# {a breaking change}[https://github.com/alda-lang/alda/blob/master/doc/alda-2-migration-guide.md#attribute-syntax-has-changed-in-some-cases]).
|
24
57
|
def to_alda_code
|
25
|
-
"
|
58
|
+
contents = -> { map { "#{_1.to_alda_code} #{_2.to_alda_code}" }.join ' ' }
|
59
|
+
if Alda.v1?
|
60
|
+
"{#{contents.()}}"
|
61
|
+
else
|
62
|
+
thread = Thread.current
|
63
|
+
if thread.inside_alda_list
|
64
|
+
"(#{contents.()})"
|
65
|
+
else
|
66
|
+
thread.inside_alda_list = true
|
67
|
+
"'(#{contents.()})".tap { thread.inside_alda_list = false }
|
68
|
+
end
|
69
|
+
end
|
26
70
|
end
|
27
71
|
|
28
72
|
##
|
29
73
|
# See Alda::Event#detach_from_parent.
|
30
|
-
def detach_from_parent
|
31
|
-
each.reverse_each
|
74
|
+
def detach_from_parent(...)
|
75
|
+
each.reverse_each { _1.detach_from_parent(...) }
|
32
76
|
end
|
33
77
|
end
|
34
78
|
|
35
79
|
##
|
80
|
+
# Contains patches to Ruby's core classes.
|
36
81
|
class String
|
37
82
|
|
38
83
|
##
|
84
|
+
# :call-seq:
|
85
|
+
# to_alda_code() -> String
|
86
|
+
#
|
39
87
|
# See Alda::Event#to_alda_code.
|
40
88
|
def to_alda_code
|
41
89
|
dump
|
@@ -43,29 +91,37 @@ class String
|
|
43
91
|
|
44
92
|
##
|
45
93
|
# See Alda::Event#detach_from_parent.
|
46
|
-
def detach_from_parent
|
94
|
+
def detach_from_parent(...)
|
47
95
|
end
|
48
96
|
end
|
49
97
|
|
50
98
|
##
|
99
|
+
# Contains patches to Ruby's core classes.
|
51
100
|
class Symbol
|
52
101
|
|
53
102
|
##
|
103
|
+
# :call-seq:
|
104
|
+
# to_alda_code() -> String
|
105
|
+
#
|
54
106
|
# See Alda::Event#to_alda_code.
|
55
107
|
def to_alda_code
|
56
|
-
?:
|
108
|
+
"#{Alda.v1? ? ?: : Thread.current.inside_alda_list ? '' : ?'}#{to_s}"
|
57
109
|
end
|
58
110
|
|
59
111
|
##
|
60
112
|
# See Alda::Event#detach_from_parent.
|
61
|
-
def detach_from_parent
|
113
|
+
def detach_from_parent(...)
|
62
114
|
end
|
63
115
|
end
|
64
116
|
|
65
117
|
##
|
118
|
+
# Contains patches to Ruby's core classes.
|
66
119
|
class Numeric
|
67
120
|
|
68
121
|
##
|
122
|
+
# :call-seq:
|
123
|
+
# to_alda_code() -> String
|
124
|
+
#
|
69
125
|
# See Alda::Event#to_alda_code.
|
70
126
|
def to_alda_code
|
71
127
|
inspect
|
@@ -73,14 +129,18 @@ class Numeric
|
|
73
129
|
|
74
130
|
##
|
75
131
|
# See Alda::Event#detach_from_parent.
|
76
|
-
def detach_from_parent
|
132
|
+
def detach_from_parent(...)
|
77
133
|
end
|
78
134
|
end
|
79
135
|
|
80
136
|
##
|
137
|
+
# Contains patches to Ruby's core classes.
|
81
138
|
class Range
|
82
139
|
|
83
140
|
##
|
141
|
+
# :call-seq:
|
142
|
+
# to_alda_code() -> String
|
143
|
+
#
|
84
144
|
# See Alda::Event#to_alda_code.
|
85
145
|
def to_alda_code
|
86
146
|
"#{first}-#{last}"
|
@@ -88,14 +148,18 @@ class Range
|
|
88
148
|
|
89
149
|
##
|
90
150
|
# See Alda::Event#detach_from_parent.
|
91
|
-
def detach_from_parent
|
151
|
+
def detach_from_parent(...)
|
92
152
|
end
|
93
153
|
end
|
94
154
|
|
95
155
|
##
|
156
|
+
# Contains patches to Ruby's core classes.
|
96
157
|
class TrueClass
|
97
158
|
|
98
159
|
##
|
160
|
+
# :call-seq:
|
161
|
+
# to_alda_code() -> String
|
162
|
+
#
|
99
163
|
# See Alda::Event#to_alda_code.
|
100
164
|
def to_alda_code
|
101
165
|
'true'
|
@@ -103,14 +167,18 @@ class TrueClass
|
|
103
167
|
|
104
168
|
##
|
105
169
|
# See Alda::Event#detach_from_parent.
|
106
|
-
def detach_from_parent
|
170
|
+
def detach_from_parent(...)
|
107
171
|
end
|
108
172
|
end
|
109
173
|
|
110
174
|
##
|
175
|
+
# Contains patches to Ruby's core classes.
|
111
176
|
class FalseClass
|
112
177
|
|
113
178
|
##
|
179
|
+
# :call-seq:
|
180
|
+
# to_alda_code() -> String
|
181
|
+
#
|
114
182
|
# See Alda::Event#to_alda_code.
|
115
183
|
def to_alda_code
|
116
184
|
'false'
|
@@ -118,14 +186,18 @@ class FalseClass
|
|
118
186
|
|
119
187
|
##
|
120
188
|
# See Alda::Event#detach_from_parent.
|
121
|
-
def detach_from_parent
|
189
|
+
def detach_from_parent(...)
|
122
190
|
end
|
123
191
|
end
|
124
192
|
|
125
193
|
##
|
194
|
+
# Contains patches to Ruby's core classes.
|
126
195
|
class NilClass
|
127
196
|
|
128
197
|
##
|
198
|
+
# :call-seq:
|
199
|
+
# to_alda_code() -> String
|
200
|
+
#
|
129
201
|
# See Alda::Event#to_alda_code.
|
130
202
|
def to_alda_code
|
131
203
|
'nil'
|
@@ -133,11 +205,12 @@ class NilClass
|
|
133
205
|
|
134
206
|
##
|
135
207
|
# See Alda::Event#detach_from_parent.
|
136
|
-
def detach_from_parent
|
208
|
+
def detach_from_parent(...)
|
137
209
|
end
|
138
210
|
end
|
139
211
|
|
140
212
|
##
|
213
|
+
# Contains patches to Ruby's core classes.
|
141
214
|
class Proc
|
142
215
|
|
143
216
|
##
|
@@ -155,6 +228,7 @@ class Proc
|
|
155
228
|
end
|
156
229
|
|
157
230
|
##
|
231
|
+
# Contains patches to Ruby's core classes.
|
158
232
|
class StringIO
|
159
233
|
|
160
234
|
##
|