1
0
Fork 0
forked from fun/fun

Added simple arrays.

This commit is contained in:
Johannes Findeisen 2025-09-15 01:36:20 +02:00
commit af16311ed5
8 changed files with 370 additions and 6 deletions

View file

@ -3,6 +3,12 @@
#include <string.h>
#include <stdio.h>
typedef struct Array {
int refcount;
int count;
Value *items; /* owns items; each item owned by array */
} Array;
Value make_int(int64_t v) {
Value val;
val.type = VAL_INT;
@ -31,6 +37,58 @@ Value make_nil(void) {
return v;
}
Value make_array_from_values(const Value *vals, int count) {
if (count < 0) count = 0;
Array *arr = (Array*)malloc(sizeof(Array));
if (!arr) {
Value nil = make_nil();
return nil;
}
arr->refcount = 1;
arr->count = count;
if (count > 0) {
arr->items = (Value*)malloc(sizeof(Value) * count);
if (!arr->items) {
free(arr);
Value nil = make_nil();
return nil;
}
for (int i = 0; i < count; ++i) {
arr->items[i] = copy_value(&vals[i]);
}
} else {
arr->items = NULL;
}
Value v;
v.type = VAL_ARRAY;
v.arr = (struct Array*)arr;
return v;
}
int array_length(const Value *v) {
if (!v || v->type != VAL_ARRAY || !v->arr) return -1;
const Array *a = (const Array*)v->arr;
return a->count;
}
int array_get_copy(const Value *v, int index, Value *out) {
if (!v || v->type != VAL_ARRAY || !v->arr) return 0;
const Array *a = (const Array*)v->arr;
if (index < 0 || index >= a->count) return 0;
if (out) *out = copy_value(&a->items[index]);
return 1;
}
int array_set(Value *v, int index, Value newElem) {
if (!v || v->type != VAL_ARRAY || !v->arr) return 0;
Array *a = (Array*)v->arr;
if (index < 0 || index >= a->count) return 0;
/* replace element: free old, take ownership of newElem */
free_value(a->items[index]);
a->items[index] = newElem;
return 1;
}
Value copy_value(const Value *v) {
Value out;
out.type = v->type;
@ -44,6 +102,12 @@ Value copy_value(const Value *v) {
case VAL_FUNCTION:
out.fn = v->fn; /* shallow copy pointer */
break;
case VAL_ARRAY: {
Array *a = (Array*)v->arr;
out.arr = (struct Array*)a;
if (a) a->refcount++;
break;
}
case VAL_NIL:
default:
break;
@ -54,6 +118,15 @@ Value copy_value(const Value *v) {
void free_value(Value v) {
if (v.type == VAL_STRING && v.s) {
free(v.s);
} else if (v.type == VAL_ARRAY && v.arr) {
Array *a = (Array*)v.arr;
if (--a->refcount == 0) {
for (int i = 0; i < a->count; ++i) {
free_value(a->items[i]);
}
free(a->items);
free(a);
}
}
/* VAL_FUNCTION: we *do not* free the Bytecode here (caller frees it) */
}
@ -69,6 +142,18 @@ void print_value(const Value *v) {
case VAL_FUNCTION:
printf("<function@%p>", (void*)v->fn);
break;
case VAL_ARRAY: {
const Array *a = (const Array*)v->arr;
printf("[");
if (a) {
for (int i = 0; i < a->count; ++i) {
if (i > 0) printf(", ");
print_value(&a->items[i]);
}
}
printf("]");
break;
}
case VAL_NIL:
default:
printf("nil");
@ -84,6 +169,10 @@ int value_is_truthy(const Value *v) {
return v->s && v->s[0] != '\0';
case VAL_FUNCTION:
return 1;
case VAL_ARRAY: {
const Array *a = (const Array*)v->arr;
return a && a->count > 0;
}
case VAL_NIL:
default:
return 0;
@ -106,6 +195,12 @@ char *value_to_string_alloc(const Value *v) {
snprintf(buf, sizeof(buf), "<function@%p>", (void*)v->fn);
return strdup(buf);
}
case VAL_ARRAY: {
int n = array_length(v);
if (n < 0) n = 0;
snprintf(buf, sizeof(buf), "[array n=%d]", n);
return strdup(buf);
}
case VAL_NIL:
default:
return strdup("nil");