## Implementing VCODE vector operations in Java

VCODE provides over 130 vector operations. These operations typically have a direct mapping to functions provided by CVL. The VCODE interpreter runs a function-dispatch loop to execute programs: fetch the next VCODE operation, decode it, pop the appropriate number of arguments from the vector stack, call the matching CVL function, and push the result(s) back onto the stack.For portability reasons we cannot rely on a machine-specific library such as CVL; all of the vector operations must be implemented as Java methods. However, the task of writing the methods is simplified because most of them fall into one of three major groups, with the code for operations in each group being very similar.

The vector methods are contained in the

VcodeEmulationclass; this also holds the stack where array references are stored. Intuitively, this class implements an abstract vector stack object and its associated vector operations. Just like their VCODE equivalents, the Java vector methods operate on the stack itself, popping their arguments and pushing their results. Figure 3 shows a Java method for the VCODE operation+ INT, which adds together two integer vectors.

void AddI () { int[] a = (int []) pop(); // pop the argument array int[] b = (int []) pop(); int[] dst = new int[a.length]; // create a result array for (int i = 0; i < a.length; i++) { // loop over the elements... dst[i] = a[i] + b[i]; // ...adding them together } push(dst); // push the result onto the stack }Figure 3:Java method to implement the VCODE operation+ INT, which adds two integer vectors.Note that this code assumes that the two argument arrays

aandbhave the same length. The+ INToperation makes the same assumption, but the VCODE interpreter can also check for vector length mismatches at runtime. In the VCODE-to-Java system, Java throws an exception if a runtime length mismatch causes the shorter array bound to be over-stepped. For full protection, we could extend the method to throw an exception immediately if the two lengths are not equal.VCODE implements NESL's nesting of data structures efficiently by using

segmented vectors[2]. Segmented vectors use two kinds of vectors to represent arbitrary sequence nesting: a normal non-nested vector to hold the data, and a series of specialized vectors (calledsegment descriptors) to describe how the data is subdivided. Many VCODE operations are defined only for segmented vectors, and require their arguments to have segment descriptors. We chose to represent a segment descriptor in Java as an array of integers holding the individual segment lengths. As a consequence, the Java implementation of a segmented operation is only slightly more complex than that of its unsegmented counterpart, with two nested loops iterating over the segments and the elements within each segment. Figure 4 shows a Java method for the VCODE operation+_REDUCE FLOAT, a segmented add-reduce (sum) that takes as arguments a segment descriptor and a floating-point data vector. The result is a vector of the sums of each of the segments.

final void AddReduceF () { int[] segd = (int []) pop (); // pop the segment descriptor double[] src = (double []) pop (); // and the source array double[] dst = new double[segd.length]; // create a result array int k = 0; for (int i = 0; i < segd.length; i++) { // loop over the segments... double sum = 0.0; // ...initializing a sum of for (int j = 0; j < segd[i]; j++) // ...all values in a segment sum += src[k++]; dst[i] = sum; // ...and storing the sum } push (dst); // push the result }Figure 4:Java method to implement the segmented VCODE operation+_REDUCE FLOAT, which sums the individual segments within a floating-point vector.