import { SyntaxKind } from "./types.js";
function visitNode(cbNode, node) {
    return node && cbNode(node);
}
function visitNodes(cbNode, cbNodes, nodes) {
    if (nodes) {
        if (cbNodes)
            return cbNodes(nodes);
        for (const node of nodes) {
            const result = cbNode(node);
            if (result)
                return result;
        }
    }
    return undefined;
}
export function forEachChild(node, cbNode, cbNodes) {
    if (!node || node.kind <= SyntaxKind.LastKeyword)
        return;
    switch (node.kind) {
        case SyntaxKind.DirectedGraph:
        case SyntaxKind.UndirectedGraph:
            return visitNodes(cbNode, cbNodes, node.statements)
                || visitNode(cbNode, node.strict)
                || visitNode(cbNode, node.id);
        case SyntaxKind.AttributeStatement:
            return visitNodes(cbNode, cbNodes, node.attributes)
                || visitNode(cbNode, node.subject)
                || visitNode(cbNode, node.terminator);
        case SyntaxKind.EdgeStatement:
            return visitNodes(cbNode, cbNodes, node.attributes)
                || visitNodes(cbNode, cbNodes, node.rhs)
                || visitNode(cbNode, node.source)
                || visitNode(cbNode, node.terminator);
        case SyntaxKind.NodeStatement:
            return visitNodes(cbNode, cbNodes, node.attributes)
                || visitNode(cbNode, node.id)
                || visitNode(cbNode, node.terminator);
        case SyntaxKind.SubGraph:
            return visitNodes(cbNode, cbNodes, node.statements)
                || visitNode(cbNode, node.id);
        case SyntaxKind.SubGraphStatement:
            return visitNode(cbNode, node.subgraph)
                || visitNode(cbNode, node.terminator);
        case SyntaxKind.IdEqualsIdStatement:
            return visitNode(cbNode, node.leftId)
                || visitNode(cbNode, node.rightId)
                || visitNode(cbNode, node.terminator);
        case SyntaxKind.QuotedTextIdentifier:
            return visitNodes(cbNode, cbNodes, node.values);
        case SyntaxKind.EdgeRhs:
            return visitNode(cbNode, node.operation)
                || visitNode(cbNode, node.target);
        case SyntaxKind.AttributeContainer:
            return visitNodes(cbNode, cbNodes, node.assignments);
        case SyntaxKind.Assignment:
            return visitNode(cbNode, node.leftId)
                || visitNode(cbNode, node.rightId)
                || visitNode(cbNode, node.terminator);
        case SyntaxKind.NormalPortDeclaration:
            return visitNode(cbNode, node.colon)
                || visitNode(cbNode, node.id)
                || visitNode(cbNode, node.compassPt);
        case SyntaxKind.CompassPortDeclaration:
            return visitNode(cbNode, node.colon)
                || visitNode(cbNode, node.compassPt);
        case SyntaxKind.NodeId:
            return visitNode(cbNode, node.port)
                || visitNode(cbNode, node.id);
        default:
            return undefined;
    }
}
//# sourceMappingURL=visitor.js.map