/*
 * This file is part of the Fun programming language.
 * https://fun-lang.xyz/
 *
 * Copyright 2025 Johannes Findeisen <you@hanez.org>
 * Licensed under the terms of the Apache-2.0 license.
 * https://opensource.org/license/apache-2-0
 */

/**
 * @file typeof.c
 * @brief Implements the OP_TYPEOF opcode for obtaining a human-readable type name.
 *
 * This snippet is included by the VM's opcode dispatch. It pops a single value
 * from the stack, determines its runtime type, pushes a new string with a
 * human-readable type name (e.g., "Number", "String", "Array"), and frees the
 * original value.
 *
 * Stack contract:
 * - Pops: value (any)
 * - Pushes: string (type name)
 */

case OP_TYPEOF: {
  Value v = pop_value(vm);
  const char *tname = "Unknown";
  switch (v.type) {
  case VAL_INT:
    tname = "Number";
    break;
  case VAL_FLOAT:
    tname = "Float";
    break;
  case VAL_BOOL:
    tname = "Boolean";
    break;
  case VAL_STRING:
    tname = "String";
    break;
  case VAL_FUNCTION:
    tname = "Function";
    break;
  case VAL_ARRAY:
    tname = "Array";
    break;
  case VAL_MAP:
    tname = "Map";
    break;
  case VAL_NIL:
    tname = "Nil";
    break;
  default:
    tname = "Unknown";
    break;
  }
  /* push a new string value; make_string duplicates the C string */
  push_value(vm, make_string(tname));
  free_value(v);
  break;
}
