// src/framework/shadowlisp/primitives/SlAtomP.ts
//
// Vision 49: Atom predicate element - IS a Matrix component
//
// <sl-atom-p><expr></sl-atom-p> => true if expr is atomic (not a list)

import type { SExpr } from '../../../lisp/SExpr';
import { SlMatrixElement } from '../SlMatrixElement';
import { SlBootstrap } from '../SlBootstrap';

/**
 * SlAtomP - Atom predicate element (McCarthy primitive #2) that IS a Matrix component.
 *
 * Returns true if the child evaluates to an atomic value.
 *
 * @example
 * <sl-atom-p><sl-num>5</sl-num></sl-atom-p>                    => true
 * <sl-atom-p><sl-list>...</sl-list></sl-atom-p>                => false
 */
export class SlAtomP extends SlMatrixElement {
  async evalSelf(env: SExpr[]): Promise<SExpr> {
    const child = this.firstElementChild;
    if (!child) {
      return true; // null is atomic
    }

    const value = await this.evalChild(child, env);
    return SlBootstrap.atom(value);
  }

  toSExpr(): SExpr {
    const child = this.firstElementChild;
    if (!child || !(child instanceof SlMatrixElement)) {
      return ['atom?', null];
    }
    return ['atom?', child.toSExpr()];
  }
}

if (!customElements.get('sl-atom-p')) {
  customElements.define('sl-atom-p', SlAtomP);
}
