diff --git a/src/pmc/pmcmatrix2d.pmc b/src/pmc/pmcmatrix2d.pmc index 1f2f4a2..74e5d9d 100644 --- a/src/pmc/pmcmatrix2d.pmc +++ b/src/pmc/pmcmatrix2d.pmc @@ -55,6 +55,16 @@ pmclass PMCMatrix2D dynpmc auto_attrs provides matrix { return ITEM_XY_ROWMAJOR(attrs->storage, x_size, y_size, x, y); } + VTABLE PMC * get_pmc_keyed_int(INTVAL key) { + Parrot_PMCMatrix2D_attributes * const attrs = PARROT_PMCMATRIX2D(SELF); + const INTVAL total_size = attrs->x * attrs->y; + if (key >= total_size) { + Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS, + "PMCMatrix2D: Matrix dimensions must match in add."); + } + return attrs->storage[key]; + } + VTABLE INTVAL get_integer_keyed(PMC * key) { PMC * item = VTABLE_get_pmc_keyed(INTERP, SELF, key); return VTABLE_get_integer(INTERP, item); @@ -126,4 +136,26 @@ pmclass PMCMatrix2D dynpmc auto_attrs provides matrix { pstr = Parrot_str_append(INTERP, pstr, newline); return pstr; } + + METHOD initialize_from_array(INTVAL rows_size, INTVAL cols_size, PMC * values) { + Parrot_PMCMatrix2D_attributes * const attrs = PARROT_PMCMATRIX2D(SELF); + PMC ** s; + INTVAL self_rows, self_cols, i, j, num = 0; + const INTVAL init_elems = VTABLE_elements(interp, values); + + resize_matrix(interp, SELF, rows_size - 1, cols_size - 1); + self_rows = attrs->y; + self_cols = attrs->x; + s = attrs->storage; + + for (i = 0; i < cols_size; i++) { + for (j = 0; j < rows_size; j++) { + PMC * const value = VTABLE_get_pmc_keyed_int(interp, values, num); + num++; + ITEM_XY_ROWMAJOR(s, self_rows, self_cols, j, i) = value; + if (num >= init_elems) + return; + } + } + } }