Added repeats
This commit is contained in:
@ -16,6 +16,10 @@ class Item(Meta):
|
|||||||
''' Class for all Ziffers text based items '''
|
''' Class for all Ziffers text based items '''
|
||||||
text: str
|
text: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Whitespace(Item):
|
||||||
|
''' Class for whitespace '''
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class DurationChange(Item):
|
class DurationChange(Item):
|
||||||
''' Class for changing duration '''
|
''' Class for changing duration '''
|
||||||
@ -73,8 +77,8 @@ class dataclass_property(property): # pylint: disable=invalid-name
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Sequence(Meta):
|
class Sequence(Meta):
|
||||||
''' Class for sequences of items'''
|
''' Class for sequences of items'''
|
||||||
values: list
|
values: list[Item]
|
||||||
text: str = None
|
text: str = field(init=False)
|
||||||
_text: str = field(default=None, init=False, repr=False)
|
_text: str = field(default=None, init=False, repr=False)
|
||||||
|
|
||||||
@dataclass_property
|
@dataclass_property
|
||||||
@ -85,23 +89,11 @@ class Sequence(Meta):
|
|||||||
def text(self, text: str) -> None:
|
def text(self, text: str) -> None:
|
||||||
self._text = text
|
self._text = text
|
||||||
|
|
||||||
wrapper: str = None
|
wrap_start: str = field(default=None, repr=False)
|
||||||
_wrapper: str = field(default=None, init=False, repr=False)
|
wrap_end: str = field(default=None, repr=False)
|
||||||
|
|
||||||
@dataclass_property
|
|
||||||
def wrapper(self) -> str:
|
|
||||||
return self._wrapper
|
|
||||||
|
|
||||||
@wrapper.setter
|
|
||||||
def wrapper(self, wrapper: str) -> None:
|
|
||||||
self._wrapper = wrapper
|
|
||||||
if self.text != None:
|
|
||||||
self.text = self.wrapper[0] + self.text + self.wrapper[1]
|
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
self.text = self.collect_text()
|
self.text = self.collect_text()
|
||||||
if self.text != None and self.wrapper != None:
|
|
||||||
self.text = self.wrapper[0] + self.text + self.wrapper[1]
|
|
||||||
|
|
||||||
def update_values(self, new_values):
|
def update_values(self, new_values):
|
||||||
''' Update value attributes from dict '''
|
''' Update value attributes from dict '''
|
||||||
@ -111,8 +103,13 @@ class Sequence(Meta):
|
|||||||
setattr(obj, key, value)
|
setattr(obj, key, value)
|
||||||
|
|
||||||
def collect_text(self) -> str:
|
def collect_text(self) -> str:
|
||||||
return "".join([val.text for val in self.values])
|
text = "".join([val.text for val in self.values])
|
||||||
|
if self.wrap_start != None:
|
||||||
|
text = self.wrap_start + text
|
||||||
|
if self.wrap_end != None:
|
||||||
|
text = text + self.wrap_end
|
||||||
|
return text
|
||||||
|
|
||||||
def pcs(self) -> list[int]:
|
def pcs(self) -> list[int]:
|
||||||
return [val.pc for val in self.values if type(val) is Pitch]
|
return [val.pc for val in self.values if type(val) is Pitch]
|
||||||
|
|
||||||
@ -125,12 +122,15 @@ class Sequence(Meta):
|
|||||||
@dataclass
|
@dataclass
|
||||||
class ListSequence(Sequence):
|
class ListSequence(Sequence):
|
||||||
''' Class for Ziffers list sequences '''
|
''' Class for Ziffers list sequences '''
|
||||||
prefix: dict = None
|
wrap_start: str = field(default="(", repr=False)
|
||||||
values: list = None
|
wrap_end: str = field(default=")", repr=False)
|
||||||
def __init__(self):
|
|
||||||
super.__init__()
|
@dataclass
|
||||||
if self.prefix!=None:
|
class RepeatedListSequence(Sequence):
|
||||||
self.update(self.prefix)
|
''' Class for Ziffers list sequences '''
|
||||||
|
repeats: Item = None
|
||||||
|
wrap_start: str = field(default="(:", repr=False)
|
||||||
|
wrap_end: str = field(default=":)", repr=False)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Subdivision(Item):
|
class Subdivision(Item):
|
||||||
@ -141,6 +141,9 @@ class Subdivision(Item):
|
|||||||
class Cyclic(Sequence):
|
class Cyclic(Sequence):
|
||||||
''' Class for cyclic sequences'''
|
''' Class for cyclic sequences'''
|
||||||
cycle: int = 0
|
cycle: int = 0
|
||||||
|
wrap_start: str = field(default="<", repr=False)
|
||||||
|
wrap_end: str = field(default=">", repr=False)
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
super().__post_init__()
|
super().__post_init__()
|
||||||
# TODO: Do spaced need to be filtered out?
|
# TODO: Do spaced need to be filtered out?
|
||||||
@ -189,6 +192,8 @@ class Operation(Item):
|
|||||||
class Eval(Sequence):
|
class Eval(Sequence):
|
||||||
''' Class for evaluation notation '''
|
''' Class for evaluation notation '''
|
||||||
result: ... = None
|
result: ... = None
|
||||||
|
wrap_start: str = field(default="{", repr=False)
|
||||||
|
wrap_end: str = field(default="}", repr=False)
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
super().__post_init__()
|
super().__post_init__()
|
||||||
self.result = eval(self.text)
|
self.result = eval(self.text)
|
||||||
@ -210,4 +215,12 @@ class Euclid(Item):
|
|||||||
length: int
|
length: int
|
||||||
onset: list
|
onset: list
|
||||||
offset: list = None
|
offset: list = None
|
||||||
rotate: int = None
|
rotate: int = None
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RepeatedSequence(Sequence):
|
||||||
|
''' Class for repeats '''
|
||||||
|
repeats: Item = None
|
||||||
|
wrap_start: str = field(default="[:", repr=False)
|
||||||
|
wrap_end: str = field(default=":]", repr=False)
|
||||||
|
|
||||||
@ -6,8 +6,11 @@ import operator
|
|||||||
|
|
||||||
class ZiffersTransformer(Transformer):
|
class ZiffersTransformer(Transformer):
|
||||||
|
|
||||||
|
def start(self,items):
|
||||||
|
return Sequence(values=items[0])
|
||||||
|
|
||||||
def sequence(self,items):
|
def sequence(self,items):
|
||||||
return Sequence(values=flatten(items))
|
return flatten(items)
|
||||||
|
|
||||||
def random_integer(self,s):
|
def random_integer(self,s):
|
||||||
val = s[0][1:-1].split(",")
|
val = s[0][1:-1].split(",")
|
||||||
@ -18,8 +21,8 @@ class ZiffersTransformer(Transformer):
|
|||||||
return Range(start=val[0],end=val[1],text=s[0])
|
return Range(start=val[0],end=val[1],text=s[0])
|
||||||
|
|
||||||
def cycle(self, items):
|
def cycle(self, items):
|
||||||
values = items[0].values
|
values = items[0]
|
||||||
return Cyclic(values=values, wrapper="<>")
|
return Cyclic(values=values)
|
||||||
|
|
||||||
def pc(self, s):
|
def pc(self, s):
|
||||||
if(len(s)>1):
|
if(len(s)>1):
|
||||||
@ -95,7 +98,7 @@ class ZiffersTransformer(Transformer):
|
|||||||
return chardur
|
return chardur
|
||||||
|
|
||||||
def WS(self,s):
|
def WS(self,s):
|
||||||
return Item(text=s[0])
|
return Whitespace(text=s[0])
|
||||||
|
|
||||||
def subdivision(self,items):
|
def subdivision(self,items):
|
||||||
values = flatten(items[0])
|
values = flatten(items[0])
|
||||||
@ -108,7 +111,7 @@ class ZiffersTransformer(Transformer):
|
|||||||
|
|
||||||
def eval(self,s):
|
def eval(self,s):
|
||||||
val = s[0]
|
val = s[0]
|
||||||
return Eval(values=val,wrapper="{}")
|
return Eval(values=val)
|
||||||
|
|
||||||
def operation(self,s):
|
def operation(self,s):
|
||||||
return s
|
return s
|
||||||
@ -122,14 +125,28 @@ class ZiffersTransformer(Transformer):
|
|||||||
def list(self,items):
|
def list(self,items):
|
||||||
if len(items)>1:
|
if len(items)>1:
|
||||||
prefixes = sum_dict(items[0:-1])
|
prefixes = sum_dict(items[0:-1])
|
||||||
seq = items[-1]
|
values = items[-1]
|
||||||
seq.wrapper = "()"
|
seq = ListSequence(values=values,wrap_start=prefixes["text"]+"(")
|
||||||
seq.text = prefixes["text"] + seq.text
|
|
||||||
seq.update_values(prefixes)
|
seq.update_values(prefixes)
|
||||||
return seq
|
return seq
|
||||||
else:
|
else:
|
||||||
seq = items[0]
|
seq = ListSequence(values=items[0])
|
||||||
seq.wrapper = "()"
|
return seq
|
||||||
|
|
||||||
|
def repeated_list(self,items):
|
||||||
|
if len(items)>2:
|
||||||
|
prefixes = sum_dict(items[0:-2]) # If there are prefixes
|
||||||
|
if items[-1]!=None:
|
||||||
|
seq = RepeatedListSequence(values=items[-2],repeats=items[-1],wrap_end=":"+items[-1].text+")")
|
||||||
|
else:
|
||||||
|
seq = RepeatedListSequence(values=items[-2],repeats=Integer(text='1', value=1))
|
||||||
|
seq.update_values(prefixes)
|
||||||
|
return seq
|
||||||
|
else:
|
||||||
|
if items[-1]!=None:
|
||||||
|
seq = RepeatedListSequence(values=items[-2],repeats=items[-1],wrap_end=":"+items[-1].text+")")
|
||||||
|
else:
|
||||||
|
seq = RepeatedListSequence(values=items[-2],repeats=Integer(text='1', value=1))
|
||||||
return seq
|
return seq
|
||||||
|
|
||||||
def SIGNED_NUMBER(self, s):
|
def SIGNED_NUMBER(self, s):
|
||||||
@ -139,6 +156,9 @@ class ZiffersTransformer(Transformer):
|
|||||||
def number(self,s):
|
def number(self,s):
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
def cyclic_number(self,s):
|
||||||
|
return Cyclic(values=s)
|
||||||
|
|
||||||
def lisp_operation(self,s):
|
def lisp_operation(self,s):
|
||||||
op = s[0]
|
op = s[0]
|
||||||
values = s[1:]
|
values = s[1:]
|
||||||
@ -167,4 +187,10 @@ class ZiffersTransformer(Transformer):
|
|||||||
return Euclid(**init)
|
return Euclid(**init)
|
||||||
|
|
||||||
def euclid_operator(self,s):
|
def euclid_operator(self,s):
|
||||||
return s.value
|
return s.value
|
||||||
|
|
||||||
|
def repeat(self,s):
|
||||||
|
if s[-1]!=None:
|
||||||
|
return RepeatedSequence(values=s[0],repeats=s[-1],wrap_end=":"+s[-1].text+"]")
|
||||||
|
else:
|
||||||
|
return RepeatedSequence(values=s[0],repeats=Integer(value=1,text='1'))
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// Root for the rules
|
// Root for the rules
|
||||||
?root: sequence
|
?root: sequence -> start
|
||||||
sequence: (pc | dur_change | oct_mod | oct_change | WS | chord | cycle | random_integer | random_pitch | random_percent | range | list | lisp_operation | list_op | subdivision | eval | euclid)*
|
sequence: (pc | dur_change | oct_mod | oct_change | WS | chord | cycle | random_integer | random_pitch | random_percent | range | list | repeated_list | lisp_operation | list_op | subdivision | eval | euclid | repeat)*
|
||||||
|
|
||||||
// Pitch classes
|
// Pitch classes
|
||||||
pc: prefix* pitch
|
pc: prefix* pitch
|
||||||
@ -14,15 +14,21 @@
|
|||||||
chord: pc pc+
|
chord: pc pc+
|
||||||
|
|
||||||
// Valid as integer
|
// Valid as integer
|
||||||
?number: SIGNED_NUMBER | random_integer
|
?number: SIGNED_NUMBER | random_integer | cyclic_number
|
||||||
|
cyclic_number: "<" number (WS number)* ">"
|
||||||
|
|
||||||
|
// Repeats
|
||||||
|
repeat: "[:" sequence ":" [number] "]"
|
||||||
|
|
||||||
// List
|
// List
|
||||||
list: prefix* "(" sequence ")"
|
list: prefix* "(" sequence ")"
|
||||||
|
repeated_list: prefix* "(:" sequence ":" [number] ")"
|
||||||
|
|
||||||
// Right recursive list operation
|
// Right recursive list operation
|
||||||
list_op: list (operator (list | number))+
|
list_op: list (operator (list | number))+
|
||||||
operator: /([\+\-\*\/%]|<<|>>)/
|
operator: /([\+\-\*\/%]|<<|>>)/
|
||||||
|
|
||||||
|
// Euclidean cycles
|
||||||
euclid: list euclid_operator list?
|
euclid: list euclid_operator list?
|
||||||
?euclid_operator: /<[0-9]+,[0-9]+(,[0-9])?>/
|
?euclid_operator: /<[0-9]+,[0-9]+(,[0-9])?>/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user