Skip to content

Instantly share code, notes, and snippets.

@tef
Created April 6, 2024 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tef/6a689d85a0ba5f063cf9bf0234e678a1 to your computer and use it in GitHub Desktop.
Save tef/6a689d85a0ba5f063cf9bf0234e678a1 to your computer and use it in GitHub Desktop.
from contextlib import contextmanager
class Node:
def __init__(self, name, args, children):
self.name = name
self.args = args
self.children = children
def __str__(self):
out = []
if self.name:
out.append(str(self.name))
else:
out.append("node")
if self.args:
out.append("(")
out.append(",".join(f"{k}:{v}" for k,v in self.args.items()))
out.append(")")
if self.children:
out.append("{")
out.append(",".join(f"{c}" for c in self.children))
out.append("}")
return "".join(out)
class Builder:
def __init__(self):
self.nodes = []
self.inside = []
def Node(self, name=None, **args):
self.nodes.append(Node(name, args, []))
@contextmanager
def Group(self, name=None, **args):
self.inside.append(name)
old_nodes = self.nodes
self.nodes = []
yield
old_nodes.append(Node(name, args, self.nodes))
self.nodes = old_nodes
def build():
def _decorate(fn):
b = Builder()
fn(b)
if len(b.nodes) == 1:
return b.nodes[0]
return Node(None, {}, b.nodes)
return _decorate
def main(argv):
@build()
def node(b):
b.Node("one")
with b.Group("two"):
b.Node(1)
b.Node(2)
b.Node(3)
b.Node("three")
print(node)
if __name__ == "__main__":
import sys
sys.exit(main(sys.argv[1:]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment