'Compiles a node, recursively.
This is one big switch on the node type.'

def compile_node(self, node):

    if (node.type == self.syms.Matcher):
        node = node.children[0]
    if (node.type == self.syms.Alternatives):
        alts = [self.compile_node(ch) for ch in node.children[::2]]
        if (len(alts) == 1):
            return alts[0]
        p = pytree.WildcardPattern([[a] for a in alts], min=1, max=1)
        return p.optimize()
    else:
        if (node.type == self.syms.Alternative):
            units = [self.compile_node(ch) for ch in node.children]
            if (len(units) == 1):
                return units[0]
            p = pytree.WildcardPattern([units], min=1, max=1)
            return p.optimize()
        if (node.type == self.syms.NegatedUnit):
            pattern = self.compile_basic(node.children[1:])
            p = pytree.NegatedPattern(pattern)
            return p.optimize()
        name = None
        nodes = node.children
        if ((len(nodes) >= 3) and (nodes[1].type == token.EQUAL)):
            name = nodes[0].value
            nodes = nodes[2:]
        repeat = None
        if ((len(nodes) >= 2) and (nodes[(-1)].type == self.syms.Repeater)):
            repeat = nodes[(-1)]
            nodes = nodes[:(-1)]
        pattern = self.compile_basic(nodes, repeat)
        if (repeat is not None):
            children = repeat.children
            child = children[0]
            if (child.type == token.STAR):
                min = 0
                max = pytree.HUGE
            elif (child.type == token.PLUS):
                min = 1
                max = pytree.HUGE
            elif (child.type == token.LBRACE):
                min = max = self.get_int(children[1])
                if (len(children) == 5):
                    max = self.get_int(children[3])
            if ((min != 1) or (max != 1)):
                pattern = pattern.optimize()
                pattern = pytree.WildcardPattern([[pattern]], min=min, max=max)
        if (name is not None):
            pattern.name = name
        return pattern.optimize()
