|
When I run the test script for Math I get this:
Runtime error: Reduce of empty array with no initial value
I am using the web IDE, I compiled the Math.jack and Main.jack files, then copied the MathTest.tst file into the Test Script section of the VM emulator. I am using Google Chrome. Does anyone know what's going wrong?
Here are my files:
Main.jack:
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/12/MathTest/Main.jack
// Tests the OS Math class.
class Main {
// Performs various mathematical operations, using calls to the Math class methods.
function void main() {
var Array r; // Stores the test results;
let r = 8000; // Base address
let r[0] = 2 * 3; // 6
let r[1] = r[0] * (-30); // 6 * (-30) = -180
let r[2] = r[1] * 100; // (-180) * 100 = -18000
let r[3] = 1 * r[2]; // 1 * (-18000) = -18000
let r[4] = r[3] * 0; // 0
let r[5] = 9 / 3; // 3
let r[6] = (-18000) / 6; // -3000
let r[7] = 32766 / (-32767); // (2^15 - 2) / (2^15 - 1) = 0
let r[8] = Math.sqrt(9); // 3
let r[9] = Math.sqrt(32767); // 181
let r[10] = Math.min(345, 123); // 123
let r[11] = Math.max(123, -345); // 123
let r[12] = Math.abs(27); // 27
let r[13] = Math.abs(-32767); // 32767
return;
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------
Math.jack:
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/12/Math.jack
/**
* A library of commonly used mathematical functions.
* All functions runs in O(n), where n is the number of bits used
* for representing a two's complement integer value (16 in the Hack computer).
* Note: Jack compilers implement multiplication and division
* using calls to OS functions in this class.
*/
class Math {
static int n; // Number of bits used for representing a two's complement integer
static Array powersOfTwo; // Stores 2^0, 2^1, 2^2,..., 2^(n-1)
// Initializes the Math library.
function void init() {
var int exponent, twoToTheExponent;
let powersOfTwo = Array.new(16);
let n = 16;
let exponent = 0;
let twoToTheExponent = 1;
while (exponent < n) {
let powersOfTwo[exponent] = twoToTheExponent;
let twoToTheExponent = twoToTheExponent + twoToTheExponent;
let exponent = exponent + 1;
}
return;
}
/** Returns the product of x and y.
* When a Jack compiler detects the multiplication operator '*'
* in an expression, it handles it by invoking this method.
* Thus, in Jack, x * y and Math.multiply(x,y) return the same value. */
function int multiply(int x, int y) {
var int result, xShifted, i;
let result = 0;
while (i < n) {
if (~((y & powersOfTwo[i]) = 0)) { // if the i'th bit of y is 1
let result = result + xShifted;
}
let xShifted = xShifted + xShifted;
let i = i + 1;
}
return result;
}
/** Returns the integer part of x / y.
* When a Jack compiler detects the division operator '/'
* an an expression, it handles it by invoking this method.
* Thus, x/y and Math.divide(x,y) return the same value. */
function int divide(int x, int y) {
var int result, resultIsPositive, remainder, powerOfTwo, xByPowerOfTwo, i;
let resultIsPositive = ((x > 0) = (y > 0));
let x = Math.abs(x);
let y = Math.abs(y);
let result = 0;
let remainder = x;
let i = n - 1;
while (i > 0) {
let powerOfTwo = powersOfTwo[i];
let xByPowerOfTwo = x * powerOfTwo;
if (~(xByPowerOfTwo > remainder)) { // if x * 2^i <= remainder
let result = result + powerOfTwo;
let remainder = remainder - xByPowerOfTwo;
}
let i = i - 1;
}
if (resultIsPositive) {
return result;
}
else {
return -result;
}
}
/** Returns the integer part of the square root of x. */
function int sqrt(int x) {
var int result, powerOfTwo, resultPlusPowerOfTwo, i;
let result = 0;
let i = n/2 - 1;
while (i > 0) {
let powerOfTwo = powersOfTwo[i];
let resultPlusPowerOfTwo = result + powerOfTwo;
if (~(resultPlusPowerOfTwo * resultPlusPowerOfTwo > x)) {
let result = resultPlusPowerOfTwo;
}
let i = i - 1;
}
return result;
}
/** Returns the greater value. */
function int max(int a, int b) {
if (a > b) {
return a;
}
else {
return b;
}
}
/** Returns the smaller value. */
function int min(int a, int b) {
if (a < b) {
return a;
}
else {
return b;
}
}
/** Returns the absolute value of x. */
function int abs(int x) {
if (x > 0) {
return x;
}
else {
return -x;
}
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------
MathTest.tst:
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/12/MathTest/MathTest.tst
load,
output-file MathTest.out,
compare-to MathTest.cmp,
output-list RAM[8000]%D2.6.1 RAM[8001]%D2.6.1 RAM[8002]%D2.6.1 RAM[8003]%D2.6.1 RAM[8004]%D2.6.1 RAM[8005]%D2.6.1 RAM[8006]%D2.6.1 RAM[8007]%D2.6.1 RAM[8008]%D2.6.1 RAM[8009]%D2.6.1 RAM[8010]%D2.6.1 RAM[8011]%D2.6.1 RAM[8012]%D2.6.1 RAM[8013]%D2.6.1;
repeat 1000000 {
vmstep;
}
output;
-------------------------------------------------------------------------------------------------------------------------------------------------------
MathTest.cmp:
|RAM[8000]|RAM[8001]|RAM[8002]|RAM[8003]|RAM[8004]|RAM[8005]|RAM[8006]|RAM[8007]|RAM[8008]|RAM[8009]|RAM[8010]|RAM[8011]|RAM[8012]|RAM[8013]|
| 6 | -180 | -18000 | -18000 | 0 | 3 | -3000 | 0 | 3 | 181 | 123 | 123 | 27 | 32767 |
|