1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#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;
}
}
|