// src/framework/shadowlisp/primitives/SlCons.ts
//
// Vision 49: Cons element - construct list - IS a Matrix component
//
// John McCarthy (LISP creator, Turing Award 1971):
//   "Cons constructs a new cell. It's the fundamental way to build
//    data structures in LISP."
//
// <sl-cons><head><tail></sl-cons> => [head, ...tail]

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

/**
 * SlCons - Cons element (McCarthy primitive #6) that IS a Matrix component.
 *
 * Constructs a new list by prepending head to tail.
 *
 * @example
 * <sl-cons>
 *   <sl-num>1</sl-num>
 *   <sl-list><sl-num>2</sl-num><sl-num>3</sl-num></sl-list>
 * </sl-cons>
 * => [1, 2, 3]
 */
export class SlCons extends SlMatrixElement {
  /**
   * Evaluate both children and cons them together.
   */
  async evalSelf(env: SExpr[]): Promise<SExpr> {
    const children = Array.from(this.children);
    if (children.length < 2) {
      throw new Error('sl-cons requires exactly 2 children (head and tail)');
    }

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

    // Apply cons
    return SlBootstrap.cons(head, tail);
  }

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

if (!customElements.get('sl-cons')) {
  customElements.define('sl-cons', SlCons);
}
