Added two options for variables
Pre-evaluated: A=(1,4) Just a clone: A~(1,4)
This commit is contained in:
@ -4,6 +4,7 @@ from itertools import product, islice, cycle
|
|||||||
from math import floor
|
from math import floor
|
||||||
import operator
|
import operator
|
||||||
import random
|
import random
|
||||||
|
from copy import deepcopy
|
||||||
from .defaults import DEFAULT_OPTIONS
|
from .defaults import DEFAULT_OPTIONS
|
||||||
from .scale import note_from_pc, midi_to_pitch_class, midi_to_freq, get_scale_length
|
from .scale import note_from_pc, midi_to_pitch_class, midi_to_freq, get_scale_length
|
||||||
from .common import euclidian_rhythm
|
from .common import euclidian_rhythm
|
||||||
@ -270,17 +271,23 @@ class Function(Event):
|
|||||||
|
|
||||||
run: str = field(default=None)
|
run: str = field(default=None)
|
||||||
|
|
||||||
|
|
||||||
@dataclass(kw_only=True)
|
@dataclass(kw_only=True)
|
||||||
class VariableAssignment(Item):
|
class VariableAssignment(Item):
|
||||||
"""Class for defining variables"""
|
"""Class for defining variables"""
|
||||||
|
|
||||||
variable: str
|
variable: str
|
||||||
value: Item
|
value: Item
|
||||||
|
pre_eval: bool
|
||||||
|
|
||||||
|
|
||||||
@dataclass(kw_only=True)
|
@dataclass(kw_only=True)
|
||||||
class Variable(Item):
|
class Variable(Item):
|
||||||
"""Class for using variables"""
|
"""Class for using variables"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
|
|
||||||
@dataclass(kw_only=True)
|
@dataclass(kw_only=True)
|
||||||
class Sequence(Meta):
|
class Sequence(Meta):
|
||||||
"""Class for sequences of items"""
|
"""Class for sequences of items"""
|
||||||
@ -345,10 +352,17 @@ class Sequence(Meta):
|
|||||||
else:
|
else:
|
||||||
yield from item.evaluate_tree(options)
|
yield from item.evaluate_tree(options)
|
||||||
elif isinstance(item, VariableAssignment):
|
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):
|
elif isinstance(item, Variable):
|
||||||
if options[item.name]:
|
if options[item.name]:
|
||||||
variable = options[item.name]
|
variable = deepcopy(options[item.name])
|
||||||
yield from _resolve_item(variable, options)
|
yield from _resolve_item(variable, options)
|
||||||
elif isinstance(item, Range):
|
elif isinstance(item, Range):
|
||||||
yield from item.evaluate(options)
|
yield from item.evaluate(options)
|
||||||
@ -367,6 +381,8 @@ class Sequence(Meta):
|
|||||||
if isinstance(item, Pitch):
|
if isinstance(item, Pitch):
|
||||||
item.update_options(options)
|
item.update_options(options)
|
||||||
item.update_note()
|
item.update_note()
|
||||||
|
if options.get("pre_eval",False):
|
||||||
|
item.duration = options["duration"]
|
||||||
if isinstance(item, Rest):
|
if isinstance(item, Rest):
|
||||||
item.update_options(options)
|
item.update_options(options)
|
||||||
elif isinstance(item, (RandomPitch, RandomInteger)):
|
elif isinstance(item, (RandomPitch, RandomInteger)):
|
||||||
@ -413,7 +429,10 @@ class Sequence(Meta):
|
|||||||
options[current.key] = current.value
|
options[current.key] = current.value
|
||||||
return options
|
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"""
|
"""Create pitch based on values and options"""
|
||||||
|
|
||||||
if "modifier" in options:
|
if "modifier" in options:
|
||||||
@ -772,7 +791,7 @@ class ListOperation(Sequence):
|
|||||||
flattened_list.append(filter_operation(item))
|
flattened_list.append(filter_operation(item))
|
||||||
elif isinstance(item, Cyclic):
|
elif isinstance(item, Cyclic):
|
||||||
value = item.get_value()
|
value = item.get_value()
|
||||||
if isinstance(value,Sequence):
|
if isinstance(value, Sequence):
|
||||||
flattened_list.extend(filter_operation(value))
|
flattened_list.extend(filter_operation(value))
|
||||||
elif isinstance(value, (Event, RandomInteger, Integer)):
|
elif isinstance(value, (Event, RandomInteger, Integer)):
|
||||||
flattened_list.append(value)
|
flattened_list.append(value)
|
||||||
@ -788,9 +807,9 @@ class ListOperation(Sequence):
|
|||||||
|
|
||||||
operators = self.values[1::2] # Fetch every second operator element
|
operators = self.values[1::2] # Fetch every second operator element
|
||||||
values = self.values[::2] # Fetch every second list element
|
values = self.values[::2] # Fetch every second list element
|
||||||
values = filter_operation(values) # Filter out
|
values = filter_operation(values) # Filter out
|
||||||
if len(values)==1:
|
if len(values) == 1:
|
||||||
return values[0] # If right hand doesnt contain anything sensible
|
return values[0] # If right hand doesnt contain anything sensible
|
||||||
left = values[0] # Start results with the first array
|
left = values[0] # Start results with the first array
|
||||||
|
|
||||||
for i, operand in enumerate(operators):
|
for i, operand in enumerate(operators):
|
||||||
|
|||||||
@ -262,8 +262,12 @@ class ZiffersTransformer(Transformer):
|
|||||||
|
|
||||||
def assignment(self, items):
|
def assignment(self, items):
|
||||||
var = items[0]
|
var = items[0]
|
||||||
content = items[1]
|
op = items[1]
|
||||||
return VariableAssignment(variable=var, value=content, text=var.text+"="+content.text)
|
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):
|
def variable(self, items):
|
||||||
return Variable(name=items[0].value, text=items[0].value)
|
return Variable(name=items[0].value, text=items[0].value)
|
||||||
|
|||||||
@ -12,7 +12,8 @@
|
|||||||
modifier: /[#b]/
|
modifier: /[#b]/
|
||||||
|
|
||||||
// Variable assignment
|
// 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]/
|
variable: /[A-Z]/
|
||||||
|
|
||||||
// Durations
|
// Durations
|
||||||
|
|||||||
Reference in New Issue
Block a user