// // array // Bytecode set support for arrays // F.J. Alberti // case kNewarray: { // Pushes reference to fresh array of the specified size, // initialised to given value int size = m->top[m->pp+1]; // array size if (size == NIL) { #if defined(SCOL_DEBUG) checkUnderflow(m) #endif m->top[++m->pp] = NIL; break; } size >>= 1; if (size < 0) throw Exception(MERRTYP, "(!) "MSGEILLARRAYSIZE"\n", size); int s = MMmalloc(m, size, TYPETAB); if (s == NIL) throw Exception(MERRMEM); // Initialise array with passed initial value #if defined(SCOL_DEBUG) checkUnderflow(m) #endif int init = m->top[m->pp++]; // initial value for (int i = 0; i < size; i++) m->tape[s+SizeHeader+i] = init; m->top[m->pp] = s<<1|0x00000001; break; } case kArraysize: { // Push array size int a = m->top[m->pp]; // array if (a == NIL) break; // Least-significant bit contains a 1 (the type of a tuple) m->top[m->pp] = m->tape[a>>1]&0xfffffffe; break; } case kArrayget: { // Get the element of the given array at the specified index #if defined(SCOL_DEBUG) checkUnderflow(m) #endif int i = m->top[m->pp++]; // index int p = m->top[m->pp]; // array if (i == NIL || p == NIL) { m->top[m->pp] = NIL; break; } m->top[m->pp] = m->tape[(p>>1)+SizeHeader+(i>>1)]; break; } case kArrayset: { // Set the element of the given array at the specified index // with the value at the top of the stack #if defined(SCOL_DEBUG) checkUnderflow(m) #endif int val = m->top[m->pp++]; // value #if defined(SCOL_DEBUG) checkUnderflow(m) #endif int i = m->top[m->pp++]; // index int p = m->top[m->pp]; // array if (i == NIL || p == NIL) { m->top[m->pp] = NIL; break; } m->tape[(p>>1)+SizeHeader+(i>>1)] = m->top[m->pp] = val; break; } case kArraycheck: { // Check if index is within the bounds of the given array. // Throw an exception if it's not the case int i = m->top[m->pp]; // index int p = m->top[m->pp+1]; // array if (i == NIL || p == NIL) break; i >>= 1; int size = (m->tape[p>>1]&0xfffffffe)>>1; if (i < 0 || i >= size) throw Exception(MERRTYP, "(!) "MSGEILLARRAYINDEX"\n", i, size); break; }