From 973d3eab2b509dd0731c03dc61c57158ef0bee71 Mon Sep 17 00:00:00 2001 From: Miika Alonen Date: Tue, 21 Feb 2023 19:48:37 +0200 Subject: [PATCH] Added range evaluation and more operators --- ziffers/classes.py | 10 ++++++++++ ziffers/defaults.py | 4 ++++ ziffers/mapper.py | 2 +- ziffers/spec/ziffers.lark | 6 +++--- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/ziffers/classes.py b/ziffers/classes.py index ed06d3d..6d80a96 100644 --- a/ziffers/classes.py +++ b/ziffers/classes.py @@ -328,6 +328,8 @@ class Sequence(Meta): yield item else: yield from item.evaluate_tree(options) + elif isinstance(item, Range): + yield from item.evaluate(options) elif isinstance(item, Cyclic): yield from _resolve_item(item.get_value(), options) elif isinstance(item, Euclid): @@ -689,6 +691,10 @@ class Range(Item): start: int = field(default=None) end: int = field(default=None) + def evaluate(self, options): + for i in range(self.start,self.end+1): + yield Pitch(pitch_class=i, kwargs=options) + @dataclass(kw_only=True) class Operator(Item): @@ -714,6 +720,7 @@ class ListOperation(Sequence): def filter_operation(input_list): flattened_list = [] + # TODO: ADD Options here and evaluate events? for item in input_list: if isinstance(item, (list, Sequence)): if isinstance(item, ListOperation): @@ -740,6 +747,7 @@ class ListOperation(Sequence): (right.values if isinstance(right, Sequence) else [right]), left ) left = [ + #TODO: Get options from x value? Pitch( pitch_class=operation(x.get_value(options), y.get_value(options)), kwargs=options, @@ -849,5 +857,7 @@ class RepeatedSequence(Sequence): self.local_options = self.local_options | item.as_options() elif isinstance(item, Rest): yield item.get_updated_item(self.local_options) + elif isinstance(item, Range): + yield from item.evaluate(options) elif isinstance(item, (Event, RandomInteger)): yield Pitch(pitch_class=item.get_value(self.local_options), kwargs=self.local_options) diff --git a/ziffers/defaults.py b/ziffers/defaults.py index 490b9ac..f1fca5c 100644 --- a/ziffers/defaults.py +++ b/ziffers/defaults.py @@ -49,6 +49,10 @@ OPERATORS = { "*": operator.mul, "/": operator.truediv, "%": operator.mod, + "|": operator.or_, + "&": operator.and_, + "<<": operator.ilshift, + ">>": operator.irshift } diff --git a/ziffers/mapper.py b/ziffers/mapper.py index a309c39..cb96361 100644 --- a/ziffers/mapper.py +++ b/ziffers/mapper.py @@ -71,7 +71,7 @@ class ZiffersTransformer(Transformer): def range(self, item) -> Range: """Parses range syntax""" val = item[0].split("..") - return Range(start=val[0], end=val[1], text=item[0]) + return Range(start=int(val[0]), end=int(val[1]), text=item[0].value) def cycle(self, items) -> Cyclic: """Parses cycle""" diff --git a/ziffers/spec/ziffers.lark b/ziffers/spec/ziffers.lark index eaf48ee..60cb49f 100644 --- a/ziffers/spec/ziffers.lark +++ b/ziffers/spec/ziffers.lark @@ -43,7 +43,7 @@ // Right recursive list operation list_op: list (operator right_op)+ right_op: list | number - operator: /([\+\-\*\/%]|<<|>>)/ + operator: /([\+\-\*\/%\|\&]|<<|>>)/ // Euclidean cycles // TODO: Support randomization etc. @@ -56,7 +56,7 @@ // Subdivision subdivision: "[" subitems "]" - subitems: (pitch_class | random_integer | random_pitch | rest | oct_mod | oct_change | WS | chord | named_roman | cycle | subdivision | list | list_op)* + subitems: (pitch_class | random_integer | random_pitch | rest | oct_mod | oct_change | WS | chord | named_roman | cycle | subdivision | list | list_op | range)* // Control characters modifying future events oct_mod: octave WS @@ -67,7 +67,7 @@ // Generative rules random_integer: /\(-?[0-9]+,-?[0-9]+\)/ - range: /-?[0-9]\.\.-?[0-9]/ + range: /-?[0-9]+\.\.-?[0-9]+/ cycle: "<" sequence ">" random_pitch: /(\?)(?!\d)/ random_percent: /(%)(?!\d)/