// src/lisp/primitives/boolean.ts
// Boolean Primitives: and, or, not

import type { IPrimitiveDefinition } from './mccarthy';

/**
 * AND - Logical conjunction (short-circuit)
 * (and true true) → true
 * (and true false) → false
 */
export const and: IPrimitiveDefinition = {
  name: 'and',
  handler: async (args, evaluate) => {
    let result: unknown = true;
    for (const arg of args) {
      result = await evaluate(arg);
      if (!result) return false;
    }
    return result;
  },
};

/**
 * OR - Logical disjunction (short-circuit)
 * (or false true) → true
 * (or false false) → false
 */
export const or: IPrimitiveDefinition = {
  name: 'or',
  handler: async (args, evaluate) => {
    for (const arg of args) {
      const result = await evaluate(arg);
      if (result) return result;
    }
    return false;
  },
};

/**
 * NOT - Logical negation
 * (not true) → false
 * (not false) → true
 */
export const not: IPrimitiveDefinition = {
  name: 'not',
  handler: async (args, evaluate) => {
    const val = await evaluate(args[0]);
    return !val;
  },
};

/**
 * All boolean primitives
 */
export const booleanPrimitives: IPrimitiveDefinition[] = [
  and,
  or,
  not,
];
