diff --git a/main.py b/main.py index fa9eba9..eae0fc9 100644 --- a/main.py +++ b/main.py @@ -24,7 +24,7 @@ if __name__ == "__main__": 'Loop cycles (for zloop or z0-z9)': "<0 <1 <2 <3 <4 5>>>>>", 'Basic operations': "(1 2 (3 4)+2)*2 ((1 2 3)+(0 9 13))-2 ((3 4 {10})*(2 9 3))%7", 'Product operations': "(0 1 2 3)+(1 4 2 3) (0 1 2)-(0 2 1)+2", - 'Euclid cycles': "(q1)<6,7>(q4 (e3 e4) q2) or (q1)<6,7<(q4 q3 q2)", + 'Euclid cycles': "(q1)<6,7>(q4 (e3 e4) q2) (q1)<6,7>(q4 q3 q2)", 'Transformations': "(0 1 2) (0 1 2)(-2 1)", 'List assignation': "A=(0 (1,6) 3) B=(3 ? 2) B A B B A", 'Random repeat': "(: 1 (2,6) 3 :4)", diff --git a/ziffers/classes.py b/ziffers/classes.py index 594409f..061e168 100644 --- a/ziffers/classes.py +++ b/ziffers/classes.py @@ -201,4 +201,13 @@ class Atom(Item): @dataclass class Integer(Item): ''' Class for integers ''' - value: int \ No newline at end of file + value: int + +@dataclass +class Euclid(Item): + ''' Class for euclidean cycles ''' + pulses: int + length: int + onset: list + offset: list = None + rotate: int = None \ No newline at end of file diff --git a/ziffers/mapper.py b/ziffers/mapper.py index 276fecb..3144620 100644 --- a/ziffers/mapper.py +++ b/ziffers/mapper.py @@ -11,7 +11,7 @@ class ZiffersTransformer(Transformer): def random_integer(self,s): val = s[0][1:-1].split(",") - return RandomInteger(min=val[0],max=val[1],text=s[0]) + return RandomInteger(min=val[0],max=val[1],text=s[0].value) def range(self,s): val = s[0].split("..") @@ -136,6 +136,9 @@ class ZiffersTransformer(Transformer): val = s.value return Integer(text=val,value=int(val)) + def number(self,s): + return s + def lisp_operation(self,s): op = s[0] values = s[1:] @@ -149,4 +152,19 @@ class ZiffersTransformer(Transformer): return Sequence(values=s) def list_op(self,s): - return ListOperation(values=s) \ No newline at end of file + return ListOperation(values=s) + + def euclid(self,s): + params = s[1][1:-1].split(",") + init = {"onset":s[0],"pulses":params[0],"length":params[1]} + text = s[0].text+s[1] + if len(params)>2: + init["rotate"] = params[2] + if len(s)>2: + init["offset"] = s[2] + text = text+s[2].text + init["text"] = text + return Euclid(**init) + + def euclid_operator(self,s): + return s.value \ No newline at end of file diff --git a/ziffers/ziffers.lark b/ziffers/ziffers.lark index 574308a..c5a2c2a 100644 --- a/ziffers/ziffers.lark +++ b/ziffers/ziffers.lark @@ -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)* + 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)* // Pitch classes pc: prefix* pitch @@ -13,14 +13,22 @@ // Chords chord: pc pc+ + // Valid as integer + ?number: SIGNED_NUMBER | random_integer + // List list: prefix* "(" sequence ")" // Right recursive list operation list_op: list (operator (list | number))+ operator: /([\+\-\*\/%]|<<|>>)/ - ?number: SIGNED_NUMBER + euclid: list euclid_operator list? + ?euclid_operator: /<[0-9]+,[0-9]+(,[0-9])?>/ + + // TODO: Support randomization etc. + //euclid_operator: (">" | "<") number "," number ["," number] (">" | "<") + // Lisp like list operation lisp_operation: "(" operator WS sequence ")" @@ -51,7 +59,7 @@ // TODO: Support for parenthesis? eval: "{" operation "}" operation: atom (operator atom)+ - atom: (SIGNED_NUMBER | DECIMAL | random_integer) + atom: (number | DECIMAL) %import common.NUMBER %import common.SIGNED_NUMBER