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