Skip to content

Commit 0b3e71e

Browse files
committed
Some bug fixes and added cyclic operator to list operations and some tests
Some bug fixes in pitch multiplication and added cyclic operator to lists: (1 2 3)<+ - *>(3 2 1) and some tests.
1 parent e199ff9 commit 0b3e71e

File tree

5 files changed

+76
-28
lines changed

5 files changed

+76
-28
lines changed

lib/parser/generative.treetop

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ grammar GenerativeSyntax
5050
end
5151

5252
rule set
53-
set_scale:(prefix_scale)? '(' ':'? content:(set_items) repeat_two:(':')? repeat_times:(integer)? ')' p:(('~' / '?') [1-9]*)? t:(transform)? a:(array_method)? o:(operation)* eval_f:(ternary)? select_range:(set_range)?
53+
set_scale:(prefix_scale)? '(' ':'? content:(set_items) repeat_two:(':')? repeat_times:(integer)? ')' p:(('~' / '?') [1-9]*)? a:(array_method)? o:(operation)* t:(transform)? eval_f:(ternary)? select_range:(set_range)?
5454
{
5555
def value
5656
reps = repeat_times.value if repeat_times.methods.include?(:value)
@@ -127,7 +127,8 @@ grammar GenerativeSyntax
127127
o.elements.each do |op|
128128
if op.methods.include?(:value) then
129129
op_values = ZiffArray.new(op.value.flatten.compact) if op.value.is_a?(Array)
130-
case op.operator
130+
op_operator = op.operator(set_id)
131+
case op_operator
131132
when '**', '*', '/', '+', '-', '^', '%', '|', '&', '<<', '>>'
132133
if op.value.kind_of?(Array)
133134
set = op_values.map do |z|
@@ -138,14 +139,14 @@ grammar GenerativeSyntax
138139
if z and c
139140
if z.is_a?(Hash) and c.is_a?(Hash)
140141
if z[:pc] and c[:pc]
141-
c_dup[:pc] = z[:pc].method(op.operator).(c[:pc])
142+
c_dup[:pc] = c[:pc].method(op_operator).(z[:pc])
142143
elsif z[:hpcs] and c[:pc]
143-
c_dup[:hpcs] = z_dup[:hpcs].map {|h| h = Marshal.load(Marshal.dump(h)) ; h[:pc] = h[:pc].method(op.operator).(c[:pc]); h}
144+
c_dup[:hpcs] = z_dup[:hpcs].map {|h| h = Marshal.load(Marshal.dump(h)) ; h[:pc] = c[:pc].method(op_operator).(h[:pc]); h}
144145
c_dup.delete(:pc)
145146
elsif c[:hpcs] and z[:pc]
146-
c_dup[:hpcs] = c[:hpcs].map {|h| h = Marshal.load(Marshal.dump(h)) ; h[:pc] = h[:pc].method(op.operator).(z[:pc]); h}
147+
c_dup[:hpcs] = c[:hpcs].map {|h| h = Marshal.load(Marshal.dump(h)) ; h[:pc] = h[:pc].method(op_operator).(z[:pc]); h}
147148
elsif c[:hpcs] and z[:hpcs]
148-
c_dup[:hpcs] = c_dup[:hpcs].map {|ch| z[:hpcs].map{|zh| zh = Marshal.load(Marshal.dump(zh)) ; zh[:pc] = zh[:pc].method(op.operator).(ch[:pc]) ; zh }}.flatten
149+
c_dup[:hpcs] = c_dup[:hpcs].map {|ch| z[:hpcs].map{|zh| zh = Marshal.load(Marshal.dump(zh)) ; zh[:pc] = ch[:pc].method(op_operator).(zh[:pc]) ; zh }}.flatten
149150
end
150151
end
151152
end
@@ -161,9 +162,9 @@ grammar GenerativeSyntax
161162
v = Marshal.load(Marshal.dump(v))
162163
if v.is_a?(Hash)
163164
if v[:pc]
164-
v[:pc] = v[:pc].to_i.method(op.operator).(operation_value)
165+
v[:pc] = v[:pc].to_i.method(op_operator).(operation_value)
165166
elsif v[:hpcs]
166-
v[:hpcs] = v[:hpcs].map {|h| h = Marshal.load(Marshal.dump(h)) ; h[:pc] = h[:pc].method(op.operator).(operation_value); h }
167+
v[:hpcs] = v[:hpcs].map {|h| h = Marshal.load(Marshal.dump(h)) ; h[:pc] = h[:pc].method(op_operator).(operation_value); h }
167168
end
168169
end
169170
v
@@ -177,19 +178,21 @@ grammar GenerativeSyntax
177178
set = set-op_values if op_values
178179
when '<*>'
179180
if op_values
180-
set = set.ois.map do |v|
181-
op_values.map do |z|
182-
z = Marshal.load(Marshal.dump(z))
183-
if z[:hpcs] and v.is_a?(Array)
184-
z[:hpcs] = v.map {|ival| z[:hpcs].map {|h| ZiffHash[{pc: h[:pc]+ival}] }}.flatten
185-
elsif z[:pc] and v.is_a?(Array)
186-
z[:hpcs] = v.map {|ival| ZiffHash[{pc: z[:pc]+ival}] }
187-
z.delete(:pc)
188-
elsif z[:hpcs] and v.is_a?(Integer)
189-
z[:hpcs] = z[:hpcs].map {|h| h[:pc] = h[:pc]+v ; h }
190-
else
191-
z[:pc] = z[:pc]+v
192-
end
181+
set = op_values.ois.map do |v|
182+
set.map do |z|
183+
if z.is_a?(Hash)
184+
z = Marshal.load(Marshal.dump(z))
185+
if z[:hpcs] and v.is_a?(Array)
186+
z[:hpcs] = v.map {|ival| z[:hpcs].map {|h| ZiffHash[{pc: h[:pc]+ival}] }}.flatten
187+
elsif z[:pc] and v.is_a?(Array)
188+
z[:hpcs] = v.map {|ival| ZiffHash[{pc: z[:pc]+ival}] }
189+
z.delete(:pc)
190+
elsif z[:hpcs] and v.is_a?(Integer)
191+
z[:hpcs] = z[:hpcs].map {|h| h[:pc] = h[:pc]+v ; h }
192+
else
193+
z[:pc] = z[:pc]+v
194+
end
195+
end
193196
z
194197
end
195198
end
@@ -423,10 +426,18 @@ grammar GenerativeSyntax
423426
end
424427

425428
rule operation
426-
op:('**' / '*' / '+' / '-' / '/' / '^' / '%' / '|' / '&' / '<<' / '>>' / '#' / '@' / '<@>' / '<&>' / '<->' / '<+>' / '<*>' / '<|>') val:(min_max / set / array)
427-
{
428-
def operator
429-
op.text_value
429+
op:(cyclic_operators / '**' / '*' / '+' / '-' / '/' / '^' / '%' / '|' / '&' / '<<' / '>>' / '#' / '@' / '<@>' / '<&>' / '<->' / '<+>' / '<*>' / '<|>') val:(min_max / set / array)
430+
{
431+
def operator(set_id)
432+
if op.methods.include?(:value)
433+
reps = (Thread.current[:tshared][:set_repeat_index] || 0)
434+
operation_cycle_index = (Thread.current[:tshared][:operation_cycle_index] || 0) + 1
435+
Thread.current[:tshared][:operation_cycle_index] = operation_cycle_index
436+
val = op.value
437+
val = resolve_cycle(val,"OP"+(reps>0?("R"+set_id.to_s):operation_cycle_index.to_s),reps) if val.is_a?(Hash) and val[:cycle]
438+
else
439+
op.text_value
440+
end
430441
end
431442
def value
432443
if val.methods.include?(:value)
@@ -439,6 +450,18 @@ grammar GenerativeSyntax
439450
}
440451
end
441452

453+
rule cyclic_operators
454+
'<' ' '* first:(operator) following:(' ' i:operator)+ ' '* '>'
455+
{
456+
def value
457+
r = following.elements.map {|v| v.i.value }
458+
r.prepend(first.value)
459+
r = r.compact
460+
{:cycle=>r}
461+
end
462+
}
463+
end
464+
442465
rule parens
443466
'[' parens_subset ']'
444467
{

lib/ziffarray.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,14 +450,14 @@ def chord_intervals
450450
def ois(r=nil)
451451
#arr = self.pitch_classes #.select {|v| v.is_a?(Integer)}.compact
452452
if self.length>0
453-
pc_list = self.select {|v| v[:pc] }.compact
453+
pc_list = self.filter{|z| z.is_a?(Hash) and z[:pc] }.select {|v| v[:pc] }.compact
454454
if !r
455455
r = pc_list[0][:pc] if pc_list[0]
456456
end
457457
if pc_list.length==0
458458
return self.map {|v| v.ois }
459459
else
460-
return self.map {|v| (v[:pc] and v[:pc].is_a?(Integer)) ? pc_int(r, v[:pc]) : v.ois }
460+
return self.filter{|z| z.is_a?(Hash) and z[:pc] }.map {|v| (v[:pc] and v[:pc].is_a?(Integer)) ? pc_int(r, v[:pc]) : v.ois }
461461
end
462462
else
463463
return nil

lib/ziffhash.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ def pcs
2626
self[:hpcs].map {|h| h[:pc] }
2727
end
2828

29+
def dgrs
30+
self[:hpcs].map {|h| h.dgr }
31+
end
32+
2933
def opcs
3034
self[:hpcs].map {|h| h[:pc]+(h[:octave] ? h[:octave]*h[:scale_length] : 0) }
3135
end

test/run_wiki_test_generative.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def test_generative
6868
a = zparse "(1 2 3)<+>(3 6 3)" # Product of two sets
6969
assert_equal(a.pcs,[1, 3, 1, 6, 1, 3, 2, 3, 2, 6, 2, 3, 3, 3, 3, 6, 3, 3])
7070
a = zparse "(1 2 3)<*>(3 6 3)" # Two sets interval multiplication
71-
assert_equal(a.pcs,[3, 6, 3, 4, 0, 4, 5, 1, 5])
71+
assert_equal(a.pcs,[1, 2, 3, 4, 5, 6, 1, 2, 3])
7272
a = zparse "(1 2 3)<&>(3 6 3)" # Intersection of two sets
7373
assert_equal(a.pcs,[3])
7474
a = zparse "(1 2 3)<|>(3 6 3)" # Union of two sets

test/run_wiki_tests_2.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,28 @@ def test_functions
9797
assert_equal(a.pcs,[2,4,6])
9898
end
9999

100+
def test_list_operations
101+
a = zparse "(1 2 3)+(3 4 5)"
102+
assert_equal(a.pcs,[4, 5, 6, 5, 6, 0, 6, 0, 1])
103+
a = zparse "(1 2 3)-(3 4 5)"
104+
assert_equal(a.pcs,[5, 6, 0, 4, 5, 6, 3, 4, 5])
105+
a = zparse "(:(1 2 3)<+ ->(3 4 5):)"
106+
assert_equal(a.pcs,[4, 5, 6, 5, 6, 0, 6, 0, 1, 5, 6, 0, 4, 5, 6, 3, 4, 5])
107+
a = zparse "(1 2 3)*(3 4 5)"
108+
assert_equal(a.pcs,[3, 6, 2, 4, 1, 5, 5, 3, 1])
109+
a = zparse "(3 4 5)/(1 2 3)"
110+
assert_equal(a.pcs,[3, 4, 5, 1, 2, 2, 1, 1, 1])
111+
a = zparse "(1 2 3)%(3 4 5)"
112+
assert_equal(a.pcs,[1, 2, 0, 1, 2, 3, 1, 2, 3])
113+
a = zparse "(1 2 3)**(3 4 5)"
114+
assert_equal(a.pcs,[1, 1, 6, 1, 2, 4, 1, 4, 5])
115+
a = zparse "(q 2 e 4 8)<*>(0 2 4 3)"
116+
assert_equal(a.pcs,[2, 4, 1, 4, 6, 3, 6, 1, 5, 5, 0, 4])
117+
end
118+
119+
100120
test_chords
101121
test_cycles
122+
test_list_operations
102123

103124
print "All tests OK"

0 commit comments

Comments
 (0)