From bcc86f4cfedca23f1b893b6152dc6ed675c1b7ca Mon Sep 17 00:00:00 2001 From: Miika Alonen Date: Thu, 23 Feb 2023 21:42:12 +0200 Subject: [PATCH] Added two options for variables Pre-evaluated: A=(1,4) Just a clone: A~(1,4) --- ziffers/classes.py | 33 ++++++++++++++++++++++++++------- ziffers/mapper.py | 8 ++++++-- ziffers/spec/ziffers.lark | 3 ++- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/ziffers/classes.py b/ziffers/classes.py index 976fa3b..6f8da6f 100644 --- a/ziffers/classes.py +++ b/ziffers/classes.py @@ -4,6 +4,7 @@ from itertools import product, islice, cycle from math import floor import operator import random +from copy import deepcopy from .defaults import DEFAULT_OPTIONS from .scale import note_from_pc, midi_to_pitch_class, midi_to_freq, get_scale_length from .common import euclidian_rhythm @@ -270,17 +271,23 @@ class Function(Event): run: str = field(default=None) + @dataclass(kw_only=True) class VariableAssignment(Item): """Class for defining variables""" + variable: str value: Item + pre_eval: bool + @dataclass(kw_only=True) class Variable(Item): """Class for using variables""" + name: str + @dataclass(kw_only=True) class Sequence(Meta): """Class for sequences of items""" @@ -345,10 +352,17 @@ class Sequence(Meta): else: yield from item.evaluate_tree(options) elif isinstance(item, VariableAssignment): - options[item.variable.name] = item.value + if item.pre_eval: + pre_options = options.copy() + pre_options["pre_eval"] = True + options[item.variable.name] = Sequence( + values=list(_resolve_item(item.value, pre_options)) + ) + else: + options[item.variable.name] = item.value elif isinstance(item, Variable): if options[item.name]: - variable = options[item.name] + variable = deepcopy(options[item.name]) yield from _resolve_item(variable, options) elif isinstance(item, Range): yield from item.evaluate(options) @@ -367,6 +381,8 @@ class Sequence(Meta): if isinstance(item, Pitch): item.update_options(options) item.update_note() + if options.get("pre_eval",False): + item.duration = options["duration"] if isinstance(item, Rest): item.update_options(options) elif isinstance(item, (RandomPitch, RandomInteger)): @@ -413,7 +429,10 @@ class Sequence(Meta): options[current.key] = current.value return options - def _create_pitch(current: Item, options: dict) -> dict: + def _create_pitch_without_note(current: Item, options: dict) -> Pitch: + return Pitch(pitch_class=current.get_value(options)) + + def _create_pitch(current: Item, options: dict) -> Pitch: """Create pitch based on values and options""" if "modifier" in options: @@ -772,7 +791,7 @@ class ListOperation(Sequence): flattened_list.append(filter_operation(item)) elif isinstance(item, Cyclic): value = item.get_value() - if isinstance(value,Sequence): + if isinstance(value, Sequence): flattened_list.extend(filter_operation(value)) elif isinstance(value, (Event, RandomInteger, Integer)): flattened_list.append(value) @@ -788,9 +807,9 @@ class ListOperation(Sequence): operators = self.values[1::2] # Fetch every second operator element values = self.values[::2] # Fetch every second list element - values = filter_operation(values) # Filter out - if len(values)==1: - return values[0] # If right hand doesnt contain anything sensible + values = filter_operation(values) # Filter out + if len(values) == 1: + return values[0] # If right hand doesnt contain anything sensible left = values[0] # Start results with the first array for i, operand in enumerate(operators): diff --git a/ziffers/mapper.py b/ziffers/mapper.py index 2204031..7316eb2 100644 --- a/ziffers/mapper.py +++ b/ziffers/mapper.py @@ -262,8 +262,12 @@ class ZiffersTransformer(Transformer): def assignment(self, items): var = items[0] - content = items[1] - return VariableAssignment(variable=var, value=content, text=var.text+"="+content.text) + op = items[1] + content = items[2] + return VariableAssignment(variable=var, value=content, text=var.text+"="+content.text, pre_eval=True if op == "=" else False) + + def ass_op(self,items): + return items[0].value def variable(self, items): return Variable(name=items[0].value, text=items[0].value) diff --git a/ziffers/spec/ziffers.lark b/ziffers/spec/ziffers.lark index 56ecf01..6e94085 100644 --- a/ziffers/spec/ziffers.lark +++ b/ziffers/spec/ziffers.lark @@ -12,7 +12,8 @@ modifier: /[#b]/ // Variable assignment - assignment: variable "=" (list | pitch_class | random_integer | random_pitch | cycle | list_op) + assignment: variable ass_op (list | pitch_class | random_integer | random_pitch | cycle | list_op) + ass_op: /[=~]/ variable: /[A-Z]/ // Durations