diff --git a/xplace/x.py b/xplace/x.py index 9d6c584..8183a6b 100644 --- a/xplace/x.py +++ b/xplace/x.py @@ -21,16 +21,17 @@ parser = Lark(r''' ?unit : parens | brackets | char ?concat_func : unit - | concat_func "{" DIGITS "}" -> concat_repeat - | concat_func "?" -> zero_or_one - | concat_func "~" -> reverse - | concat_func "~" NUMBER -> roll - | concat_func "~{" NUMBER ["," DIGITS] "}" -> roll - | concat_func "!" -> collapse - | concat_func "!" DIGIT+ -> collapse - | concat_func "!{" numrange ("," numrange)* "}" -> collapse_ranges - | concat_func "\\" DIGIT+ -> index - | concat_func "\\{" numrange ("," numrange)* "}" -> index_ranges + | concat_func "{" DIGITS "}" -> concat_repeat + | concat_func "?" -> zero_or_one + | concat_func "~" -> reverse + | concat_func "~" NUMBER -> roll + | concat_func "~{" NUMBER ["," DIGITS] "}" -> roll + | concat_func "!-" -> split + | concat_func "!" -> collapse + | concat_func "\\-" DIGIT+ -> negindex + | concat_func "\\-{" numrange ("," numrange)* "}" -> negindex_ranges + | concat_func "\\" DIGIT+ -> index + | concat_func "\\{" numrange ("," numrange)* "}" -> index_ranges ?concat : concat_func+ @@ -146,22 +147,23 @@ class Expand(Transformer): result.append(x[i % len(x)]) return result + def negindex(self, args): + x = args[0] + inds = set(int(i.value) % len(x) for i in args[1:]) + inds = set(range(len(x))) - inds + return [x[i] for i in sorted(inds)] + + def negindex_ranges(self, args): + x = args[0] + inds = set(i % len(x) for arg in args[1:] for i in arg) + inds = set(range(len(x))) - inds + return [x[i] for i in sorted(inds)] + + def split(self, args): + return list(''.join(args[0])) + def collapse(self, args): - result, x = '', args[0] - if len(args) > 1: - for i in args[1:]: - result += x[int(i.value) % len(x)] - else: - result = ''.join(args[0]) - return [result] - - def collapse_ranges(self, args): - result, x = '', args[0] - for arg in args[1:]: - for i in arg: - result += x[i % len(x)] - return [result] - + return [''.join(args[0])] def concat_repeat(self, args): return self.concat([args[0]] * int(args[1].value))