* calls cache(...) on it and returns it.
* @return let t = lookup(intExpr) | some t => t,
* cache(intExpr, intExpr.left.accept(this) intExpr.op intExpr.right.accept(this))
*/
public final Int visit(NaryIntExpression intExpr) {
Int ret = lookup(intExpr);
if (ret!=null) return ret;
final Int first = intExpr.child(0).accept(this);
final Int[] rest = new Int[intExpr.size()-1];
for(int i = 0; i < rest.length; i++) { rest[i] = intExpr.child(i+1).accept(this); }
switch(intExpr.op()) {
case PLUS : ret = first.plus(rest); break;
case MULTIPLY : ret = first.multiply(rest); break;
case AND : ret = first.and(rest); break;
case OR : ret = first.or(rest); break;
default :
throw new IllegalArgumentException("Unknown nary operator: " + intExpr.op());
}
return cache(intExpr, ret);
}