Added simple arrays.
This commit is contained in:
parent
0b6cab8672
commit
af16311ed5
8 changed files with 370 additions and 6 deletions
95
src/value.c
95
src/value.c
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue