#!/usr/bin/ruby

#
## Type comparisons
#

func dump(arg) {
    try{
        arg.dump
    }
    catch{
        'nil'
    }
}

func ne(a, b, c) {
    if ((a != b) == c) {
        say "NE: (#{dump(a)} != #{dump(b)}) == #{dump(c)}";
    } else {
        die "error: (#{dump(a)} != #{dump(b)}) != #{dump(c)}";
    }
}

func is(a, b, c) {
    if ((a == b) == c) {
        say "EQ: (#{dump(a)} == #{dump(b)}) == #{dump(c)}";
    } else {
        die "error: (#{dump(a)} == #{dump(b)}) != #{dump(c)}";
    }
}

# string-nil
is("", nil, false);
ne("", nil, true);

# nil-string
is(nil, "", false);
ne(nil, "", true);

# string-number
is("", 0, false);
is(0, "", false);

ne("", 0, true);
ne(0, "", true);

is("4", 4, false);
is(4, "4", false);

is("-1", -1, false);
is(-1, "-1", false);

is("2", 1, false);
is(1, "2", false);

ne("4", 4, true);
ne(4, "4", true);

ne("2", 1, true);
ne(1, "2", true);

# array-string
is([], "", false);
ne([], "", true);

# string-array
is("", [], false);
ne("", [], true);

# array-array
is([], [], true);
is([], [1], false);
is([1], [], false);
is([1],[1], true);

ne([], [], false);
ne([], [1], true);
ne([1], [], true);
ne([1], [1], false);

# hash-string
is(:(), "", false);
is("", :(), false);

ne(:(), "", true);
ne("", :(), true);

# hash-array
is(:(), [], false);
ne(:(), [], true);

# hash-hash
is(:(), :(), true);
is(:(a=>1), :(), false);
is(:(a=>1), :(a=>1), true);

ne(:(), :(), false);
ne(:(a=>1), :(), true);
ne(:(a=>1), :(a=>1), false);

# hash-block
is(:(), {}, false);
ne(:(), {}, true);

# block-hash
is({}, :(), false);
ne({}, :(), true);

# file-string
is(%f"f.txt", "f.txt", true);
is("f.txt", %f"f.txt", true);

ne(%f"a.txt", "a.txt", false);
ne("a.txt", %f"a.txt", false);

# dir-file
is(%f"a", %d"a", true);
is(%d"a", %f"a", true);

# dir-string
is(%d"a", "a", true);
is("a", %d"a", true);

ne(%d"a", "a", false);
ne("a", %d"a", false);

# dir-block
is(%d"a", {}, false);
is({}, %d"a", false);

# file-hash
is(%f"a", :(), false);
is(:(), %f"a", false);

# array-block
is([], {}, false);
is({}, [], false);

ne([], {}, true);
ne({}, [], true);

# chars-array
is(%c"ab", ['a','b'], true);
is(['a','b'], %c"ab", true);

is(%c"ab", ['a','c'], false);
is(['a','c'], %c"ab", false);

# nested arrays
is([[1]], [[1]], true);
is([[2]], [[1]], false);

is([[""]], [[0]], false);
is([[0]], [[""]], false);

is([[]], [[]], true);
is([[]], [], false);
is([], [[]], false);

is([], [nil], false);
is([nil], [], false);
is([[]], [nil], false);
is([nil], [[]], false);

is([:()], [:()], true);
is([[]], [:()], false);
is([:()], [[]], false);

# nil-string
is("", nil, false);
is(nil, "", false);

ne("", nil, true);
ne(nil, "", true);

# nil-numbers
is(0, nil, false);
is(nil, 0, false);

# nil-array
is(nil, [], false);
is([], nil, false);

# nil-hash
is(nil, :(), false);
is(:(), nil, false);

# nil-nil
is(nil, nil, true);
ne(nil, nil, false);

# nil-block
is(nil, {}, false);
is({}, nil, false);