/* Test overloaded operators + and - */
using namespace oadl;

class complex {
    public var real, imag;
    public proc create(r, i) {
        real = r;
        imag = (oadl::nargs() > 1) ? i : 0;
    }
    operator + (rhs) {
        var result;
        if (rhs.parent == complex) {
            result = new complex(real + rhs.real, imag + rhs.imag);
        }
        else {
            result = new complex(real + rhs, imag);
        }
        return result;
    }
    operator \+ (lhs) {
        // Note that, by definition, the lhs is NOT a complex,
        // since it did not have a + operator
        var result;
        result = new complex(lhs + real, imag);
        return result;
    }
    operator - (rhs) {
        var result;
        if (rhs.parent == complex) {
            result = new complex(real - rhs.real, imag - rhs.imag);
        }
        else {
            result = new complex(real - rhs, imag);
        }
        return result;
    }
    operator \- (lhs) {
        var result;
        result = new complex(lhs - real, -imag);
        return result;
    }
    operator !- () {
        var result;
        result = new complex(-real, -imag);
        return result;
    }
    operator => (rhs) {
        if (rhs == String) {
            // Convert to a string representation
            return "{" ## (real => String) ## "," ## (imag => String) ## "}";
        }
        else if (oadl::is_a(rhs, Array[*])) {
            // Convert to an array
            return [real, imag] => rhs;
        }
        else {
            // Probably a scalar; just return the real part
            return real => rhs;
        }
    }
    operator \=> (lhs) {
        return new complex(lhs, 0.);
    }
}

proc main()
{
    var a = complex(1,2);
    var b = complex(3,4);
    "a = ", String(a), '\n';
    "b = ", String(b), '\n';
    var c;
    c = a + b;
    "a + b = ", String(c), '\n';
    c = a - b;
    "a - b = ", String(c), '\n';
    c = -a;
    "-a = ", String(c), '\n';
    c = 3 + b;
    "3 + b = ", String(c), '\n';
    c = 3 - b;
    "3 - b = ", String(c), '\n';
    var d : Float;
    d = c;
    "Float(3 - b) = ", d, '\n';
    var e : PackFloat;
    e = c;
    "PackFloat(3 - b) = ", e, '\n';
    c = 3.0 => complex;
    "3.0 => complex = ", String(c), '\n';
    c = complex(4.0);
    "complex(4.0) = ", String(c), '\n';
}