svoid test_TypeSystem() { GOperator iround = new GOperator("iround").arg(double.class).returns(int.class); GOperator plus_int = new GOperator("plus_int").arg(int.class).arg(int.class).returns(int.class); GOperator plus_dbl = new GOperator("plus_dbl").arg(double.class).arg(double.class).returns(double.class); print(iround); print(plus_int); print(plus_dbl); GPolymorphicOperator plus = new("+", plus_int, plus_dbl); print(plus.toStringWithDefinitions()); new TypeSystem ts; assertTrueVerbose(ts.operatorCanTakeArguments(plus_dbl, double.class, double.class)); assertFalseVerbose(ts.operatorCanTakeArguments(plus_dbl, double.class, int.class)); assertFalseVerbose(ts.operatorCanTakeArguments(plus_dbl, int.class, double.class)); assertFalseVerbose(ts.operatorCanTakeArguments(plus_dbl, double.class)); assertFalseVerbose(ts.operatorCanTakeArguments(plus_dbl, double.class, double.class, double.class)); assertEqualsVerbose(ll(plus_int), ts.resolve(plus, int.class, int.class)); assertEqualsVerbose(ll(plus_dbl), ts.resolve(plus, double.class, double.class)); // can't resolve because we haven't defined any subtype relations so int and double are incompatible assertEqualsVerbose(ll(), ts.resolve(plus, int.class, double.class)); // Now let's test subtypes. Let's say an int is convertible to a double. ts.isActualSupertypeOf = (a, b) -> a == double.class && b == int.class; assertTrueVerbose(ts.operatorCanTakeArguments(plus_int, int.class, int.class)); assertFalseVerbose(ts.operatorCanTakeArguments(plus_int, double.class, int.class)); assertTrueVerbose(ts.operatorCanTakeArguments(plus_dbl, int.class, int.class)); assertTrueVerbose(ts.operatorCanTakeArguments(plus_dbl, double.class, int.class)); }