alda-rb 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +18 -0
- data/.gitignore +2 -2
- data/CHANGELOG.md +271 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +54 -0
- data/README.md +56 -7
- data/Rakefile +2 -2
- data/alda-rb.gemspec +3 -3
- 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 +29 -0
- data/lib/alda-rb/commandline.rb +139 -33
- data/lib/alda-rb/error.rb +82 -9
- data/lib/alda-rb/event.rb +441 -49
- data/lib/alda-rb/event_list.rb +54 -7
- data/lib/alda-rb/patches.rb +88 -14
- data/lib/alda-rb/repl.rb +311 -59
- data/lib/alda-rb/utils.rb +47 -0
- data/lib/alda-rb/version.rb +1 -1
- data/lib/alda-rb.rb +1 -0
- metadata +17 -7
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)
|
@@ -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
|
##
|
@@ -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
|
##
|