module expr;
import dots;
import operator;
import equation;
import var;
import var_expr;
import zz_const;
class Expr
{
public:
void opBinary(string op)(string s) const
{
static if (op == "+")
{
Expr right = null;
if (s == ".." || s == "..." || s == "....")
{
right = new Dots();
}
if (right !is null)
return new Op("+", [this, right]);
}
}
override string toString() const
{
assert(0);
}
Expr sub(Expr x, Expr y)
{
if (this == x)
return y;
return this;
}
Expr sub(Expr x, ref Var y)
{
return sub(x, new VarExpr(y));
}
Expr sub(ref Var x, Expr y)
{
return sub(new VarExpr(x), y);
}
Expr sub(int x, Expr y)
{
return sub(ZZ(x), y);
}
Expr sub(Expr x, int y)
{
return sub(x, ZZ(y));
}
Expr sub(ref Var x, ref Var y)
{
return sub(new VarExpr(x), new VarExpr(y));
}
Expr sub(ref Var x, int y)
{
return sub(new VarExpr(x), ZZ(y));
}
Expr sub(int x, ref Var y)
{
return sub(ZZ(x), new VarExpr(y));
}
override bool opEquals(Object o) {
return this is o;
}
}
See all the overloads I had to make to sub in order to bypass identity assignment for classes. I.e. Var can't be of type Expr. Anyway, this approach is not working because code calling Expr.sub(int, Var)
is not seeing the definitions. It says no function matching those args, but clearly there are!