@the-little-books/little
Version:
139 lines • 4.57 kB
JavaScript
;
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