UNPKG

@the-little-books/little

Version:

139 lines 4.57 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.match_nodes = exports.match = void 0; const ut = __importStar(require("../ut")); function match(pattern, node, result = {}) { const matched = match_nodes(pattern, [node], result); if (matched === null) { return null; } else { const [_remain_nodes, result] = matched; return result; } } exports.match = match; function match_tag(pattern_tag, tag) { if (typeof pattern_tag === "string") { return pattern_tag === tag; } else if (pattern_tag instanceof RegExp) { return pattern_tag.test(tag); } else if (pattern_tag instanceof Array) { return pattern_tag.some((p_tag) => match_tag(p_tag, tag)); } else { throw new Error(`unknown pattern_tag: ${pattern_tag} for tag: ${tag}.`); } } // NOTE No side effect on the argument `result`. // - `result` is used as env for name lookup. function match_nodes(pattern, nodes, result = {}) { if (pattern.kind === "Pattern.Var") { if (nodes.length === 0) { return null; } const [node] = nodes; const previous = result[pattern.name]; if (previous === undefined) { return [nodes.slice(1), { ...result, [pattern.name]: node }]; } else if (ut.equal(previous, node)) { return [nodes.slice(1), result]; } else { return null; } } else if (pattern.kind === "Pattern.End") { if (nodes.length === 0) { return [[], result]; } else { return null; } } else if (pattern.kind === "Pattern.ListVar") { const previous = result[pattern.name]; if (previous === undefined) { return [[], { ...result, [pattern.name]: nodes }]; } else if (ut.equal(previous, nodes)) { return [[], result]; } else { return null; } } else if (pattern.kind === "Pattern.Element") { if (nodes.length === 0) { return null; } const [node] = nodes; if (node.kind === "Node.Element") { if (!match_tag(pattern.tag, node.tag)) { return null; } else { let new_result = { ...result }; let remain_nodes = node.contents; for (let i = 0; i < pattern.contents.length; i++) { const sub_pattern = pattern.contents[i]; const matched = match_nodes(sub_pattern, remain_nodes, new_result); if (matched === null) { return null; } const [next_remain_nodes, next_new_result] = matched; new_result = next_new_result; remain_nodes = next_remain_nodes; } return [nodes.slice(1), new_result]; } } else { return null; } } else if (pattern.kind === "Pattern.Text") { if (nodes.length === 0) { return null; } const [node] = nodes; if (node.kind === "Node.Text") { if (typeof pattern.value === "string") { return pattern.value === node.value ? [nodes.slice(1), result] : null; } else { return pattern.value.test(node.value) ? [nodes.slice(1), result] : null; } } else { return null; } } else { return null; } } exports.match_nodes = match_nodes; //# sourceMappingURL=pattern-match.js.map