@taml/ast
Version:
Abstract Syntax Tree types and utilities for TAML (Terminal ANSI Markup Language)
128 lines • 7.24 kB
JavaScript
/**
* Visitor pattern implementation for TAML AST
*/
import { isDocumentNode, isElementNode, isTextNode } from "./nodes.js";
/**
* Visit an AST node and its children using the visitor pattern
*/
export function visit(node, visitor) {
// Call enter hook if provided
visitor.enterNode?.(node);
// Visit the node based on its type
if (isDocumentNode(node)) {
visitor.visitDocument?.(node);
// Visit children
for (const child of node.children) {
visit(child, visitor);
}
}
else if (isElementNode(node)) {
visitor.visitElement?.(node);
// Visit children
for (const child of node.children) {
visit(child, visitor);
}
}
else if (isTextNode(node)) {
visitor.visitText?.(node);
}
// Call exit hook if provided
visitor.exitNode?.(node);
}
/**
* Transform an AST node using the transformer pattern
*/
export function transform(node, transformer) {
if (isDocumentNode(node)) {
if (transformer.visitDocument) {
return transformer.visitDocument(node);
}
}
else if (isElementNode(node)) {
if (transformer.visitElement) {
return transformer.visitElement(node);
}
}
else if (isTextNode(node)) {
if (transformer.visitText) {
return transformer.visitText(node);
}
}
throw new Error(`No transformer method found for node type: ${node.type}`);
}
/**
* Visit nodes asynchronously
*/
export async function visitAsync(node, visitor) {
// Call enter hook if provided
await visitor.enterNode?.(node);
// Visit the node based on its type
if (isDocumentNode(node)) {
await visitor.visitDocument?.(node);
// Visit children
for (const child of node.children) {
await visitAsync(child, visitor);
}
}
else if (isElementNode(node)) {
await visitor.visitElement?.(node);
// Visit children
for (const child of node.children) {
await visitAsync(child, visitor);
}
}
else if (isTextNode(node)) {
await visitor.visitText?.(node);
}
// Call exit hook if provided
await visitor.exitNode?.(node);
}
/**
* Create a visitor that only visits specific node types
*/
export function createTypedVisitor(nodeTest, callback) {
return {
enterNode(node) {
if (nodeTest(node)) {
callback(node);
}
},
};
}
/**
* Create a visitor that collects nodes of a specific type
*/
export function createCollectorVisitor(nodeTest) {
const nodes = [];
return {
nodes,
enterNode(node) {
if (nodeTest(node)) {
nodes.push(node);
}
},
};
}
/**
* Create a visitor that counts nodes by type
*/
export function createCounterVisitor() {
const counts = {
document: 0,
element: 0,
text: 0,
};
return {
counts,
visitDocument() {
counts.document++;
},
visitElement() {
counts.element++;
},
visitText() {
counts.text++;
},
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzaXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3Zpc2l0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFHSCxPQUFPLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUM7QUE4QnZFOztHQUVHO0FBQ0gsTUFBTSxVQUFVLEtBQUssQ0FBQyxJQUFjLEVBQUUsT0FBZ0I7SUFDcEQsOEJBQThCO0lBQzlCLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUUxQixtQ0FBbUM7SUFDbkMsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN6QixPQUFPLENBQUMsYUFBYSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUIsaUJBQWlCO1FBQ2pCLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2xDLEtBQUssQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUM7U0FBTSxJQUFJLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQy9CLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixpQkFBaUI7UUFDakIsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEMsS0FBSyxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztTQUFNLElBQUksVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDNUIsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCw2QkFBNkI7SUFDN0IsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzNCLENBQUM7QUFFRDs7R0FF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