Hi,

I have the following code:

interface Visitable(RETURN) {
        RETURN accept(Visitor!RETURN);
}

interface Exp :  Visitable!string,  Visitable!int {

}

interface Visitor(RETURN) {
        RETURN visitLit(Lit e);
        RETURN visitAdd(Add e);
}

class Lit : Exp {
        int val;
        this(int val) {
                this.val = val;
        }
        override int accept(Visitor!int v) {
                return v.visitLit(this);
        }
        override string accept(Visitor!string v) {
                return v.visitLit(this);
        }
}
class Add : Exp {
        Exp lhs, rhs;
        this(Exp lhs, Exp rhs) {
                this.lhs = lhs;
                this.rhs = rhs;
        }
        override int accept(Visitor!int v) {
                return v.visitAdd(this);
        }
        override string accept(Visitor!string v) {
                return v.visitAdd(this);
        }
}

class Eval : Visitor!int {
        override int visitLit(Lit e) {
                return e.val;
        }
        override int visitAdd(Add e) {
                return e.lhs.accept(this) + e.rhs.accept(this);
        }
}

class Print : Visitor!string {
        override string visitLit(Lit e) {
                return to!string(e.val);
        }
        override string visitAdd(Add e) {
return "(" ~ e.lhs.accept(this) ~ " + " ~ e.rhs.accept(this) ~ ")";
        }
}

unittest {
        auto val = new Add(new Lit(1), new Lit(6)).accept(new Eval());
        assert(val == 7);
        auto s = new Add(new Lit(1), new Lit(6)).accept(new Print());
        assert(s == "(1 + 6)");
}

Which is a dummy AST. It's an example of a visitor pattern. The compiler gives the following error for this code:

Error: function Visitable!string.Visitable.accept (Visitor!string) is not callable using argument types (Eval) Error: function Visitable!string.Visitable.accept (Visitor!string) is not callable using argument types (Eval)

in Eval.visitAdd.

When i swap the order of implemented interfaces in Exp, there's a symmetrical error in Print.visitAdd with Visitor!int.

To me this suggests that the dispatch by templated interface type Visitor!(RETURN) doesn't work. IMO the order of interfaces shouldn't matter here and the code should simply work.

Any ideas?

Reply via email to