// src/framework/shadowlisp/primitives/SlCdr.ts
//
// Vision 49: Cdr element - rest of list - IS a Matrix component
//
// John McCarthy (LISP creator, Turing Award 1971):
//   "CDR stood for 'Contents of Decrement Register'. It returns
//    everything except the first element."
//
// <sl-cdr><list></sl-cdr> => list without first element

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

/**
 * SlCdr - Cdr element (McCarthy primitive #5) that IS a Matrix component.
 *
 * Returns all but the first element of a list.
 *
 * @example
 * <sl-cdr><sl-list><sl-num>1</sl-num><sl-num>2</sl-num><sl-num>3</sl-num></sl-list></sl-cdr>
 * => [2, 3]
 */
export class SlCdr extends SlMatrixElement {
  /**
   * Evaluate the child and return everything except the first.
   */
  async evalSelf(env: SExpr[]): Promise<SExpr> {
    const child = this.firstElementChild;
    if (!child) {
      throw new Error('sl-cdr requires a child element');
    }

    // Evaluate the child to get the list
    const list = await this.evalChild(child, env);

    // Apply cdr
    return SlBootstrap.cdr(list as SExpr[]);
  }

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

if (!customElements.get('sl-cdr')) {
  customElements.define('sl-cdr', SlCdr);
}
