"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var expression_exports = {};
__export(expression_exports, {
  InvalidPicsExpressionError: () => InvalidPicsExpressionError,
  PicsExpression: () => PicsExpression
});
module.exports = __toCommonJS(expression_exports);
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
class PicsExpression {
  #definition;
  #ast;
  constructor(definition) {
    this.#definition = definition;
    this.#ast = parse(definition);
  }
  evaluate(file) {
    return test(this.#ast, file);
  }
  toString() {
    return this.#definition;
  }
}
class InvalidPicsExpressionError extends Error {
  constructor(definition, token) {
    let why;
    if (token === void 0) {
      why = "Incomplete PICS expression";
    } else {
      why = `Unexpected "${token.kind === "name" ? token.name : token.kind}`;
    }
    super(`Invalid PICS expression "${definition}": ${why}`);
  }
}
function parse(definition) {
  const tokenizer2 = tokenize(definition);
  function parsePrefix() {
    const token = tokenizer2.next();
    switch (token?.kind) {
      case "name":
        return token;
      case "(":
        const result2 = parseExpr();
        if (tokenizer2.peek()?.kind !== ")") {
          throw new InvalidPicsExpressionError(definition, tokenizer2.peek());
        }
        tokenizer2.next();
        return result2;
      case "!":
        return {
          kind: "!",
          operand: parsePrefix()
        };
    }
    throw new InvalidPicsExpressionError(definition, token);
  }
  function parseExpr() {
    const expr = parsePrefix();
    switch (tokenizer2.peek()?.kind) {
      case "&":
        tokenizer2.next();
        return {
          kind: "&",
          lhs: expr,
          rhs: parseExpr()
        };
      case "|":
        tokenizer2.next();
        return {
          kind: "|",
          lhs: expr,
          rhs: parseExpr()
        };
      default:
        return expr;
    }
  }
  const result = parseExpr();
  if (tokenizer2.peek() !== void 0 && tokenizer2.peek()?.kind !== "(") {
    throw new InvalidPicsExpressionError(definition, tokenizer2.peek());
  }
  return result;
}
const SYMBOLS = ["&", "|", "!", "(", ")"];
const WHITESPACE = /* @__PURE__ */ new Set([" ", "\r", "\n", "	"]);
const SYMBOL_SET = new Set(SYMBOLS);
function tokenize(definition) {
  const iterator = tokenizer(definition);
  let next = iterator.next();
  return {
    next() {
      if (!next.done) {
        const value = next.value;
        next = iterator.next();
        return value;
      }
    },
    peek() {
      return next.value;
    }
  };
}
function* tokenizer(definition) {
  let pos = 0;
  while (pos < definition.length) {
    let ch = definition[pos];
    switch (ch) {
      case "&":
      case "|":
      case "!":
      case "(":
      case ")":
        yield { kind: ch };
        break;
      default:
        if (WHITESPACE.has(ch)) {
          break;
        }
        const name = [ch];
        while (true) {
          ch = definition[pos + 1];
          if (ch === void 0 || WHITESPACE.has(ch) || SYMBOL_SET.has(ch)) {
            break;
          }
          name.push(ch);
          pos++;
        }
        yield { kind: "name", name: name.join("") };
        break;
    }
    pos++;
  }
}
function test(ast, file) {
  switch (ast.kind) {
    case "!":
      return !test(ast.operand, file);
    case "name":
      return file.values[ast.name] === 1;
    case "&":
      return test(ast.lhs, file) && test(ast.rhs, file);
    case "|":
      return test(ast.lhs, file) || test(ast.rhs, file);
    default:
      throw new Error(`Internal error: Invalid PICS AST kind "${ast.kind}"`);
  }
}
//# sourceMappingURL=expression.js.map
