about summary refs log tree commit diff stats
path: root/js/scripting-lang/baba-yaga-c/src/value.c
diff options
context:
space:
mode:
Diffstat (limited to 'js/scripting-lang/baba-yaga-c/src/value.c')
-rw-r--r--js/scripting-lang/baba-yaga-c/src/value.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/js/scripting-lang/baba-yaga-c/src/value.c b/js/scripting-lang/baba-yaga-c/src/value.c
new file mode 100644
index 0000000..562f3a7
--- /dev/null
+++ b/js/scripting-lang/baba-yaga-c/src/value.c
@@ -0,0 +1,215 @@
+/**
+ * @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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#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), "<table:%zu>", size);
+        return strdup(buffer);
+    }
+    case VAL_FUNCTION: {
+        char buffer[64];
+        const char* name = function_get_name(value);
+        snprintf(buffer, sizeof(buffer), "<function:%s>", 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";
+}