#include "shed/arrays.h" #include "shed/gc.h" #include "shed/ints.h" #include "./Lists.h" struct ShedArrayBuilder { struct ShedGcObjectHeader object_header; // TODO: in principle, this should really be a PatioInt since the GC should // assumes everything is stored in a Patio int. In practice, pointers in // C are the same size as PatioInt, and indeed the GC assumes this is the // case (at the time of writing at least), so this should also work. struct ShedArray* array; PatioInt capacity; PatioInt size; bool is_owner; }; // TODO: move other array code into `shed/arrays`? static struct ShedArray* array_copy(struct ShedArray* source, PatioInt size, PatioInt capacity) { struct ShedArray* array = shed__runtime__gc_alloc( sizeof(struct ShedArray) + sizeof(ShedObject) * capacity, 1 ); array->size = size; for (PatioInt element_index = 0; element_index < size; element_index++) { array->elements[element_index] = source->elements[element_index]; } return array; } ShedObject shed__runtime__namespace__Std__Lists__arrayBuilder(ShedClosurePointer closurePointer, ShedObject capacityObject) { PatioInt capacity = shed__runtime__int_value(capacityObject); struct ShedArray* array = shed__runtime__gc_alloc( sizeof(struct ShedArray) + sizeof(ShedObject) * capacity, 1 ); array->size = 0; struct ShedArrayBuilder* array_builder = shed__runtime__gc_alloc(sizeof(struct ShedArrayBuilder), 2); array_builder->array = array; array_builder->capacity = capacity; array_builder->size = 0; array_builder->is_owner = true; return (ShedObject) array_builder; } ShedObject shed__runtime__namespace__Std__Lists__method__Array__unsafeGet(ShedClosurePointer closurePointer, ShedObject arg0, ShedObject arg1) { struct ShedArray* array = (struct ShedArray*) arg0; PatioInt index = shed__runtime__int_value(arg1); return array->elements[index]; } ShedObject shed__runtime__namespace__Std__Lists__method__Array__size(ShedClosurePointer closurePointer, ShedObject arg0) { struct ShedArray* array = (struct ShedArray*) arg0; return shed__runtime__int_create(array->size); } ShedObject shed__runtime__namespace__Std__Lists__method__ArrayBuilder__capacity(ShedClosurePointer closurePointer, ShedObject arg0) { struct ShedArrayBuilder* array_builder = (struct ShedArrayBuilder*) arg0; return shed__runtime__int_create(array_builder->capacity); } ShedObject shed__runtime__namespace__Std__Lists__method__ArrayBuilder__size(ShedClosurePointer closurePointer, ShedObject arg0) { struct ShedArrayBuilder* array_builder = (struct ShedArrayBuilder*) arg0; return shed__runtime__int_create(array_builder->size); } ShedObject shed__runtime__namespace__Std__Lists__method__ArrayBuilder__unsafeAdd(ShedClosurePointer closurePointer, ShedObject arg0, ShedObject arg1) { struct ShedArrayBuilder* array_builder = (struct ShedArrayBuilder*) arg0; struct ShedArray* array; if (array_builder->is_owner) { array_builder->is_owner = false; array = array_builder->array; } else { array = array_copy( array_builder->array, array_builder->size, array_builder->capacity ); } array->elements[array_builder->size] = arg1; struct ShedArrayBuilder* new_array_builder = shed__runtime__gc_alloc(sizeof(struct ShedArrayBuilder), 2); new_array_builder->array = array; new_array_builder->capacity = array_builder->capacity; new_array_builder->size = array_builder->size + 1; new_array_builder->is_owner = true; return (ShedObject) new_array_builder; } ShedObject shed__runtime__namespace__Std__Lists__method__ArrayBuilder__unsafeEnlarge(ShedClosurePointer closurePointer, ShedObject arg0, ShedObject capacity) { // TODO: implement return arg0; } ShedObject shed__runtime__namespace__Std__Lists__method__ArrayBuilder__build(ShedClosurePointer closurePointer, ShedObject arg0) { struct ShedArrayBuilder* array_builder = (struct ShedArrayBuilder*) arg0; if (array_builder->is_owner) { array_builder->is_owner = false; array_builder->array->size = array_builder->size; return (ShedObject) array_builder->array; } else { struct ShedArray* array = array_copy( array_builder->array, array_builder->size, array_builder->size ); return (ShedObject) array; } }