Source code for sexpr.sexpr

from copy import deepcopy


[docs]def inject(sexpr, func): body = func(*sexpr[1:] if sexpr else None) body = body if isinstance(body, tuple) else (body, ) return [sexpr[0], *body]
[docs]def extend(sexpr, func): return func(sexpr)
[docs]class Sexpr(object): def __init__(self, sexpr, grammar=None, **kwargs): self.sexpr = sexpr self.grammar = grammar def __getitem__(self, index): return self.sexpr[index] @property def tag(self): return self.sexpr[0] if self.sexpr else None @property def body(self): return self.sexpr[1:] if self.sexpr else None
[docs] def inject(self, func): self.sexpr = inject(self.sexpr, func)
[docs] def extend(self, func): self.sexpr = extend(self.sexpr, func)
[docs] def copy(self): return deepcopy(self.body)
def __repr__(self): return repr(self.sexpr) def __str__(self): return pformat(self.sexpr) def __len__(self): return len(self.sexpr)
[docs] def with_insert(self, index, sexpr): self.sexpr.insert(index, sexpr) return self
[docs] def with_replace(self, index, sexpr): self.sexpr[index] = sexpr return self
[docs] def find_closest_child(self, *tags): """Search for a tag among direct children of the s-expression.""" for child in self.body: if isinstance(child, Sexpr) and child.tag in tags: return child
[docs] def find_child(self, tag): for s in self.sexpr: if s.tag == tag: return s else: candidate = self.find_child(s) if candidate and candidate.tag == tag: return candidate
[docs] def find_and_replace(self, test, replace): for i, c in enumerate(self.body): if test(c): self.sexpr[i + 1] = replace(c) elif isinstance(c, Sexpr): self.sexpr[i + 1] = c.find_and_replace(test, replace) return self
from .print import pformat