01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package composite.one;
public interface Expr {
  int eval();
}

final class Const implements Expr {
  private final int v;
  public Const(int v) {
    this.v = v;
  }
  public int eval() {
    return v;
  }
  public String toString() {
    return Integer.toString(v);
  }
}

final class Plus implements Expr {
  private final Expr l;
  private final Expr r;
  public Plus(Expr l, Expr r) {
    if ((l == null) || (r == null)) {
      throw new IllegalArgumentException();
    }
    this.l = l;
    this.r = r;
  }
  public int eval() {
    return l.eval() + r.eval();
  }
  public String toString() {
    return l.toString() + " " + r.toString() + " +";
  }
}

final class Minus implements Expr {
  private final Expr l;
  private final Expr r;
  public Minus(Expr l, Expr r) {
    if ((l == null) || (r == null)) {
      throw new IllegalArgumentException();
    }
    this.l = l;
    this.r = r;
  }
  public int eval() {
    return l.eval() - r.eval();
  }
  public String toString() {
    return l.toString() + " " + r.toString() + " -";
  }
}

final class Mult implements Expr {
  private final Expr l;
  private final Expr r;
  public Mult(Expr l, Expr r) {
    if ((l == null) || (r == null)) {
      throw new IllegalArgumentException();
    }
    this.l = l;
    this.r = r;
  }
  public int eval() {
    return l.eval() * r.eval();
  }
  public String toString() {
    return l.toString() + " " + r.toString() + " *";
  }
}

final class Quot implements Expr {
  private final Expr l;
  private final Expr r;
  public Quot(Expr l, Expr r) {
    if ((l == null) || (r == null)) {
      throw new IllegalArgumentException();
    }
    this.l = l;
    this.r = r;
  }
  public int eval() {
    return l.eval() / r.eval();
  }
  public String toString() {
    return l.toString() + " " + r.toString() + " /";
  }
}