/** * @file value.c * @brief Value system implementation for Baba Yaga * @author eli_oat * @version 0.0.1 * @date 2025 * * This file implements the value system for the Baba Yaga language, * including value creation, destruction, and utility functions. */ #include #include #include #include #include "baba_yaga.h" /* ============================================================================ * Value Creation Functions * ============================================================================ */ Value baba_yaga_value_number(double number) { Value value; value.type = VAL_NUMBER; value.data.number = number; return value; } Value baba_yaga_value_string(const char* string) { Value value; value.type = VAL_STRING; if (string != NULL) { value.data.string = strdup(string); } else { value.data.string = NULL; } return value; } Value baba_yaga_value_boolean(bool boolean) { Value value; value.type = VAL_BOOLEAN; value.data.boolean = boolean; return value; } Value baba_yaga_value_nil(void) { Value value; value.type = VAL_NIL; return value; } /* ============================================================================ * Value Management Functions * ============================================================================ */ void baba_yaga_value_destroy(Value* value) { if (value == NULL) { return; } switch (value->type) { case VAL_STRING: if (value->data.string != NULL) { free(value->data.string); value->data.string = NULL; } break; case VAL_TABLE: table_decrement_ref(value); break; case VAL_FUNCTION: function_decrement_ref(value); break; default: /* No cleanup needed for other types */ break; } value->type = VAL_NIL; } Value baba_yaga_value_copy(const Value* value) { if (value == NULL) { return baba_yaga_value_nil(); } DEBUG_DEBUG("baba_yaga_value_copy: copying value with type %d", value->type); switch (value->type) { case VAL_NUMBER: return baba_yaga_value_number(value->data.number); case VAL_STRING: return baba_yaga_value_string(value->data.string); case VAL_BOOLEAN: return baba_yaga_value_boolean(value->data.boolean); case VAL_TABLE: { Value new_table = baba_yaga_value_table(); if (new_table.type != VAL_TABLE) { return baba_yaga_value_nil(); } /* Copy all entries from the original table using the public API */ size_t old_size = baba_yaga_table_size(value); if (old_size > 0) { /* Get all keys from the original table */ char* keys[100]; /* Assume max 100 keys */ size_t key_count = baba_yaga_table_get_keys(value, keys, 100); /* Copy each key-value pair */ for (size_t i = 0; i < key_count; i++) { Value old_value = baba_yaga_table_get(value, keys[i]); new_table = baba_yaga_table_set(&new_table, keys[i], &old_value); baba_yaga_value_destroy(&old_value); free(keys[i]); } } return new_table; } case VAL_FUNCTION: { /* For now, just increment the reference count of the original function */ Value new_func = *value; function_increment_ref(&new_func); return new_func; } case VAL_NIL: default: return baba_yaga_value_nil(); } } /* ============================================================================ * Utility Functions * ============================================================================ */ ValueType baba_yaga_value_get_type(const Value* value) { if (value == NULL) { return VAL_NIL; } return value->type; } bool baba_yaga_value_is_truthy(const Value* value) { if (value == NULL) { return false; } switch (value->type) { case VAL_NUMBER: return value->data.number != 0.0; case VAL_STRING: return value->data.string != NULL && strlen(value->data.string) > 0; case VAL_BOOLEAN: return value->data.boolean; case VAL_TABLE: /* Tables are truthy if they have any elements */ return baba_yaga_table_size(value) > 0; case VAL_FUNCTION: return true; case VAL_NIL: default: return false; } } char* baba_yaga_value_to_string(const Value* value) { if (value == NULL) { return strdup("nil"); } switch (value->type) { case VAL_NUMBER: { char buffer[128]; if (value->data.number == (long)value->data.number) { snprintf(buffer, sizeof(buffer), "%ld", (long)value->data.number); } else { snprintf(buffer, sizeof(buffer), "%.16g", value->data.number); } return strdup(buffer); } case VAL_STRING: if (value->data.string != NULL) { return strdup(value->data.string); } else { return strdup(""); } case VAL_BOOLEAN: return strdup(value->data.boolean ? "true" : "false"); case VAL_TABLE: { char buffer[64]; size_t size = baba_yaga_table_size(value); snprintf(buffer, sizeof(buffer), "", size); return strdup(buffer); } case VAL_FUNCTION: { char buffer[64]; const char* name = function_get_name(value); snprintf(buffer, sizeof(buffer), "", name ? name : "anonymous"); return strdup(buffer); } case VAL_NIL: default: return strdup("nil"); } } /* ============================================================================ * Version Information * ============================================================================ */ const char* baba_yaga_get_version(void) { return "0.0.1"; }