<!DOCTYPE html>
<html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>evaluation order and times.</title>
<script src="js/test-harness.js"></script>
<script src="../js/webgpu-functions.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
const whlslTests = {};

whlslTests.dontEvaluateTwice = async () => {
    const program = `
        uint bar(thread uint* ptr) {
            uint old = *ptr;
            *ptr = *ptr + 1;
            return old;
        }

        bool foo() {
            uint x = 0;
            int[42] arr;
            arr[0] = 42;

            int result = arr[bar(&x)];
            return result == 42 && x == 1;
        }
    `;

    assert_equals(await callBoolFunction(program,  "foo", []), true);
};

whlslTests.dontEvaluateTwice2 = async () => {
    const program = `
        uint bar(thread uint[] arr, uint index, thread uint* ptr) {
            uint old = *ptr;
            arr[index] = old;
            *ptr = *ptr + 1;
            return 0;
        }

        bool foo() {
            uint x = 1;

            uint[3] indices;

            uint[4][4][4] arr;

            arr[bar(@indices, 0, &x)][bar(@indices, 1, &x)][bar(@indices, 2, &x)] = 42;
            return arr[0][0][0] == 42
                && indices[0] == 1 
                && indices[1] == 2 
                && indices[2] == 3
                && x == 4;
        }
    `;

    assert_equals(await callBoolFunction(program,  "foo", []), true);
};

whlslTests.dontEvaluateTwice3 = async () => {
    const program = `
        uint[2][2] base(thread uint[] arr, uint index, thread uint* ptr) {
            uint old = *ptr;
            arr[index] = old;
            *ptr = *ptr + 1;
            uint[2][2] result;
            result[0][0] = 42;
            return result;
        }

        uint bar(thread uint[] arr, uint index, thread uint* ptr) {
            uint old = *ptr;
            arr[index] = old;
            *ptr = *ptr + 1;
            return 0;
        }

        bool foo() {
            uint x = 1;

            uint[3] indices;

            uint result = base(@indices, 0, &x)[bar(@indices, 1, &x)][bar(@indices, 2, &x)];

            return result == 42
                && indices[0] == 1
                && indices[1] == 2 
                && indices[2] == 3
                && x == 4;
        }
    `;

    assert_equals(await callBoolFunction(program,  "foo", []), true);
};

whlslTests.dontEvaluateTwice4 = async () => {
    const program = `
        uint bar(thread uint* ptr) {
            uint old = *ptr;
            *ptr = *ptr + 1;
            return old;
        }

        bool foo() {
            uint[2] arr;

            uint x = 1;

            arr[bar(&x)] += 666;

            return arr[1] == 666 && x == 2;
        }
    `;

    assert_equals(await callBoolFunction(program,  "foo", []), true);
};

whlslTests.dontEvaluateTwice5 = async () => {
    const program = `
        thread uint* getPtr(thread uint* ptr) {
            *ptr = *ptr + 1;
            return ptr;
        }

        bool foo() {
            uint x = 1;
            uint result = (*getPtr(&x))++;
            return x == 3 && result == 2;
        }
    `;

    assert_equals(await callBoolFunction(program,  "foo", []), true);
};

whlslTests.dontEvaluateTwice6 = async () => {
    const program = `
        thread uint* getPtr(thread uint* ptr) {
            *ptr = *ptr + 1;
            return ptr;
        }

        bool foo() {
            uint x = 1;
            uint result = ++(*getPtr(&x));
            return x == 3 && result == 3;
        }
    `;

    assert_equals(await callBoolFunction(program,  "foo", []), true);
};

whlslTests.dontEvaluateTwice7 = async () => {
    const program = `
        thread uint[] getArr(thread uint[] value, thread uint[] indices, uint index, thread uint* ptr) {
            indices[index] = *ptr;
            *ptr = *ptr + 1;
            return value;
        }

        uint getValue(uint ret, thread uint[] indices, uint index, thread uint* ptr) {
            indices[index] = *ptr;
            *ptr = *ptr + 1;
            return ret;
        }

        bool foo() {
            uint x = 1;
            uint[3] arr;
            uint[1] value;
            value[0] = 1;

            getArr(@value, @arr, 0, &x)[getValue(0, @arr, 1, &x)] += getValue(665, @arr, 2, &x);
            return x == 4
                && arr[0] == 1
                && arr[1] == 2
                && arr[2] == 3
                && value[0] == 666;
        }
    `;

    assert_equals(await callBoolFunction(program,  "foo", []), true);
};

whlslTests.dontEvaluateTwice8 = async () => {
    const program = `
        uint getValue(uint ret, thread uint[] indices, uint index, thread uint* ptr) {
            indices[index] = *ptr;
            *ptr = *ptr + 1;
            return ret;
        }

        thread uint[] getArr(thread uint[] value, thread uint[] indices, uint index, thread uint* ptr) {
            indices[index] = *ptr;
            *ptr = *ptr + 1;
            return value;
        }

        bool foo() {
            uint x = 1;
            uint[3] arr;
            uint[1] value;
            value[0] = 1;

            getArr(@value, @arr, 0, &x)[arr[getValue(0, @arr, 1, &x)]] += getValue(665, @arr, 2, &x);

            return x == 4
                && arr[0] == 1
                && arr[1] == 2
                && arr[2] == 3
                && value[0] == 666;
        }
    `;

    assert_equals(await callBoolFunction(program,  "foo", []), true);
};

whlslTests.dontEvaluateTwice9 = async () => {
    const program = `
        thread uint[1]* getValue(thread uint[1]* arr, thread uint[] indices, uint index, thread uint* ptr) {
            indices[index] = *ptr;
            *ptr = *ptr + 1;
            return arr;
        }

        bool foo() {
            uint x = 1;
            uint[1] arr;
            uint[1] value;
            value[0] = 1;

            (*getValue(&value, @arr, 0, &x))[0] += 665;

            return x == 2
                && arr[0] == 1
                && value[0] == 666;
        }
    `;

    assert_equals(await callBoolFunction(program,  "foo", []), true);
};

runTests(whlslTests);
</script>
</html>
