/
NumMatrix2D.pmc~
71 lines (62 loc) · 2.32 KB
/
NumMatrix2D.pmc~
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
#define GET_INDICES_FROM_KEY(i, k, x, y) \
do { \
(x) = VTABLE_get_integer((i), (k)); \
(k) = VTABLE_shift_pmc((i), (k)); \
(y) = VTABLE_get_integer((i), (k)); \
} while(0);
#define ITEM_XY_ROWMAJOR(s, x_max, y_max, x, y) \
(s)[((x_max) * (x)) + (y)]
#define ITEM_XY_COLMAJOR(s, x_max, y_max, x, y) \
(s)[((y_max) * (y)) + (x)]
#define INDEX_MIN(a, b) (((a) <= (b))?(a):(b))
#define INDEX_MAX(a, b) (((a) >= (b))?(a):(b))
void
resize_matrix(PARROT_INTERP, PMC * self, INTVAL new_x, INTVAL new_y)
{
Parrot_NumMatrix2D_attributes * const attrs = PARROT_NUMMATRIX2D(self);
const INTVAL old_x = attrs->x;
const INTVAL old_y = attrs->y;
const INTVAL newsize = new_x * new_y;
FLOATVAL * new_s = (FLOATVAL *)calloc(newsize * sizeof (FLOATVAL));
FLOATVAL * old_s = attrs->storage;
const INTVAL min_x = INDEX_MIN(old_x, new_x);
const INTVAL min_y = INDEX_MIN(old_y, new_y);
INTVAL i, j;
for (i = 0; i < min_x; i++) {
for (j = 0; j < min_y; j++) {
ITEM_XY_ROWMAJOR(new_s, new_x, new_y, i, j) =
ITEM_XY_ROWMAJOR(old_s, old_x, old_y, i, j);
}
}
attrs->storage = new_s;
free(old_s);
}
pmclass NumMatrix2D auto_attrs {
ATTR FLOATVAL * storage;
ATTR INTVAL x;
ATTR INTVAL y;
VTABLE void init() {
/* The allocator should zero out the fields automatically */
}
VTABLE FLOATVAL get_number_keyed(PMC * key) {
INTVAL x, y, x_size, y_size;
Parrot_NumMatrix2D_Attributes * const attrs = PARROT_NUM_MATRIX
x_size = attrs->x;
y_size = attrs->y;
GET_INDICES_FROM_KEY(INTERP, key, x, y);
if (x >= x_size || y >= y_size)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"NumMatrix2d: indices out of bounds");
return ITEM_XY_ROWMAJOR(attrs->storage, x_size, y_size, x, y);
}
VTABLE void set_number_keyed(PMC * key, FLOATVAL value) {
INTVAL x, y, x_size, y_size;
Parrot_NumMatrix2D_Attributes * const attrs = PARROT_NUM_MATRIX
x_size = attrs->x;
y_size = attrs->y;
GET_INDICES_FROM_KEY(INTERP, key, x, y);
if (x >= x_size || y >= y_size)
resize_matrix(INTERP, SELF, x, y);
ITEM_XY_ROWMAJOR(attrs->storage, x_size, y_size, x, y) = value;
}
}