next up previous
Next: 2. Object-Oriented Data Structures Up: 1.12 The Visitor Pattern Previous: 1.12.2 Openness in Data

1.12.3 Visitors with Arguments

We have not yet discussed how to use visitors to implement methods that take arguments in addition to the receiver (visitor host). We can illustrate this use of visitors by extending our previous example to include variables in the type ArithExpr. To accommodate variables, our composite hierarchy must include an additional concrete variant:

class Var extends ArithExpr {
  String name;
  Var(String n) {
    name = n;
  }
  public String toString() {
    return name;
  }
  int apply(Visitor v) {
    return v.forVar(this);
  }
}
Then the visitor interface for ArithExprs with variables has the form:

interface Visitor {
  int forConst(Const c);
  int forSum(Sum c);
  int forNeg(Neg n);
  int forVar(Var v);
}

The concrete visitor class that implements expression evaluation is:

class EvalVisitor implements Visitor {
  Env env;  // an environment for looking up variables
  EvalVisitor(Env e) { env = e; }
  public int forConst(Const c) { return c.getValue(); }
  public int forSum(Sum s) {
    return (s.getLeft().apply(this)).getValue()) +
           (s.getRight().apply(this)).getValue());
  }
  public int forNeg(Neg n) {
    return -(p.getArg());
  }
  int forVar(Var v) { return env.lookup(v.name); }
}
The environment env, which was an explicit parameter of the eval method in our method-based implementation for evaluation, is now a field of the visitor. As before, it is directly used only for evaluating instances of Var, but now we don't need to explicitly pass the environment through method argument lists.

Since we are programming in a functional style, the forConst method only needs to return its argument as the result, rather than allocating a copy. The forSum and forNeg methods are straightforward, evaluating their subexpressions first and applying the appropriate arithmetic operation to the results.

The forVar method looks up the value of the variable in the current environment. The environment is passed in when an EvalVisitor is created, and is presumably given bindings for the existing variables beforehand.


Finger Exercise Finish the visitor-based implementation of expression evaluation, including the definition of the Environment class, by yourself. Can you think of other operations on expressions that the visitor pattern might helper you implement?


next up previous
Next: 2. Object-Oriented Data Structures Up: 1.12 The Visitor Pattern Previous: 1.12.2 Openness in Data
Corky Cartwright
2001-08-02