// src/framework/shadowlisp/primitives/SlEq.ts
//
// Vision 49: Equality predicate element - IS a Matrix component
//
// <sl-eq><a><b></sl-eq> => true if a equals b

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

/**
 * SlEq - Equality predicate element (McCarthy primitive #3) that IS a Matrix component.
 *
 * Returns true if both children evaluate to equal atomic values.
 *
 * @example
 * <sl-eq><sl-num>5</sl-num><sl-num>5</sl-num></sl-eq>          => true
 * <sl-eq><sl-sym>a</sl-sym><sl-sym>b</sl-sym></sl-eq>          => false
 */
export class SlEq extends SlMatrixElement {
  async evalSelf(env: SExpr[]): Promise<SExpr> {
    const children = Array.from(this.children);
    if (children.length < 2) {
      throw new Error('sl-eq requires exactly 2 children');
    }

    const a = await this.evalChild(children[0], env);
    const b = await this.evalChild(children[1], env);

    return SlBootstrap.eq(a, b);
  }

  toSExpr(): SExpr {
    const args = Array.from(this.children).map(c =>
      (c instanceof SlMatrixElement) ? c.toSExpr() : null
    );
    return ['eq?', ...args];
  }
}

if (!customElements.get('sl-eq')) {
  customElements.define('sl-eq', SlEq);
}
