def redirectnode(s, input, type, output, heredoc=None): return ast.node(kind='redirect', input=input, type=type, output=output, heredoc=heredoc, s=s)
def compoundnode(s, *parts, **kwargs): redirects = kwargs.pop('redirects', []) assert not kwargs return ast.node(kind='compound', s=s, list=list(parts), redirects=redirects)
def listnode(s, *parts): for i in range(len(parts)): if i % 2 == 0: assert parts[i].kind in ('command', 'pipeline', 'compound'), parts[i].kind else: assert parts[i].kind == 'operator', parts[i].kind return ast.node(kind='list', parts=list(parts), s=s)
def pipelinenode(s, *parts): oldparts = parts if parts[0].kind == 'reservedword' and parts[0].word == '!': parts = parts[1:] for i in range(len(parts)): if i % 2 == 0: assert parts[i].kind in ('command', 'compound'), parts[i].kind else: assert parts[i].kind == 'pipe', parts[i].kind return ast.node(kind='pipeline', s=s, parts=list(oldparts))
def procsubnode(s, command): return ast.node(kind='processsubstitution', s=s, command=command)
def reservedwordnode(word, s): return ast.node(kind='reservedword', word=word, s=s)
def operatornode(op, s): return ast.node(kind='operator', op=op, s=s)
def whilenode(s, *parts): return ast.node(kind='while', parts=list(parts), s=s)
def tildenode(value, s): return ast.node(kind='tilde', value=value, s=s)
def parameternode(value, s): return ast.node(kind='parameter', value=value, s=s)
def heredocnode(value, s=None): if s is None: s = value return ast.node(kind='heredoc', value=value, s=s)
def wordnode(word, s=None, parts=None): if s is None: s = word if parts is None: parts = [] return ast.node(kind='word', word=word, s=s, parts=list(parts))
def functionnode(s, name, body, *parts): return ast.node(kind='function', name=name, body=body, parts=list(parts), s=s)
def commandnode(s, *parts): return ast.node(kind='command', s=s, parts=list(parts))
def comsubnode(s, command): return ast.node(kind='commandsubstitution', s=s, command=command)
def pipenode(pipe, s): return ast.node(kind='pipe', pipe=pipe, s=s)
def ifnode(s, *parts): return ast.node(kind='if', parts=list(parts), s=s)
def fornode(s, *parts): return ast.node(kind='for', parts=list(parts), s=s)